2013年4月7日 星期日

OpenGL基本瞭解(五) OPENGL 基本Function

OPENGL 基本Function

官方網址
http://www.opengl.org/sdk/docs/man/

前段是基本列表
後面是中文說明

glTranslatef(x,y,z) 移動座標系統位置
glRotatef(angle,x,y,z) 旋轉座標系統
glScalef(x,y,z)  縮放座標系統

glColor3f(r,g,b) {0 <= r,g,b <= 1}線段顏色
glBegin() [GL_LINES]
 glVertex2f(x,y) , 
 glVertex3f(x,y,z)
glEnd()

glutInitDisplayMode() [GLUT_DOUBLE | GLUT_RGB]
glutInitWindowSize(x,y) {x:width, y:height}視窗大小
glutInitWindowPosition(x,y) 視窗位置
glutCreateWindow(char*) 視窗名字

glClearColor(r,g,b,alpha) {0 <= r,g,b,alpha(透明色) <= 1}視窗背景顏色

glClear()  
 GL_COLOR_BUFFER_BIT 
 GL_DEPTH_BUFFER_BIT
  //清理深度緩衝區(32-bit),3D畫面會用到
  //目的是讓近的物體能擋住遠的物體,符合現實
glMatrixMode() 
 //OpenGL總共有三個矩陣堆疊供三種矩陣模式使用
 GL_PROJECTION
  //選擇投影矩陣模式,資料是3D,但是螢幕卻是2D
  //所以讓3維圖形化為2維平面
 GL_MODELVIEW
  //盡量處於此模式,下面通常接glLoadIdentity(),清理用
glLoadIdentity()
 //將OpenGL的矩陣設為單位矩陣,所謂的單位矩陣,就是乘法下的單位元素
 //此function的作用,是不希望之前的矩陣資料殘留到現在的運算
glViewport(x,y,w,h)
 //想像OpenGL是一個畫家,視窗就是他的畫框
 //glViewPort則是決定畫布的長寬大小,所以前兩個參數是畫布左下角的座標
 //通常是(0,0),如果是(100,100)則表示畫布往右上100
glOrtho(xl,xr, yb,yu, zn,zf)
 //定義一個box的大小,這個box就是你眼睛看到的部份
 //這個box是被放在座標系的原點,所以如果box涵蓋的範圍愈大,
 //代表看到的物體愈小
gluLookAt(x1,y1,z1, x2,y2,z2, x3,y3,z3)
 //眼睛(攝影機)看得世界,由三個座標構成參數,
 //應該是畫家看畫布的視野,當然數字太大就gg
 //第一個座標:眼睛的位置
 //第二個座標:眼睛看的位置(通常是物體座標系原點)
 //第三個座標:頭頂上方的向量
 //例如:有一棟建築,位於(x+,y+,z+),為了符合看得角度,
 //所以要讓他平躺在x-y平面,我們可以利用gluLookAt(-1,-1,1,0,0,0,0,0,1)
gluSwapBuffers()
 //雙緩衝區的輸出(double buffer)
glFlush()
 //single buffer
glutPostRedisplay()
 //將此視窗設成要重新顯示顯示的狀態,所以會去call glutDisplayFunc
glutIdleFunc(function)
 //閒置一段時間(沒事件發生)時呼叫一次
glutReshapeFunc(function)
 //當一開始產生視窗時會呼叫一次,後來都是當視窗大小變動時才會呼叫
glShadeModel()
 //上色的技巧
 GL_FLAT  //flat shading
 GL_SMOOTH //gouraud shading
glPolygonMode(face, mode)
 //多邊形有正反兩面(face),逆時針的點順序是正面
 //此function為控制多邊形的繪製方式
 face:
  GL_FRONT_AND_BACK //正反面都畫(default)
  GL_FRONT
  GL_BACK
 mode:
  GL_FILL  //填滿多邊形內部(default)
  GL_LINE  //只畫多邊形的框線
  GL_POINT //只畫多邊形的端點

void keyboard(unsigned char, int, int)  //第一個參數是輸入的鍵碼,
     //後兩個參數是滑鼠在"視窗"的座標

