簡體   English   中英

glReadPixels depth_buffer_component 總是返回 1

[英]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錯誤,可以通過glGetErrorDebug Output檢測到:

 glEnable(GL_DEPTH | GL_DEPTH_TEST);

它一定要是

glEnable(GL_DEPTH_TEST);

無論如何GL_DEPTH不是glEnable的有效參數,但它可能是glCopyPixels的參數。
注意,枚舉常量GL_DEPTH_TEST值為0x0B71GL_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM