電腦遊戲製作開發設計論壇 首頁 電腦遊戲製作開發設計論壇
任何可以在PC上跑的遊戲都可以討論,主要以遊戲之製作開發為主軸,希望讓台灣的遊戲人有個討論、交流、教學、經驗傳承的園地
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入 

Google
OpenGL入門教學(04)

 
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫
上一篇主題 :: 下一篇主題  
發表人 內容
還是零分
散播福音的祭司


註冊時間: 2007-09-19
文章: 164

653.83 果凍幣

發表發表於: 2008-7-1, PM 12:45 星期二    文章主題: OpenGL入門教學(04) 引言回覆

OpenGL的矩陣模式有3種:投影矩陣、模型矩陣、貼圖矩陣( GL_PROJECTION , GL_MODELVIEW , GL_TEXTURE )

我覺得3種模式中最重要的就是模型矩陣了
Display()中的gluLookAt()就是個模型矩陣
藉由gluLookAt()的調整,3D畫面就整個換了個角度

模型矩陣做的事大概分成3種:旋轉、平移、縮放
旋轉是以原點為中心做旋轉
平移是改變位置,方向沒變
縮放是以原點為中心改變大小

下面的範例只有用到glRotatef()來做旋轉
至於gluLookAt()的話,它打從一開始就有在做事了
它不是已經把玩家的觀點從原點沿著z軸往後拉了10的距離嗎?
這就算平移了


//================================================================================
//模型矩陣(MODELVIEW)
//================================================================================

//------glRotatef( dgree , x , y , z );
//
//是個旋轉矩陣,第一個參數是角度
//xyz是設一個向量當旋轉軸

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

//------glTranslatef( x , y , z );
//
//是個平移矩陣,xyz代表三個軸的移動量

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

//------glScalef( x , y , z );
//
//是個縮放矩陣,xyz代表三個軸的縮放係數





//================================================================================
//設定用來接收滑鼠訊息的CallBack函數
//================================================================================

//------glutMouseFunc(自定函式);
//
//指定一個自定函式接收滑鼠按下和放開時的訊息,按住和沒按住的過程並沒有動作
//
//自定函式:void Function( button , state , x , y );
//
//button:按左鍵時值為0,按右鍵值為2(中間按鍵大概是1,我家滑鼠沒中鍵,有的人幫我試試)
//state:按下時值為0,放開時值為1
//x,y是按下和放開時的視窗座標

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

//------glutMotionFunc(自定函式);
//
//滑鼠按住並移動的狀態下,所經過的視窗座標
//自定函式:void Function( x , y );



代碼:
//-----------------------------------------------------------------------------
//                                                              2008/6/28
//                            Rotating Objects
//                                                              by還是零分
//-----------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <GL\glut.h>
int old_rot_x=0;   //剛按下滑鼠時的視窗座標
int old_rot_y=0;

int rot_x=0;      //拖曳後的相對座標,用這決定要旋轉幾度
int rot_y=0;

int record_x=0;      //紀錄上一次旋轉的角度
int record_y=0;

void WindowSize(int , int );            //負責視窗及繪圖內容的比例
void Keyboard(unsigned char , int, int );   //獲取鍵盤輸入
void Mouse(int , int , int , int );         //獲取滑鼠按下和放開時的訊息
void MotionMouse(int , int );            //獲取滑鼠按下期間的訊息
void Display(void);                     //描繪

int main()
{
   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize(400,400);         //視窗長寬
   glutInitWindowPosition(600,80);         //視窗左上角的位置
   glutCreateWindow("這裡是視窗標題");      //建立視窗

   //下面五個是用來指定Callback函數
   glutReshapeFunc(WindowSize);
   glutKeyboardFunc(Keyboard);
   glutMouseFunc(Mouse);
   glutMotionFunc(MotionMouse);
   glutDisplayFunc(Display);

   glutMainLoop();
   return 0;
}

void Display(void)
{
   glClearColor(1.0, 1.0, 1.0, 1.0);   //用白色塗背景
   glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   gluLookAt(0,0,10.0f,0,0,0,0,1,0);   //視線的座標及方向
   glRotatef((float)rot_y+(float)record_y, 1.0, 0.0, 0.0);//以x軸當旋轉軸
   glRotatef((float)rot_x+(float)record_x, 0.0, 1.0, 0.0);//以y軸當旋轉軸
   glBegin(GL_TRIANGLES);
      glColor3f( 1, 0, 0);glVertex3f( 8.6603, -5, -3);
      glColor3f( 0, 1, 0);glVertex3f(      0, 10, -3);
      glColor3f( 0, 0, 1);glVertex3f(-8.6603, -5, -3);

      glColor3f( 1, 0, 0);glVertex3f( 8.6603, -5, 0);
      glColor3f( 0, 1, 0);glVertex3f(      0, 10, 0);
      glColor3f( 0, 0, 1);glVertex3f(-8.6603, -5, 0);

      glColor3f( 1, 0, 0);glVertex3f( 8.6603, -5, 3);
      glColor3f( 0, 1, 0);glVertex3f(      0, 10, 3);
      glColor3f( 0, 0, 1);glVertex3f(-8.6603, -5, 3);
   glEnd();
   glutSwapBuffers();
}

void Keyboard(unsigned char key, int x, int y)
{
   printf("你所按按鍵的碼是%x\t此時視窗內的滑鼠座標是(%d,%d)\n", key, x, y);
}

void WindowSize(int w, int h)
{
   printf("目前視窗大小為%dX%d\n",w,h);
   glViewport(0, 0, w, h);            //當視窗長寬改變時,畫面也跟著變
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(-10,10,-10,10,-10,30);      //正交投影
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

void Mouse(int button, int state, int x, int y)
{
   if(state)
   {
      record_x += x - old_rot_x;
      record_y += y - old_rot_y;
      
      rot_x = 0;   //沒有歸零會有不理想的結果
      rot_y = 0;
   }
   else
   {
      old_rot_x = x;
      old_rot_y = y;
   }
}

void MotionMouse(int x, int y)
{
   rot_x = x - old_rot_x;
   rot_y = y - old_rot_y;
   glutPostRedisplay();
}




如果旋轉的角度小於90度的還看不出有什麼奇怪的
當大於90度將三角形翻面的話會發現
原本能遮住其他三角形的第一個三角形即使翻面了還是繼續遮住其他三角形?!

這簡單的程式原本就不知道近物能蓋住遠物的道理
而是先畫的先墊底,後畫的就蓋過前面畫過的東西了
回頂端
檢視會員個人資料 發送私人訊息 參觀發表人的個人網站
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫 所有的時間均為 台灣時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
可以 在這個版面附加檔案
可以 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作