我只需要创建一个透明的纹理。(alpha为0的像素)。
func layerTexture()-> MTLTexture {
let width = Int(self.drawableSize.width )
let height = Int(self.drawableSize.height )
let texDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgra8Unorm, width: width , height: height, mipmapped: false)
let temparyTexture = self.device?.makeTexture(descriptor: texDescriptor)
return temparyTexture!
}
当我使用预览打开temparyTexture时,它似乎是黑色的。这里缺少什么?
更新
我只是尝试使用透明图像创建纹理。 代码。
func layerTexture(imageData:Data)-> MTLTexture {
let width = Int(self.drawableSize.width )
let height = Int(self.drawableSize.height )
let bytesPerRow = width * 4
let texDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .rgba8Unorm, width: width , height: height, mipmapped: false)
let temparyTexture = self.device?.makeTexture(descriptor: texDescriptor)
let region = MTLRegionMake2D(0, 0, width, height)
imageData.withUnsafeBytes { (u8Ptr: UnsafePointer<UInt8>) in
let rawPtr = UnsafeRawPointer(u8Ptr)
temparyTexture?.replace(region: region, mipmapLevel: 0, withBytes: rawPtr, bytesPerRow: bytesPerRow)
}
return temparyTexture!
}
方法调用如下
let image = UIImage(named: "layer1.png")!
let imageData = UIImagePNGRepresentation(image)
self.layerTexture(imageData: imageData!)
其中layer1.png是透明png。但是,即使在尝试替换纹理时,它也出现消息“线程1:EXC_BAD_ACCESS(code = 1,address = 0x107e8c000)”,当机后,它仍然崩溃。我认为这是因为图像数据已压缩,并且rawpointer应该指向未压缩的数据。我该如何解决?
我是走正确的道路还是完全走错了方向?还有其他选择吗?我只需要创建透明的纹理即可。
答案 0 :(得分:2)
预编辑:快速查看透明纹理时,它将显示为黑色。我只是仔细检查了一些在生产中已经稳定运行的代码-这是预期的结果。
后期编辑:正确,您不应该将PNG或JPEG数据直接复制到MTLTexture的内容中。我建议做这样的事情:
var pixelBuffer: CVPixelBuffer?
let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue,
kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue,
kCVPixelBufferMetalCompatibilityKey: kCFBooleanTrue]
var status = CVPixelBufferCreate(nil, Int(image.size.width), Int(image.size.width),
kCVPixelFormatType_32BGRA, attrs as CFDictionary,
&pixelBuffer)
assert(status == noErr)
let coreImage = CIImage(image: image)!
let context = CIContext(mtlDevice: MTLCreateSystemDefaultDevice()!)
context.render(coreImage, to: pixelBuffer!)
var textureWrapper: CVMetalTexture?
status = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
GPUManager.shared.textureCache, pixelBuffer!, nil, .bgra8Unorm,
CVPixelBufferGetWidth(pixelBuffer!), CVPixelBufferGetHeight(pixelBuffer!), 0, &textureWrapper)
let texture = CVMetalTextureGetTexture(textureWrapper!)!
// use texture now for your Metal texture. the texture is now map-bound to the CVPixelBuffer's underlying memory.
您遇到的问题是,要完全掌握位图的工作原理以及如何以不同的方式布置它们实际上是非常困难的。图形是一个非常封闭的领域,具有许多深奥的术语,其中一些是指需要花费数年才能掌握的事物,其中一些是指琐碎的事物,但人们只是选择了一个奇怪的词来称呼它们。我的主要指标是: