37148

Problems outputting gl_PrimitiveID to custom frame buffer object (FBO)

Question:

I have a very basic fragment shader which I want to output 'gl_PrimitiveID' to a fragment buffer object (FBO) which I have defined. Below is my fragment shader:

#version 150 uniform vec4 colorConst; out vec4 fragColor; out uvec4 triID; void main(void) { fragColor = colorConst; triID.r = uint(gl_PrimitiveID); }

I setup my FBO like this:

GLuint renderbufId0; GLuint renderbufId1; GLuint depthbufId; GLuint framebufId; // generate render and frame buffer objects glGenRenderbuffers( 1, &renderbufId0 ); glGenRenderbuffers( 1, &renderbufId1 ); glGenRenderbuffers( 1, &depthbufId ); glGenFramebuffers ( 1, &framebufId ); // setup first renderbuffer (fragColor) glBindRenderbuffer(GL_RENDERBUFFER, renderbufId0); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, gViewWidth, gViewHeight); // setup second renderbuffer (triID) glBindRenderbuffer(GL_RENDERBUFFER, renderbufId1); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB32UI, gViewWidth, gViewHeight); // setup depth buffer glBindRenderbuffer(GL_RENDERBUFFER, depthbufId); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, gViewWidth, gViewHeight); // setup framebuffer glBindFramebuffer(GL_FRAMEBUFFER, framebufId); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbufId0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, renderbufId1); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbufId ); // check if everything went well GLenum stat = glCheckFramebufferStatus(GL_FRAMEBUFFER); if(stat != GL_FRAMEBUFFER_COMPLETE) { exit(0); } // setup color attachments const GLenum att[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; glDrawBuffers(2, att); // render mesh RenderMyMesh() // copy second color attachment (triID) to local buffer glReadBuffer(GL_COLOR_ATTACHMENT1); glReadPixels(0, 0, gViewWidth, gViewHeight, GL_RED, GL_UNSIGNED_INT, data);

For some reason glReadPixels gives me a 'GL_INVALID_OPERATION' error? However if i change the internal format of renderbufId1 from 'GL_RGB32UI' to 'GL_RGB' and I use 'GL_FLOAT' in glReadPixels instead of 'GL_UNSIGNED_INT' then everything works fine. Does anyone know why I am getting the 'GL_INVALID_OPERATION' error and how I can solve it?

Is there an alternative way of outputting 'gl_PrimitiveID'?

PS: The reason I want to output 'gl_PrimitiveID' like this is explained here: <a href="https://stackoverflow.com/questions/9079361/picking-triangles-in-opengl-core-profile-when-using-gldrawelements" title="Picking triangles in OpenGL core profile when using glDrawElements" rel="nofollow">Picking triangles in OpenGL core profile when using glDrawElements</a>

Answer1:

<blockquote>

glReadPixels(0, 0, gViewWidth, gViewHeight, GL_RED, GL_UNSIGNED_INT, data);

</blockquote>

As stated <a href="http://www.opengl.org/wiki/Pixel_Transfer#Pixel_format" rel="nofollow">on the OpenGL Wiki</a>, you need to use GL_RED_INTEGER when transferring true integer data. Otherwise, OpenGL will try to use floating-point conversion on it.

BTW, make sure you're using <a href="http://www.opengl.org/wiki/GLAPI/glBindFragDataLocation" rel="nofollow">glBindFragDataLocation</a> to set up which buffers those fragment shader outputs go to. Alternatively, you can <a href="http://www.opengl.org/wiki/GLSL_Type_Qualifiers#Fragment_shader_buffer_output" rel="nofollow">set it up explicitly in the shader</a> if you're using GLSL 3.30 or above.

Recommend