一、提要
视图变换是3D图形中的一个很重要的概念,需要一些抽象的思维去理解。说完概念之后我们会写一个自旋转的地球的例子来帮助理解。
二、照相机比喻
在《OpenGL Programming Guide 》中将所有的3D变换统一到一个有意思的现实世界模型,照相机比喻。
1.确定照相机的位置的过程对应于“视图变换”(Viewing Transformations)
2.确定物体位置的过程对应于“模型变换”(Modeling Transformations)
3.确定照相机放大倍数的过程对应于“投影变换”(Projection Transformations)
4.确定照片大小的过程对应于“视口变换”(Viewport Transformations)
之前我们有解释过一个函数:gluPerspective,它的作用就类似于设置摄像机的参数。
今天我们要重点了解的是:
void gluLookAt( GLdouble eyeX,
GLdouble eyeY,
GLdouble eyeZ,
GLdouble centerX,
GLdouble centerY,
GLdouble centerZ,
GLdouble upX,
GLdouble upY,
GLdouble upZ);
一共有9个参数,还是用一台摄像机来比喻,前三个参数就是摄像机所处的位置,
中间三个参数是摄像机要对准的地方,最后三个是摄像机观察的角度(横着看,竖着看,斜着看...).
三、自旋转地球
编程的思路:首先在空间建立一个球体,然后赋予地球的材质,利用之前的动画原理使它不断地绕着轴线旋转,通过改变不同的视图,我们可以观察到地球不同的旋转方式,而模型位置没有任何改变。
主要代码:
void NeHeWidget::initializeGL()
{
//载入纹理
loadGLTextures();
// 启用阴影平滑
glShadeModel( GL_SMOOTH );
// 黑色背景
glClearColor( 0.0, 0.0, 0.0, 0.0 );
// 设置深度缓存
glClearDepth( 1.0 );
// 启用深度测试
glEnable( GL_DEPTH_TEST );
//启用纹理
glEnable( GL_TEXTURE_2D );
// 所作深度测试的类型
glDepthFunc( GL_LEQUAL );
// 告诉系统对透视进行修正
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
// 开启剔除操作效果
glEnable(GL_CULL_FACE);
// 使用平滑法线
gluQuadricNormals(mySphere, GL_SMOOTH);
// 使用纹理
gluQuadricTexture(mySphere, GL_TRUE);
// 设置球纹理映射
}
void NeHeWidget::paintGL()
{
// 清除屏幕和深度缓存
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//移到屏幕的左半部分,并且将视图推入屏幕背后足够的距离以便我们可以看见全部的场景
//glTranslatef(0.0f,0.0f,zoom);
glRotatef( yRot, 0.0, 0.0, 1.0 );
glColor3f(1.0,1.0,1.0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glPushMatrix();
gluSphere(mySphere, 0.55f, 40, 40);
glPopMatrix();
//旋转速度
yRot += 0.4;
glLoadIdentity();
//gluLookAt (2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
//gluLookAt (0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0);
gluLookAt (2.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0);
glFlush();
//fps的字体颜色
glColor3f(0.0f,0.0f,1.0f);
//计算FPS
calFrequency();
}
这里用到的建立球的方式是二次曲面建模,比较简单主要过程如下:
//声明一个二次曲面
GLUquadricObj *mySphere;
//初始化
mySphere=gluNewQuadric();
//通过二次曲面建立球体
gluSphere(mySphere, 0.55f, 40, 40);
给二次曲面添加纹理的方法如下:
//剔除背面
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// 使用平滑法线
gluQuadricNormals(mySphere, GL_SMOOTH);
// 使用纹理
gluQuadricTexture(mySphere, GL_TRUE);
// 设置球纹理映射
glBindTexture(GL_TEXTURE_2D, texture[0]);
系统默认是两面贴图的,前面的两句话用于剔除我们看不到的面,节省系统开销。
但是,需要说明的是,背面剔除后,在转换视角,到背面变成正面的那一瞬间,会需要重新渲染背面,此时效率较低,事实上,这么一个简单的程序,再没有开启背面剔除时,从正面到背面的转换非常流畅,开启后,转换会有明显的小小迟缓,但是好处就是背面没有需要显示的时候是不占用资源的了,孰优孰劣,开启与否,那就只能看情况把握了。
最后的效果如下:
通过调节gluLookAt的参数,我们可以切换不同的视角。
参考资料
1.《OpenGL Reference Manual》,OpenGL参考手册
2.《OpenGL编程指南》(《OpenGL Programming Guide》),Dave Shreiner,Mason Woo,Jackie Neider,Tom Davis著,徐波译,机械工业出版社
3. 《win32 OpenGL编程 》 一个大牛的博客 http://blog.csdn.net/vagrxie/article/category/628716/3
分享到:
相关推荐
Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt...
这是Qt结合openGL的小程序,功能比较简单,仅供新手学习。本程序开发环境:Qt Creator4.0.2+Qt5.7 注:如果程序运行出错,那是因为缺少glut库。可以参考下面链接解决:...
Qt+opengl加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种...
qt下,利用opengl模拟了月球绕地球旋转的情况,加入光照,纹理;
如果我们要绘制一个3D的四棱锥只需要绘制这5个面即可,绘制的方法和前一篇文章OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)的相同。只不过这里的顶点坐标是3维的,所以图像深度那一维不一定为0。因此我们可以事先...
用QT5 写的Opengl 图形旋转小实例, 直接运行起来后, 需要拖动窗口,让窗口不停地重绘,才会出现有动态的效果。
qt + OpenGL,做的3D扫雷,包括3D场景的旋转,鼠标位置计算,雷的计算等。
Qt+OpenGL实现三维地形显示,数字地图使用图片形式存储
ubuntu16.04 下在qt 5.9.0 下采用opengl 利用glut画3维坐标系
OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿...
Linux下用QT开发OpenGL教程,浅显易懂!
opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移...
qt打包提示确实Qt5OpenGL.dll,可以用这个,或者下载威龙触摸屏程序安装后也可以得到
本人原创,浅显易懂,QT+OPENGL多线程,采用2D纹理贴图的方式,多线程进行纹理拷贝和渲染。
用QT的opengl显示图片,一个类的定义文件。
qt+opengl实现帧缓冲qt+opengl实现帧缓冲qt+opengl实现帧缓冲qt+opengl实现帧缓冲qt+opengl实现帧缓冲qt+opengl实现帧缓冲qt+opengl实现帧缓冲qt+opengl实现帧缓冲qt+opengl实现帧缓冲qt+opengl实现帧缓冲qt+opengl...
Qt+opengl实现爆破物体Qt+opengl实现爆破物体Qt+opengl实现爆破物体Qt+opengl实现爆破物体Qt+opengl实现爆破物体Qt+opengl实现爆破物体Qt+opengl实现爆破物体Qt+opengl实现爆破物体Qt+opengl实现爆破物体Qt+opengl...
Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl...
这是我的毕设题目中写的软件,基本功能是输入数据,就会在opengl框中绘制图像,用到了matlab,opengl,是基于qt开发的(vs2013中的qt插件),里面都是调用到的操作opengl的方法,也是比较新的,网上有很多老的方法...
基于QT的OpenGL实例源码