Jump to content
  • Advertisement
Sign in to follow this  
ksssp

Does glReadPixels return a pointer or a copy of the data read.

This topic is 2905 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey,
I have been facing serious trouble with glReadPixels.
I need to render a 3d scene, read the framebuffer using glReadpixels and draw the data array after some post processing using glDrawpixelse. When I draw each time the entire 3d scene, read the same details and do the post processing, it works fine. But, due to the size of the scene, it is a waste of time. I have tried just drawing the scene for the first time, reading it for the first time. But, in the second case, I get a blank screen in every round of rendering of the displayFunc.

So, is it that glReadpixels returns a pointer to the location on the framebuffer where the colorbuffer is stored, or returns a copy of the intensity values that are rendered on the screen? Probably is it that the glutSwapbuffers/glClear are clearing the data array read by glReadpixels? My code is pasted below.


CAM_CHANGED = true;
void renderScene() {

if(CAM_CHANGED) {
// CAM_CHANGED = false;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1,1,1);
glPushMatrix();
glTranslatef(0,0,-10);
glutSolidTeapot(3);
glPopMatrix();

glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_FLOAT, novelColor[0]);
}

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawPixels(WIDTH, HEIGHT, GL_RGB, GL_FLOAT, novelColor[0]);
//cout << " After drawing novelColor[0]\n";

glutSwapBuffers();
glutPostRedisplay();
}


If CAM_CHANGED is always true, i.e. the scene is drawn every time, the gldrawpixels works, else it doesn't.

Share this post


Link to post
Share on other sites
Advertisement
glReadPixels reads pixel data from the framebuffer and puts it into main memory i.e. it copies it. glDraw pixels copies pixel info from main memory and _copies_ it to the framebuffer.

What is happening to novelColor[0] outside the renderScene function? Are you somehow deleting its contents outside the renderScene function?

Share this post


Link to post
Share on other sites
No. I am not changing the novelColor[0] anywhere outside the renderScene. It doesn't work even after commenting all the other modifications.

Case 1: With the "CAM_CHANGED = false" not commented -> Doesn't work
Case 2: With the "CAM_CHANGED = false" commented. -> works fine.

I have even tried using a wholly dedicated matrix for this purpose that is not modified anywhere else, but that also doesn't seem to work.

Share this post


Link to post
Share on other sites
Quote:
Original post by ksssp
So, is it that glReadpixels returns a pointer to the location on the framebuffer where the colorbuffer is stored, or returns a copy of the intensity values that are rendered on the screen?


As already said, glReadPixels copies the framebuffer pixels to a given buffer. Are you sure that novelColor[0] points to an according buffer ( = new glFloat[WIDTH*HEIGHT*3] ) ?

Also ensure that you don't change the draw/read buffer with glDrawBuffer/glReadBuffer (default should be GL_BACK).

Share this post


Link to post
Share on other sites
You might have to post more code (a minimum working example if possible). I'm convinced the problem is with novelColor[0]. We need to see what is happening outside the render function.

Share this post


Link to post
Share on other sites
As mentioned, I guess novelColor[0] was being modified outside renderScene. I started with a simple situation and was able to sort it.

Since, it was working with the actual framebuffer, I tried to render into an FBO, and read from it again, do the postProcessing and then render into the the normal screen. But now, I am facing a new problem. There is a slight shift in the whole scene upwards when I read from the fbo. Can somebody suggest why it happens. I tried to read multiple times from the FBO, but each time I do, there is a slight shift upwards.

Here's the code:

void postProcessArray() {
for(int i=0;i<WIDTH*HEIGHT*3;i++) {
finalColor = novelColor[0] + 0.2;
if(finalColor>1.0f)
finalColor = 1.0f;
}
}

void renderToFBO() {
cout << "Rendering and Reading from the FBO\n";
// Initialize the FBO
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

glGenRenderbuffersEXT(1, &crbo);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, crbo);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, WIDTH, HEIGHT);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, crbo );

glGenRenderbuffersEXT(1, &drbo);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, drbo);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, WIDTH, HEIGHT);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, drbo );

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
GLenum status;
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status == GL_FRAMEBUFFER_COMPLETE_EXT)
cout << "Framebuffer is ready for rendering\n";

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1,1,1);
glPushMatrix();
glTranslatef(0,0,-10);
glutSolidTeapot(3);
glPopMatrix();

cout << "After drawing the vertexArray of camID " << camID << endl;
glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_FLOAT, novelColor[0]);

cout << "After glReadPixels of camID " << camID << endl;
glReadPixels(0, 0, WIDTH, HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, novelDepth[0]);

glDeleteRenderbuffersEXT(1, &crbo);
glDeleteRenderbuffersEXT(1, &drbo);
glDeleteFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

}

void renderScene() {

if(CAM_CHANGED) {
CAM_CHANGED = false;
renderToFBO();
postProcessArray();
}

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawPixels(WIDTH, HEIGHT, GL_RGB, GL_FLOAT, finalColor);

glutSwapBuffers();
glutPostRedisplay();
}

Share this post


Link to post
Share on other sites
Quote from glDrawPixels:
"...
glDrawPixels reads pixel data from memory and writes it into the frame buffer
relative to the current raster position, provided that the raster
position is valid. Use
glRasterPos or glWindowPos to set the current raster position; use
glGet with argument GL_CURRENT_RASTER_POSITION_VALID
to determine if the specified raster position is valid, and
glGet with argument GL_CURRENT_RASTER_POSITION
to query the raster position.
..."

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!