glReadPixels deep_buffer_component всегда возвращает 1 - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь получить мировые координаты из любой отрисованной вершины в окне OpenGL (я предпочитаю использовать библиотеку GLUT).Проблема в том, что когда я вызываю функцию glReadPixels, чтобы получить значение глубины вершины, она всегда возвращает значение 1, когда я щелкаю мышью в любом месте.

Я застрял в этом вопросе, уже прочитал тонну статей, но не получил никакого ответа.

Вот мой код:

функция отображения

void display(){

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glEnable(GL_DEPTH | GL_DEPTH_TEST);
 glDepthFunc(GL_LEQUAL);
 glDepthRange(200, 2000);

 //here i put some glBegins and glEnds

 glutSwapBuffers();}

основная функция

int main(int argc, char **argv){   

 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
 glutInitWindowSize(1280, 720);
 glutInitWindowPosition(50, 86);
 glutCreateWindow("2D correlation function");
 glClearColor(1,1,1,1.0);

 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 glFrustum(-150, 150, -150, 150, 200, 2000);
 glutMouseFunc(mouse);
 glutMotionFunc(motion);
 glutKeyboardFunc(keyboard);
 gluLookAt(200,400,200,0,0.0,0.0,0.0,0.0,1.0);
 glScalef(0.4, 0.4, 0.4);
 glutDisplayFunc(display);
 timer();
 glutMainLoop();


 return 0;}

функция щелчка мыши

void mouse(int button, int state, int x, int y){

 GLdouble objX, objY, objZ;
 GLdouble matModelView[16], matProjection[16];
 GLint viewport[4];
 glGetDoublev(GL_MODELVIEW_MATRIX, matModelView);
 glGetDoublev(GL_PROJECTION_MATRIX, matProjection);
 glGetIntegerv(GL_VIEWPORT, viewport);
 GLfloat winX = x;
 GLfloat winY = viewport[3] - y;
 GLfloat winZ = 0;
 glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
 cout << winX << " " << winY << " " << winZ << " " <<endl;
 gluUnProject(winX, winY, winZ, matModelView, matProjection, viewport, &objX, &objY, &objZ);
 cout << objX << " " << objY << " " << objZ << " " <<endl;}

Из-за этого мои мировые координаты отображаются неправильно:

пример щелчка мышью

другой пример

Я думаю, что я делаю что-то не так в Дисплей Процедура

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Параметр glEnable должен быть одной константой перечислителя.Параметр не является битовым полем.

Следующее недопустимо и приведет к ошибке GL_INVALID_ENUM, которая может быть обнаружена с помощью glGetError или Отладочный вывод :

glEnable(GL_DEPTH | GL_DEPTH_TEST);

Это должно быть

glEnable(GL_DEPTH_TEST);

В любом случае GL_DEPTH не является допустимым параметром для glEnable, но, возможно, это параметр glCopyPixels.
Обратите внимание, что значение константы счетчика GL_DEPTH_TEST равно 0x0B71, а значение GL_DEPTH равно 0x1801.Бинарная или (|) операция обеих констант не имеет никакого смысла.

Из-за этого проверка глубины никогда не была включена, и ничего не было записано в буфер глубины.


Также обратите внимание, что значения, которые принимаются для диапазона глубины glDepthRange, должны находиться в диапазоне [0, 1].Значения, которые передаются в glDepthRange, фиксируются в этом диапазоне, прежде чем они будут приняты.

Это означает, что

glDepthRange(200, 2000);

равно

glDepthRange(1, 1);

, поэтому диапазон глубины равен [1, 1] и все значения, возвращаемые glReadPixels, тоже равны 1.

Пропустить glDepthRange(200, 2000); для решения проблемы.


glGetDoublev(GL_MODELVIEW_MATRIX, matModelView) получает текущую модель представления матрицы из матрицы GL_MODELVIEW.glGetDoublev(GL_PROJECTION_MATRIX, matProjection) получает текущую матрицу проекции из стека матрицы GL_PROJECTION.

Таким образом, вы должны поместить матрицу проекции в стек матрицы GL_PROJECTION и матрицу вида в стек матрицы GL_MODELVIEW (см. glMatrixMode):

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-150, 150, -150, 150, 200, 2000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(200,400,200,0,0.0,0.0,0.0,0.0,1.0);
0 голосов
/ 22 февраля 2019

Вы пытались передать GLUT_DEPTH в glutInitDisplayMode?

Согласно документации GLUT, этот флаг необходим для создания буфера глубины.

...