glLoadIdentity()


將當(dāng)前的用戶坐標(biāo)系的原點(diǎn)移到了屏幕中心:類似于一個(gè)復(fù)位操作
1.X坐標(biāo)軸從左至右,Y坐標(biāo)軸從下至上,Z坐標(biāo)軸從里至外。
2.OpenGL屏幕中心的坐標(biāo)值是X和Y軸上的0.0f點(diǎn)。
3.中心左面的坐標(biāo)值是負(fù)值,右面是正值。
   移向屏幕頂端是正值,移向屏幕底端是負(fù)值。
   移入屏幕深處是負(fù)值,移出屏幕則是正值。

glTranslatef(x, y, z)

沿著 X, Y 和 Z 軸移動(dòng)。

注意在glTranslatef(x, y, z)中,當(dāng)您移動(dòng)的時(shí)候,您并不是相對(duì)屏幕中心移動(dòng),而是相對(duì)與當(dāng)前所在的屏幕位置。其作用就是將你繪點(diǎn)坐標(biāo)的原點(diǎn)在當(dāng)前原點(diǎn)的基礎(chǔ)上平移一個(gè)(x,y,z)向量。

畫(huà)三角形之前調(diào)用的glTranslatef(x, y, z) 是為了讓你所有的場(chǎng)景在可視區(qū)內(nèi)。

因?yàn)閛pengl默認(rèn)的攝像機(jī)位置在坐標(biāo)原點(diǎn)(沒(méi)有調(diào)用gluLookAt改變視圖坐標(biāo)系), 方向是 Z負(fù)向。如果不把物體畫(huà)在 -z 的區(qū)間上, 在此攝像機(jī)可視區(qū)內(nèi)是看不到的。


/////////////////////////////////////////////////////////////////////////////////////////////////////////////

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();

/////////////////////////////////////////////////////////////////////////////////////

程序的運(yùn)行結(jié)果如下:

 

左邊的三角形是第一步繪制的,可以看到該三角形繪制的坐標(biāo)系,實(shí)際上是以(-1.5f,0.0f,-6.0f)為原點(diǎn)的。

第二個(gè)三角形繪制的時(shí)候,由于使用glLoadIdentity()使原點(diǎn)重新回到屏幕中心來(lái),因此其原點(diǎn)位于屏幕的中心。

glRotatef(angle, x, y, z)
與glTranslatef(x, y, z)類似,glRotatef(angle, x, y, z)也是對(duì)坐標(biāo)系進(jìn)行操作。
旋轉(zhuǎn)軸經(jīng)過(guò)原點(diǎn),方向?yàn)?x,y,z),旋轉(zhuǎn)角度為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();
////////////////////////////////////////////////////////////////
在未旋轉(zhuǎn)的情況下如圖所示:

 

////////////////////////////////////////////////////////////////
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軸正向旋轉(zhuǎn)45度角,因?yàn)閆軸正方向由屏幕內(nèi)指向屏幕外,由右手定則可知方向?yàn)槟鏁r(shí)針轉(zhuǎn)動(dòng)。
由于直角頂點(diǎn)即為原點(diǎn),因此將圍繞直角逆時(shí)針旋轉(zhuǎn)。

 

////////////////////////////////////////////////////////////////
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();
////////////////////////////////////////////////////////////////
在旋轉(zhuǎn)之后加了一個(gè)復(fù)位的指令,圖形就不會(huì)旋轉(zhuǎn)了。

終于搞明白gluPerspective和gluLookAt的關(guān)系了

函數(shù)原型
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)

一個(gè)一個(gè)來(lái),首先得設(shè)置gluPerspective,來(lái)看看它的參數(shù)都表示什么意思
fovy,這個(gè)最難理解,我的理解是,眼睛睜開(kāi)的角度,即,視角的大小,如果設(shè)置為0,相當(dāng)你閉上眼睛了,所以什么也看不到,如果為180,那么可以認(rèn)為你的視界很廣闊,
aspect,這個(gè)好理解,就是實(shí)際窗口的縱橫比,即x/y
zNear,這個(gè)呢,表示你近處,的裁面,
zFar表示遠(yuǎn)處的裁面,

如果還沒(méi)有理解就繼續(xù)看,
我們知道,遠(yuǎn)處的東西看起來(lái)要小一些,近處的東西看起來(lái)會(huì)大一些,這就是透視原理
如下圖所示




假設(shè)那兩條線表示公路,理論上講,它們的兩條邊是平行的,
但現(xiàn)實(shí)情況中,它們?cè)谶h(yuǎn)方(可以無(wú)限遠(yuǎn))總要相交于一點(diǎn),
實(shí)際線段AB的長(zhǎng)度=CD的長(zhǎng)度,只是在此例中使用了透視角,故會(huì)有如上的效果,是不是很接近現(xiàn)實(shí)的情況?

結(jié)合我們剛才這兩個(gè)函數(shù)
zNear,眼睛距離近處的距離,假設(shè)為10米遠(yuǎn),請(qǐng)不要設(shè)置為負(fù)值,OpenGl就傻了,不知道怎么算了,
zFar表示遠(yuǎn)處的裁面,假設(shè)為1000米遠(yuǎn),
就是這兩個(gè)參數(shù)的意義了,

