zoukankan      html  css  js  c++  java
  • OpenGl从零开始之坐标变换(下)

      这节主要来理解投影变换和视口变换的使用。

    1、正射投影:glOrtho

    函数原型:

    void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far);
    //left和right:矩形视景体的左右平面,之间的距离为“宽”
    //bottom和top:矩形视景体的上下平面,之间的距离为“高”
    //near和far:矩形视景体的前后平面,之间的距离为“深度”
    void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top);//同glOrtho一样,只不过物体的Z轴坐标为0,缺省的近远平面距离为-1和1

    *注意:和glFrustum中的近远平面距离的含义不同:

      glFrustum中的近远平面距离:视点近、远平面的距离,只考虑距离,不考虑方向,所以必须是的。

      glOrtho中的近远平面距离:距离视点前后的距离,即视点可以在视景体内部(不可以设在物体内部),(-1,10),近平面在视点的后面1单位的距离,远平面在视点前方10单位距离

    void myDisplay(void)
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glColor3f(0,1,0);
    
        //glMatrixMode(GL_PROJECTION);下面的函数自动做了矩阵变换,这里可以不写
        glOrtho(-1,1,-1,1,-1,15);//视点在原点,而物体位移到-10处,为了能够看到物体,视景体就必须包含住物体,所以设置15
    
        //glMatrixMode(GL_MODELVIEW);下面的函数自动做了矩阵变换,这里可以不写
        glTranslatef(0,0,-10);
    
        glutWireTeapot(1);
    
        glFlush();
    }

    2、透视投影:glFrustum

    函数原型:

    void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far);

    left, right:裁剪窗口左右边界的平面距离,距离(视点与物体连线:中心线)的两侧距离。左右边界决定了视口的宽。

    bottom, top:裁剪窗口下上边界的平面距离,距离(视点与物体连线:中心线)的上下距离。上下边界决定了视口的高。

    znear, zfar:视点近、远平面的距离,必须是正的。

    由于使用的不多,所以直接看效果变换。

    (1)近平面距离为0

    void myDisplay(void)
    {
        glColor3f(0.0f, 1.0f, 0.0f);
        {
            //透视投影,通过参数GL_PROJECTION,将矩阵转为投影矩阵,然后设置系数,调节投影
            glMatrixMode(GL_PROJECTION);
            glFrustum(-1,1, -1,1, 0,2);//前四个变量控制棱台的宽高,宽:2,高:2 ,后两个调节远近。
    
            //模型变换,由于默认视点和模型都在原点,所以如果不设置模型移动,则视点在模型内部中心处,投影不能看到模型的整体
            glMatrixMode(GL_MODELVIEW);//可以不写,转换函数内部已转换矩阵模式
            glTranslatef(0,0,-1);
            glutWireSphere(0.5,20,20);
        }
        glFlush();
    }

    (2)改变宽和高

    glFrustum(-1,0,  -1,1, 1,2);//宽:1,高:2, "右半部分不显示==视线左移1",若近平面的距离为0,此时成像固定,其他参数调节不起作用。

    右半部分不显示==视线左移1

    (3)调节远近

    glFrustum(-1,1,  -1,1, 0.5,2);//近平面的距离为0.5:由于之前物体距离视点的距离为1,所以只能在0~1之间变化
    glFrustum(-1,1,  -1,1, 0.2,2);//近平面的距离为0.2:由于之前物体距离视点的距离为1,所以只能在0~1之间变化

    3、透视投影:gluPerspective

    函数原型:

    void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);
    //fovy:  指定视景体的视野的角度,以度数为单位,x、z平面张开的角度,比喻人眼的余光的范围。角度变小好比“眯眼”时,视野收缩到正前方,此时看到的物体会变小,距离会拉远。
    //aspect:指定你的视景体的宽高比,影响投影图像的宽高比例
    //zNear: 指定观察者到视景体的最近的裁剪面的距离(必须为正数)
    //zFar:  指定观察者到视景体的最远的裁剪面的距离(必须为正数)

    个人的理解:投影成像与图中是一个反过程,图中是向外放大到荧幕上,而视觉里则是逆向过程,汇聚成像。

    void myDisplay(void)
    {
        glColor3f(0.0f, 1.0f, 0.0f);
        {
            //透视投影,通过参数GL_PROJECTION,将矩阵转为投影矩阵,然后设置系数,调节投影
            glMatrixMode(GL_PROJECTION);
            gluPerspective(150,1,0,100);
    
            //模型变换,由于默认视点和模型都在原点,所以如果不设置模型移动,则视点在模型内部中心处,投影不能看到模型的整体
            glMatrixMode(GL_MODELVIEW);
            glTranslatef(0,0,-1);
            glutWireSphere(0.5,20,20);
        }
        glFlush();
    }

     

    (1)先看角度的变化效果

    直接修改上面代码中的gluPerspective(150,1,0,100),第一个参数代表实现张开的角度。

    借用一篇博客中对这部分的理解:http://blog.csdn.net/shuaihj/article/details/7228575

    我们眯眼时,视线张开的角度小,看到前方的物体就会更清晰,类似小孔成像、望远镜或者相机聚焦的感觉,成像的物体会拉近,显示比较大。当睁大眼睛时,我们的视野变大,发散,物体在视野内的变小,或者说眼大无神-_-。

    gluPerspective(55,1,0,100);
    gluPerspective(15,1,0,100);
    gluPerspective(170,1,0,100);

    (左边:55° ,中间:15° 右边:170°)

    (2)再看距离的变化效果

    物体的位置不动时,投影的成像结果是由角度决定的,视野角度固定,那么结果是不变的。这点与glFrustum不一样,更侧重于用角度来控制成像。

    需要注意的是,最近的平面:zNear,一定要在视点和物体之间,否则是无法成像的。

  • 相关阅读:
    oracle中Blob和Clob类型的区别
    为什么要分库分表
    Enable file editing in Visual Studio's debug mode
    SQL Server Dead Lock Log
    Debug .NET Framework Source
    SQL Server text field里面有换行符的时候copy到excel数据会散乱
    诊断和修复Web测试记录器(Web Test Recorder)问题
    Can't load Microsoft.ReportViewer.ProcessingObjectModel.dll
    'telnet' is not recognized as an internal or external command
    Linq to XML
  • 原文地址:https://www.cnblogs.com/gl5773477/p/4138460.html
Copyright © 2011-2022 走看看