iOS GLKit:使用相机输出设置GLKBaseEffect纹理

时间:2014-02-24 23:26:48

标签: ios avcapturesession glkit

我已经设置了一个AVCapture会话,并且在委托方法中,使用以下代码尝试使用输出设置GLKBaseEffect纹理,但是我得到的只是黑色。我该怎么做才能让它发挥作用?

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer (CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {

CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);

effect.texture2d0.name = CVOpenGLESTextureGetName(pixelBuffer);
}

1 个答案:

答案 0 :(得分:1)

TLDR:我不认为您可以使用GLKBaseEffect的相机输出 - 来自相机的数据是双平面YUV格式,因此您需要一个自定义片段着色器将其转换为渲染时的RGB,GLKBaseEffect不执行自定义着色器。

看起来这里有一些API混淆,所以请继续阅读,如果你想要更多背景......

虽然CVOpenGLESTexture类型派生自CVPixelBuffer,但您从CMSampleBufferGetImageBuffer返回的图片缓冲区并非自动为OpenGL ES纹理。每次使用CVOpenGLESTextureCache从相机获取帧时,都需要从图像缓冲区创建纹理。

Apple的GLCameraRipple示例代码说明了如何执行此操作。这是一个快速概述:

  1. 设置GL上下文后,setupAVCapture方法调用CVOpenGLESTextureCacheCreate以创建与该上下文关联的纹理缓存。
  2. captureOutput:didOutputSampleBuffer:fromConnection:中,他们使用CMSampleBufferGetImageBuffer从示例缓冲区获取图像缓冲区,然后使用纹理缓存的CVOpenGLESTextureCacheCreateTextureFromImage函数从中创建两个OpenGL ES纹理。您需要两个纹理,因为图像缓冲区在两个位平面中具有YUV颜色数据。
  3. 使用glBindTexture,每个纹理在创建后立即被绑定以进行渲染。通常,您可以设置glBindTexture的{​​{1}}并将其告知GLKBaseEffect来替换texture2d0.name来电,但prepareToDraw无法呈现YUV。< / LI>
  4. 使用着色器程序绘制两个绑定纹理,其片段着色器首先通过组合来自Y和UV纹理的组件生成YUV向量,然后根据HDTV将简单矩阵乘以将其转换为RGB像素颜色色空间规格。
  5. 因为你需要一个用于YUV到RGB转换的自定义片段着色器,GLKBaseEffect对你没有帮助。但是,正如GLKBaseEffect示例所示,您需要编写的自定义着色器并不那么可怕。