OpenGL之視口變換

OpenGL之視口變換

視口(Viewport)即渲染窗口大小,每當窗口大小發生改變都要使用glViewport()進行設定.視口變換在投影變換之後進行

視口設定 簡介
void glViewport(

GLint x, GLint y, 視口的左下角坐標

GLsizei width, 視口的寬度

GLsizei height); 視口的高度

視口的左下角坐標設為0,0

視口的寬高設為窗口大寬高

 

重設窗口大小,在WM_SIZE(窗口大小發生改變)消息下調用

  1. glViewport(0,0,width,height);將視口重置為新的尺寸
  2. glViewport(0,0,OpenGL_Width,OpenGL_Height);
  3. glMatrixMode(GL_PROJECTION); 設定投影矩陣
  4. glLoadIdentity();載入單位矩陣
  5. gluPerspective(0f, Width/Height,1.0f,1000.0f);
  6. glMatrixMode(GL_MODELVIEW);設定模型視圖矩陣
  7. glLoadIdentity();載入單位矩陣

 

OpenGL之矩陣

OpenGL之矩陣

OpenGL的變換運算均使用4×4矩陣進行.OpenGL使用堆棧保存矩陣.各種變換運算均針對棧頂進行操作.

矩陣 簡介
void glMatrixMode (GLenum mode); 設定當前矩陣堆棧
GL_MODELVIEW 模型視圖矩陣
GL_PROJECTION 投影矩陣
GL_COLOR 顏色矩陣
GL_TEXTURE 紋理矩陣

示例

  1. glMatrixMode(GL_MODELVIEW); 設定當前矩陣為模型視圖矩陣
  2. glLoadIdentity();載入單位矩陣,並且朝向負Z軸
  3. 進行其它變換
矩陣堆棧 簡介
void glPushMatrix(void); 複製當前矩陣(棧頂)並壓棧.
void glPopMatrix(void); 當前矩陣堆棧出棧並丟棄.

將當前坐標系統切換為新坐標系統,渲染完成後恢復原始坐標系統.示例:

  1. glMatrixMode(GL_MODELVIEW);設定模型視圖矩陣
  2. glPushMatrix();複製當前矩陣並壓棧.
  3. glLoadIdentity();載入單位矩陣
  4. glTranslatef(x,y,x);移動坐標系
  5. glPopMatrix();出棧,恢復源始坐標系統

不同矩陣堆棧有不同的深度,可通過glGetIntegerv()獲取

參數 深度 簡介
GL_MAX_MODELVIEW_STACK_DEPTH 32 模型視圖矩陣堆棧的深度
GL_MAX_PROJECTION_STACK_DEPTH 10 投影矩陣堆棧的深度
GL_MAX_TEXTURE_STACK_DEPTH 10 紋理矩陣堆棧的深度
GL_MAX_ATTRIB_STACK_DEPTH 16 屬性矩陣堆棧的深度

獲取模型視圖矩陣深度示例:

  1. GLint params[1];
  2. glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH,params);

OpenGL之旋轉

OpenGL之旋轉

旋轉glRotatef()使模形圍繞軸向量進行旋轉.先設定旋轉矩陣後繪畫模型.

旋轉 簡介
void glRotatef (

GLfloat angle,

GLfloat x,

GLfloat y,

GLfloat z);

單精度版本

angle:旋轉角度

逆時針旋轉:角度為正

順時針旋轉:角度為負

xyz:旋轉軸向量

void glRotated (

GLdouble angle,

GLdouble x,

GLdouble y,

GLdouble z);

雙精度版本

函式示例分別對XYZ進行旋轉:

  1. 設定模型視圖矩陣glMatrixMode(GL_MODELVIEW);
  2. 載入單位矩陣glLoadIdentity();
  3. 繞X軸旋轉glRotatef(angleX,1,0,0);
  4. 繞Y軸旋轉glRotatef(angleY,0,1,0);
  5. 繞Z軸旋轉glRotatef(angleZ,0,0,1);
  6. 繪畫立方體Draw();
旋轉示例 簡介
glRotatef(45.0f,1.0f,0.0f,0.0f); 繞X軸以逆時針方向旋轉45度
glRotatef(-90.0f,0.0f,1.0f,0.0f); 繞Y軸以順時針方向旋轉45度
glRotatef(135.0f,0.0f,0.0f,1.0f); 繞Z軸以逆時針方向旋轉135度

