實驗5 OpenGL變換綜合練習

1.實驗目的:html

理解掌握OpenGL程序的投影變換,能正確使用投影變換函數,實現正投影與透視投影。編程

2.實驗內容:函數

(1)使用圖a中的尺寸繪製小桌,三維效果圖見圖b。要求繪製小桌各部件時只能使用函數glutSolidCube()和變換函數,不能使用函數glVertex()等直接指定頂點位置;oop

(2)添加鍵盤按鍵或右鍵菜單控制實現小桌效果圖在正投影和透視投影模式間的切換;在此基礎上,考慮一點透視、兩點透視、三點透視三類效果圖的顯示。動畫

clip_image002clip_image004

3.實驗原理:.net

OpenGL經過相機模擬、能夠實現計算機圖形學中最基本的三維變換,即幾何變換、投影變換、視口變換等,同時,OpenGL還實現了矩陣堆棧等。理解掌握了有關座標變換的內容,就算真正走進了精彩地三維世界。設計

1、OpenGL中的三維物體的顯示orm

(一)座標系統htm

在現實世界中,全部的物體都具備三維特徵,但計算機自己只能處理數字,顯示二維的圖形,將三維物體及二維數據聯繫在一塊兒的惟一紐帶就是座標。blog

爲了使被顯示的三維物體數字化,要在被顯示的物體所在的空間中定義一個座標系。這個座標系的長度單位和座標軸的方向要適合對被顯示物體的描述,這個座標系稱爲世界座標系。世界座標系是始終固定不變的。

OpenGL還定義了局部座標系的概念,所謂局部座標系,也就是座標系以物體的中心爲座標原點,物體的旋轉或平移等操做都是圍繞局部座標系進行的,這時,當物體模型進行旋轉或平移等操做時,局部座標系也執行相應的旋轉或平移操做。須要注意的是,若是對物體模型進行縮放操做,則局部座標系也要進行相應的縮放,若是縮放比例在案各座標軸上不一樣,那麼再通過旋轉操做後,局部座標軸之間可能再也不相互垂直。不管是在世界座標系中進行轉換仍是在局部座標系中進行轉換,程序代碼是相同的,只是不一樣的座標系考慮的轉換方式不一樣罷了。

計算機對數字化的顯示物體做了加工處理後,要在圖形顯示器上顯示,這就要在圖形顯示器屏幕上定義一個二維直角座標系,這個座標系稱爲屏幕座標系。這個座標系座標軸的方向一般取成平行於屏幕的邊緣,座標原點取在左下角,長度單位常取成一個象素。

(二)三維物體的相機模擬

爲了說明在三維物體到二維圖象之間,須要通過什麼樣的變換,咱們引入了相機(Camera)模擬的方式,假定用相機來拍攝這個世界,那麼在相機的取景器中,就存在人眼和現實世界之間的一個變換過程。

clip_image005

圖1、相機模擬OpenGL中的各類座標變換

從三維物體到二維圖象,就如同用相機拍照同樣,一般都要經歷如下幾個步驟:

一、將相機置於三角架上,讓它對準三維景物,它至關於OpenGL中調整視點的位置,即視點變換(Viewing Transformation)。

二、將三維物體放在場景中的適當位置,它至關於OpenGL中的模型變換(Modeling Transformation),即對模型進行旋轉、平移和縮放。

三、選擇相機鏡頭並調焦,使三維物體投影在二維膠片上,它至關於OpenGL中把三維模型投影到二維屏幕上的過程,即OpenGL的投影變換(Projection Transformation),OpenGL中投影的方法有兩種,即正射投影和透視投影。爲了使顯示的物體能以合適的位置、大小和方向顯示出來,必需要經過投影。有時爲了突出圖形的一部分,只把圖形的某一部分顯示出來,這時能夠定義一個三維視景體(Viewing Volume)。正射投影時通常是一個長方體的視景體,透視投影時通常是一個棱臺似的視景體。只有視景體內的物體能被投影在顯示平面上,其餘部分則不能。

