Opengl GL_QUADS generates error 0x506

I have code in OpenGL to display a YUV image in an OpenGL viewport. The program works without problems when working on nvidia cards, but when an error occurs when working with Intel HD 3000, unfortunately, this is the target machine. The point where the error is generated is marked in the code.

Shader programs

// 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; }; 

Then I run the program as follows:

 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); 

update , because the error occurs with frame buffers, I found that they are used as follows: when the program starts, a frame buffer is created as follows:

 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(); 

The YUV image comes in the form of tiles that are going to be rendered in this fbo. Whenever a frame starts, this is done:

 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); 

Then the code above is executed, and after all the tiles have been assembled together

 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(); 
+6
source share
4 answers

I solved the problem. This was a problem with extensions, which caused the render buffer object to disappear. I basically changed this

 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); 

for this

 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); 

and then it worked. I still wonder what the problem is, but so far I am pleased with the result. Special thanks to @luke, who replied, helped find the exact point of the problem.

+1
source

What is the status value after:

 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 

If the value has a value other than GL_FRAMEBUFFER_COMPLETE , OpenGL will probably suffocate when it tries to read from FBO.

glCheckFramebufferStatus docs describes the other (errors) values ​​that it can return and what causes them.

Of particular interest may be:

If the currently connected framebuffer is not a framebuffer, then this is an error when trying to use the framebuffer for writing or reading. This means that the rendering commands (glDrawArrays and glDrawElements), as well as the commands that read the framebuffer (glReadPixels, glCopyTexImage2D and glCopyTexSubImage2D) will generate the GL_INVALID_FRAMEBUFFER_OPERATION error if it is not frammed by the frame.

(my emphasis)

change based on your comments:

Paraphrase documents by GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:

Not all framebuffer attachment points are complete. This means that one of the following occurs:

  • At least one anchor point with an attached rendering buffer or texture has an attached object no longer exists or has an attached image with a width or height of zero,
  • The color attachment point has an attached image without color. Color rendering formats include GL_RGBA4, GL_RGB5_A1, and GL_RGB565.
  • The depth attachment point has an attached image without depth. GL_DEPTH_COMPONENT16 is the only format displayed in depth.
  • The stencil attachment point has an attached image without a stencil. GL_STENCIL_INDEX8 is the only format for rendering stencils.

We can exclude the last 2 bullets, because it is not visible that you are using the depth or stencil settings. This leaves two calls for verification:

 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); 

From the opengl.org wiki for FBOs :

You get GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT if any of the attachments is "incomplete." Criteria for completeness:

  • The original object for the image still exists and has the same type with which it was associated.
  • Image has nonzero width and height.
  • A layer for 3D texture or array attachments is less than texture depth.
  • The image format must meet the requirements of the anchor point, as defined above. Color rendering formats for color attachments, etc.

The wiki talks about GL_COLOR_ATTACHMENTi:

These attachment points can only have color rendering images associated with them. All compressed image formats are not color rendering and therefore cannot be tied to FBO.

Double check that fbo_texture and rbo_id are still valid and that their height / width are not equal to 0. Lastly, it could be the fbo_texture format. You have set GL_RGBA8, but the docs say that valid parameters include GL_RGBA4, GL_RGB5_A1 and GL_RGB565. I'm not sure if this excludes all other formats (e.g. your GL_RGBA8). Wikis believe that any non-compressed format should work. Try switching it to GL_RGBA4 and see if it works.

+7
source

glGetError stick error codes and will not be automatically cleared. If something at the beginning of your program generates an OpenGL error And you check the 1000 opengl error code later, the error will still be here.

So, if you want to understand what REALLY happens, check for errors after each OpenGL call, or call glGetError in a loop until all error codes are returned (as the OpenGL documentation suggests).

+1
source

Exactly which command is causing the error? Try replacing GL_QUADS with GL_TRIANGLE_FAN .

0
source

Source: https://habr.com/ru/post/915394/


All Articles