Не удается загрузить большой JPEG в текстуру MTL с MTKTextureLoader - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь загрузить большое изображение в текстуру MTL, и она работает с изображениями 4000x6000.Но когда я пытаюсь с 6000x8000, это не может.

func setTexture (устройство: MTLDevice, imageName: String) -> MTLTexture?{let textureLoader = MTKTextureLoader (device: device)

    var texture: MTLTexture? = nil

    //  In iOS 10 the origin was changed.
    let textureLoaderOptions: [MTKTextureLoader.Option: Any]
    if #available(iOS 10.0, *) {
        let origin = MTKTextureLoader.Origin.bottomLeft.rawValue
        textureLoaderOptions = [MTKTextureLoader.Option.origin : origin]
    } else {
        textureLoaderOptions = [:]
    }

    if let textureURL = Bundle.main.url(forResource: imageName, withExtension: nil, subdirectory: "Images") {
        do {
            texture = try textureLoader.newTexture(URL: textureURL, options: textureLoaderOptions)
        } catch {
            print("Texture not created.")
        }
    }
    return texture
}

Довольно простой код.Я запускаю его на iPad Pro с чипом A9, семейство GPU 3. Он должен обрабатывать текстуры такого размера.Должен ли я как-то вручную разложить его, если он не принимает этот размер?В таком случае, что является лучшим подходом: использование MTLRegionMake для копирования байтов, нарезка в Core Image или в контексте Core Graphics ...

Я ценю любую помощь

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

После ваших полезных комментариев я решил загрузить его вручную, рисуя в CGContext и копируя в MTLTexture.Я добавляю код решения ниже.Контекст не должен создаваться каждый раз при создании текстуры, лучше поместить ее вне функции и продолжать использовать ее повторно.

    // Grab the CGImage, w = width, h = height...

    let context = CGContext(data: nil, width: w, height: h, bitsPerComponent: bpc, bytesPerRow: (bpp / 8) * w, space: colorSpace!, bitmapInfo: bitmapInfo.rawValue)

    let flip = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: CGFloat(h))
    context?.concatenate(flip)
    context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: CGFloat(w), height: CGFloat(h)))

    let textureDescriptor = MTLTextureDescriptor()
    textureDescriptor.pixelFormat = .rgba8Unorm
    textureDescriptor.width = w
    textureDescriptor.height = h

    guard let data = context?.data else {print("No data in context."); return nil}

    let texture = device.makeTexture(descriptor: textureDescriptor)
    texture?.replace(region: MTLRegionMake2D(0, 0, w, h), mipmapLevel: 0, withBytes: data, bytesPerRow: 4 * w)

    return texture
0 голосов
/ 15 февраля 2019

У меня была эта проблема раньше, текстура загружалась на одном устройстве, а не на другом.Я думаю, что это ошибка в загрузчике текстур.

Вы можете загрузить текстуру вручную, используя CGImage и CGContext, нарисовав изображение в контексте.Создайте буфер MTLTexture, затем скопируйте байты из CGContext в текстуру, используя MTLRegion.

Это не глупо, вы должны убедиться, что используете правильный пиксельный формат для металлического буфера, или вы получитестранные результаты, поэтому вы либо пишете код для определенного формата импортируемого изображения, либо делаете много проверок. Пример базового текстурирования для яблок показывает, как вы можете изменить порядок цветов перед записью байтов в текстуру с помощью MTLRegion.

...