四、沖洗底片,決定二維相片的大小,它至關與OpenGL中的視口變換(Viewport Transformation)(在屏幕窗口內能夠定義一個矩形,稱爲視口(Viewport),視景體投影后的圖形就在視口內顯示)規定屏幕上顯示場景的範圍和尺寸。

2、OpenGL中的幾種變換

OpenGL中的各類轉換是經過矩陣運算實現的,具體的說,就是當發出一個轉換命令時,該命令會生成一個4X4階的轉換矩陣(OpenGL中的物體座標一概採用齊次座標,即(x, y, z, w),故全部變換矩陣都採用4X4矩陣),當前矩陣與這個轉換矩陣相乘,從而生成新的當前矩陣。例如,對於頂點座標v ,轉換命令一般在頂點座標命令以前發出,若當前矩陣爲C,轉換命令構成的矩陣爲M,則發出轉換命令後,生成的新的當前矩陣爲CM,這個矩陣再乘以頂點座標v,從而構成新的頂點座標CMv。上述過程說明,程序中繪製頂點前的最後一個變換命令最早做用於頂點之上。這同時也說明,OpenGL編程中,實際的變換順序與指定的順序是相反的。

(一)視點變換

視點變換肯定了場景中物體的視點位置和方向,就向上邊提到的,它象是在場景中放置了一架照相機,讓相機對準要拍攝的物體。確省時,相機(即視點)定位在座標系的原點(相機初始方向都指向Z負軸),它同物體模型的缺省位置是一致的,顯然,若是不進行視點變換,相機和物體是重疊在一塊兒的。

執行視點變換的命令和執行模型轉換的命令是相同的,想想,在用相機拍攝物體時,咱們能夠保持物體的位置不動,而將相機移離物體,這就至關於視點變換;另外,咱們也能夠保持相機的固定位置,將物體移離相機,這就至關於模型轉換。這樣,在OpenGL中,以逆時針旋轉物體就至關於以順時針旋轉相機。所以,咱們必須把視點轉換和模型轉換結合在一塊兒考慮,而對這兩種轉換單獨進行考慮是毫無心義的。

除了用模型轉換命令執行視點轉換以外,OpenGL實用庫還提供了gluLookAt()函數,該函數有三個變量,分別定義了視點的位置、相機瞄準方向的參考點以及相機的向上方向。該函數的原型爲:

void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery, GLdouble centerz ,GLdouble upx,GLdouble upy,GLdouble upz);

該函數定義了視點矩陣,並用該矩陣乘以當前矩陣。eyex,eyey,eyez定義了視點的位置;centerx、centery和centerz變量指定了參考點的位置,該點一般爲相機所瞄準的場景中心軸線上的點;upx、upy、upz變量指定了向上向量的方向。

一般,視點轉換操做在模型轉換操做以前發出,以便模型轉換先對物體發生做用。場景中物體的頂點通過模型轉換以後移動到所但願的位置,而後再對場景進行視點定位等操做。模型轉換和視點轉換共同構成模型視圖矩陣。

(二)模型變換

模型變換是在世界座標系中進行的。缺省時,物體模型的中心定位在座標系的中心處。OpenGL在這個座標系中,有三個命令,能夠模型變換。

glTranslate{fd}(TYPE x,TYPE y,TYPE z);

glRotate{fd}(TYPE angle,TYPE x,TYPE,y,TYPE z);

glScale{fd}(TYPE x,TYPE y,TYPE z);

(三)投影變換

通過模型視景的轉換後,場景中的物體放在了所但願的位置上,但因爲顯示器只能用二維圖象顯示三維物體,所以就要靠投影來下降維數(投影變換相似於選擇相機的鏡頭)。

事實上,投影變換的目的就是定義一個視景體,使得視景體外多餘的部分裁剪掉,最終進入圖像的只是視景體內的有關部分。投影包括透視投影(Perspective Projection)和正視投影(Orthographic Projection)兩種。

