Странный результат после glUnproject и перерисовки сцены - PullRequest
0 голосов
/ 21 августа 2011

Для алгоритма, который я пишу, мне нужно распечатать мои экранные координаты и перепроектировать их в световое пространство. Это происходит следующим образом: я заполняю буфер глубины просмотра от точки зрения (используя 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 должны остаться равными нулю.

1 Ответ

2 голосов
/ 21 августа 2011

Похоже, вы неправильно установили параметры хранения пикселей (шаг, выравнивание и т. П.), Особенно параметры PACK.Посмотрите на http://www.opengl.org/sdk/docs/man/xhtml/glPixelStore.xml для полного набора опций.В вашем случае вы хотите установить

glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);

прямо перед вызовом glReadPixels


РЕДАКТИРОВАТЬ / Обновить:

В вашем коде есть еще одна проблема: способ адресации массива пикселей.Вы написали

gluUnProject( …, z[X*600 + Y], …)

Это неправильно.Каждая строка (в вашем случае) имеет ширину 800 пикселей, поэтому для продвижения вперед на одну строку необходимо сместить 800 элементов.Таким образом, для адресации пикселя (x, y) в линейном массиве (ширина, высота) вы должны написать

data[y*width + x]

или в вашем случае

z[Y*800 + X]

вместо жесткого кодирования 800 × 600кстати, вы должны использовать переменные или именованные константы;сохраняет ваш код обслуживаемым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...