C++ Opengl四元组生成错误0x506

C++ Opengl四元组生成错误0x506,c++,opengl,glsl,C++,Opengl,Glsl,我在OpenGL中有一些代码,可以将YUV图像渲染到OpenGL视口中。该程序在nvidia卡上运行时不会出现问题,但在Intel HD 3000上运行时会产生错误,不幸的是,Intel HD 3000是目标机器。在代码中标记生成错误的点 着色器程序是 // Vertex Shader #version 120 void main() { gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = gl_ModelViewProjectionMat

我在OpenGL中有一些代码,可以将YUV图像渲染到OpenGL视口中。该程序在nvidia卡上运行时不会出现问题,但在Intel HD 3000上运行时会产生错误,不幸的是,Intel HD 3000是目标机器。在代码中标记生成错误的点

着色器程序是

// Vertex Shader
#version 120
void main() {
  gl_TexCoord[0] = gl_MultiTexCoord0;
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

// fragment shader
#version 120
uniform sampler2D texY;
uniform sampler2D texU;
uniform sampler2D texV;
void main() {
  vec4 color;
  float y = texture2D(texY, gl_TexCoord[0].st).r;
  float u = texture2D(texU, gl_TexCoord[0].st).r;
  float v = texture2D(texV, gl_TexCoord[0].st).r;
  color.r = (1.164 * (y - 0.0625)) + (1.596 * (v - 0.5));
  color.g = (1.164 * (y - 0.0625)) - (0.391 * (u - 0.5)) - (0.813 * (v - 0.5));
  color.b = (1.164 * (y - 0.0625)) + (2.018 * (u - 0.5));
  color.a = 1.0;
  gl_FragColor = color;
};
然后我像这样运行程序:

GLuint textures[3];
glGenTextures(3, textures);

glBindTexture(GL_TEXTURE_2D, textures[YTEX]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glBindTexture(GL_TEXTURE_2D, textures[UTEX]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glBindTexture(GL_TEXTURE_2D, textures[VTEX]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glBindTexture(GL_TEXTURE_2D, 0);

GLsizei size = width * height;

GLvoid *y = yuv_buffer;
GLvoid *u = (GLubyte *)y + size;
GLvoid *v = (GLubyte *)u + (size >> 2);

glUseProgram(program_id);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE,
            GL_UNSIGNED_BYTE, y);
glUniform1i(glGetUniformLocation(program_id, "texY"), 0);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width >> 1, height >> 1, 0,
            GL_LUMINANCE, GL_UNSIGNED_BYTE, u);
glUniform1i(glGetUniformLocation(program_id, "texU"), 1);

glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, textures[2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width >> 1, height >> 1, 0,
            GL_LUMINANCE, GL_UNSIGNED_BYTE, u);
glUniform1i(glGetUniformLocation(program_id, "texV"), 2);

glBegin(GL_QUADS);
glTexCoord2f(texLeft, texTop);
glVertex2i(left, top);
glTexCoord2f(texLeft, texBottom);
glVertex2i(left, bottom);
glTexCoord2f(texRight, texBottom);
glVertex2i(right, bottom);
glTexCoord2f(texRight, texTop);
glVertex2i(right, top);
glEnd();

// glError() returns 0x506 here

glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);

glUseProgram(0);
glViewport(0, 0, (GLint)width, (GLint)height);

glGenFramebuffers(1, &fbo_id);
glGenTextures(1, &fbo_texture);
glGenRenderbuffers(1, &rbo_id);

glBindTexture(GL_TEXTURE_2D, fbo_texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
            GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);

glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo_id);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                          GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                            GL_RENDERBUFFER_EXT, rbo_id);

GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);

glPushAttrib(GL_TEXTURE_BIT);

