gpt4 book ai didi

ios - MTKView - 一次绘制两个 View

转载 作者:行者123 更新时间:2023-11-28 11:51:20 25 4
gpt4 key购买 nike

我得到了什么

我正在关注 Apple 示例代码 AVCamPhotoFilter MTKView 上显示相机画面。

我想做什么

除了上面的MTKView,我还需要显示第二个MTKView。但是,第二个将显示与第一个完全相同的内容。所以我不想重复代码并做两次工作。

当前绘制方法

override func draw(_ rect: CGRect) {
var pixelBuffer: CVPixelBuffer?
var mirroring = false
var rotation: Rotation = .rotate0Degrees

syncQueue.sync {
pixelBuffer = internalPixelBuffer
mirroring = internalMirroring
rotation = internalRotation
}

guard let drawable = currentDrawable,
let currentRenderPassDescriptor = currentRenderPassDescriptor,
let previewPixelBuffer = pixelBuffer else {
return
}

// Create a Metal texture from the image buffer
let width = CVPixelBufferGetWidth(previewPixelBuffer)
let height = CVPixelBufferGetHeight(previewPixelBuffer)

if textureCache == nil {
createTextureCache()
}
var cvTextureOut: CVMetalTexture?
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
textureCache!,
previewPixelBuffer,
nil,
.bgra8Unorm,
width,
height,
0,
&cvTextureOut)
guard let cvTexture = cvTextureOut, let texture = CVMetalTextureGetTexture(cvTexture) else {
print("Failed to create preview texture")

CVMetalTextureCacheFlush(textureCache!, 0)
return
}

if texture.width != textureWidth ||
texture.height != textureHeight ||
self.bounds != internalBounds ||
mirroring != textureMirroring ||
rotation != textureRotation {
setupTransform(width: texture.width, height: texture.height, mirroring: mirroring, rotation: rotation)
}

// Set up command buffer and encoder
guard let commandQueue = commandQueue else {
print("Failed to create Metal command queue")
CVMetalTextureCacheFlush(textureCache!, 0)
return
}

guard let commandBuffer = commandQueue.makeCommandBuffer() else {
print("Failed to create Metal command buffer")
CVMetalTextureCacheFlush(textureCache!, 0)
return
}

guard let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: currentRenderPassDescriptor) else {
print("Failed to create Metal command encoder")
CVMetalTextureCacheFlush(textureCache!, 0)
return
}

commandEncoder.label = "Preview display"
commandEncoder.setRenderPipelineState(renderPipelineState!)
commandEncoder.setVertexBuffer(vertexCoordBuffer, offset: 0, index: 0)
commandEncoder.setVertexBuffer(textCoordBuffer, offset: 0, index: 1)
commandEncoder.setFragmentTexture(texture, index: 0)
commandEncoder.setFragmentSamplerState(sampler, index: 0)
commandEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4)
commandEncoder.endEncoding()

commandBuffer.present(drawable) // Draw to the screen
commandBuffer.commit()
}

问题

有没有一种方法可以简单地将纹理传递给第二个 MTKView 并在不进行两次工作的情况下进行绘制?

最佳答案

如果您将第一个 MTKViewframebufferOnly 属性设置为 false,您可以提交从其可绘制纹理读取的命令。然后,您可以使用 blit 命令编码器将第一个可绘制对象的纹理复制到第二个可绘制对象的纹理(如果它们兼容)。否则,您可以将四边形绘制到第二个可绘制对象的纹理,并将第一个可绘制对象的纹理作为四边形纹理的来源。

就个人而言,我想我更希望所有渲染都转到您自己创建的纹理(而不是任何可绘制对象的纹理)。然后,将其复制/绘制到两个可绘制纹理。

无论如何,如果你需要两个 View 完美同步更新,你应该将两个 View 的presentsWithTransaction设置为true,同步等待(使用-waitUntilScheduled)对于执行(至少)复制/绘制到可绘制纹理的命令缓冲区,然后直接在两个可绘制对象上调用 -present。 (也就是说,不要在命令缓冲区上使用 -presentDrawable:。)

关于ios - MTKView - 一次绘制两个 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51861512/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com