1.方法一:
見連結: OpenGL之坐标轉換
最後要注意的事情是在擷取變換矩陣和視口的時候有可能發生錯誤,是以這時需要重新做變換矩陣代碼如下:
<span style="white-space:pre"> </span>GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;
glPushMatrix();
openglPaint();
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
render();
winX = x;
winY = (float)viewport[3] - y;
glReadPixels((int)x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
glPopMatrix();
Point3d v(posX, posY, posZ);
return v;
2.方法2:這種方法主要針對透視投影,而且需要手動維護變換矩陣。根據透視投影關系得到螢幕坐标對應的物體平面上的點在世界坐标系下的坐标
<span style="white-space:pre"> </span>// 視口中心的螢幕坐标
int w,h,x,y;
w= width;
h = height;
x = w/2;
y = h/2;
// 計算在center平面上的投影點
double dis = distance(center, eye);
double viewHeight = dis * tan(PI * fovy / 360 ) * 2;
double viewWidth = aspect * viewHeight;
// 計算近平面的中心
Vector3d nCenter = dir.SetUnit() * dis ;
nCenter += eye;
Vector3d vt;
vt = up^dir;
up.SetUnit();
vt.SetUnit();
double xData = (double)(point.x - x) / (double)w * viewWidth;
double yData = ((double)(h - point.y -y) / (double)h * viewHeight);
p3d = nCenter + vt * xData +up * yData;
3.方法3:針對正交投影,這種情況比較特殊,很容易計算,但是這種情況下獲得的x,y坐标是正确的,z坐标可以根據需要來指定。
int centerx = width/2;
int centery = height/2;
double x = point.x - centerx;
double y = height - point.y - centery;
double z = 0;
p3d.setAll(x,y,z);