openglvbofbo

Error copying FBO to VBO


After doing some computation on the GPU I want to copy the results stored in the FBO to VBOs for rendering.

The problem: It looks like some of the data is corrupted when I do the copy. I've already checked both buffers' format and size, and also checked that the data stored in the FBO is correct.

Consider the following code that initializes the FBO:

unsigned int verticesTextureId = AllocateTexture(GL_TEXTURE_RECTANGLE, mVBOSize, 1, GL_RGBA32F, GL_RGBA);
CHECK_FOR_OPENGL_ERRORS();

unsigned int normalsTextureId = AllocateTexture(GL_TEXTURE_RECTANGLE, mVBOSize, 1, GL_RGBA32F, GL_RGBA);
CHECK_FOR_OPENGL_ERRORS();

SetUpViewport(mVBOSize, 1);

glBindFramebuffer(GL_FRAMEBUFFER, mFBOId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, verticesTextureId, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_RECTANGLE, normalsTextureId, 0);

And the following code that initializes the VBOs and copies data from the FBO to the VBOs:

mVerticesBufferId = AllocateVBO();
CHECK_FOR_OPENGL_ERRORS();

glBindBuffer(GL_PIXEL_PACK_BUFFER, mVerticesBufferId);
glBufferData(GL_PIXEL_PACK_BUFFER, mVBOSize * 4 * sizeof(float), 0, GL_STATIC_DRAW);

mNormalsBufferId = AllocateVBO();
CHECK_FOR_OPENGL_ERRORS();

glBindBuffer(GL_PIXEL_PACK_BUFFER, mNormalsBufferId);
glBufferData(GL_PIXEL_PACK_BUFFER, mVBOSize * 4 * sizeof(float), 0, GL_STATIC_DRAW);

glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, mVerticesBufferId);
glReadPixels(0, 0, mVBOSize, 1, GL_RGBA, GL_FLOAT, 0);

glReadBuffer(GL_COLOR_ATTACHMENT1);
glBindBuffer(GL_PIXEL_PACK_BUFFER, mNormalsBufferId);
glReadPixels(0, 0, mVBOSize, 1, GL_RGBA, GL_FLOAT, 0);

Here I bind the VBOs as vertex/normal attributes and call the draw:

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, mVerticesBufferId);
glVertexPointer(4, GL_FLOAT, 4 * sizeof(float), 0);

glBindBuffer(GL_ARRAY_BUFFER, mNormalsBufferId);
glNormalPointer(GL_FLOAT, 4 * sizeof(float), 0);

glDrawArrays(GL_POINTS, 0, mVBOSize);

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

After this call, most points appear correctly on screen, but some appear strangely out of place. This seems to be unrelated to signal or clamping because vertices with negative or greater than 1 components are being displayed correctly.

I'm attaching pictures of a kosh snowflake (a curve) that's not being correctly rendered.

1) Vertices rendered as points:

Kosh Snowflake (with wrong vertices rounded with red circles)

2) Vertices rendered as line strips, using a simple geometry shader:

Kosh Snowflake (wrong vertices circled in red)

Reference Image:

Correct Kosh Snowflake


Solution

  • Using gDEBugger I found that the data on my VBOs were also correct. The problem was that after fragment shader computation, the homogeneous component of my vectors (the w) had garbage on them, which produced unwanted effects on transforms.