透視投影,符合人們心理習慣,即離視點近的物體大,離視點遠的物體小,遠到極點即爲消失,成爲滅點。它的視景體相似於一個頂部和底部都被進行切割過的棱椎,也就是棱臺。這個投影一般用於動畫、視覺仿真以及其它許多具備真實性反映的方面。

OpenGL透視投影函數有兩個,其中函數glFrustum()的原型爲:

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

它建立一個透視視景體。其操做是建立一個透視投影矩陣,而且用這個矩陣乘以當前矩陣。這個函數的參數只定義近裁剪平面的左下角點和右上角點的三維空間座標,即(left,bottom,-near)和(right,top,-near);最後一個參數far是遠裁剪平面的Z負值,其左下角點和右上角點空間座標由函數根據透視投影原理自動生成。near和far表示離視點的遠近,它們總爲正值。

另外一個透視函數是:

void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);

它也建立一個對稱透視視景體,但它的參數定義於前面的不一樣,參數fovy定義視野在X-Z平面的角度,範圍是[0.0, 180.0];參數aspect是投影平面寬度與高度的比率;參數zNear和Far分別是遠近裁剪面沿Z負軸到視點的距離,它們總爲正值。

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

正射投影,又叫平行投影。這種投影的視景體是一個矩形的平行管道,也就是一個長方體,如圖五所示。正射投影的最大一個特色是不管物體距離相機多遠,投影后的物體大小尺寸不變。這種投影一般用在建築藍圖繪製和計算機輔助設計等方面,這些行業要求投影后的物體尺寸及相互間的角度不變,以便施工或製造時物體比例大小正確。

OpenGL正射投影函數也有兩個,一個函數是:

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)。全部的near和far值同時爲正或同時爲負。若是沒有其餘變換,正射投影的方向平行於Z軸,且視點朝向Z負軸。這意味着物體在視點前面時far和near都爲負值,物體在視點後面時far和near都爲正值。

另外一個函數是:

void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)

它是一個特殊的正射投影函數,主要用於二維圖像到二維屏幕上的投影。它的near和far缺省值分別爲-1.0和1.0,全部二維物體的Z座標都爲0.0。所以它的裁剪面是一個左下角點爲(left,bottom)、右上角點爲(right,top)的矩形。

(四)視口變換。

視口變換就是將視景體內投影的物體顯示在二維的視口平面上。運用相機模擬方式,咱們很容易理解視口變換就是相似於照片的放大與縮小。在計算機圖形學中,它的定義是將通過幾何變換、投影變換和裁剪變換後的物體顯示於屏幕窗口內指定的區域內,這個區域一般爲矩形,稱爲視口。OpenGL中相關函數是:

glViewport(GLint x,GLint y,GLsizei width, GLsizei height);

這個函數定義一個視口。函數參數(x, y)是視口在屏幕窗口座標系中的左下角點座標,參數width和height分別是視口的寬度和高度。缺省時,參數值即(0, 0, winWidth, winHeight) 指的是屏幕窗口的實際尺寸大小。全部這些值都是以象素爲單位,全爲整型數。

4.示範代碼:

#include <GL/glut.h>

#include <stdlib.h>

void init(void)

{

glClearColor (0.0, 0.0, 0.0, 0.0);

glShadeModel (GL_FLAT);

glEnable(GL_DEPTH_TEST);

}

void display(void)

{

glClear (GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);

glColor3f (0.5, 0.5, 0.5);

glRotatef (30, 0.0, 1.0, 0.0);

glutSolidCube(1);

glColor3f (1.0, 0.0, 1.0);

glutWireCube(1);

glutSwapBuffers();

}

void reshape (int w, int h)

{

glViewport (0, 0, (GLsizei) w, (GLsizei) h);

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

}

int main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

glutInitWindowSize (500, 500);

glutInitWindowPosition (100, 100);

glutCreateWindow (argv[0]);

init ();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutMainLoop();

return 0;

}

分類: CG實驗指導

相關文章
相關標籤/搜索