螢幕座標到opengl世界座標轉換

2021-05-27 16:32:01 字數 2473 閱讀 8228

很多人用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...

SharpMap 螢幕座標到世界座標

計算機中有很多座標系,物件座標系 世界座標系 裁剪座標系 螢幕座標系!opengl流水線很容易實現上述順序的轉換。從網上查的資訊 1.裝置座標系與螢幕座標系 裝置座標 device coordinate 又稱為物理座標 physical coordinate 是指輸出裝置上的座標。通常將螢幕上的裝置...

opengl 螢幕座標

建立opengl模型過程 opengl座標變換很有特點,為了簡單描述先定義2個座標系 1 世界座標系 無論如何變換,世界座標系都不動,以螢幕中心為原點 0,0,0 你面對螢幕,你的右邊是x正軸,上面是y正軸,螢幕指向你的為z正軸。2 當前繪圖座標系 即區域性座標系 當前繪圖座標系是繪製物體時的座標系...