首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在OpenGl ES 2.0中为iOS写入单通道像素缓冲区

在OpenGl ES 2.0中为iOS写入单通道像素缓冲区
EN

Stack Overflow用户
提问于 2013-10-23 00:10:51
回答 1查看 1.2K关注 0票数 2

我正在编写一个iOS视频应用程序,使用OpenGL ES 2.0进行图像处理。

我的视频输入和输出格式是YUV 4:2:0,这是iPhone 3GS之后大多数设备的本地像素格式。对于A5处理器和更高版本,我只需创建一个luma纹理和一个色度纹理,并将它们附加到屏幕外的框架缓冲区中。我创建我的文本如下:

代码语言:javascript
复制
CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
                                                   _videoTextureCache,
                                                   pixelBuffer,
                                                   NULL,
                                                   GL_TEXTURE_2D,
                                                   GL_RED_EXT,
                                                   (int)CVPixelBufferGetWidthOfPlane(pixelBuffer, 0),
                                                   (int)CVPixelBufferGetHeightOfPlane(pixelBuffer, 0),
                                                   GL_RED_EXT,
                                                   GL_UNSIGNED_BYTE,
                                                   0,
                                                   &lumaTexture);

然后我把它附加到程序中,就像:

代码语言:javascript
复制
glActiveTexture([self getTextureUnit:textureUnit]);
glBindTexture(CVOpenGLESTextureGetTarget(texture), CVOpenGLESTextureGetName(texture));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if(uniform != -1)
{
    glUniform1i(uniforms[uniform], textureUnit);
}

在我的着色器里,我可以简单地做:

代码语言:javascript
复制
gl_FragColor.r = texture2D(SamplerY, textureRead).r;

将luma值分配给缓冲区并将结果视频帧保存到磁盘。

不幸的是,我遇到了iPhone 4的问题,因为它没有使用A5处理器,因此不支持GL_RED_EXT

然后,我尝试找到一种在OpenGL ES中写入1通道luma缓冲区的方法,但始终遇到问题。我尝试简单地将GL_RED_EXT更改为GL_LUMINANCE,但发现不可能将其写入GL_LUMINANCE

然后,我尝试将颜色附件和深度附件注册为:

代码语言:javascript
复制
GLuint colorRenderbuffer;
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8_OES, (int)CVPixelBufferGetWidthOfPlane(renderData.destinationPixelBuffer, 0), (int)CVPixelBufferGetHeightOfPlane(renderData.destinationPixelBuffer, 0));
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER, colorRenderbuffer);

GLuint depthRenderbuffer;
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, (int)CVPixelBufferGetWidthOfPlane(renderData.destinationPixelBuffer, 0), (int)CVPixelBufferGetHeightOfPlane(renderData.destinationPixelBuffer, 0));
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER, depthRenderbuffer);

在我的片段着色器中写入深度缓冲区:

代码语言:javascript
复制
gl_FragDepth.z = texture2D(SamplerY, textureRead).r;

然后将结果写入像素缓冲区,如下所示:

代码语言:javascript
复制
glReadPixels(0, 0, (int)CVPixelBufferGetWidthOfPlane(renderData.destinationPixelBuffer, 0), (int)CVPixelBufferGetHeightOfPlane(renderData.destinationPixelBuffer, 0), GL_LUMINANCE, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddressOfPlane(renderData.destinationPixelBuffer, 0));

但是,我在规范中再次看到,OpenGL es2.0不支持直接写入深度缓冲区。

因此,我没有明显的方法来创建一个单一通道的颜色附件,我不知道我如何能够写到一个RGB颜色附件,只复制一个通道到我的像素缓冲区。

很抱歉发了这么长的邮件,只是想提供尽可能多的信息。

有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-15 19:25:49

因此,如果扩展不可用,我最终如何解决这个问题,就是使用GL_LUMINANCE和GL_LUMINANCE_ALPHA,而不是红色和RG。然后,我将在呈现传递之后添加一个步骤,使用glReadPixels手动将像素复制到预先分配的像素缓冲区的预期格式中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19530533

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档