glReadPixels depth_buffer_component 总是 returns 1
glReadPixels depth_buffer_component always returns 1
我正在尝试从我在 OpenGL 中渲染的任何顶点获取世界坐标 window(我更喜欢使用 GLUT 库)。问题是当我调用 glReadPixels
函数来获取顶点的深度值时,它总是 returns a 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;}
因此,我的世界坐标显示不正确:
鼠标点击示例
另一个例子
我认为我在 显示 过程中做错了什么
您是否尝试过将 GLUT_DEPTH 传递给 glutInitDisplayMode?
根据 GLUT 文档,创建深度缓冲区需要标志。
glEnable
的参数必须是单个枚举器常量。该参数不是位域。
以下无效,会产生GL_INVALID_ENUM
错误,可通过glGetError
or Debug Output检测:
glEnable(GL_DEPTH | GL_DEPTH_TEST);
必须是
glEnable(GL_DEPTH_TEST);
无论如何 GL_DEPTH
不是 glEnable
的有效参数,但它可能是 glCopyPixels
.
的参数
注意,枚举数常量GL_DEPTH_TEST
的值为0x0B71
,GL_DEPTH
的值为0x1801
。两个常量的二进制或 (|
) 运算没有任何意义。
因此,depth test 从未被启用,也没有任何内容写入深度缓冲区。
进一步注意,深度范围 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);
我正在尝试从我在 OpenGL 中渲染的任何顶点获取世界坐标 window(我更喜欢使用 GLUT 库)。问题是当我调用 glReadPixels
函数来获取顶点的深度值时,它总是 returns a 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;}
因此,我的世界坐标显示不正确:
鼠标点击示例
另一个例子
我认为我在 显示 过程中做错了什么
您是否尝试过将 GLUT_DEPTH 传递给 glutInitDisplayMode?
根据 GLUT 文档,创建深度缓冲区需要标志。
glEnable
的参数必须是单个枚举器常量。该参数不是位域。
以下无效,会产生GL_INVALID_ENUM
错误,可通过glGetError
or Debug Output检测:
glEnable(GL_DEPTH | GL_DEPTH_TEST);
必须是
glEnable(GL_DEPTH_TEST);
无论如何 GL_DEPTH
不是 glEnable
的有效参数,但它可能是 glCopyPixels
.
的参数
注意,枚举数常量GL_DEPTH_TEST
的值为0x0B71
,GL_DEPTH
的值为0x1801
。两个常量的二进制或 (|
) 运算没有任何意义。
因此,depth test 从未被启用,也没有任何内容写入深度缓冲区。
进一步注意,深度范围 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);