基于OpenGL显示平台功能开发-鼠标操作篇
2016-11-03 20:16
399 查看
基于OpenGL显示平台功能开发-鼠标操作篇
简介
前面章节已经讲了如何在MFC的 (View/Doc) 工程下搭建opengl应用程序,接下来主要讲如何对所搭建的应用程序添加用户操作,如场景模型支持鼠标的平移、旋转、缩放及透视投影与正交投影之间的相互切换功能。场景的平移与旋转
对场景的平移与旋转操作就好比一个静止不动的相机拍摄物体,此时如果相机视场范围内的物体发生了位移,那么物体投影到相机里所成的像也相应地发生了位移,那么就可以认为对场景里的模型进行了平移,对模型的旋转也是一样的道理。在OpenGL中,对场景模型进行平移和旋转所对应的操作分别要用到glTranslatef(…)和glRotatef(…)两个函数,功能代码实现如下:BOOL CMyOpenGLProjectView::RunScene() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // 实施投影变换,正投影,透视投影 Projection(); glPushMatrix(); // 视图沿 x,y轴平移 glTranslatef(m_xTranslation,m_yTranslation,0.0); // 场景绕 x,y,z轴旋转 glRotatef( sceneRot[0], 1.0F, 0.0F, 0.0F ); glRotatef( sceneRot[1], 0.0F, 1.0F, 0.0F ); glRotatef( sceneRot[2], 0.0F, 0.0F, 1.0F ); // 绘制场景 glPushMatrix(); m_pSceneRoot->Draw(); glPopMatrix(); glPopMatrix(); //交互缓冲区 ::SwapBuffers(m_pDC->GetSafeHdc()); return TRUE; }
场景的缩放
对场景的缩放不能简单地对模型直接用glScalef(…)函数来实现,这样虽然能实现物体的缩放功能,但并不是理想的效果。在实际应用中,我们可以调整相机与物体之间的距离或改变相机的视角来实现物体的缩放效果。但我们往往会选择后者,因为调整相机与物体之间的距离并不能保证物体始终处于相机的视眼范围之内,也就是在相机的近裁剪面与远裁剪面之外了,这样给用户的操作体验很不好。所以我们会从改变相机的观察视角来做这件事。1. 正投影和透视投影
物体在相机上的投影可分为正投影和透视投影。
正投影可用如下相机模型来表示:
这个函数的原型为:
glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far) ;
六个参数, 前两个是x轴最小坐标和最大坐标,中间两个是y轴,最后两个是z轴值
它创建一个平行视景体(就是一个长方体空间区域)。
实际上这个函数的操作是创建一个正射投影矩阵,并且用这个矩阵乘以当前矩阵。
其中近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),
右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。
注意,所有的near和far值同时为正或同时为负, 值不能相同。如果没有其他变换,正射投影的方向平行于Z轴,且视点朝向Z负轴。这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。
只有在视景体里的物体才能显示出来。
透视投影可以用如下相机模型来表示:
这个函数原型为:
void glFrustum(GLdouble left, GLdouble Right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
创建一个透视型的视景体。其操作是创建一个透视投影的矩阵,并且用这个矩阵乘以当前矩阵。这个函数的参数只定义近裁剪平面的左下角点和右上角点的三维空间坐标,即(left,bottom,-near)和(right,top,-near);最后一个参数far是远裁剪平面的离视点的距离值,其左下角点和右上角点空间坐标由函数根据透视投影原理自动生成。near和far表示离视点的远近,它们总为正值(near/far 必须>0),
gluPerspective(…)是glFrustum(…)的一个特例。
场景缩放可以通过如下调整相机的视角来实现,实现代码如下:
BOOL CMyOpenGLProjectView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (zDelta<0) { if (m_fViewAngle>=0.001f&&m_fViewAngle<2.5f) { m_fViewAngle+=0.1f; } else if (m_fViewAngle>=2.5f&&m_fViewAngle<179.0f) { m_fViewAngle += 2.5f; } } else { if (m_fViewAngle>=0.001f&&m_fViewAngle<=2.5f) { m_fViewAngle -= 0.1f; } else if (m_fViewAngle >2.5f&&m_fViewAngle<=179.0f) m_fViewAngle -= 2.5f; } if (m_fViewAngle<0.01f) m_fViewAngle = 0.01f; if (m_fViewAngle >=179.0f) m_fViewAngle = 179.0f; RunScene(); return CView::OnMouseWheel(nFlags, zDelta, pt); }
透视投影与正交投影的相互变换关系
根据相机的透视投影与正交投影模型,两者之间存在着特定的变换关系。实现代码如下:void CMyOpenGLProjectView::Projection() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (m_iProjectionMode == _ORTHO) // 正投影 { float oAngle,oLeft,oRight,oBottom,oTop; oAngle = m_fViewAngle*M_PI/180.0/2; oTop = camPos[2]*tan(oAngle); // 1500表示相机距离原点位置 oBottom = -oTop; oRight = oTop*m_width/m_height; oLeft = -oRight; glOrtho(oLeft,oRight,oBottom,oTop,1.0f,1000000.0f); } else { float pAngle,pLeft,pRight,pBottom,pTop; pAngle = m_fViewAngle*M_PI/180.0/2; pTop = 1.0f*tan(pAngle); //1.0f表示近距裁剪面 pBottom = -pTop; pRight = pTop*m_width/m_height; pLeft = -pRight; glFrustum(pLeft,pRight,pBottom,pTop,1.0f,1000000.0f); //gluPerspective(45.0F, m_width/m_height, 1.0F, 100000 a62b 0.0F); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(camPos[0],camPos[1],camPos[2],0,0,0,0,1,0); }
这样在实际应用时,只要改变m_iProjectionMode 这个参数的传入值就可以实现场景的透视投影与正交投影的相互变换了。
相关文章推荐
- 基于OpenGL显示平台功能开发-概述篇
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台一(C#开发)-系统功能介绍及展示
- 微软计划在开发平台集成F#语言 基于功能编程概念
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台一(C#开发)-系统功能介绍及展示
- 度量快速开发平台:网格部件焦点行数据实现窗体功能的显示与隐藏控制
- 全志平台boot里TVD倒车显示功能开发
- 安卓开发——Androidstudio设置鼠标悬浮其上显示文档注释功能
- 全志平台boot里TVD倒车显示功能开发
- 基于ArcEngine+C#开发的空间数据管理平台架构设计及功能说明
- 三、东软实践项目2-基于android平台的应用开发:打电话功与发短信功能
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台一(C#开发)-系统功能介绍及展示
- 基于组件化的监控平台开发监控Tomcat服务及邮件通知功能
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台二(C#开发)-登录功能模块
- 基于组件化的监控平台开发监控Tomcat服务及邮件通知功能
- 度量快速开发平台:网格部件焦点行数据实现窗体功能的显示与隐藏控制
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台二(C#开发)-登录功能模块
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台三(C#开发)-多皮肤主界面功能
- 全志平台boot里TVD倒车显示功能开发
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台三(C#开发)-多皮肤主界面功能
- 通用信息化开发平台 -- 通用权限管理系统改进登录日志显示功能