glBindTexture(GL_TEXTURE_2D, m_frameTexture->texture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glPopAttrib();
更新由于帧缓冲区发生错误,我发现它们的使用方式如下: 当程序被实例化时,帧缓冲区如下所示:

GLuint textures[3];
glGenTextures(3, textures);

glBindTexture(GL_TEXTURE_2D, textures[YTEX]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glBindTexture(GL_TEXTURE_2D, textures[UTEX]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glBindTexture(GL_TEXTURE_2D, textures[VTEX]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glBindTexture(GL_TEXTURE_2D, 0);

GLsizei size = width * height;

GLvoid *y = yuv_buffer;
GLvoid *u = (GLubyte *)y + size;
GLvoid *v = (GLubyte *)u + (size >> 2);

glUseProgram(program_id);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE,
            GL_UNSIGNED_BYTE, y);
glUniform1i(glGetUniformLocation(program_id, "texY"), 0);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width >> 1, height >> 1, 0,
            GL_LUMINANCE, GL_UNSIGNED_BYTE, u);
glUniform1i(glGetUniformLocation(program_id, "texU"), 1);

glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, textures[2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width >> 1, height >> 1, 0,
            GL_LUMINANCE, GL_UNSIGNED_BYTE, u);
glUniform1i(glGetUniformLocation(program_id, "texV"), 2);

glBegin(GL_QUADS);
glTexCoord2f(texLeft, texTop);
glVertex2i(left, top);
glTexCoord2f(texLeft, texBottom);
glVertex2i(left, bottom);
glTexCoord2f(texRight, texBottom);
glVertex2i(right, bottom);
glTexCoord2f(texRight, texTop);
glVertex2i(right, top);
glEnd();

// glError() returns 0x506 here

glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);

glUseProgram(0);
glViewport(0, 0, (GLint)width, (GLint)height);

glGenFramebuffers(1, &fbo_id);
glGenTextures(1, &fbo_texture);
glGenRenderbuffers(1, &rbo_id);

glBindTexture(GL_TEXTURE_2D, fbo_texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
            GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);

glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo_id);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                          GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                            GL_RENDERBUFFER_EXT, rbo_id);

GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);

glPushAttrib(GL_TEXTURE_BIT);

glBindTexture(GL_TEXTURE_2D, m_frameTexture->texture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glPopAttrib();
YUV图像拼接在平铺中,通过在此fbo中渲染来组装。每当帧开始时,将执行以下操作:

glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
glDrawBuffer(GL_BACK);

glViewport(0, 0, (GLint)width, (GLint)height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (double)width, 0.0, (double)height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_id);
然后执行上面的代码,在所有的瓷砖组装在一起之后

glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
glPushAttrib(GL_VIEWPORT_BIT | GL_TEXTURE_BIT | GL_ENABLE_BIT);
glViewport(0, 0, width, height);

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glPushMatrix();

glLoadIdentity();
glOrtho(0.0, (double)width, 0.0, (double)height, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);

glBindTexture(GL_TEXTURE_2D, fbo_texture);

glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2f(renderLeft, renderTop);
glTexCoord2i(0, 1);
glVertex2f(renderLeft, renderTop + renderHeight);
glTexCoord2i(1, 1);
glVertex2f(renderLeft + renderWidth, renderTop + renderHeight);
glTexCoord2i(1, 0);
glVertex2f(renderLeft + renderWidth, renderTop);
glEnd();

glPopMatrix();

glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();

确切地说,什么命令会引发错误?尝试用
GL\u三角形\u风扇
替换
GL\u四边形
,错误代码“粘滞”且不会自动清除。如果您的程序在开始时产生OpenGL错误,并且您稍后检查错误代码1000 OpenGL调用,则错误仍将存在


因此,如果您想了解实际情况,请在每次OpenGL调用或循环调用后检查错误,直到返回所有错误代码(如OpenGL文档所示)。

以下操作后的
状态值是多少:

GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
如果该值不是
GL\u FRAMEBUFFER\u COMPLETE
,则OpenGL在尝试从FBO读取时可能会阻塞

描述了它可以返回的其他(错误)值,以及导致这些值的原因

特别令人感兴趣的可能是:

如果当前绑定的帧缓冲区未完成,则 尝试使用帧缓冲区进行写入或删除是错误的 阅读这意味着渲染命令(glDrawArrays)和 gldrawerelements)以及读取帧缓冲区的命令 (glReadPixels、glCopyTexImage2D和glCopyTexSubImage2D)将 如果在调用时调用,则生成错误GL\u INVALID\u FRAMEBUFFER\u操作 帧缓冲区未完成。