matrix
 //可以用glGetFloatv(GL_MODELVIEW_MATRIX, ModelviewMat)把現在modelview的matrix
 //放到 float ModelviewMat[16],然後用for(i= 0; i < 16; i++)印出來
 //就會發現其實矩陣應該是長這樣的
 //[0 , 4 , 8 , 12]
 //[1 , 5 , 9 , 13]
 //[2 , 6 , 10, 14]
 //[3 , 7 , 11, 15]
     
27 ESC
50 2
52 4
54 6
56 8 
 
 
reference:
http://www.gamelife.idv.tw/viewtopic.php?t=598


以下是網路上的常用function的中文資料

//------glViewport(橫座標,縱座標,寬度,高度);
//
//想像OpenGL是一個畫家
//視窗就是它的畫框
//glViewport則是決定畫布的長寬大小
//畫布的size跟畫框不符是很糟糕的
//
//glViewport的前兩個參數是畫布左下角的視窗座標位置
//後兩個參數是畫布的size

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

//------glMatrixMode(GL_PROJECTION);
//
//顧名思義是選擇矩陣模式的意思
//而且選的還是個投影矩陣
//
//之所以要扯到矩陣是因為3D繪圖是向量圖不是點陣圖
//畫面精緻的2D遊戲常常是點陣圖而不是向量圖(畫面不怎麼精緻的flash遊戲是向量圖)
//
//3D電腦圖學最重要的資料就是座標點了
//3D遊戲中的畫面都受到座標點的控制
//改變座標點就能改變整個三維世界
//
//所以矩陣是最適合3D向量繪圖的數學工具了
//大學中教矩陣的這門課是叫做線性代數,是代數學的分支(代數學對資料壓縮有所貢獻)
//
//而資料是立體的,螢幕卻是平面的
//有必要讓3維圖形化為2維平面
//那不就是投影矩陣了嗎?
//
//glMatrixMode(GL_PROJECTION)先選了投影矩陣模式
//這樣待會兒有個指令要放出一個矩陣給OpenGL才不會放錯地方
//(OpenGL還有另外兩種矩陣模式,總共有三個矩陣堆疊供三種矩陣模式使用)

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

//------glLoadIdentity();
//
//glLoadIdentity是將OpenGL中的矩陣設為單位矩陣
//所謂的單位矩陣是矩陣乘法下的單位元素
//任何矩陣乘上單位矩陣都還是等於自己
//
//我不想提太多數學,這樣我會沒有放暑假的感覺
//總之glLoadIdentity()的作用是不希望之前的矩陣資料殘留到現在的運算
//如同遊戲畫面一樣,要不斷的清理,不能讓之前的遊戲畫面殘留

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

//------glOrtho(左邊界,右邊界,下邊界,上邊界,近邊界,遠邊界);
//
//這個指令給了OpenGL一個正交投影矩陣
//正交是垂直的代名詞,一個垂直的投影如同陽光底下的影子一樣
//物體跟地面的距離不會影響大小,適合2D遊戲使用
//
//對於glOrtho()的參數
//你可以想像將一個箱子放到3維座標系的原點
//它左右邊的面被x軸貫穿,交了兩個點
//x值就是左右邊界
//箱子的六個面都交了一點
//六個點六個邊界,定義了箱子的範圍
//將箱子前後壓扁就是視窗上的樣子啦

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

//------glMatrixMode(GL_MODELVIEW);
//
//把矩陣模式改成MODELVIEW(不知道該怎麼翻)
//在Display函式中還會再確認一次
//OpenGL的矩陣模式要盡量處於MODELVIEW模式
//glMatrixMode(GL_MODELVIEW)下一行的glLoadIdentity()這時清理的是MODELVIEW矩陣


//void Keyboard(unsigned char , int, int );
//
//第一個參數得到你輸入的鍵碼
//後兩個參數是你按按鍵時,滑鼠的座標(是視窗座標不是螢幕座標)


以後會寫switch條件判斷式來依據不同的按鍵來執行各自的功能
長的像這樣


