CVPixelBuffer 到 FBO

Posted

技术标签:

【中文标题】CVPixelBuffer 到 FBO【英文标题】:CVPixelBuffer to FBO 【发布时间】:2013-02-01 10:15:00 【问题描述】:

我有一个应用程序,我想使用 FBO 来显示 QuickTime 电影的图像。 我对 FBO 完全陌生,只对 OpenGL 有一点了解。 我在理解 FBO 范式与绑定纹理和东西时遇到了问题,我希望你们能提供帮助。

为了获取电影的当前图像,我正在使用

QTVisualContextCopyImageForTime(theContext, NULL, NULL, &currentFrameTex); 其中currentFrameTex 是一个 CVImageBufferRef。

为了设置 FBO,我所做的只是:

glGenFramebuffersEXT(1, &idFrameBuf);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, idFrameBuf);

我正在使用以下代码来绘制图像:

// get the texture target (for example, GL_TEXTURE_2D) of the texture
GLint target = CVOpenGLTextureGetTarget(currentFrameTex);
// get the texture target name of the texture
GLint texID = CVOpenGLTextureGetName(currentFrameTex);

// get the texture coordinates for the part of the image that should be displayed
CVOpenGLTextureGetCleanTexCoords(currentFrameTex,
                                 bottomLeft, bottomRight,
                                 topRight, topLeft);
glBindTexture(target, texID);
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexImage2D(target, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, texID, 0);

我只是得到一个黑色的图像,我不知道我做错了什么。 如有必要,可以提供更多信息。提前致谢!

【问题讨论】:

【参考方案1】:

请参阅http://www.opengl.org/wiki/Framebuffer_Object 。 FBO 允许您将图形渲染到屏幕外缓冲区,然后对其进行处理。 您的代码覆盖了 currentFrameTex 提供的纹理,这没有多大意义。 一旦您使用非零 idFrameBuf 调用 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, idFrameBuf),则所有图形都将绘制到此 FBO,而不会出现在屏幕上。

【讨论】:

嗨,Maf,感谢您的回答。我在哪里覆盖一些东西?我需要做什么才能正确绘制纹理?我已经读过那篇文章,但我错过了一些东西。非常感谢! 你不需要 FBO 来渲染你的纹理。直接渲染到屏幕上。 CVOpenGLTextureGetName(currentFrameTex) 返回已经包含图像的纹理。使用此纹理绑定调用 glTexImage2D 会使用新内容和新维度重新分配此纹理,因此您可以松开电影帧。当您将此新纹理附加到 FBO (glFramebufferTexture2D) 时,您实际上是在绘制此纹理(通过 FBO)。如果你真的需要 FBO,那么要么创建一个新纹理 (glGenTextures) 并将其附加到 FBO,要么使用渲染缓冲区 (glRenderbufferStorage​)。 这将与外部视频硬件结合使用。硬件稍后将使用 glReadPixels 从 FBO 读取信息。我需要做什么才能将纹理附加到 FBO?很抱歉,我只是不明白它背后的范式。 FBO 只是一种将事物绘制到不可见内存(纹理或渲染缓冲区)的方法。对于您的情况,我建议创建一个渲染缓冲区(opengl.org/wiki/Renderbuffer_Object)然后是 FBO,然后将 RB 附加到 FBO(glFramebufferRenderbuffer​)。在应用程序初始化时执行一次。将 QT 纹理绘制到 FBO 后,您将能够从此 FBO 中 glReadPixels 并复制到您的硬件。

以上是关于CVPixelBuffer 到 FBO的主要内容,如果未能解决你的问题,请参考以下文章

修改 CVPixelBuffer

克隆 CVPixelBuffer - 如何?

使用 UIImage.draw() 写入 CVPixelBuffer 太慢了

调整CVPixelBuffer的大小

从 ARKit 获取 RGB“CVPixelBuffer”

是否可以更改 CVPixelBuffer 中捕获的 AR 图像的分辨率?