旋轉演示程式如上圖:下載

  1. 按UP/DOWN鍵繞X軸旋轉
  2. 按LEFT/RIGHT鍵繞Y軸旋轉
  3. 按Z+LEFT/Z+RIGHT鍵繞Z軸旋轉
  4. 按F1鍵打開幫助
  5. 按ESC鍵模型旋轉角度重置

OpenGL之縮放

OpenGL之縮放

縮放glScalef()可在XYZ三軸指定不同縮放系數,放大或縮小模型或坐標系統的大小.

放大: 縮放系數大於(>1),若設為2放大一倍

縮小: 縮放系數為(1.0~0.0),若設為0.5側縮小一倍

函式示例:

  1. 設定模型視圖矩陣glMatrixMode(GL_MODELVIEW);
  2. 載入單位矩陣glLoadIdentity();
  3. 縮放glScalef(x,y,z);參數xyz為縮放系數,若縮放系數为1侧不缩放.縮放操作就是乘以縮放系數.
  4. 繪畫立方體Draw();
縮放 簡介
void glScalef(

GLfloat x,

GLfloat y,

GLfloat z);

單精度版本

對模型放大一倍:

1.    縮放glScalef(2,2,2)

2.    後再繪畫Draw()

void glScaled(

GLdouble x,

GLdouble y,

GLdouble z);

雙精度版本

縮放演示程式如上圖:下載

  1. 按UP/DOWN鍵對XYZ三軸進行模型縮放
  2. 按LEFT/RIGHT鍵繞Y軸旋轉
  3. 按F1鍵打開幫助
  4. 按ESC鍵模型縮放重置

OpenGL之平移

OpenGL之平移

平移Translate可將模型在3D世界中移動,先設定平移矩陣後繪畫模型:

函式示例:

  1. 設定模型視圖矩陣glMatrixMode(GL_MODELVIEW);
  2. 載入單位矩陣glLoadIdentity();
  3. 移動3D坐標glTranslatef(x,y,z);參數xyz為3D世界坐標的偏移量
  4. 繪畫立方體Draw();
平移 簡介
void glTranslatef(

GLfloat x,

GLfloat y,

GLfloat z);

單精度版本

如在3D世界(6,6,6)繪畫模型:

1.     先平移glTranslatef(6,6,6)

2.     後在繪畫Draw()

void glTranslated(

GLdouble x,

GLdouble y,

GLdouble z);

雙精度版本

平移演示程式如上圖:下載

  1. 按LEFT/RIGHT鍵模型在X軸中移動
  2. 按UP/DOWN鍵模型在Z軸中移動
  3. 按F1鍵打開幫助
  4. 按ESC鍵模型歸位

OpenGL之投影變換

OpenGL之投影變換

投影變換是指設定視口面積和剪切平面,它在模型變換與視圖變換之後執行,用於確定那些多邊型模型位於視口之內. OpenGL支持兩類投影

投影變換(PROJECTION transformation) 簡介
透視投影

glFrustum()

gluPerspective()

用於3D世界的顯示與真實世界一樣, 多邊型模型呈現近大遠小
正交投影

glOrtho()

gluOrtho2D()

不考濾與攝影機的距離,顯示多邊型模型真實的大小,常用於CAD軟件和2D遊戲,文本顯示

 

透視投影 簡介
void gluPerspective (

GLdouble fovy,

GLdouble aspect,

GLdouble zNear,

GLdouble zFar);

直接指定視角和屏幕寬高比從而計算觀察截體.
Fovy 可視角度一般設為45度至90度
Aspect 屏幕的寬高比(Width/Height)
zNear 近端剪切面距離
zFar 遠端剪切面距離

 

透視投影 簡介
void glFrustum (

GLdouble left,

GLdouble right,

GLdouble bottom,

GLdouble top,

GLdouble zNear,

GLdouble zFar);

觀察截體的計算由近端剪切面與遠端剪切面確定
Left right bottom top 近端剪切面的範圍
zNear 近端剪切面距離
zFar 遠端剪切面距離

 

正交投影 簡介
Void glOrtho (

GLdouble left,

GLdouble right,

GLdouble bottom,

GLdouble top,

GLdouble zNear,

GLdouble zFar);

相同的模型不管與攝影機距離的遠近,其呈現的相同大小
left right bottom top 剪切面的範圍
zNear 近端剪切面距離
zFar 遠端剪切面距離

 