代碼:
void Keyboard(unsigned char key, int x, int y)
{
   switch (key)
   {
   case 'a':
      執行按下a之後對應的指令;
      break;
   case 'b':
      執行按下b之後對應的指令;
      break;
   case 'c':
      執行按下c之後對應的指令;
      break;
   }
}



//================================================================================
//Display:
//這裡是OpenGL的舞台
//其中有些指令其實對於這個code並沒有用處
//但是到後面還是鐵定會用到
//所以在第一篇的code裡就先寫入了
//================================================================================


//------glClearColor( 紅 , 綠 , 藍 , 透明色 );
//
//設定用來清理顏色緩衝區的顏色,避免畫面殘留
//只是設定而已,還沒動手清理
//參數值全是介於0到1之間的浮點數

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

//------glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
//
//真正動手清理緩衝區
//GL_COLOR_BUFFER_BIT指定要清理顏色緩衝區
//GL_DEPTH_BUFFER_BIT指定要清理深度緩衝區(32位元)
//
//深度緩衝區是3D畫面會用到的
//用來做深度測試,目的是讓近的物體能擋到遠方的物體,這樣才符合現實
//不過這個程式還沒啟動深度測試

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

//------gluLookAt( x1 , y1 , z1 , x2 , y2 , z2 , x3 , y3 , z3 );
//
//這是個glu函式,是用來幫助gl函式的
//glu的功能其實用gl就寫的出來,
//不過glu改良後的用法較方便且直觀
//
//這個函式像個攝影機一樣
//可以調整攝影機的位置、調整攝影機的方向
//
//gluLookAt有9個參數,好像代表3個座標點
//其實是兩個座標點和一個向量
//第一個座標是攝影機的位置座標
//第二個座標是攝影機所要拍攝的物體位置座標,只是要確定拍攝方向
//第三個座標是攝影機正上方的向量,不懂要這幹什麼嗎?
//
//OpenGL只知道攝影機的位置、攝影機的拍攝方向還不夠啊
//誰知道你要躺著拍還是倒立著拍

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

//------glBegin(GL_TRIANGLES); & glEnd();
//
//告訴OpenGL要動筆畫圖了,使用了glBegin之後開始繪圖指令
//畫完之後要打上glEnd();結束繪圖
//開啟了什麼就要關掉什麼,這點在DirectX還有很多API上面也是一樣的
//
//GL_TRIANGLES選擇你要畫的是三角形
//除了三角形還有GL_POINTS、GL_LINES和GL_QUADS(四邊形)以及更特別的可以選(但不重要)

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

//------glColor3f( 紅 , 綠 , 藍 ); & glVertex3f( x , y , z );
//
//glColor3f的3個顏色值都介於0到1之間
//glVertex3f設定座標點,它的顏色取決於它前面的glColor3f
//由於前面的glBegin選擇要畫三角形
//所以在glBegin()和glEnd之間給出3個座標點可以定義一個三角形
//給出6個座標點可以定義兩個三角形
//給4個或5個會怎樣我不知道,你可以try看看

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

//------glutSwapBuffers();
//
//當你使用雙緩衝區時,可以說是提供了兩張畫布供OpenGL作畫
//已經畫好的那一張先貼上視窗,另外一張正在OpenGL的手上趕工
//
//如果用單緩衝區的話,就要等OpenGL趕稿了
//稿子完成了貼上視窗,趕稿期間畫面被glClear清乾淨了,只剩背景色
//完稿了又貼上畫面,趕著畫下一張,畫面又被glClear清乾淨了
//如此循環下去,即使電腦的手腳很快,畫面還是難免有閃爍感(不舒服)
//
//所以全世界的遊戲都會採用雙緩衝區這個方法
//
//glutSwapBuffers()所做的就是在OpenGL繪畫完成之後趕緊變更顯示的緩衝區
//將新的畫作呈現在螢幕上,然後OpenGL在另一個緩衝區繼續趕稿
//畫好了之後glutSwapBuffers()又變更顯示的緩衝區
//將最新的畫作呈現在螢幕上,舊畫面被glClear清理了,以供OpenGL再次趕稿
//視窗上永遠有一張圖來撐場面,於是就沒有閃爍感了

沒有留言: