1.從moodle下載week05的專案,執行後可知道會出現一個全白的圖。

2.接著打開Transformation的source code,搜尋light的相關程式碼,將其複製到此專案檔。執行

3.我們可以看到此執行解果破圖了,於是將原始碼的深度測試複製進來,執行後發現沒有畫面,這是因為此圖是背對著你,而光從前面打,所以改變打光的位置,變成從後面打,就可以出現一個背對著我們的人物了。

Note:
a.打光程式碼如下:
GLfloat pos[] = { 0.0, 0.0, -1.0, 0.0 }; //打光的位置
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
b.深度測試程式碼:
glEnable(GL_DEPTH_TEST);
Class: Keyboard
1.接著引入鍵盤控制,為了確認程式可以收到我們的輸入,我們在副程式中將鍵盤的輸入顯示於螢幕(包含此時滑鼠的座標)。
Note:
a.鍵盤控制程式碼如下:
glutKeyboardFunc(keybord);// glut的鍵盤控制,連結到keyboard副程式
keyboard(unsigned char key, int x, int y)// 副程式,裡面決定了鍵盤輸入時對應的動作
b.此時副程式中的內容為printf("%c (%d, %d)\n", key, x, y);所以可以如圖印出輸入及座標
a.鍵盤控制程式碼如下:
glutKeyboardFunc(keybord);// glut的鍵盤控制,連結到keyboard副程式
keyboard(unsigned char key, int x, int y)// 副程式,裡面決定了鍵盤輸入時對應的動作
b.此時副程式中的內容為printf("%c (%d, %d)\n", key, x, y);所以可以如圖印出輸入及座標
2.接著我們將副程式的內容更改為:
輸入'1'時,繞著x軸轉
輸入'2'時,繞著y軸轉
輸入'3'時,繞著z軸轉
此時副程式如下:
void keybord(unsigned char key, int x, int y)
{
if(key == '1') rotateX++;//輸入1時,rotateX加1
if(key == '2') rotateY++;//輸入2時,rotateY加1
if(key == '3') rotateZ++;//輸入3時,rotateZ加1
glutPostRedisplay();//重畫
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(rotateX, 1, 0, 0);//對X軸旋轉rotateX度
glRotatef(rotateY, 0, 1, 0);//對Y軸旋轉rotateY度
glRotatef(rotateZ, 0, 0, 1);//對Z軸旋轉rotateZ度
drawmodel();
glPopMatrix();
glutSwapBuffers();
}
a.rotateX, rotateY , rotateZ 為全域變數,可以讓我們在輸入時在對應軸作旋轉
b.但是程式並不能及時轉動,所以要在最後加glutPostRedisplay(); 讓系統重畫圖形
c.此時會動到圖形的座標,所以在display副程式中加入glPushMatrix(); glPopMatrix();
3.只要更動副程式,我們就可以得到我們想要的各種鍵盤控制
Class: Mouse
1.接著是滑鼠控制,滑鼠控制與鍵盤控制大同小異,我們一樣是呼叫函式且寫個可以讓我們確認輸入的副程式,如圖

Note:
a.滑鼠控制程式碼如下:
glutMouseFunc(mouse);// glut的滑鼠控制,連結到mouse副程式
mouse(int buttom, int state, int x, int y)// 副程式,裡面決定了滑鼠輸入時對應的動作
b.此時副程式中的內容為printf("bottom = %d, state = %d, (%d, %d)\n", buttom, state, x, y);所以
可以如圖印出輸入座標、左右中鍵及當時狀態
2.跟鍵盤控制不同的是,如果我們要依照滑鼠的動作而有對應的效果,我們需要再多呼叫一個副程式glutMotionFunc(motion); ,此副程式可以在滑鼠有動作時執行相應的效果
3.接著我們用這兩個副程式達到下面的效果
壓下滑鼠橫向滑動時,圖形繞著Y軸轉
壓下滑鼠縱向滑動時,圖形繞著X軸轉
程式碼如下:
void mouse(int buttom, int state, int x, int y)
{
if(state == GLUT_DOWN)//當壓下滑鼠按鍵
{
oldX = x; oldY = y;//設定舊座標為此時座標
}
}
void motion(int x, int y)
{
rotateY += -(x-oldX);//對著Y軸旋轉滑鼠的橫向移動量
rotateX += -(y-oldY);//對著X軸旋轉滑鼠的縱向移動量
oldX = x; oldY = y;//設定舊座標為此時座標
glutPostRedisplay();//重畫
}
Note:
a.rotateX, rotateY , rotateZ 一樣為全域變數,可以讓我們在對應軸作旋轉
b.但是程式並不能及時轉動,所以一樣要在最後加glutPostRedisplay(); 讓系統重畫圖形
c.此時會動到圖形的座標,所以在display副程式中加入glPushMatrix(); glPopMatrix();
d.經過測試後發現圖背對我們應該是座標相反了,所以在移動量那邊加負號,才會如期轉動

沒有留言:
張貼留言