屏幕坐标向OpenGL坐标的转换(完整版)

转载 2014年03月30日 20:27:22
屏幕坐标向OpenGL坐标的转换(完整版) 
我顶 字号:  

    很多人用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坐标转换      很多人用OpenGL绘图会遇到一个问题即屏幕坐标向OpenGL坐标转换,在网上流传着如下类似的代码:    注:(x, y)是屏幕坐标,(winX, winY...
  • Augusdi
  • Augusdi
  • 2014-08-15 23:27:13
  • 2640

opengl 获取鼠标在世界坐标系中的坐标

glMouseFun(fun);回调的函数void fun(int button,int state, int x, int y)中,(x,y)表示的是鼠标在窗口内的位置,我们需要将其转化为世界坐标系...
  • ivebeenready
  • ivebeenready
  • 2015-09-29 21:32:20
  • 2401

OpenGL实现鼠标绕任意轴旋转/平移/缩放

刚刚学opengl的童鞋肯定有个苦恼的麻烦,只会绘制一个三角形,但是想像那些三维软件那样用鼠标控制视角还是有点困难的,所以我就封装了一个场景漫游类:RoamingScenceManager,这个类使用...
  • trustguan
  • trustguan
  • 2016-03-06 10:57:03
  • 9994

OPENGL设备坐标系(dns)是左手坐标系,屏幕坐标系原点在左下角向上向右增加

OPENGL屏幕坐标系原点在左下角向上向右增加,D3D屏幕坐标系原点在左上角向下向右增加。 所以glViewPort的从设备坐标系变换到屏幕空间的变换公式为: 使得(-1,-1)到左下...
  • Blues1021
  • Blues1021
  • 2016-05-06 11:00:24
  • 2433

OpenGL中各种坐标系的理解

OPENGL坐标系可分为:世界坐标系和当前绘图坐标系。   世界坐标系:在OpenGL中,世界坐标系是以屏幕中心为原点(0, 0, 0),且是始终不变的。你面对           ...
  • meegomeego
  • meegomeego
  • 2013-03-18 13:40:07
  • 31905

Android OpenGL20 世界坐标系,屏幕坐标系,纹理坐标系 <8>

在  http://blog.csdn.net/qq_31726827/article/details/51265186这一篇大概介绍了坐标系,但是如何应用的呢?并没有特别说明,下面通过测试Sam...
  • qq_31726827
  • qq_31726827
  • 2016-05-20 19:23:22
  • 2448

OpenGL坐标系之间的转换

1. OpenGL 渲染管线 OpenGL渲染管线分为两大部分,模型观测变换(ModelView Transformation)和投影变换(Projection Transformation)。...
  • sac761
  • sac761
  • 2016-08-11 09:31:02
  • 5556

OpenGL之坐标转换(好文-清晰版)

下面这篇文章详细讲述了OpenGL里的坐标转换,清晰,明了。但是其所谓的渲染管线只包括modelview 转换 和 投影变换,我觉得不是这样的。这只是从坐标角度吧。比如什么顶点着色、光栅化、送至帧缓存...
  • zhongjling
  • zhongjling
  • 2013-01-10 11:17:26
  • 23892

利用OpenGL实现屏幕坐标与世界坐标的相互变换

  • 2009年03月07日 19:05
  • 154KB
  • 下载

屏幕坐标向OpenGL坐标转换

 很多人用OpenGL绘图会遇到一个问题即屏幕坐标向OpenGL坐标转换,在网上流传着如下类似的代码: GLint    viewport[4];  GLdouble modelview[16];  ...
  • sunnyjones
  • sunnyjones
  • 2007-06-06 14:58:00
  • 4620
收藏助手
不良信息举报
您举报文章:屏幕坐标向OpenGL坐标的转换(完整版)
举报原因:
原因补充:

(最多只允许输入30个字)