[英]glReadPixels depth_buffer_component always returns 1
我正在嘗試從 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
值為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);
您是否嘗試過將 GLUT_DEPTH 傳遞給 glutInitDisplayMode?
根據 GLUT 文檔,需要標志來創建深度緩沖區。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.