如何在不使用CAMetalDrawable的情况下获得渲染纹理?

时间:2020-05-03 09:45:59

标签: ios swift rendering metal

我要渲染纹理并获取其结果,以便可以将纹理重新用于下一步渲染步骤。但是我不知道如何获得渲染结果。

这是我用来渲染的代码:

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()
    }

我在片段着色器中使用texture完成了我需要的一切,但是我不明白如何在快速核心中获得最终的MTLTexture对象?如果我尝试在texture之后获取commandBuffer.commit()的内容,则与渲染之前的内容相同。

1 个答案:

答案 0 :(得分:0)

您的实现是错误的,您应该在应用程序的开头初始化帧缓冲区纹理,然后在更新功能上重用。

相关问题