再解釋下那個(gè)"眼睛睜開(kāi)的角度"是什么意思,
首先假設(shè)我們現(xiàn)在距離物體有50個(gè)單位距離遠(yuǎn)的位置,
在眼睛睜開(kāi)角度設(shè)置為45時(shí),請(qǐng)看大屏幕:


我們可以看到,在遠(yuǎn)處一個(gè)球,,很好玩哈,
現(xiàn)在我們將眼睛再?gòu)堥_(kāi)點(diǎn)看,將"眼睛睜開(kāi)的角度"設(shè)置為178
(180度表示平角,那時(shí)候我們將什么也看不到,眼睛睜太大了,眼大無(wú)神)


我們只看到一個(gè)點(diǎn),,,,,,,,,,,,,,,,,,,,,,,,,,,
因?yàn)槲覀兛吹姆秶罅?這個(gè)球本身大小沒(méi)有改變,但是它在我們的"視界"內(nèi)太小了,


反之,我們將眼睛閉小些,改為1度看看會(huì)出現(xiàn)什么情況呢?


在我們距離該物體3000距離遠(yuǎn),"眼睛睜開(kāi)的角度"為1時(shí),我們似乎走進(jìn)了這個(gè)球內(nèi),這個(gè)是不是類似于相機(jī)的焦距?

當(dāng)我們將"透視角"設(shè)置為0時(shí),我們相當(dāng)于閉上雙眼,這個(gè)世界清靜了,

我們什么也看不到,,,,,,,,,



現(xiàn)在來(lái)看gluLookAt(GLdoble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);

它共接受三對(duì)坐標(biāo),
分別為eye,center,up
故名思義,eye表示我們眼睛在"世界坐標(biāo)系"中的位置,
center表示眼睛"看"的那個(gè)點(diǎn)的坐標(biāo),
最后那個(gè)up坐標(biāo)表示觀察者本身的方向,如果將觀察點(diǎn)比喻成我們的眼睛,那么這個(gè)up則表示我們是正立還是倒立異或某一個(gè)角度在看,所看的影像大不相同,故此時(shí)需要指明我們現(xiàn)在正立,那么X,Z軸為0,Y軸為正即可,通常將其設(shè)置為1,只要表示一個(gè)向上的向量(方向)即可
球是畫(huà)在世界坐標(biāo)系的原點(diǎn)上的,即O(0,0,0)坐標(biāo)上,我們的眼睛位于觀察點(diǎn)A(0,0,100),Z軸向屏幕里看去的方向?yàn)樨?fù),屏幕外我們的位置,Z軸為正值,其實(shí)很好理解,即我們距離原點(diǎn)的距離,設(shè)置100,將觀察到如下圖所示的影像

如果我們向前或向后移動(dòng),則相應(yīng)的圖像會(huì)變大或變小,這里其實(shí)就是運(yùn)用了透視原理,近處的物體大,遠(yuǎn)處的物體小,實(shí)際物體的大小是不變的,

同理改變center坐標(biāo)(眼睛看去的那個(gè)點(diǎn),可簡(jiǎn)單理解為視線的終點(diǎn))也會(huì)影響球的大小,同樣可以認(rèn)為是改變了物體與觀察點(diǎn)的距離所致,

最后那個(gè)up坐標(biāo)表示觀察者本身的方向,如果將觀察點(diǎn)比喻成我們的眼睛,那么這個(gè)up則表示我們是正立還是倒立異或某一個(gè)角度在看,所看的影像大不相同,故此時(shí)需要指明我們現(xiàn)在正立,那么X,Z軸為0,Y軸為正即可,通常將其設(shè)置為1,只要表示一個(gè)向上的向量(方向)即可,我們指定0.1f或0.00001f異或1000.0f,效果是一樣的,只要能表示方向即可,




以上理解了之后,來(lái)做一個(gè)測(cè)試
透視圖不變,最遠(yuǎn)處仍為3000,近處為0.1

gluPerspective                            // 設(shè)置透視圖
        (45,                            // 透視角設(shè)置為 45 度,在Y方向上以角度為單位的視野
        (GLfloat)x/(GLfloat)y,    // 窗口的寬與高比
        0.1f,                                // 視野透視深度:近點(diǎn)1.0f
        3000.0f                            // 視野透視深度:始點(diǎn)0.1f遠(yuǎn)點(diǎn)1000.0f
        );


將我們的觀察點(diǎn)置于A(0,10,0),
將觀察位置(視線終點(diǎn))坐標(biāo)置于(0,0,0)
然后在原點(diǎn)開(kāi)始繪圖,畫(huà)一個(gè)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運(yùn)行效果如下圖


上圖證實(shí)了我們的推測(cè)











//---------------------------------------------
    //生成網(wǎng)絡(luò)
    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)表示將當(dāng)前圖形向x軸平移0,向y軸平移-20,向z軸平移-40
glScaled(10.0f,10.0f,10.0f)表示將當(dāng)前圖形沿x,y,z軸分別放大為原來(lái)的10倍
glRotatef(-80.0f,10.0f,1.0f,0.0f)表示將當(dāng)前圖形沿方向向量(-10,1,0)順時(shí)針旋轉(zhuǎn)80