還是零分 散播福音的祭司
註冊時間: 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度將三角形翻面的話會發現
原本能遮住其他三角形的第一個三角形即使翻面了還是繼續遮住其他三角形?!
這簡單的程式原本就不知道近物能蓋住遠物的道理
而是先畫的先墊底,後畫的就蓋過前面畫過的東西了 |
|