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,一定要在視點和物體之間,否則是無法成像的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM