For an algorithm I’m writing I need to unproject my screen coordinates and reproject them into lightspace. This goes as follows: I fill the depth buffer viewing from my eye point (using glLookAt), I then unproject all visible pixels to world space. Then I reproject them into light space.
I was checking everything to make sure I made no mistakes (I have to do some other stuff after this), so I drew my newly projected pixels seeing from lightspace. To be sure I got the right result I made the presumption that my light was at the same spot as my eye.
Is the original scene. I then unproject and redraw them, i get this result:
void getObjectCoords(){
std::vector<GLfloat> z(800*600, 0);
std::vector< Vertex > lightPoints;
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLdouble posX, posY, posZ;
//Setting our original viewpoint for unprojecting
gluLookAt(4.0,4.0,15.0, 0.0,0.0,0.0,0.0,1.0,0.0);
//Getting Modelviewx, Projection and viewport matrix
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );
//Reset the modelview
glLoadIdentity();
//Get the depth coordinate of the original points
glReadPixels( 0, 0,800, 600,GL_DEPTH_COMPONENT,GL_FLOAT, &z[0] );
//Unprojecting X and Y.
int count = 0;
Vertex temp;
for( int X = 0; X < 800; ++X){
for( int Y = 0; Y < 600; ++Y){
gluUnProject( X, Y, z[X*600 + Y], modelview, projection, viewport, &posX, &posY, &posZ);
if( z[X*600 + Y] < 1){
++count;
temp.x = posX;
temp.y = posY;
temp.z = posZ;
lightPoints.push_back(temp);
}
}
}
std::cout << count << " pixels closer to the viewpoint" << std::endl;
//Projecting the original points to lightspace
gluLookAt( 4.0, 4.0, 15.0, 0.0,0.0,0.0,0.0,1.0,0.0);
//We get the new modelview matrix
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
//We reset the modelview matrix
glLoadIdentity();
GLdouble winX, winY, winZ;
//Projecting the points into lightspace and saving the sample points
for(vector<Vertex>::iterator vertex = lightPoints.begin(); vertex != lightPoints.end(); ++vertex){
gluProject( vertex->x, vertex->y, vertex->z,modelview, projection, viewport, &winX, &winY, &winZ );
temp.x = winX;
temp.y = winY;
temp.z = winZ;
samplePoints.push_back(temp);
}
//std::cout << count << " pixels with depth greater or smaller than 1 " << std::endl;
// Duplicate code below is to draw the sample points
gluLookAt( 4.0, 4.0, 15.0, 0.0,0.0,0.0,0.0,1.0,0.0);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glBegin(GL_POINTS);
for(vector<Vertex>::iterator vertex = lightPoints.begin(); vertex != lightPoints.end(); ++vertex){
glColor3f(0.0,1.0,0.0);
glVertex3f(vertex->x, vertex->y, vertex->z);
}
glEnd();
}
It seems to me the scene is on its side, though I have no idea why. You can also see the scene partially at different heights, if these are all on the same height my image is complete (and I have the correct result).
So, what is the reason that it’s on it’s side and so spread out? (Something tells me these two things might be connected).
EDIT:
Following the suggestion given below I started experimenting with the different pixelstore options:
GL_PACK_ALIGNEMENT does not seem to be having any effect, I tried 1,2,4 and 8.
GL_PACK_ROW_LENGTH is correct at 0, it takes the width specified in readpixels.
Seeing that I don’t want to skip anything, the SKIP options should remain zero aswell.


This looks like you’ve not properly set your pixel store parameters (stride, alignment, the like), notably the PACK parameters. Have a look at http://www.opengl.org/sdk/docs/man/xhtml/glPixelStore.xml for the full set of options. In your case you want to set
right before calling glReadPixels
EDIT/Update:
There’s another issue in your code: The way you address your pixel array. You wrote
This is wrong. Each row (in your case) is 800 pixels wide, so to advance one row you must offset by 800 elements. Thus to address pixel (x,y) in a linear array of (width, height) you must write
or in your case
Instead of hardcoding 800×600 you should use variables or named constants by the way; keeps your code maintainable.