MFC+OpenGL 屏幕坐标转OpenGL坐标
程序员文章站
2022-07-04 09:09:10
...
最近在写一个例子用到了OpenGL,OpenGL的中心点(0, 0)点刚好是我们屏幕的中心点。因为我是需要动态的作图(画点、线、圆、弧...)需要平移 缩放图形,所以我在坐标转换这个问题上卡住了。
鼠标点击屏幕上的一点可以很方便的获得通过OnLButtonDown(),但是把取到的屏幕点转到OpenGL对应点却需要做相应的计算。用到的核心函数是gluUnProject(),如下:
glPushMatrix(); //与之相对应的glPopMatrix()也一定不能少
//这里的变换需要和绘图时一致,否则坐标会产生错误
glScalef(...); //缩放
glRotatef(...); //旋转
glTranslatef(...); //平移
glGetIntegerv( GL_VIEWPORT,viewport ); //得到的是最后一个设置视口的参数
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glPopMatrix();
winX = (float)point.x;
winY = (float)viewport[3] - (float)point.y;
glReadPixels(point.x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
从屏幕坐标向OpenGL坐标转换需要经过两步:第一步是屏幕坐标向视景体坐标转换,第二步是视景体坐标向OpenGL坐标转换。上述代码中winX = (float)point.x; winY = (float)viewport[3] - (float)point.y;反映第一步,gluUnProject()是第二步。一般说来,gluUnProject()的转换是不会出问题的。
想要不出现问题就必须:
1. 在glGetIntegerv()之前必须添上模型变换的代码,即和绘图时使用的模型变换代码一样;
2. 必须保证平移、缩放、旋转的顺序和绘图时的一致;另外,屏幕坐标向视景体坐标转换要正确;
3. 在多视口情况下,活动视口必须最后绘制,使它作为当前的视口,这样才能保证glGetIntegerv()等取值函数能够得到正确的值;
以下是我绘图时的代码,注意各种变换的顺序要和左边转换时一致
glPushMatrix();
glLoadIdentity();
glScalef(...);
glRotatef(...);
glTranslatef(...);
//两条坐标轴
glBegin(GL_LINES );
glColor3f(0.5f,1.0f,1.0f);
glVertex2f(ptStartX, ptStartY);
glVertex2f(ptEndX, ptEndY);
glEnd();
glPopMatrix();
上一篇: OpenGL学习(2)——绘制三角形
下一篇: GLFW绘制两个三角形拼接为一个矩形