OpenGL學習——glut/ glMatrixMode()、旋轉、平移

因爲可能要做太陽系,所以通過此程序先了解一下,順便學習以下知識。沒有列出來的,代碼裏如果有註釋的話,也要看一下。

學習要點

理解glMatrixMode()設置的幾種變換。

瞭解gluPerspective()和gluLookAt()的參數,清楚他們該如何使用的。理解OpenGL下的三維座標的展示,觀察一個物體的角度。

理解深度緩衝區。

瞭解怎麼用glutSolidSphere()畫一個圓。

關於旋轉和平移的用法,glRotatef(),glTranslatef()。

相關學習資料

glMatrixMode()

gluPerspective()和gluLookAt()

要點簡單解析

其實就是註釋裏寫的,解釋的比較簡單,主要是函數參數解釋,詳細解釋和深入理解還得看其他的文章。

投影變換

glMatrixMode(GL_PROJECTION);

gluPerspective(75, 1, 1, 2000);

在投影變換下才能設置。透視投影空間, 近大遠小的那種感覺。

參數:
眼睛睜開的角度,實際窗口的縱橫比,眼睛距離近處的距離,遠處的裁面(即後面兩個參數表示眼睛能看的多遠)。

函數設置投視角設爲75度, 在y軸方向上以角度爲單位的視野, 度數越大離的越遠看的越小。

模型變換

在模型變換下可以對矩陣進行變換,移動旋轉縮放等。

glMatrixMode(GL_MODELVIEW);

gluLookAt(0, -200, 200, 0, 0, 0, 0, 0, 1)

參數:每三個參數表示一個座標
eye眼睛在世界座標系的位置,center眼睛看的那個點的座標,up觀察者本身的方向,比如正立還是倒立異或某一個角度在看。

函數表示在(0, -200, -200)的位置正着向(0, 0, 0)點看去。

深度緩衝區

opengl默認是沒有開啓深度檢測的,也就是說, 後繪製的物體覆蓋先繪製的物體。

當開啓更新深度緩衝區的功能,也就是,如果通過比較後,深度值發生變化了,會進行更新深度緩衝區的操作。啓動後,OpenGL就可以跟蹤在Z軸上的像素,這樣,它只會再那個像素前方沒有東西時,纔會繪製這個像素。

#include<Windows.h>
#include<GL\glut.h>
//太陽、地球和月亮
//假設每個月都是30天
//一年12個月,共是360天
static int day = 200; // day的變化:從0到359
void myDisplay(void)
{
    /*用來開啓更新深度緩衝區的功能,也就是,如果通過比較後深度值發生變化了,
    會進行更新深度緩衝區的操作。啓動它,OpenGL就可以跟蹤再Z軸上的像素,
    這樣,它只會再那個像素前方沒有東西時,纔會繪畫這個像素。*/
    glEnable(GL_DEPTH_TEST);

    /*opengl默認是沒有開啓深度檢測的,也就是說,
    後繪製的物體覆蓋先繪製的物體(顏色緩衝區中,先繪製的物體 被 後繪製的物體 覆蓋)。*/
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);    //投影變換
    glLoadIdentity();   //調用單位矩陣
    //投視角設爲75度, 在y軸方向上以角度爲單位的視野, 度數越大離的越遠看的越小
    //參數 眼睛睜開的角度  實際窗口的縱橫比  眼睛距離近處的距離  遠處的裁面(即眼睛能看的多遠)
    gluPerspective(75, 1, 1, 2000); //透視投影空間, 近大遠小

    glMatrixMode(GL_MODELVIEW); //模型變換
    glLoadIdentity();
    //eye眼睛在世界座標系的位置,
    //center眼睛看的那個點的座標,
    //up觀察者本身的方向,比如正立還是倒立異或某一個角度在看
    gluLookAt(0, -200, 200, 0, 0, 0, 0, 0, 1);

//繪製紅色的“太陽”
    glColor3f(1.0f, 0.0f, 0.0f);
    glutSolidSphere(69.6, 100, 100);

//繪製藍色的“地球”
    glColor3f(0.0f, 0.0f, 1.0f);
    glRotatef(day / 360.0*360.0, 0.0f, 0.0f, -1.0f);
    //相對當前所在屏幕位置移動
    glTranslatef(150, 0.0f, 0.0f);
    glutSolidSphere(15.945, 100, 100);

//繪製黃色的“月亮”
    glColor3f(1.0f, 1.0f, 0.0f);
    glRotatef(day / 30.0*360.0 - day / 360.0*360.0, 0.0f, 0.0f, -1.0f);
    glRotatef(day / 30.0*360.0, 0.0f, 0.0f, -1.0f);
    glTranslatef(38, 0.0f, 0.0f);
    glutSolidSphere(4.345, 100, 100);

    //glFlush();  //這句加不加好像都行,因爲用的是雙緩衝區
    glutSwapBuffers();
}
void myIdle(void)
{
    Sleep(50);
    ++day;
    if (day >= 360)
        day = 0;
    myDisplay();
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutInitWindowPosition(200, 100);
    glutInitWindowSize(600, 600);
    glutCreateWindow("平移旋轉");
    glutDisplayFunc(&myDisplay);
    //如果不存在其他尚未完成的,就執行這個函數(當沒有窗口事件到達時,就執行這個回調函數
    glutIdleFunc(&myIdle);
    glutMainLoop();
    return 0;
}

在這裏插入圖片描述

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