I want to render my texture and get the result of it so I can reuse the texture for next render step. But I don't know how to get the result of rendering.
this is the code I use to render:
var destinationTexture: MTLTexture?
func update(texture: MTLTexture) {
// Create render targets for offscreen camera image and scene render
let width = texture.width
let height = texture.height
let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: texture.pixelFormat,
width: width,
height: height,
mipmapped: false)
textureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite]
guard let newTexture = destinationTexture ?? texture.makeTextureView(pixelFormat: texture.pixelFormat) else {
fatalError("Could not create texture of size: (\(width), \(height))")
}
_ = inFlightSemaphore.wait(timeout: DispatchTime.distantFuture)
if let commandBuffer = commandQueue.makeCommandBuffer() {
updateBufferStates()
updateState()
let vertexBuffer = sharedMetalRenderingDevice.device.makeBuffer(bytes: kImagePlaneVertexData,
length: kImagePlaneVertexData.count * MemoryLayout<Float>.size, options: [])!
let renderPass = MTLRenderPassDescriptor()
renderPass.colorAttachments[0].texture = newTexture
renderPass.colorAttachments[0].clearColor = MTLClearColorMake(1, 0, 0, 1)
renderPass.colorAttachments[0].storeAction = .store
renderPass.colorAttachments[0].loadAction = .clear
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPass) else {
fatalError("Could not create render encoder")
}
renderEncoder.setRenderPipelineState(strip.renderPipelineState)
// Setup plane vertex buffers
renderEncoder.setVertexBuffer(imagePlaneVertexBuffer, offset: 0, index: 0)
renderEncoder.setVertexBuffer(scenePlaneVertexBuffer, offset: 0, index: 1)
renderEncoder.setFragmentBuffer(sharedUniformBuffer, offset: sharedUniformBufferOffset, index: Int(kBufferIndexSharedUniforms.rawValue))
// ... set pipelane state and so on
renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4)
renderEncoder.endEncoding()
commandBuffer.addCompletedHandler { _ in
let updatedTexture = renderPass.colorAttachments[0].texture
self.destinationTexture = updatedTexture
}
commandBuffer.commit()
}
inFlightSemaphore.signal()
}
I do everything I need with texture
in my fragment shader but I do not understand how to get final MTLTexture
object in swift core? If I try to get content of texture
after commandBuffer.commit()
it is the same as before rendering.
Your implementation is wrong, you should initialize your framebuffer texture at the start of the application, and reuse on your update function.