Created
March 28, 2023 06:32
-
-
Save scornflake/4738673eea3fffc112ee2f1c6dd41c7f to your computer and use it in GitHub Desktop.
Sample CA -> metal texture
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Metal | |
import MetalKit | |
// Create a MTLTexture for rendering | |
let textureDescriptor = MTLTextureDescriptor() | |
textureDescriptor.pixelFormat = .bgra8Unorm | |
textureDescriptor.width = Int(layer.bounds.width) | |
textureDescriptor.height = Int(layer.bounds.height) | |
let texture = device.makeTexture(descriptor: textureDescriptor)! | |
// Create a CAMetalRenderCommandEncoder | |
let renderPassDescriptor = MTLRenderPassDescriptor() | |
renderPassDescriptor.colorAttachments[0].texture = texture | |
renderPassDescriptor.colorAttachments[0].loadAction = .clear | |
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 1) | |
let commandBuffer = commandQueue.makeCommandBuffer()! | |
let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)! | |
// Create a CALayer and render it to the CAMetalRenderCommandEncoder | |
let metalLayer = CAMetalLayer() | |
metalLayer.framebufferOnly = true | |
metalLayer.pixelFormat = .bgra8Unorm | |
metalLayer.frame = layer.bounds | |
metalLayer.drawsAsynchronously = true | |
layer.addSublayer(metalLayer) | |
let drawable = metalLayer.nextDrawable()! | |
renderEncoder.setRenderPipelineState(pipelineState) | |
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0) | |
renderEncoder.setFragmentTexture(drawable.texture, index: 0) | |
renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4) | |
// Finish rendering and get the contents of the MTLTexture | |
renderEncoder.endEncoding() | |
commandBuffer.commit() | |
commandBuffer.waitUntilCompleted() | |
let bytesPerRow = 4 * Int(layer.bounds.width) | |
let imageData = UnsafeMutableRawPointer.allocate(byteCount: bytesPerRow * Int(layer.bounds.height), alignment: 1) | |
texture.getBytes(imageData, bytesPerRow: bytesPerRow, from: MTLRegionMake2D(0, 0, textureDescriptor.width, textureDescriptor.height), mipmapLevel: 0) | |
let colorSpace = CGColorSpaceCreateDeviceRGB() | |
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue) | |
let context = CGContext(data: imageData, width: Int(layer.bounds.width), height: Int(layer.bounds.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)! | |
let cgImage = context.makeImage()! | |
let uiImage = UIImage(cgImage: cgImage) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment