OpenGL固定管線設置投影矩陣

0.前言

OpenGL如果沒有設置投影矩陣,默認使用一個座標範圍在[-1.0,1.0]的正交投影。如果使用固定管線編程時要切換投影矩陣,步驟如下:

//切換當前矩陣爲投影矩陣
glMatrixMode(GL_PROJECTION);
//將當前矩陣置爲單位矩陣,即拋棄之前的更改
//OpenGL是狀態機,會保存之前的狀態
glLoadIdentity(); 
//設置投影矩陣
//如:設置爲正交投影
//void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
//如:設置透視投影
//void glFrustum(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble zNear,GLdouble zFar);
//或者這個透視投影
//void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);


//切換當前矩陣爲模型矩陣
glMatrixMode(GL_MODELVIEW);
//將當前矩陣置爲單位矩陣,即拋棄之前的更改
//OpenGL是狀態機,會保存之前的狀態
glLoadIdentity();
//一些view視圖或者model實體的操作,如視圖矩陣
//void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);

1.正交投影設置

對於正交投影,可使用glOrtho函數:

void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far) ;

創建一個正交投影矩陣,並且用這個矩陣乘以當前矩陣。
其中,近裁剪平面是一個矩形,矩形左下角點三維空間座標是(left,bottom,-near),右上角點是(right,top,-near);遠裁剪平面也是一個矩形,左下角點空間座標是(left,bottom,-far),右上角點是(right,top,-far)。只有在視景體裏的物體才能顯示出來。如果最後兩個值是(0,0),也就是near和far值相同了,視景體深度沒有了,也就沒法正常顯示。
注意,所有的near和far值同時爲正或同時爲負, 值不能相同。如果沒有其他變換,正交投影的方向平行於Z軸,且視點朝向Z負軸。這意味着物體在視點前面時far和near都爲負值,物體在視點後面時far和near都爲正值。

攝像機可以位於裁剪體內,所以near和far可以取兩個正值或者一正一負。

如:glOrtho(-1.0,2.0,-3.0,4.0,-5.0,6.0); 創建了一個x-left=-1,x-right=2,y-bottom=-3,y-top=4,z-near=5,z-far=-6的一個裁剪體,z爲一正一負說攝像機爲默認值時在內部。

2.透視投影設置

對於透視投影,可使用glFrustum或者gluPerspective函數。

首先看glFrustum:

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

創建一個透視投影的矩陣,並且用這個矩陣乘以當前矩陣。

這個函數的參數只定義近裁剪平面的左下角點和右上角點的三維空間座標,即(left,bottom,-near)和(right,top,-near);最後一個參數far是遠裁剪平面的離視點的距離值,其左下角點和右上角點空間座標由函數根據透視投影原理自動生成。near和far表示離視點的遠近,它們總爲正值(near/far 必須>0)。

攝像機不可以位於裁剪體內(?待研究),所以near和far都必須取正值,它的參數矩陣定義了裁剪體以及投影的類型,但是未定義攝像機的方位。OpenGL中的攝像機位於原點,並指向了Z軸的負方向。函數glFrustum只是修改了攝像機的 透鏡,並非位置,爲了改變位置或者朝向可以藉助於模型視圖矩陣相對於攝像機移動場景中的對象,或者通過變換,或者用函數gluLookAt()。因爲glFrustum對參數far和near非常敏感,修改near和far則遠景可能就影響很大,所以常用於觀察近景。

再來看gluPerspective(glu開頭的函數需要引入glu頭文件或相關庫):

void glPerspective(GLdouble fov, GLdouble aspect, GLdouble near, GLdouble far);

創建一個對稱的透視型視景體,並且用這個矩陣乘以當前矩陣。

gluPerspective功能和glFrustum函數類似,參數不一樣。參數fovy定義視野在Y-Z平面的角度,範圍是[0.0, 180.0];參數aspect是投影平面寬度與高度的比率;參數Near和Far分別是近遠裁剪面到視點(沿Z負軸)的距離,它們總爲正值,意義和glFrustum的一樣。

以上兩個函數缺省時,視點都在原點,視線沿Z軸指向負方向。

使用glFrustum自定義一個gluPerspective:

//這樣寫
void MyPerspective( GLdouble fov, GLdouble aspectRatio, GLdouble zNear, GLdouble zFar )
{
    GLdouble rFov = fov * 3.14159265 / 180.0;
    glFrustum( -zNear * tan( rFov / 2.0 ) * aspectRatio,
              zNear * tan( rFov / 2.0 ) * aspectRatio,
              -zNear * tan( rFov / 2.0 ),
              zNear * tan( rFov / 2.0 ),
              zNear, zFar );
}

//或者這樣寫
void MyPerspective(double fovy, double aspect, double zNear, double zFar)
{
    double xmin, xmax, ymin, ymax;
    ymax = zNear * tan(fovy * 3.14159265 / 360.0);
    ymin = -ymax;
    xmin = ymin * aspect;
    xmax = ymax * aspect;

    glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar);
}

3.參考

《OpenGL超級寶典》中文第五版

博客:https://blog.csdn.net/jiangdf/article/details/8460012

博客:https://www.cnblogs.com/zjzyh/p/4074583.html

博客:https://blog.csdn.net/peng6662001/article/details/7082436

博客:http://anony3721.blog.163.com/blog/static/51197420113206471827/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章