# How do I get the correct values from glReadPixels in OpenGL 3.0?

I'm currently trying to Implement mouse selection into my game editor and I ran into a little problem when I look at the values stored in &pixel[0],&pixel[1],&pixel[2],&pixel[3]; I get

r: 0
g: 0
b: 0
a: 0


As you can see I'm not able to get the correct values from glReadPixels();

My 3D models are red colored using glColor3f(255,0,0);

I was hoping someone could help me figure this out.

Here is the source code:

  case WM_LBUTTONDOWN:

{

GetCursorPos(&pos);
ScreenToClient(hwnd, &pos);

GLenum err = glGetError();

while (glGetError() != GL_NO_ERROR) {cerr << err << endl;}

glReadPixels(pos.x, SCREEN_HEIGHT - 1 - pos.y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel[0] );

cerr << "r: "<< (int)pixel[0] << endl;
cerr << "g: "<< (int)pixel[1] << endl;
cerr << "b: "<< (int)pixel[2] << endl;
cerr << "a: "<< (int)pixel[3] << endl;

cout << pos.x << endl;
cout << pos.y << endl;

}

break;


I use :

WIN32 API
OPENGL 3.0
C++


FBOs shouldn't be relevant in this case as it's happening outside of the main render.

glReadPixels definitely works as advertised in this kind of setup - I just copied and pasted your code into a program and got expected results. That indicates to me that your problem is most likely elsewhere.

You should check the current value of glReadBuffer - if it's not GL_BACK then you may not get the end result you want. Also check that you're not doing anything weird like creating a single-buffered context.

Check your value of SCREEN_HEIGHT - is it actually the height of your window's client rect? If not then the read will be off-location. At this point I have to bring up the fact that the size you create your window at is not necessarily the size of your client rect - if you're running in a windowed mode then the size params you pass to CreateWindow(Ex) will be inclusive of title bar, borders, etc. You may already be aware of this - ignore if so.

You're not showing the definition of your "pixel" variable - "unsigned char pixel[4]" is what it should be here. Check that too.

Purely cosmetic but you don't need to pass "&pixel[0]" as your data parameter. Just "pixel" will do.

Reading as GL_RGB won't give you a meaningful value in your alpha channel (which you may not have anyway if your pixel format doesn't have destination alpha) - use GL_RGBA instead.

Also cosmetic, but I'm not certain what you're trying to achieve with that glGetError loop - glGetError doesn't behave like that, and you're not going to get meaningful or helpful info from it.

• According to the docs, glGetError() yields one error kind at a time per call. He seems to have lost the part where he should check for new errors after his function. – Lars Viklund Jun 1 '12 at 20:36
• opengl.org/sdk/docs/man/xhtml/glGetError.xml - the error flag is set when an error occurs and no other errors are recorded until it's cleared (by a call to glGetError) so multiple successive calls to glGetError with no other GL calls between them will achieve nothing; only the first call is of value. In this case the first call will give a valid result, but the subsequent calls (in the while loop) are meaningless - also, the loop will never run (and never output an error) because the first call (outside the loop) will have cleared the error flag. – Maximus Minimus Jun 2 '12 at 1:40
• Ah, it seems that this code is slightly different from the one he tried to get help for on IRC. Yay for shotgunning questions at all the places at once. – Lars Viklund Jun 3 '12 at 0:56
• Interesting about glGetError(). At some point, I too learned that there could be more than one and you needed to loop over it. I wonder why I was taught that? – user1118321 Dec 18 '18 at 8:06