2010-09-25 131 views
12

我已經看過很多Screen-Coordinate的世界座標帖子,但還沒有看到相反的情況。從我看過的任何角度看,有沒有一種簡單的方法可以從3d點獲取屏幕座標?我使用C++和OpenGL如何從3D點獲取屏幕座標? Opengl

+0

這是一個確切的副本http://stackoverflow.com/questions/724219/how-to-convert-a-3d-point-into-2d-perspective-projection/866749#866749 – 2010-09-25 10:53:13

+2

@Mads Elvheim:幾乎一個確切的副本。這個問題是針對C++和OpenGL的。另一個問題不是。事實上,另一個問題被標記爲「Java」。 – 2011-11-18 19:20:01

回答

4

屏幕座標的頂點就是它的投影和模型視圖矩陣乘法這樣頂點的結果:

screen_coordinates = projection_matrix * modelview_matrix * world_coordinates

您可以自己動手完成它(尤其是如果你用一些數學庫在基質上做操作),或者使用gluProject,例如:

std::array<GLfloat, 16> projection; 
std::array<GLfloat, 16> modelview; 
std::array<GLfloat, 3> screen_coords; 

glGetFloatv(GL_PROJECTION_MATRIX, projection.data()); 
glGetFloatv(GL_MODELVIEW_MATRIX, modelview.data()); 

gluProject(world_coords[0], world_coords[1], world_coords[2], 
    modelview.data(), projection.data(), 
    screen_coords.data(), screen_coords.data() + 1, screen_coords.data() + 2); 
+1

Downvote。 gluProject做正確的事情,但你的解釋不。將一個點與模型視圖矩陣和投影矩陣相乘即可​​得出剪輯空間座標,但*之前*除以w。它不會給你屏幕空間的座標。見巴巴爾的答案。 – 2010-09-25 10:49:06

+0

要判斷它是否提供了正確的空間座標,您需要更多關於OP的世界設置的詳細信息,例如我幾乎沒有使用視角設置爲我的2D遊戲。但看起來你的水晶球完美無缺,所以thv爲downvote :) – erjot 2010-09-26 21:04:03

+0

PS。不是OpenGL的(固定功能流水線)視口的PROJECTION矩陣包含設置?你需要明確地除以w的情況是什麼? GLSL默認是這樣做的。你使用的是視口,不管你是否知道,你使用的是 – erjot 2010-09-26 21:09:26

20

erjot的答案是不完整的。

還有兩件事要考慮。

  1. homogeneous = P . M . world,homogeneous向量是均勻空間中的4維向量。特別是,要使其回到[-1:1]^3立方體,需要將其前3個座標除以homogeneous.wcube.x = homogeneous.x/homogeneous.w(有人稱之爲投影鴻溝)。
  2. 然後,您需要通過對其應用視口轉換將[-1:1]^3立方體轉換爲窗口座標。 window.x = viewport.x + viewport.width * (cube.x+1)/2

如果你關心最終的Z,轉換不是通過視口,而是通過DepthRange。

2

另一件事。記住,gluProject給出座標系的起點在左下角開始的座標。屏幕座標從左上角開始。爲了獲得正確的屏幕座標值,必須從OpenGL設備的高度中減去y的值。

例如,在Qt的GLWidget繪製在(0,1,2)世界座標不言而喻文本:

gluProject(0,1,2,modelMatrix,projMatrix,sc.x,sc.y, sc.z); renderText(sc.x,height() - sc.y,「(0,1,2)」);