`
mmdev
  • 浏览: 12919411 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

Qt下的OpenGL 编程(9)3D视图变换、旋转的地球

 
阅读更多
一、提要
        视图变换是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+openglEs2加载3D模型Qt...

    Qt下openGL编程

    这是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加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种...

    qt opengl模拟地球—月球模型

    qt下,利用opengl模拟了月球绕地球旋转的情况,加入光照,纹理;

    Qt_OpenGL3D图形的绘制和旋转

    如果我们要绘制一个3D的四棱锥只需要绘制这5个面即可,绘制的方法和前一篇文章OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)的相同。只不过这里的顶点坐标是3维的,所以图像深度那一维不一定为0。因此我们可以事先...

    QT Opengl 图形旋转

    用QT5 写的Opengl 图形旋转小实例, 直接运行起来后, 需要拖动窗口,让窗口不停地重绘,才会出现有动态的效果。

    qt下OpenGL做的3d扫雷

    qt + OpenGL,做的3D扫雷,包括3D场景的旋转,鼠标位置计算,雷的计算等。

    Qt+OpenGL实现三维地形显示

    Qt+OpenGL实现三维地形显示,数字地图使用图片形式存储

    ubuntu下 qt5.5 利用opengl画3d坐标系

    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抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿...

    Linux下用QT开发OpenGL教程

    Linux下用QT开发OpenGL教程,浅显易懂!

    opengl+qt实现模型旋转平移

    opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移opengl+qt实现模型旋转平移...

    Qt5OpenGl.dll

    qt打包提示确实Qt5OpenGL.dll,可以用这个,或者下载威龙触摸屏程序安装后也可以得到

    QT+OPENGL 多线程测试

    本人原创,浅显易懂,QT+OPENGL多线程,采用2D纹理贴图的方式,多线程进行纹理拷贝和渲染。

    glwidget_QT_用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实现分屏效果Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl实现分屏效果Qt+opengl...

    基于Qt的OpenGL编程并能实现相应按钮点击事件

    这是我的毕设题目中写的软件,基本功能是输入数据,就会在opengl框中绘制图像,用到了matlab,opengl,是基于qt开发的(vs2013中的qt插件),里面都是调用到的操作opengl的方法,也是比较新的,网上有很多老的方法...

    基于QT的OpenGL实例源码

    基于QT的OpenGL实例源码

Global site tag (gtag.js) - Google Analytics