在iOS上生成渐变图像纹理

时间:2019-01-22 20:14:34

标签: ios opengl-es uiimage metal texture-mapping

我需要在iOS上生成256x1纹理。我有4种颜色,一端是红色,另一端是蓝色,另一端是蓝色,红色,绿色,黄色,蓝色,黄色和绿色分别在3/4和1/4位置。两者之间的颜色需要线性插值。我需要在Metal中使用此纹理在着色器代码中查找。在代码中生成此纹理的最简单方法是什么?

1 个答案:

答案 0 :(得分:1)

由于MTKTextureLoader当前不支持一维纹理的创建(至少自2016年以来就是一项功能要求),因此您需要手动创建纹理。

假设您已经加载了图像,则可以要求其提供CGImage,然后使用此方法提取像素数据并将其加载到纹理中:

func texture1DForImage(_ cgImage: CGImage, device: MTLDevice) -> MTLTexture? {
    let width = cgImage.width
    let height = 0
    let bytesPerRow = width * 4 // RGBA, 8 bits per component

    let bitmapInfo: UInt32 = /* default byte order | */ CGImageAlphaInfo.premultipliedLast.rawValue
    let colorSpace = CGColorSpace(name: CGColorSpace.sRGB)!
    let context = CGContext(data: nil,
                            width: width,
                            height: height,
                            bitsPerComponent: 8,
                            bytesPerRow: bytesPerRow,
                            space: colorSpace,
                            bitmapInfo: bitmapInfo)!

    let bounds = CGRect(x: 0, y: 0, width: width, height: height)
    context.draw(cgImage, in: bounds)

    guard let data = context.data?.bindMemory(to: UInt8.self, capacity: bytesPerRow) else { return nil }

    let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .rgba8Unorm,
                                                                     width: width,
                                                                     height: height,
                                                                     mipmapped: false)
    textureDescriptor.textureType = .type1D
    textureDescriptor.usage = [ .shaderRead ]

    let texture = device.makeTexture(descriptor: textureDescriptor)!
    texture.replace(region: MTLRegionMake1D(0, width), mipmapLevel: 0, withBytes: data, bytesPerRow: bytesPerRow)

    return texture
}