Для алгоритма, который я пишу, мне нужно распечатать мои экранные координаты и перепроектировать их в световое пространство. Это происходит следующим образом: я заполняю буфер глубины просмотра от точки зрения (используя glLookAt), затем я проецирую все видимые пиксели в мировое пространство. Затем я перепроектирую их в светлое пространство.
Я проверял все, чтобы убедиться, что я не допустил ошибок (после этого я должен был сделать некоторые другие вещи), поэтому я нарисовал свои недавно спроецированные пиксели, глядя из светового пространства. Чтобы быть уверенным, что я получил правильный результат, я предположил, что мой свет был в том же месте, что и мой глаз.
Правильный результат http://img825.imageshack.us/img825/5971/correct.png
Это оригинальная сцена. Затем я снимаю и перерисовываю их, получаю следующий результат:
Неверный результат http://img268.imageshack.us/img268/4072/resultak.png
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();
}
Мне кажется, что сцена на его стороне, хотя я понятия не имею, почему. Вы также можете частично увидеть сцену на разных высотах, если все они на одной высоте, мое изображение завершено (и у меня правильный результат).
Итак, в чем причина того, что он на своей стороне и так разложен? (Что-то подсказывает мне, что эти две вещи могут быть связаны).
EDIT:
Следуя предложенному ниже предложению, я начал экспериментировать с различными параметрами хранилища пикселей:
GL_PACK_ALIGNEMENT, похоже, не имеет никакого эффекта, я пробовал 1,2,4 и 8.
GL_PACK_ROW_LENGTH является правильным в 0, он принимает ширину, указанную в пикселях чтения.
Видя, что я не хочу ничего пропускать, параметры SKIP должны остаться равными нулю.