2017年10月22日 星期日

詠銓_Week06_Note

Class:Lighting

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);所以可以如圖印出輸入及座標  

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();  
}
 Note:                                        
   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.經過測試後發現圖背對我們應該是座標相反了,所以在移動量那邊加負號,才會如期轉動

沒有留言:

張貼留言