• 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,一定要在视点和物体之间,否则是无法成像的。

  • 相关阅读:
    ubuntu20.04.2设置配置静态ip方法
    如何在windows10上面运行HyperLedger Fabric1.4
    powershell中临时修改环境变量
    openssl查看pem格式证书细节
    git clone的时候遭遇fatal: early EOF fatal: index-pack failed解决办法
    修改sourcetree的推送账户
    ubuntu上kafka的配置与使用(二)--kafka和zookeeper集群的配置(kafka自带的zookeeper)
    ubuntu上kafka的配置与使用(一)--单机kafka的配置
    李航老师的《统计学习方法》第二章算法的matlab程序
    第8题——计算糖果
  • 原文地址:https://www.cnblogs.com/gl5773477/p/4138460.html
Copyright © 2020-2023  润新知