螢幕座標向opengl三維座標轉換

2021-06-08 09:29:57 字數 2504 閱讀 5549

很多人用opengl繪圖會遇到乙個問題即螢幕座標向opengl座標轉換,在網上流傳著如下類似的**:

glint    viewport[4]; 

gldouble modelview[16]; 

gldouble projection[16]; 

glfloat  winx, winy, winz; 

gldouble posx, posy, posz;

glgetintegerv(gl_viewport, viewport); 

glgetdoublev(gl_modelview_matrix, modelview); 

glgetdoublev(gl_projection_matrix, projection);

winx = (float)x; 

winy = viewport[3] - (float)y;

glreadpixels((int)winx, (int)winy, 1, 1, gl_depth_component, gl_float, &winz); 

gluunproject(winx, winy, winz, modelview, projection, viewport, &posx, &posy, &posz); 

注:(x, y)是螢幕座標,(winx, winy, winz)是視景體座標及深度座標,(posx, posy, posz是opengl座標

上述**並不保險,只針對一種特殊情況才好使,即glviewport(0, 0, screenwidth, screenheight),screenwidth、screenheight分別是客戶區的寬和高,視口左下角座標恰好是(0,0),並且未經過任何模型變換。

從螢幕座標向opengl

座標要經過兩步,第一步是螢幕座標向視景體座標轉換,第二步是視景體座標向opengl座標轉換。上述**中winx = (float)x;  winy = viewport[3] - (float)y;反映第一步,gluunproject是第二步。一般說來,gluunproject的轉換是不會出問題的。

如何進行正確的轉換呢?首先,在glgetintegerv之前添上模型變換的**,和繪圖時使用的模型變換**一樣,另外必須保證平移,縮放,旋轉的順序和繪圖時的一樣。其次,螢幕座標向視景體座標轉換有兩種方式(注意!在多視口情況下,活動視應當最後繪製,它將作為當前的視口,保證glgetintegerv等取值函式能得到正確的值)。①winx = x – viewport[0]; winy = screenheight – viewport[1] - y; viewport[0] = viewport[1] = 0;②winx = x; winy = screenheight – y;第一種比較直觀,前兩句是將螢幕座標轉換為視景體內的座標,後兩句將視景體的左下角點座標改為(0,0),因為在設定裁剪視口時,使用glviewport設定視口的左下角點座標不一定是(0,0),而在視景體內的點其視景體座標與左下角點是相對的,即把視景體座標看作是座標系原點。第二種方式比較簡略,但是同樣的道理,只不過是glunproject函式對winx和winy又做了一次轉換。

好了,現在給出完整的**,如下:

glint    viewport[4]; 

gldouble modelview[16]; 

gldouble projection[16]; 

glfloat  winx, winy, winz; 

gldouble posx, posy, posz;

glpushmatrix();

// 變換要繪圖函式裡的順序一樣,否則座標轉換會產生錯誤

glscalef(m_srtmatrix[0], m_srtmatrix[1], m_srtmatrix[2]); // 縮放、平移、旋轉變換

glrotatef(m_srtmatrix[3], 1.0f, 0.0f, 0.0f);

glrotatef(m_srtmatrix[4], 0.0f, 1.0f, 0.0f);

glrotatef(m_srtmatrix[5], 0.0f, 0.0f, 1.0f);

gltranslatef(m_srtmatrix[6], m_srtmatrix[7], m_srtmatrix[8]);

glgetintegerv(gl_viewport, viewport); // 得到的是最後乙個設定視口的引數

glgetdoublev(gl_modelview_matrix, modelview); 

glgetdoublev(gl_projection_matrix, projection);

glpopmatrix();

winx = x; 

winy = screenheight - y;

glreadpixels((int)winx, (int)winy, 1, 1, gl_depth_component, gl_float, &winz); 

gluunproject(winx, winy, winz, modelview, projection, viewport, &posx, &posy, &posz);

來自:

OpenGL由螢幕座標轉換三維座標

很多人用opengl繪圖會遇到乙個問題即螢幕座標向opengl座標轉換,在網上流傳著如下類似的 glint viewport 4 gldouble modelview 16 gldouble projection 16 glfloat winx,winy,winz gldouble posx,pos...

opengl中將三維座標轉換到螢幕座標

opengl的通過四個變換,得到的結果就是螢幕上的畫素座標。前三個變換 model,view,projection 都是4x4矩陣,操作物件是四維向量,所以需要把 x,y,z 補上w分量,變成 x,y,z,1 然後把前三個變換的矩陣依次左乘到這個向量上,得到的四維向量做齊次除法 所有分量都除以w分量...

OpenGL 螢幕座標向OpenGL座標轉換

螢幕座標向opengl座標轉換 很多人用opengl繪圖會遇到乙個問題即螢幕座標向opengl座標轉換,在網上流傳著如下類似的 glint viewport 4 gldouble modelview 16 gldouble projection 16 glfloat winx,winy,winz g...