通过将 SDK 提供的 OpenGL 上下文 ( ) 与SceneKitEAGLContext的SCNRenderer. 这让我能够利用 SceneKit 的 3D API 的简单性,同时受益于 Vuforia 的高精度图像检测。现在,我想通过用 Metal 替换 OpenGL 来做同样的事情。
一些背景故事
我能够在 Vuforia 使用OpenGL绘制的实时视频纹理之上绘制 SceneKit 对象,而没有出现重大问题。
这是我与OpenGL一起使用的简化设置:
func configureRenderer(for context: EAGLContext) {
self.renderer = SCNRenderer(context: context, options: nil)
self.scene = SCNScene()
renderer.scene = scene
// other scenekit setup
}
func render() {
// manipulate scenekit nodes
renderer.render(atTime: CFAbsoluteTimeGetCurrent())
}
Apple 在 iOS 12 上弃用 OpenGL
由于Apple 宣布将在 iOS 12 上弃用 OpenGL,我认为尝试迁移此项目以使用Metal而不是OpenGL.
这在理论上应该很简单,因为 Vuforia 开箱即用地支持 Metal。然而,当试图整合它时,我碰壁了。
问题
该视图似乎只渲染 SceneKit 渲染器的结果,或 Vuforia 编码的纹理,但绝不会同时渲染两者。这取决于首先编码的内容。我该怎么做才能将两个结果融合在一起?
简而言之,这是有问题的设置:
func configureRenderer(for device: MTLDevice) {
let renderer = SCNRenderer(device: device, options: nil)
self.scene = SCNScene()
renderer.scene = scene
// other scenekit setup
}
func render(viewport: CGRect, commandBuffer: MTLCommandBuffer, drawable: CAMetalDrawable) {
// manipulate scenekit nodes
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = drawable.texture
renderPassDescriptor.colorAttachments[0].loadAction = .load
renderPassDescriptor.colorAttachments[0].storeAction = .store
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(red: 0.0, green: 0, blue: 0, alpha: 0)
renderer!.render(withViewport: viewport, commandBuffer: commandBuffer, passDescriptor: renderPassDescriptor)
}
我尝试render在encoder.endEncoding以下或之前拨打电话commandBuffer.renderCommandEncoderWithDescriptor:
metalDevice = MTLCreateSystemDefaultDevice();
metalCommandQueue = [metalDevice newCommandQueue];
id<MTLCommandBuffer>commandBuffer = [metalCommandQueue commandBuffer];
//// -----> call the `render(viewport:commandBuffer:drawable) here <------- \\\\
id<MTLRenderCommandEncoder> encoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
// calls to encoder to render textures from Vuforia
[encoder endEncoding];
//// -----> or here <------- \\\\
[commandBuffer presentDrawable:drawable];
[commandBuffer commit];
在任何一种情况下,我只看到SCNRenderer OR结果的结果encoder,但从来没有在同一个视图中看到。
在我看来,好像上面的编码传递和SCNRenderer.render, 正在覆盖彼此的缓冲区。
我在这里想念什么?