我已经实现了示例代码,使用适用于 Android 的 openGL ES 3.0 将 YUV 色彩空间转换为 RGB。我有顶点和片段着色器,我在其中定义了转换公式。
我创建了如下纹理,
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &ytex);
glBindTexture(GL_TEXTURE_2D,ytex);
GLint textureBinding;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
if(textureBinding == 0)
{
char* infoLog = (char*) malloc(100);
glGetProgramInfoLog(programObject, textureBinding, NULL, infoLog);
errormsg = infoLog;
free (infoLog);
}
// Setup the texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//Define the texture image
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 640, 480, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, yBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ytex, 0);
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &utex);
glBindTexture(GL_TEXTURE_2D,utex);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
if(textureBinding == 0)
{
char* infoLog = (char*) malloc(100);
glGetProgramInfoLog(programObject, textureBinding, NULL, infoLog);
errormsg = infoLog;
free (infoLog);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 320, 240, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, uBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, utex, 0);
glActiveTexture(GL_TEXTURE2);
glGenTextures(1, &vtex);
glBindTexture(GL_TEXTURE_2D,vtex);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
if(textureBinding == 0)
{
char* infoLog = (char*) malloc(100);
glGetProgramInfoLog(programObject, textureBinding, NULL, infoLog);
errormsg = infoLog;
free (infoLog);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 320, 240, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
当我使用 glGetError() 进行验证时,我没有收到任何错误。
我不想在视口上显示纹理的输出,而是想将其存储在一个缓冲区中,以便稍后使用输出。所以我创建了帧缓冲区和渲染缓冲区,如下所示,
//Framebuffer
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, vtex, 0);
//Check the framebuffer status
GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE)
{
char* infoLog = (char*) malloc(100);
glGetProgramInfoLog(programObject, status, NULL, infoLog);
errormsg = infoLog;
free (infoLog);}
当我验证状态时,它总是返回 36054(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),但当我在调用 glCheckFrameBufferStatus() 之前取消绑定缓冲区时,同样返回 GL_FRAMEBUFFER_COMPLETE
glbindFrameBuffer(GL_FRAMEBUFFER, 0);
所以后来我想使用 glReadpixels() 读取帧缓冲区的输出,但这也失败了。请有人帮助如何解决这个问题?
36054 表示 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 检查您的视图框架是否正确?
没有 OpenGL / OpenGL ES 的实现支持 Alpha 或亮度纹理作为可颜色渲染。您可以使用 GL_R8、GL_RG8 复制该行为。当您想要使用 FBO 绘制为一通道或两通道图像格式时,这两种格式非常有用(因为 GL_LUMINANCE、GL_ALPHA 和 GL_LUMINANCE_ALPHA 不是可颜色渲染的格式)。
尝试用 GL_R8 替换内部格式,用 GL_RED 替换格式。
这里也出现了这个问题,但是由于调整framebuffer的大小,问题出现在特定的手机上。我最后是怎么解决这个问题的?