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