PDA

View Full Version : Why can't I read color information...?



Southp
05-17-2004, 01:14 AM
In fact,recently I'd ask a "what" question about it. After reading API documents,I thought it was easy to use. But, it's not. My question is:"How to use glReadPixels to get color information of a pixel?"
I've written a simple test program.The following are parts of it:
...
...
...
glColor3f(1.0,0.0,0.0);
glBegin(GL_QUADS);
glVertex3f(50,50,0);
glVertex3f(100,50,0);
glVertex3f(100,100,0);
glVertex3f(50,100,0);
glEnd();

GLubyte p[3];
glReadPixels(60,
60,
1,
1,
GL_RGB,GL_UNSIGNED_BYTE,
p);
...
...
...

All I want to do is get the RGB value of the point (60,60).However,there is no any value assign to p array.

I've tried to search related topics,but,seems it's too basic,I can't find it.

Please someone tell me what's wrong of it.
Thanks!

charliejay
05-17-2004, 02:24 AM
I'm guessing, but maybe you need to make a call to glReadBuffer somewhere, to tell OpenGL which buffer to read from?

plasmonster
05-17-2004, 02:26 AM
In addition to that...

I don't see anything wrong with the snippet you posted. It could be that the problem lies in your projection matrix setup. (remember that the ReadPixels() origin is lower left corner of the screen).

Try flipping the y in your call

glReadPixels( x, screenHeight - y, w, h, format, type, pix );

Southp
05-17-2004, 02:43 AM
Thanks for reply.
However,I still can't solve the problem.So I think the problem occurs elsewhere in my code.

Here is the code:
readpixeltest.cpp (http://southp.cis95.net/readpixeltest.cpp)

Thanks for help!

plasmonster
05-17-2004, 02:51 AM
...
glutDisplayFunc(draw);

GLubyte p[3];
glReadBuffer(GL_FRONT);
glReadPixels(60,60,0,0,GL_RGB,GL_UNSIGNED_BYTE,p);

cout<<p[0]-'0'<<' '<<p[1]-'0'<<' '<<p[2]-'0'<<' '<<endl;

glutMainLoop();The problem is that you're reading the pixels before you've drawn anything. Setting the display function does not force an update, it just gives glut a pointer to your update function. You need to enter the main loop, respond to an update by drawing something, then do a read afterward.

Southp
05-17-2004, 03:19 AM
Originally posted by Portal:

...
glutDisplayFunc(draw);

GLubyte p[3];
glReadBuffer(GL_FRONT);
glReadPixels(60,60,0,0,GL_RGB,GL_UNSIGNED_BYTE,p);

cout<<p[0]-'0'<<' '<<p[1]-'0'<<' '<<p[2]-'0'<<' '<<endl;

glutMainLoop();The problem is that you're reading the pixels before you've drawn anything. Setting the display function does not force an update, it just gives glut a pointer to your update function. You need to enter the main loop, respond to an update by drawing something, then do a read afterward.Sorry...I don't get it.
You mean that I need to make sure something was drawn before read anything,right?
But how...?
I tried to put glReadPixels in the bottom of draw(),which is the display function.
But it didn't work...I'm wrong again.

How to respond an update by drawing something?

Sorry for the plenty of basic question...

plasmonster
05-17-2004, 03:30 AM
Southp, try something like this


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

using namespace std;

void init()
{
glClearColor(0.0,0.0,0.0,1.0);
}

// this is a nice function to define
// to handle a window resize
void reshape( int w, int h )
{
glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D( 0, w, 0, h );

glMatrixMode( GL_MODELVIEW );
}

void draw()
{
glClear(GL_COLOR_BUFFER_BIT);

// you might want to position your camera
// here - I just loaded a modelview identity
// to make sure the stack is clean.
glLoadIdentity();

// draw your stuff
glColor3f(1.0,0.0,0.0);
glBegin(GL_QUADS);
glVertex3i(50,50,0);
glVertex3i(100,50,0);
glVertex3i(100,100,0);
glVertex3i(50,100,0);
glEnd();
glFlush();



// all I did was move the read code up here
GLfloat p[3];

// this is the default for single buffer
glReadBuffer(GL_FRONT);

// do the read
glReadPixels(60,60,1,1,GL_RGB,GL_FLOAT,p);

// if you print this in a loop, you will
// get a blizzard of text, and it will
// slow your app down big time.
cout<<p[0]<<' '<<p[1]<<' '<<p[2]<<' '<<endl;
}

int main(int argc,char* argv[])
{
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,300);
glutCreateWindow("Test");

init();

glutDisplayFunc(draw);
glutReshapeFunc(reshape);
glutMainLoop();

}edit:

*I've made quite a few edits - I keep thinking of things to add.

*I just built this, and it works. I changed the (w,h) in the read call from (0,0) to (1,1)

Southp
05-17-2004, 03:42 AM
Finally,it's work!
Thanks for your help :)