OpenGL 螢幕二維座標轉化為三維模型座標

2021-07-09 03:21:32 字數 1586 閱讀 5166

我們把opengl裡模型的三維座標往二維座標的轉化稱為投影,則螢幕上的二維座標往三維座標轉化則可以稱為反投影,下面我們來介紹一下反投影的方法。

主要是gluunproject函式的使用,下面是**:

[cpp]view plain

copy

void

screen2glpoint()  

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

網上有的文章說還要考慮模型的旋轉、平移與縮放,即反投影的時候也要進行反旋轉、反平移與反縮放,但是經過我的實驗,這個是不用考慮的,因為反投影的時候匯出的三個矩陣就包含旋轉、平移與縮放的矩陣資訊。

但是,glreadpixels((

int)winx, (

int)winy, 1, 1, gl_depth_component, gl_float, &winz); 經常會出現winz值為1.0的情況。就像我所做的,功能是移動物體,如果winz的值為1.0之後,物體就跑的沒影了。

我們可以使用trace("point:%f, %f, %f  \t", winx, winy, winz);

trace("pos  :%f, %f, %f \n", posx, posy, posz);

跟蹤一下,居然發現如下的輸出:

point:633.000000, 301.000000, 0.963236

pos  :0.318562, -9.291403, 0.769923

point:633.000000, 298.000000, 1.000000

pos  :39.343056, -1186.848810, -9917.619793

注意這裡:當winz的值變成1.0的時候就出現錯誤了

經過多方查詢資料,發現了乙個重大的問題:

glrealpixels的定義是什麼?

——theglreadpixelsfunction reads a block of pixels from the framebuffer.

問題就出現在這裡。如果framebuffer裡面沒有東西,當然就讀取不出來了啊。所以就會出現上面的錯誤。

經驗證,果不然,如果滑鼠點在空白的位置   point:439.000000, 356.000000, 1.000000 

pos  :-2504.841247, -426.216424, -9799.354916

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

從螢幕座標向opengl

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

更多opengl章,請參考該部落格: 

遊戲世界座標轉化為UGUI螢幕座標

很多時候,我們需要把遊戲場景裡面的座標轉化為在ugui中顯示的座標。比如,血條的製作。這種方式和思路是一種通用思路,不論是ngui和ugui,思路都適用。下面針對於ugui 貼一下座標系轉化關係。如下 遊戲場景裡的物件的世界座標轉化到ui介面上的座標 賦值操作 物件.transform.positi...

Excle 二維表轉化為一維表

現在我們想做如下操作 想把表1的資料轉化為表2的資料,那麼我們只需要如下這段 即可解決需求 sub 轉置 dim i arr t1 ubound arr t2 ubound arr,2 redim brr 1 to t1 t2,1 to 3 for i 2 to t1 m 1 for k i to ...

OpenGL 三維到二維,座標系統

現實中的三維物體要畫到紙上,二維平面畫圖,就是點和線,三維是點線面,需要把三維的每個位置的空間座標 x,y,z 對映到二維平面座標 x,y 這可以通過線性代數知識解決。opengl通過各種變換實現,都是矩陣運算實現的 幾種變換簡介 參見opengl超級寶典第5章 變換用途 檢視指定觀察點的位置 模型...