zoukankan      html  css  js  c++  java
  • OpenGL中的投影使用

    OpenGL中的投影使用


             在OpenGL中,投影矩阵指定了可视区域的大小和形状。对于正投影与透视投影这两种不同的投影类型,它们分别有各自的用途。

    正投影

             它适用于2D图形,如文本、建筑画图等。在它的应用场合,我们希望在屏幕上展示准确的物体大小和度量。



    透视投影

             它使用透视除法,对距离观察者较远的物体进行缩短和收缩。由于可视区域前端和后端的宽度度量方法并不同样,导致两个逻辑大小同样的物体,当它们分别位于可视区域的前面和后面时,前者看上去要比后者大一些。

             下图展示了平截头体(frustum)所定义的透视投影,它的观察方向是从狭窄端到宽阔端。工具函数gluPerspective能够方便的定义一个平截头体:

          

             void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far);

            

             參数 fovy表示垂直方向的视野角度,aspect表示宽度与高度的纵横比,near与far表示近端和远端裁剪平面之间的距离。





             以下的代码设置使用了透视投影,展示了一个由太阳(黄色)、地球(红色)、月亮(灰色)三者构成的运动系统。这是一个经典的嵌套变换的样例,我们使用矩阵堆栈将一个物体依据还有一个物体进行变换,执行结果如图所看到的:






    /* 程序清单 4-3

     * 2014/5/18

     */

    #include <glut.h>

    #include <math.h>

     

    // 旋转的步进值

    static float fMoonRot =0.0f;

    static float fEarthRot= 0.0f;

     

    // 设置渲染状态

    void SetupRC()

    {

             // 设置清除窗体的颜色(黑色背景)

             glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

             // 设置画图颜色为绿色

             glColor3f(0.0f, 1.0f, 0.0f);

             // 打开深度測试

             glEnable(GL_DEPTH_TEST);

    }

     

    // 绘制场景(显示回调函数)

    void RenderScene()

    {

             // 用当前的清除颜色清除窗体

             glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);

             // 保存矩阵状态(模型视图矩阵)

             glMatrixMode(GL_MODELVIEW);

             glPushMatrix();

             // 平移坐标系,注意是相对于视觉坐标的位置

             glTranslatef(0.0f, 0.0f, -300.0f);

     

             // 绘制太阳

             glColor3ub(255, 255, 0);

             glutSolidSphere(15.0f, 15, 15);

             // 旋转坐标系,累加效果

             glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f);

     

             // 绘制地球

             glColor3ub(255, 0, 0);

             // 平移坐标系,累加效果

             glTranslatef(105.0f, 0.0f, 0.0f);

             // 设置地球的旋转步进

             fEarthRot += 5.0f;

             if(fEarthRot > 360.0f) {

                      fEarthRot = 0.0f;

             }

             glutSolidSphere(15.0f, 15, 15);

     

             // 绘制月球

             glColor3ub(200, 200, 200);

             // 旋转坐标系,累加效果

             glRotatef(fMoonRot, 0.0f, 1.0f, 0.0f);

             // 平移坐标系,累加效果

             glTranslatef(30.0f, 0.0f, 0.0f);

             // 设置月亮的旋转步进

             fMoonRot += 15.0f;

             if(fMoonRot > 360.0f) {

                      fMoonRot = 0.0f;

             }

             glutSolidSphere(6.0f, 15, 15);

     

             // 恢复矩阵状态(当前坐标系与视觉坐标重合)

             glPopMatrix();

     

             // 交换缓冲区,显示画面

             glutSwapBuffers();

    }

     

    // 当窗体大小改变时由GLUT函数库调用

    void ChangeSize(GLsizei w, GLsizei h)

    {

             // 窗体的纵横比

             GLfloat fAspect;

             // 防止被0

             if (0== h) {

                      h = 1;

             }

             // 将视口设置为窗体的大小

             glViewport(0, 0, w, h);

             // 计算窗体的纵横比

             fAspect = (GLfloat)w / (GLfloat)h;

             // 设置当前操作的矩阵为投影矩阵

             glMatrixMode(GL_PROJECTION);

             glLoadIdentity();

             // 定义平截头体, 45度视野,近、远平面为1.0425.0

             gluPerspective(45.0f,fAspect, 1.0, 425.0);

             // 设置当前操作的矩阵为模型视图矩阵

             glMatrixMode(GL_MODELVIEW);

             glLoadIdentity();

    }

     

    // 计时器函数,每秒触发10次窗体重绘事件

    void TimerFunc(intvalue)

    {

             glutPostRedisplay();

             glutTimerFunc(100, TimerFunc, 1);

    }

     

    int main(int argc,char *argv[])

    {

             // 传递命令行參数,并对GLUT函数库进行初始化

             glutInit(&argc, argv);

             // 设置创建窗体时的显示模式(双缓冲区、RGB颜色模式)

             glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);

             // 设置窗体的初始大小

             glutInitWindowSize(480, 320);

             // 创建窗体

             glutCreateWindow("Bounce");

             // 设置显示回调函数

             glutDisplayFunc(RenderScene);

             // 设置当窗体的大小发生变化时的回调函数

             glutReshapeFunc(ChangeSize);

             // 设置计时器函数

             glutTimerFunc(100, TimerFunc, 1);

             // 设置渲染状态

             SetupRC();

             // 启动GLUT框架的执行,一经调用便不再返回,直到程序终止

             glutMainLoop();

     

             return0;

    }

  • 相关阅读:
    VS2010下配置CxImage
    Visual Studio 2010 开发配置
    主机屋使用感受
    Web开发者必备的20款超赞jQuery插件
    自动页面居中
    jQuery+CSS打造的网页背景颜色切换效果
    小按钮,大学问
    【网站开发必备】——12款响应式 Lightbox(灯箱)效果插件
    修正 IE 的双倍页边距 bug
    a>b?a:b
  • 原文地址:https://www.cnblogs.com/yxwkf/p/3852793.html
Copyright © 2011-2022 走看看