c++ - glReadPixels depth_buffer_component 总是返回 1

标签 c++ visual-studio opengl glut glreadpixels

我正在尝试从我在 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;}

因此,我的世界坐标显示不正确:

鼠标点击示例

另一个例子

我认为我在显示过程中做错了什么

最佳答案

glEnable 的参数必须是单个枚举器常量。该参数不是位域。

以下是无效的,会产生一个GL_INVALID_ENUM错误,可以通过glGetError检测到或 Debug Output :

glEnable(GL_DEPTH | GL_DEPTH_TEST);

必须是

glEnable(GL_DEPTH_TEST);

无论如何,GL_DEPTH 不是glEnable 的有效参数,但它可能是glCopyPixels 的参数。 .
注意,枚举常量 GL_DEPTH_TEST 的值为 0x0B71GL_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 矩阵堆栈获取当前模型 View 矩阵。 glGetDoublev(GL_PROJECTION_MATRIX, matProjection)GL_PROJECTION 矩阵堆栈中获取当前投影矩阵。

因此,您应该将投影矩阵放在 GL_PROJECTION 矩阵堆栈上,将 View 矩阵放在 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);

关于c++ - glReadPixels depth_buffer_component 总是返回 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54834214/

相关文章:

c++ - 更改子类 CStatic 控件的背景颜色

javascript - Native Client 模块可以呈现由 C++ 代码生成的 HTML 吗?

c++ - 什么可能导致 OpenGL 在 "Start Debugging"和 "Start without debugging"选项下表现不同?

OpenGL 2D 形状问题

c++ - 对 staticMetaObject 的 undefined reference

c++ - Octave - 访问 octave_value_list 中的值

visual-studio-2010 - 执行 Ctrl + M、P 后无法折叠代码段

c++ - SetWindowshookEx 有时在 dll 注入(inject)后不起作用

asp.net-mvc - 将 razor View 渲染为字符串而不修改 html

OpenGL 和 Direct3D