我正在编写一个iOS视频应用程序,使用OpenGL ES 2.0进行图像处理。
我的视频输入和输出格式是YUV 4:2:0,这是iPhone 3GS之后大多数设备的本地像素格式。对于A5处理器和更高版本,我只需创建一个luma纹理和一个色度纹理,并将它们附加到屏幕外的框架缓冲区中。我创建我的文本如下:
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);然后我把它附加到程序中,就像:
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);
}在我的着色器里,我可以简单地做:
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。
然后,我尝试将颜色附件和深度附件注册为:
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);在我的片段着色器中写入深度缓冲区:
gl_FragDepth.z = texture2D(SamplerY, textureRead).r;然后将结果写入像素缓冲区,如下所示:
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颜色附件,只复制一个通道到我的像素缓冲区。
很抱歉发了这么长的邮件,只是想提供尽可能多的信息。
有什么想法吗?
发布于 2016-02-15 19:25:49
因此,如果扩展不可用,我最终如何解决这个问题,就是使用GL_LUMINANCE和GL_LUMINANCE_ALPHA,而不是红色和RG。然后,我将在呈现传递之后添加一个步骤,使用glReadPixels手动将像素复制到预先分配的像素缓冲区的预期格式中。
https://stackoverflow.com/questions/19530533
复制相似问题