我已经设置了一个AVCapture会话,并且在委托方法中,使用以下代码尝试使用输出设置GLKBaseEffect纹理,但是我得到的只是黑色。我该怎么做才能让它发挥作用?
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer (CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
effect.texture2d0.name = CVOpenGLESTextureGetName(pixelBuffer);
}
答案 0 :(得分:1)
TLDR:我不认为您可以使用GLKBaseEffect
的相机输出 - 来自相机的数据是双平面YUV格式,因此您需要一个自定义片段着色器将其转换为渲染时的RGB,GLKBaseEffect
不执行自定义着色器。
看起来这里有一些API混淆,所以请继续阅读,如果你想要更多背景......
虽然CVOpenGLESTexture
类型派生自CVPixelBuffer
,但您从CMSampleBufferGetImageBuffer
返回的图片缓冲区并非自动为OpenGL ES纹理。每次使用CVOpenGLESTextureCache
从相机获取帧时,都需要从图像缓冲区创建纹理。
Apple的GLCameraRipple
示例代码说明了如何执行此操作。这是一个快速概述:
setupAVCapture
方法调用CVOpenGLESTextureCacheCreate
以创建与该上下文关联的纹理缓存。captureOutput:didOutputSampleBuffer:fromConnection:
中,他们使用CMSampleBufferGetImageBuffer
从示例缓冲区获取图像缓冲区,然后使用纹理缓存的CVOpenGLESTextureCacheCreateTextureFromImage
函数从中创建两个OpenGL ES纹理。您需要两个纹理,因为图像缓冲区在两个位平面中具有YUV颜色数据。glBindTexture
,每个纹理在创建后立即被绑定以进行渲染。通常,您可以设置glBindTexture
的{{1}}并将其告知GLKBaseEffect
来替换texture2d0.name
来电,但prepareToDraw
无法呈现YUV。< / LI>
因为你需要一个用于YUV到RGB转换的自定义片段着色器,GLKBaseEffect
对你没有帮助。但是,正如GLKBaseEffect
示例所示,您需要编写的自定义着色器并不那么可怕。