正交投影 簡介
void gluOrtho2D (

GLdouble left,

GLdouble right,

GLdouble bottom,

GLdouble top);

相當於glOrtho(left,right,bottom,top,-1,1);
left right bottom top 剪切面的範圍

投影示例

  1. 選擇投影矩陣堆棧glMatrixMode(GL_PROJECTION);
  2. 載入單位矩陣glLoadIdentity()
  3. 設定透視投影或正交投影

投影函式

void Set_Projection_OpenGL(bool Is3D)

{

::glViewport(0,0,OpenGL_Width,OpenGL_Height); // 重置視區尺寸

::glMatrixMode(GL_PROJECTION); // 設定投影矩陣

::glLoadIdentity();// 載入單位矩陣

if(Is3D == true) // 3D投影計算窗口尺寸比例

gluPerspective(54.0f,(GLfloat)OpenGL_Width/(GLfloat)OpenGL_Height,1.0f,1000.0f);

else  // 設為2D投影

gluOrtho2D(0, OpenGL_Width, 0, OpenGL_Height);

::glMatrixMode(GL_MODELVIEW);  // 設定模型視圖矩陣

::glLoadIdentity();// 載入單位矩陣

}

投影演示程式如上圖:下載

  1. 按P鍵在正交投影與透視投影之間切換
  2. 按S鍵切換抗鋸齒功能
  3. 按1鍵切換為黃色
  4. 按2鍵切換為綠色
  5. 按3鍵切換為紅色
  6. 按F1鍵打開幫助
  7. 按ESC鍵旋轉角度清零
  8. 按+鍵加大直線寬度
  9. 按-鍵減小直線寬度

Windows訪問鍵盤

Windows訪問鍵盤

此程式用於查閱鍵消息的虛擬代碼(Virtual Code)與按鍵狀態(Key state)如上圖:下載程式

在Windows訪問鍵盤有五種方法

  1. 接收WM_CHAR消息
  2. 接收WM_KEYDOWN消息
  3. 接收WM_KEYUP消息
  4. 調用GetAsyncKeyState()函式,需要輸入虛擬代碼(Virtual Code)
  5. DirectInput
Windows鍵盤消息 觸發條件
WM_CHAR 按下鍵盤
WM_KEYDOWN 按下鍵盤
WM_KEYUP 鬆開鍵盤
GetAsyncKeyState() 任何時候都可讀取鍵盤

 

Windows鍵盤消息 wParam lParam
WM_CHAR ASCII碼(ASCII Code) 按鍵狀態Key state
WM_KEYDOWN 虛擬代碼(Virtual Code)
WM_KEYUP

 

按鍵狀態Key state(BIT) 變量 簡介
0~15 整數 按鍵重複次數(repeat count)
16~12 整數 掃描碼(scan code)
24 bool 擴展鍵標識,若為1為該鍵為擴展鍵,如右側的ALT鍵和CTRL鍵
25~28 無使用
29 bool 若為1則ALT鍵被按下,否則為0
30 bool 前一個鍵的狀態
31 bool 若為1鍵被釋放,若為0鍵被按住.

 

OpenGL之繪畫多邊形

OpenGL之繪畫多邊形

OpenGL多邊形的演示程式如上圖:下載

  1. 按鼠標左鍵點擊繪畫多邊形,繪畫時頂點的走向為逆時針多邊形為正面,否則為背面.
  2. 按+鍵加大直線寬度
  3. 按-鍵減小直線寬度
  4. 按S鍵切換抗鋸齒功能
  5. 按.鍵切換多邊形點畫模式
  6. 按C鍵切換多邊形隱面裁剪
  7. 按1鍵填充模式
  8. 按2鍵線框模式
  9. 按3鍵頂點模式
  10. 按4鍵切換為白色
  11. 按5鍵切換為黃色
  12. 按6鍵切換為紅色
  13. 按F1鍵打開幫助
  14. 按ESC鍵清空畫面

繪畫多邊形,頂點不能小於3個

  1. glBegin(GL_POLYGON);準備繪畫多邊形
  2. for (int i = 0; i < count; ++i)
  3. glVertex3f(v[i].x,v[i].y,v[i].z);繪畫多邊形頂點
  4. glEnd();結束繪畫

多邊形其它設定請參考三角形

OpenGL之繪畫四邊形

OpenGL之繪畫四邊形

