2023年3月8日 星期三

DTang---Week04_旋轉 Rotation

 step01-1_下載上課用檔案

上老師的網站( https://jsyeh.org/3dcg10/ )下載 

下載檔案及名稱:1. data.zip、2. win32.zip、3. glut32.dll

解壓縮

windows.zip => 獨立解出一個資料夾

data.zip => 將data解壓縮到window資料夾內

執行時可移動xyz的座標


本週上課內容為"旋轉 Rotation"

x軸旋轉時如圖一

y軸選轉時如圖二

z軸旋轉時為圖三

同理右手安培定則,想像z軸面向我們而來,x軸即為水平線,y軸為垂直線



圖1  以x軸旋轉時

圖2  以y軸選轉時

圖3  以z軸旋轉時


圖4  x、y軸同時旋轉時


==>進入專案實作

新增專案:week04_rotate

step02-1 旋轉茶壺

利用上周的矩陣matrix程式碼,加入glRotatef(angle ,x ,y ,z); 給定一個角度值(angle),透過main裡新增的函數glutIdleFunc( );呼叫display,喚醒matrix啟動旋轉函式,程式及結果如下圖:

float angle = 0; ///step02-1

void display()

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  ///清背景

    glPushMatrix();  ///step01-2 備份矩陣

        glRotatef(angle,0,1,0); /// step02-1 旋轉的角度angle

        glutSolidTeapot(0.3); ///劃出實心茶壺;大小0.3

    glPopMatrix();  ///還原矩陣

    glutSwapBuffers(); ///請GLUT畫面swap送到顯示的地方

    angle++; /// step02-1 把角度++


}

int main(int argc, char *argv[])

{

    glutInit(&argc, argv);///開啟GLUT

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);///設定顯示模式

    glutCreateWindow("week04");///開視窗

    glutDisplayFunc(display);///要顯示的對應函示"display()"

    glutIdleFunc(display);

   glutMainLoop();/// 壓最後

}



----------------------------------------------------------------------------------------------------------------------------

step02-2 加入打光(陰影)

加入打光程式碼,讓茶壺有光澤變化

打光程式碼可在專案預設的程式碼中找到,大約20+行數

const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };

const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };

const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };

const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };


const GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };

const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };

const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };

const GLfloat high_shininess[] = { 100.0f };

............

void mylight(){

    glEnable(GL_DEPTH_TEST);

    glDepthFunc(GL_LESS);


    glEnable(GL_LIGHT0);

    glEnable(GL_NORMALIZE);

    glEnable(GL_COLOR_MATERIAL);

    glEnable(GL_LIGHTING);


    glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);

    glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);

    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

    glLightfv(GL_LIGHT0, GL_POSITION, light_position);


    glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);

    glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);

    glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);

    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);

}

最後在main裡呼叫mylight();


----------------------------------------------------------------------------------------------------------------------
step02-3 加入顏色

加入背景跟茶壺顏色

void display()

{


    glClearColor(1,1,1,1); /// step02-3 用來清背景的顏色R,G,B,A ((A在GLUT_RGB裡用不到

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  ///清背景

    glPushMatrix();  ///備份矩陣

        glColor3f(1,1,0); /// step02-3 加入色彩

        glRotatef(angle,0,1,0); /// step02-1 旋轉的角度angle

        glutSolidTeapot(0.3); ///劃出實心茶壺;大小0.3

    glPopMatrix();  ///還原矩陣

    glutSwapBuffers(); ///請GLUT畫面swap送到顯示的地方

    angle++; /// step02-1 把角度++

}



------------------------------------------------------------------------------------------------------------------------

step03-1 移動與旋轉

移動與旋轉程式碼交換行列後,結果會大不相同

因為程式是由下往上讀,所以下方程式碼會優先被執行

所以如果是先寫Translate 再寫Rotate==>結果會於原地自轉

如果先寫Rotate 再寫Translate==>結果會呈現公轉


step03-2 移動與旋轉-實作範例

在Display()裡加入兩者程式碼,並查看差異

void display() {

    glEnable(GL_DEPTH_TEST); /// 記得加

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  ///清背景


    glPushMatrix();  ///備份矩陣

        glColor3f(1,1,0); 

        glTranslatef( 0.6, 0, 0); ///step03-2 先移動在旋轉

        glRotatef(angle,0,1,0); /// step02-1 旋轉的角度angle

        glutSolidTeapot(0.3); 

    glPopMatrix();  ///還原矩陣


    glPushMatrix();  ///備份矩陣

        glColor3f(1,0,0); /// 紅

        glRotatef(angle,0,1,0); /// step02-1 旋轉的角度angle

        glTranslatef( 0.6, 0, 0); ///step03-2 先旋轉在移動

        glutSolidTeapot(0.3); 

    glPopMatrix();  ///還原矩陣

    glutSwapBuffers(); ///請GLUT畫面swap送到顯示的地方

    angle++; /// step02-1 把角度++

}





沒有留言:

張貼留言