Why can't I read color information...?

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!

I’m guessing, but maybe you need to make a call to glReadBuffer somewhere, to tell OpenGL which buffer to read from?

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 );

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

Thanks for help!

...
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.

Originally posted by Portal:
[b]

...
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.[/b]
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…

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)

Finally,it’s work!
Thanks for your help :slight_smile: