glLoadIdentity()
將當前的用戶坐標系的原點移到了屏幕中心:類似于一個復位操作 1.X坐標軸從左至右,Y坐標軸從下至上,Z坐標軸從里至外。 2.OpenGL屏幕中心的坐標值是X和Y軸上的0.0f點。 3.中心左面的坐標值是負值,右面是正值。 移向屏幕頂端是正值,移向屏幕底端是負值。 移入屏幕深處是負值,移出屏幕則是正值。
glTranslatef(x, y, z)
沿著 X, Y 和 Z 軸移動。
注意在glTranslatef(x, y, z)中,當您移動的時候,您并不是相對屏幕中心移動,而是相對與當前所在的屏幕位置。其作用就是將你繪點坐標的原點在當前原點的基礎上平移一個(x,y,z)向量。
畫三角形之前調用的glTranslatef(x, y, z) 是為了讓你所有的場景在可視區內。
因為opengl默認的攝像機位置在坐標原點(沒有調用gluLookAt改變視圖坐標系), 方向是 Z負向。如果不把物體畫在 -z 的區間上, 在此攝像機可視區內是看不到的。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
glLoadIdentity();
glTranslatef(-1.5f,0.0f,-6.0f); glBegin(GL_TRIANGLES); glVertex3f(0.0f,0.0f, 0.0f); glVertex3f(1.0f,0.0f, 0.0f); glVertex3f(0.0f,1.0f, 0.0f); glEnd();
glLoadIdentity(); glTranslatef(0.0f,0.0f,-6.0f); glBegin(GL_TRIANGLES); glVertex3f(0.0f,0.0f, 0.0f); glVertex3f(1.0f,0.0f, 0.0f); glVertex3f(0.0f,1.0f, 0.0f); glEnd();
/////////////////////////////////////////////////////////////////////////////////////
程序的運行結果如下:
左邊的三角形是第一步繪制的,可以看到該三角形繪制的坐標系,實際上是以(-1.5f,0.0f,-6.0f)為原點的。
第二個三角形繪制的時候,由于使用glLoadIdentity()使原點重新回到屏幕中心來,因此其原點位于屏幕的中心。
glRotatef(angle, x, y, z) 與glTranslatef(x, y, z)類似,glRotatef(angle, x, y, z)也是對坐標系進行操作。 旋轉軸經過原點,方向為(x,y,z),旋轉角度為angle,方向滿足右手定則。 //////////////////////////////////////////////////////////////// glLoadIdentity(); glTranslatef(0.0f,0.0f,-6.0f); glBegin(GL_TRIANGLES); glVertex3f(0.0f,0.0f, 0.0f); glVertex3f(1.0f,0.0f, 0.0f); glVertex3f(0.0f,1.0f, 0.0f); glEnd(); //////////////////////////////////////////////////////////////// 在未旋轉的情況下如圖所示:
//////////////////////////////////////////////////////////////// glLoadIdentity(); glRotatef(45,0.0f,0.0f,1.0f); glTranslatef(0.0f,0.0f,-6.0f); glBegin(GL_TRIANGLES); glVertex3f(0.0f,0.0f, 0.0f); glVertex3f(1.0f,0.0f, 0.0f); glVertex3f(0.0f,1.0f, 0.0f); glEnd(); //////////////////////////////////////////////////////////////// 繞Z軸正向旋轉45度角,因為Z軸正方向由屏幕內指向屏幕外,由右手定則可知方向為逆時針轉動。 由于直角頂點即為原點,因此將圍繞直角逆時針旋轉。

//////////////////////////////////////////////////////////////// glLoadIdentity(); glRotatef(45,0.0f,0.0f,1.0f); glLoadIdentity(); glTranslatef(0.0f,0.0f,-6.0f); glBegin(GL_TRIANGLES); glVertex3f(0.0f,0.0f, 0.0f); glVertex3f(1.0f,0.0f, 0.0f); glVertex3f(0.0f,1.0f, 0.0f); glEnd(); //////////////////////////////////////////////////////////////// 在旋轉之后加了一個復位的指令,圖形就不會旋轉了。
終于搞明白gluPerspective和gluLookAt的關系了
函數原型 gluLookAt(GLdoble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);
gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)
一個一個來,首先得設置gluPerspective,來看看它的參數都表示什么意思 fovy,這個最難理解,我的理解是,眼睛睜開的角度,即,視角的大小,如果設置為0,相當你閉上眼睛了,所以什么也看不到,如果為180,那么可以認為你的視界很廣闊, aspect,這個好理解,就是實際窗口的縱橫比,即x/y zNear,這個呢,表示你近處,的裁面, zFar表示遠處的裁面,
如果還沒有理解就繼續看, 我們知道,遠處的東西看起來要小一些,近處的東西看起來會大一些,這就是透視原理 如下圖所示
假設那兩條線表示公路,理論上講,它們的兩條邊是平行的, 但現實情況中,它們在遠方(可以無限遠)總要相交于一點, 實際線段AB的長度=CD的長度,只是在此例中使用了透視角,故會有如上的效果,是不是很接近現實的情況? 結合我們剛才這兩個函數 zNear,眼睛距離近處的距離,假設為10米遠,請不要設置為負值,OpenGl就傻了,不知道怎么算了, zFar表示遠處的裁面,假設為1000米遠, 就是這兩個參數的意義了, 再解釋下那個"眼睛睜開的角度"是什么意思, 首先假設我們現在距離物體有50個單位距離遠的位置, 在眼睛睜開角度設置為45時,請看大屏幕:
我們可以看到,在遠處一個球,,很好玩哈, 現在我們將眼睛再張開點看,將"眼睛睜開的角度"設置為178 (180度表示平角,那時候我們將什么也看不到,眼睛睜太大了,眼大無神)
我們只看到一個點,,,,,,,,,,,,,,,,,,,,,,,,,,, 因為我們看的范圍太大了,這個球本身大小沒有改變,但是它在我們的"視界"內太小了, 反之,我們將眼睛閉小些,改為1度看看會出現什么情況呢?
 在我們距離該物體3000距離遠,"眼睛睜開的角度"為1時,我們似乎走進了這個球內,這個是不是類似于相機的焦距? 當我們將"透視角"設置為0時,我們相當于閉上雙眼,這個世界清靜了, 我們什么也看不到,,,,,,,,,
現在來看gluLookAt(GLdoble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz); 它共接受三對坐標, 分別為eye,center,up 故名思義,eye表示我們眼睛在"世界坐標系"中的位置, center表示眼睛"看"的那個點的坐標, 最后那個up坐標表示觀察者本身的方向,如果將觀察點比喻成我們的眼睛,那么這個up則表示我們是正立還是倒立異或某一個角度在看,所看的影像大不相同,故此時需要指明我們現在正立,那么X,Z軸為0,Y軸為正即可,通常將其設置為1,只要表示一個向上的向量(方向)即可 球是畫在世界坐標系的原點上的,即O(0,0,0)坐標上,我們的眼睛位于觀察點A(0,0,100),Z軸向屏幕里看去的方向為負,屏幕外我們的位置,Z軸為正值,其實很好理解,即我們距離原點的距離,設置100,將觀察到如下圖所示的影像
如果我們向前或向后移動,則相應的圖像會變大或變小,這里其實就是運用了透視原理,近處的物體大,遠處的物體小,實際物體的大小是不變的,
同理改變center坐標(眼睛看去的那個點,可簡單理解為視線的終點)也會影響球的大小,同樣可以認為是改變了物體與觀察點的距離所致,
最后那個up坐標表示觀察者本身的方向,如果將觀察點比喻成我們的眼睛,那么這個up則表示我們是正立還是倒立異或某一個角度在看,所看的影像大不相同,故此時需要指明我們現在正立,那么X,Z軸為0,Y軸為正即可,通常將其設置為1,只要表示一個向上的向量(方向)即可,我們指定0.1f或0.00001f異或1000.0f,效果是一樣的,只要能表示方向即可, 以上理解了之后,來做一個測試 透視圖不變,最遠處仍為3000,近處為0.1
gluPerspective // 設置透視圖 (45, // 透視角設置為 45 度,在Y方向上以角度為單位的視野 (GLfloat)x/(GLfloat)y, // 窗口的寬與高比 0.1f, // 視野透視深度:近點1.0f 3000.0f // 視野透視深度:始點0.1f遠點1000.0f );
將我們的觀察點置于A(0,10,0), 將觀察位置(視線終點)坐標置于(0,0,0) 然后在原點開始繪圖,畫一個V字形,并將Z軸的值從-1000遞增加到+1000,增量為10, 代碼如下
glColor3f(0.5f, 0.7f, 1.0f);
glBegin(GL_LINES); for(int i=-1000;i<=1000;i+=10) { glVertex3f(0,0,i); glVertex3f(10,10,i);
glVertex3f(0,0,i); glVertex3f(-10,10,i); } glEnd(); F5運行效果如下圖

上圖證實了我們的推測
//--------------------------------------------- //生成網絡 glColor3f(0.5f, 0.7f, 1.0f); int x=(int)(40*2); glBegin(GL_LINES); for(int i=-x;i<=x;i+=4) { glVertex3i(-x,0,i); glVertex3i(x,0,i); glVertex3i(i,0,x); glVertex3i(i,0,-x); } glEnd(); //生成球體 GLUquadricObj * pObj; pObj = gluNewQuadric(); gluQuadricDrawStyle(pObj,GLU_LINE); gluQuadricNormals(pObj,GLU_SMOOTH); gluSphere(pObj,16,16,16); glTranslatef(0.0f,-20.0f,-40.0f)表示將當前圖形向x軸平移0,向y軸平移-20,向z軸平移-40 glScaled(10.0f,10.0f,10.0f)表示將當前圖形沿x,y,z軸分別放大為原來的10倍 glRotatef(-80.0f,10.0f,1.0f,0.0f)表示將當前圖形沿方向向量(-10,1,0)順時針旋轉80
|