前面整理过一个,不过后来感觉不是很对,这里重新写一下。先解释一下这个问题,在OpenGL编程中,经常会需要与用户的交互,比如对视图进行指定点旋转,获取模型坐标点等。而这些操作最方便的就是通过鼠标进行操作,但鼠标只能获得屏幕坐标,那么如何转换到OpenGL世界坐标就成了一个亟待解决的问题。
一、理论基础
主要需要的是一些OpenGL观察流程相关知识,但也不是十分必要,大致了解即可。
二、屏幕坐标转换成世界坐标
// 数据结构
struct
{
};
// 函数体
Point3D
{
}
|
上面的函数的输入参数CPoint winpt可以由MFC的鼠标消息响应函数直接得到,当然,用其他语言应该也有相应的方法得到。
注意,网上有人认为需要增加视图已经做过的变换,个人认为不是很必要,因为modelview包含了需要的一切信息。
上面函数的关键语句是
这就是通过模型变换矩阵,投影矩阵,视口矩阵,由窗口坐标得到GL世界坐标的方法。
三、世界坐标转换成屏幕坐标
语句类似,关键几句为
glPushMatrix();
glGetDoublev(GL_MODELVIEW_MATRIX,
glGetDoublev(GL_PROJECTION_MATRIX,
glGetIntegerv(GL_VIEWPORT,
glPopMatrix();
gluProject(
|
四、计算固定点经过模型变换后坐标
这也是一个常见的问题,这并不需要什么特别的函数,只要将modelview乘以固定点的齐次坐标即可,对于三维空间中的点,其齐次坐标为[x, y, z, 1],另外前面说过,modelvew是一个16个元素的数组,就是一个列序的4x4矩阵,因此正好可以进行矩阵相乘。
struct
{
};
glGetFloatv(
Point3D
{
|
上面的m_mv获取是用
版权声明:本文为博主原创文章,未经博主允许不得转载。
- 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);
http://www.opengl.org/sdk/docs/man/xhtml/gluUnProject.xml gluUnProject()
http://www.opengl.org/sdk/docs/man/xhtml/gluProject.xml gluProject()
http://blog.csdn.net/abcdef8c/article/details/6716737 屏幕坐标到opengl世界坐标转换