作者:手机用户2602879975 | 来源:互联网 | 2022-12-06 16:35
我通过将SDK提供的OpenGL上下文()与SceneKit的实例相结合,成功地将Vuforia SDK图像目标跟踪功能集成到iOS项目中.这使我能够利用SceneKit 3D API的简单性,同时受益于Vuforia的高精度图像检测.现在,我想通过用Metal替换OpenGL来做同样的事情.EAGLContext
SCNRenderer
一些背景故事
我能够使用OpenGL在Vuforia绘制的实时视频纹理之上绘制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];
idcommandBuffer = [metalCommandQueue commandBuffer];
//// -----> call the `render(viewport:commandBuffer:drawable) here <------- \\\\
id 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
,正在覆盖彼此的缓冲区.
我在这里错过了什么?