(强调矿山)

根据您的评论进行编辑:

要解释文档wrt GL_FRAMEBUFFER_complete_附件:

并非所有帧缓冲区连接点都已完成帧缓冲区连接。 这意味着发生以下情况之一:

  • 至少一个附着了renderbuffer或纹理的附着点的附着对象已不存在,或者附着的图像的宽度或高度为零
  • 颜色附着点附着了非颜色可渲染图像。颜色可渲染格式包括GL_RGBA4、GL_RGB5_A1和GL_RGB565
  • 深度附着点附着了不可深度渲染的图像。GL_DEPTH_COMPONENT16是唯一的深度渲染格式
  • 模具附着点附着了非模具可渲染图像。GL_STENCIL_INDEX8是唯一可渲染的模具格式
我们可以排除最后2个项目符号,因为您似乎没有使用深度或模板附件。剩下两个电话需要检查:

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo_id);
从:

当任何附件“不完整”时,您将获得GL\u帧缓冲区\u不完整\u附件。完整性的标准是:

  • 图像的源对象仍然存在,并且与附加的源对象具有相同的类型
  • 图像具有非零宽度和高度
  • 3D或阵列纹理附件的层小于纹理的深度
  • 如上所述,图像的格式必须符合附着点的要求。用于颜色附件等的颜色可渲染格式
维基上说的是GL_COLOR_ATTACHMENTi​:

这些附着点只能使用绑定到它们的图像 颜色可渲染格式。并非所有压缩图像格式都是 颜色可渲染,因此无法附加到FBO


仔细检查fbo_纹理和rbo_id是否仍然有效,以及它们的高度/宽度是否不是0。最后,它可能是fbo_纹理的格式。您已将其设置为GL_RGBA8,但文档称有效选项包括GL_RGBA4、GL_RGB5_A1和GL_RGB565。我不确定这是否排除了所有其他格式(如GL_RGBA8)。维基似乎建议任何非压缩格式都应该有效。尝试将其切换到GL_RGBA4,看看是否可行

我解决了这个问题。这是一个使渲染缓冲区对象消失的扩展问题。我基本上改变了这个

glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo_id);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                          GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                            GL_RENDERBUFFER_EXT, rbo_id);

GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
为此

glBindRenderbuffer(GL_RENDERBUFFER, rbo_id);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);

glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                          GL_TURE_2D, fbo_texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                            GL_RENDERBUFFER, rbo_id);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

然后它成功了。我仍然想知道到底是什么问题,但到目前为止,我对结果感到满意。特别感谢@luke,他的回答帮助我们找到了问题的确切症结所在。

在gDEBugger下运行。这些操作中的任何一个都可能失败,你不能在随机选择的地方调用glError一次。我在整个程序中都遇到了glGetError。我只是简化了这里的代码。我知道它确实在那里失败了。0x506是GL\u无效的\u帧缓冲区\u操作,这可能是个麻烦。您的代码中是否使用了FBO?事实上,我是这样做的,但我还没有弄清楚管道的哪个点使用TRIANGLE_FAN在一批中绘制多个四边形会导致四边形连接在一起,从而严重破坏纹理。最好每个四边形使用两个三角形,并用三角形绘制。正如我在上面的评论中提到的,我确实在程序中有GLGETRROR,几乎在每个语句之后。事实上,这里的许多语句是从其他函数调用的,或者是在其他类的方法中,我在这里这样写是为了让它可读。@Samatyon:“我在这里这样写”所以,不是产生问题的代码片段,而是编写了一些其他的代码片段。“太好了”。“几乎在每个语句之后”根据墨菲定律,你的“几乎”意味着在语句之后没有错误检查