Jump to content
  • Advertisement
Sign in to follow this  
michaeljmcd

OpenGL glReadPixels only works close to the origin

This topic is 4491 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

I've been trying to do some color-coded selection (rendering the entire scene in unique colors on the back buffer, then reading the pixels in order to ID the object selected), but when I glReadPixels it only works near (100-200 pixels away in both x and y directions) OpenGL's origin. Within this small area, glReadPixels reads and stores the pixel data as it should. Outside this area (which is most of the scene), glReadPixels does not alter the pixel array passed to it. What is causing this?

Share this post


Link to post
Share on other sites
Advertisement
C Code:

#include <stdio.h>
#include <GL/gl.h>
#include <GL/glut.h>

void ordinary_render();
void color_render();
void mouse_handler(int, int, int, int);

int main (int argcp, char* argv[])
{
glutInit(&argcp, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("Pickin'");

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glutDisplayFunc(ordinary_render);
glutMouseFunc(mouse_handler);
glutMainLoop();
return 0;
}

void ordinary_render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3ub(255, 255, 255);

glutSolidCube(0.075);

glTranslatef(0.0, 0.04, 0.0);
glRotatef(90, 0.0, 1.0, 0.0);
glRotatef(-90, 1.0, 0.0, 0.0);

glutSolidCone(0.035, .1, 15, 15);

glRotatef(90, 1.0, 0.0, 0.0);
glRotatef(-90, 0.0, 1.0, 0.0);
glTranslatef(0.0, -.04, 0.0);

glutSwapBuffers();
}

void color_render()
{
glColor3ub(255, 0, 0);
glutSolidCube(0.075);

glTranslatef(0.0, 0.04, 0.0);
glRotatef(90, 0.0, 1.0, 0.0);
glRotatef(-90, 1.0, 0.0, 0.0);

glColor3ub(0, 255, 0);
glutSolidCone(0.035, .1, 15, 15);

glRotatef(90, 1.0, 0.0, 0.0);
glRotatef(-90, 0.0, 1.0, 0.0);
glTranslatef(0.0, -.04, 0.0);
}

void mouse_handler(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
int viewport[4] = {1, 2, 3, 4};
unsigned char pixel[3] = {12, 17, 1};

glGetIntegerv(GL_VIEWPORT, viewport);

glDisable(GL_DITHER);
color_render();
glEnable(GL_DITHER);

glReadPixels(x, viewport[3] - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, (void*)pixel);

printf("RGB vals: %u, %u, %u\n", (unsigned int)pixel[0], (unsigned int)pixel[1], (unsigned int)pixel[2]);
}
else
return;
}
----------------------------------------------------------------------------------------------------------
Basically, it's just a sample program that I wrote to work out the issues before integrating the ideas in the larger program. It draws a cone on top of a cube. On a mouse click, it prints out (or is supposed to) the RGB values of the back buffer location corresponding to that selfsame mouseclick. When the mouse is clicked, the pixel array remains unchanged unless the click is near the OpenGL origin as I posted earlier.

Share this post


Link to post
Share on other sites
Which compiler were you using? I am running gcc version 3.4.6 on Gentoo Linux (kernel version 2.6), and the values remain unaltered except near the lower left hand corner.

Share this post


Link to post
Share on other sites
The behaviour is not dependent on the compiler, but the OpenGL implementation. After all, it's glReadPixel not working as expected, and that function isn't provided by the compiler. I'm using the latest drivers from NVIDIA for Windows. Try update your drivers if possible (or go back to older ones if you already have the latest, or just to check the behaviour) The code you provided is correct.

Share this post


Link to post
Share on other sites
Wait, I just realized what could be wrong the second I posted the reply. When drawing the colored image for selection, you don't clear the buffer. After presenting the back buffer to the front buffer, the content of the back buffer is undefined. Then you draw the colored image to a back buffer with undefined content, so the result is also undefined. Clear the back buffer before drawing the colored selection image.

So the code isn't correct, and my implementation just happened to give the expected result, but that was just luck.

Share this post


Link to post
Share on other sites
Adding glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); to the top of color_render() failed to alter the result at all. Unless I am mistaken, that is the method to clear the back buffer.

Share this post


Link to post
Share on other sites
Then try changing drivers and see what happens. Also try read back the entire window and dump to an image and see what you get. Try reading both the whole window in one call, and for each pixel individually and see if there is any difference. Also check glGetError.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!