OpenGL四邊形的演示程式如上圖:下載

  1. 按鼠標左鍵點擊繪畫四邊形,繪畫時頂點的走向為逆時針四邊形為正面,否則為背面.
  2. 按+鍵加大直線寬度
  3. 按-鍵減小直線寬度
  4. 按S鍵切換抗鋸齒功能
  5. 按.鍵切換四邊形點畫模式
  6. 按C鍵切換四邊形隱面裁剪
  7. 按1鍵填充模式
  8. 按2鍵線框模式
  9. 按3鍵頂點模式
  10. 按4鍵每四個頂點組成四邊形
  11. 按5鍵頂點相連的四邊形

繪畫四邊形

  1. glBegin(GL_TRIANGLES);準備繪畫四邊形
  2. for (int i = 0; i < count; ++i)
  3. glVertex3f(v[i].x,v[i].y,v[i].z);繪畫四邊形頂點
  4. glEnd();結束繪畫
glBegin()繪畫四邊形參數 簡介
GL_QUADS 每四個頂點組成四邊形
GL_QUAD_STRIP 頂點相連的四邊形,需要把第三第四個頂點的渲染順序交換.

四邊形也屬於多邊形其它設定請參考三角形

 

OpenGL之繪畫三角形

OpenGL之繪畫三角形

OpenGL三角形屬於多邊形.演示程式如上圖:下載

  1. 按鼠標左鍵點擊繪畫三角形,繪畫時頂點的走向為逆時針三角形為正面,否則為背面.
  2. 按+鍵加大直線寬度
  3. 按-鍵減小直線寬度
  4. 按S鍵切換抗鋸齒功能
  5. 按.鍵切換三角形點畫模式
  6. 按C鍵切換三角形隱面裁剪
  7. 按1鍵填充模式
  8. 按2鍵線框模式
  9. 按3鍵頂點模式
  10. 按4鍵每三個頂點組成三角形
  11. 按5鍵頂點相連的三角形
  12. 按6鍵第一個頂點作為三角形的共同頂點

繪畫三角形

  1. glBegin(GL_TRIANGLES);準備繪畫三角形
  2. glVertex3f(x1,y1,z1);繪畫三角形頂點1
  3. glVertex3f(x2,y2,z2);繪畫三角形頂點2
  4. glVertex3f(x3,y3,z3);繪畫三角形頂點3
  5. glEnd();結束繪畫
glBegin()繪畫直線參數 簡介
GL_TRIANGLES 每三個頂點組成三角形
GL_TRIANGLE_STRIP 頂點相連的三角形
GL_TRIANGLE_FAN 第一個頂點作為三角形的共同頂點

因屏幕由像素組成,三角形邊緣會產生鋸齒,啟用抗鋸齒算法後會變得平滑,並修改邊緣像素的顏色:

  1. glEnable(GL_POLYGON_SMOOTH);啟用多邊形的平滑模式(抗鋸齒功能)
  2. glEnable(GL_BLEND);啟用混合

多邊形模式(正面默認為填充模式)

void glPolygonMode(GLenum face,GLenum mode);

多邊形面(face) 簡介
GL_FRONT 多邊形正面:頂點的走向為逆時針(默認)
GL_BACK 多邊形背面:頂點的走向為順時針
GL_FRONT_AND_BACK 正面與背面

 

多邊形模式(mode) 簡介
GL_FILL 填充模式:對多邊形內部進行顏色填充(默認)
GL_LINE 線框模式:多邊形只繪畫直先不填充
GL_POINT 頂點模式:只繪畫多邊形頂點

設置多邊形隱面裁剪

3D圖形渲染的工作量非常大,把不可見的面剔除則可節減大量變換和渲染時間.

  1. glEnable(GL_CULL_FACE);啟用隱面裁剪
  2. glCullFace(GL_BACK);設背面為隱面
  3. glFrontFace(GL_CCW);多邊形正面使用逆時針
正面模式(MODE) 簡介
GL_CCW 多邊形正面使用逆時針
GL_CW 多邊形反面使用順時針

多邊形點畫模式可用於簡單的填充(不太常用)

void glPolygonStipple(GLushort * mask);

mask:掩碼大小寬8byte*高16byte=128(byte)=1024(bit),1填充像素,0不填充

  1. glEnable(GL_POLYGON_STIPPLE);啟用點畫模式
  2. glPolygonStipple(mask);設置掩碼