1 / 40

Introduction to OpenGL (2)

Introduction to OpenGL (2). 靜宜大學資工系 蔡奇偉 副教授 2001-2008. Red Book 第二章. 大綱. OpenGL 的命名慣例 OpenGL/GLUT hello 程式 清除視窗的內容 設定目前的繪圖顏色 glFlush() 與 glFinish() OpenGL 的基本幾何元件 設定 / 讀取 OpenGL 的狀態 設定圖形的屬性. OpenGL 的命名慣例. 函式名稱以 gl 開頭,而且名稱中每個字的字首使用大寫,如 glClearColor() 。

pepper
Download Presentation

Introduction to OpenGL (2)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduction to OpenGL (2) 靜宜大學資工系 蔡奇偉 副教授 2001-2008 Red Book 第二章

  2. 大綱 • OpenGL 的命名慣例 • OpenGL/GLUT hello 程式 • 清除視窗的內容 • 設定目前的繪圖顏色 • glFlush() 與 glFinish() • OpenGL 的基本幾何元件 • 設定/讀取 OpenGL 的狀態 • 設定圖形的屬性

  3. OpenGL 的命名慣例 • 函式名稱以 gl 開頭,而且名稱中每個字的字首使用大寫,如 glClearColor()。 • 常數名稱全為大寫字母並以 GL 開頭,名稱中每個字用底線字元(_) 隔開,如 GL_COLOR_BUFFER_BIT。 • 某些函式的字尾暗示參數的個數與型態,如glVertex3f (float x, float y, float z) /* 3 個浮點數 */ • glVertex2i (int x, int y) /* 2 個整數 */ • glVetex3fv (float *vl) /* 3 個浮點數組成的陣列 */

  4. 字尾 資料型態 OpenGL 資料型態 b signed char GLbyte s short GLshort i int (or long) GLint, GLsizei f float GLfloat, GLclampf d double GLdouble, GLclampd ub unsigned char GLubyte, GLboolean us unsigned short GLushort ui unsigned int GLuint, GLenum, GLbitfield (or unsigned long) 此外,參數為陣列的函式通常以字母 v 為結尾。

  5. OpenGL/GLUT hello 程式 • hello.c 原始碼 • GLUT 初始化函式 • 事件驅動程式 • GLUT callback 函式 • GLUT mainloop 函式

  6. /* * hello.c * This is a simple, introductory OpenGL program. */ #include <GL/glut.h>

  7. void display(void) { glClear (GL_COLOR_BUFFER_BIT); /* clear all pixels */ /* draw white polygon (rectangle) with corners at * (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0) */ glColor3f (1.0, 1.0, 1.0); glBegin(GL_POLYGON); glVertex3f (0.25, 0.25, 0.0); glVertex3f (0.75, 0.25, 0.0); glVertex3f (0.75, 0.75, 0.0); glVertex3f (0.25, 0.75, 0.0); glEnd(); /* don't wait! * start processing buffered OpenGL routines */ glFlush (); }

  8. void init (void) { /* select clearing color */ glClearColor (0.0, 0.0, 0.0, 0.0); /* initialize viewing values */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); }

  9. /* * Declare initial window size, position, and display mode * (single buffer and RGBA). Open window with "hello" * in its title bar. Call initialization routines. * Register callback function to display graphics. * Enter main loop and process events. */ int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (250, 250); glutInitWindowPosition (100, 100); glutCreateWindow ("hello"); init (); glutDisplayFunc(display); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }

  10. GLUT 初始化函式 • glutInit (int *argc, char ** argv) • 設定啟動 GLUT 所需的初值,然後處理一些指令行的參數(用於 X Window 系統)。呼叫這個函式後才能夠開始呼叫其他的 GLUT 函式。

  11. glutInitDisplayMode (unsigned int mode) • 設定顯示的模式。你可以用 bitwise OR(|)的方式來選取以下的模式 : • GLUT_RGBA(或 GLUT_RGB), GLUT_INDEX • GLUT_SINGLE, GLUT_DOUBLE • GLUT_ACCUM • GLUT_ALPHA • GLUT_DEPTH • GLUT_STENCIL • GLUT_LUMINANCE

  12. glutInitWindowSize (int width, int height) 設定視窗的初始大小為 width x height像素。 glutInitWindowPosition (int x, int y) 設定視窗在螢幕上的初始位置為 (x, y) 像素。 glutCreateWindow (char *name) 建立和顯示最上層的視窗並把視窗的標題設成 name。

  13. 事件驅動程式 目前流行的視窗系統(如 X Window、MS Windows)是採用事件驅動(event-driven)的模式。視窗系統必須處理許多不同的事件(event)— 如:鍵盤輸入、滑鼠移動、壓下滑鼠按鍵、放開滑鼠按鍵等等使用者的動作,以及視窗遮蓋、視窗浮現等等螢幕狀態的改變。這些事件依序地擺放在所謂的事件佇列(event queue)中,然後用循覆的方式依序處理(稱為事件迴路(event loop))。我們以下圖說明之:

  14. front rear 加入新事件 event queue 取出下一個事件 event loop 判斷是何事件 呼叫該事件的 處理函式

  15. GLUT callback 函式 • GLUT 利用 callback 函式的機制來註冊事件處理函式。GLUT 提供了一些函式來設定事件處理函式。 • glutDisplayFunc (void (*func)(void)) • 設定 func為處理視窗內容變動事件的函式。我們必須把所有繪製視窗內容的程式碼寫在函式 func 之中。

  16. glutReshapeFunc (void (*func)(int w, int h)) • 設定 func為處理視窗大小變動事件的函式。參數 w和 h是視窗的新寬度與新高度。 • glutKeyboardFunc (void (*func)(unsigned char key, int x, int y)) • 設定 func為處理鍵盤事件的函式。參數 key是按鍵的 ASCII 碼,參數 (x, y) 是按鍵時滑鼠所在的座標。 • glutMouseFunc (void (*func)(int button, int x, int y)) • 設定 func為處理滑鼠按鍵事件的函式。參數 button是所按下或放開的滑鼠鍵,參數 (x, y) 是按鍵時滑鼠所在的座標。

  17. glutMotionFunc (void (*func)(int x, int y)) • 設定 func為處理按住滑鼠鍵並移動滑鼠事件的函式。參數 x和 y是滑鼠目前所在的座標。 • glutPassiveMotionFunc (void (*func)(int x, int y)) • 設定 func為處理滑鼠移動事件(未按下滑鼠鍵)的函式。參數 x和 y是滑鼠目前所在的座標。 • glutIdleFunc (void (*func)(void)) • 設定 func為處理「空事件(即無任何事件發生)」的函式。

  18. glutTimerFunc (insigned int msec, void (*func)(int value ), int value ) • 設定 func為處理定時器事件的函式。參數 msec是啟動定時器的間隔時間,其單位是毫秒(千分之一秒)。系統會每隔 msec 毫秒自動呼叫函式 func,並以glutTimerFunc第三個參數 value的值為其參數值。

  19. void glutMainLoop (void) 在程式中你應該只呼叫glutMainLoop 函式一次來進入事件迴圈。這個函式的責任是不斷地檢驗事件的種類,然後呼叫你所指定的事件處理 callback 函式。此外,這個函式本身是一個無限迴圈,無法結束執行而回到主函式。

  20. 清除視窗的內容 • glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) • 設定清除的顏色。各顏色的成份值必須介於 0.0 和 1.0 之間。值愈小表示成份愈少。所以 (0.0, 0.0, 0.0, 0.0) 代表黑色、 (1.0, 1.0, 1.0, 0.0) 代表白色、 (1.0, 0.0, 0.0, 0.0)代表紅色、…、等等。第四個參數 alpha用來設定透明度。

  21. glClear (GLbitfield mask) • 用目前的清除值來清除參數 mask所選定的緩衝區。以下的緩衝區可以用 bitwise OR 的方式來選取: • GL_COLOR_BUFFER_BIT (glClearColor) • GL_DEPTH_BUFFER_BIT (glClearDepth) • GL_ACCUM_BUFFER_BIT (glClearAccum) • GL_STENCIL_BUFFER_BIT (glClearStencil) • 註:不同的緩衝區需要用不同的函式(上表的右方)來設定清除值。

  22. 範例: • glClearColor(0.0, 0.0, 0.0, 0.0); • glClearDepth(1.0); • glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  23. 設定目前的繪圖顏色 OpenGL 的繪圖函式並不需要指定顏色,而是利用目前所設定的繪圖顏色。目前的繪圖顏色是由 glColor*() 這一類的函式來指定,如: glColor3f (GLfloat red, GLfloat green, GLfloat blue) glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) glColor3fv(GLfloat *color_array) /* color_array has 3 elements */

  24. 常見的顏色值

  25. glFlush() 和 glFinish() glFlush() 函式和 glFinish() 函式都會要求立刻執行之前所下達的 OpenGL 指令。兩者不同的地方在於: glFlush() 要求後就結束函式的執行,而 glFinish() 必須等到這些指令都完成後,才會結束函式的執行。 透過網路來執行的 OpenGL 程式可以運用這兩個函式來增進執行的效率。

  26. OpenGL 的基本幾何元件 • Vertices(端點) • 由端點組成的基本圖形

  27. Vertices(端點) • OpenGL 的幾何圖形都是由端點組成。你可以用 glVertex*()指令來設定端點的位置: • glVertex{234}{sifd}[v] (TYPE coords); • 例如: • glVertex2s(2, 3); • glVertex3d(0.0, 0.0, 3.14159); • glVertex4f(2.3, 1.2, 3.1, 2.0); • GLdouble dvect[] = {1.0, 2.0, 3.0}; • glVertex3dv(dvect);

  28. 由端點組成的基本圖形 • 我們可以用下面的結構來繪製 OpenGL 的基本圖形: • glBegin(type); • /* 一連串的 glVertex*() 的呼叫 */ • glEnd(); • 其中 glBegin 函式的參數 type用來指定所需的圖形,它的可能值與相對的圖形如底下幾頁所示。

  29. v0 v2 v4 v1 v3 v5 GL_POINTS v0 v2 v4 v0 v2 v4 v0 v2 v4 v1 v3 v5 v1 v3 v5 v1 v3 v5 GL_LINE_LOOP GL_LINES GL_LINE_STRIP

  30. v2 v0 v2 v4 v0 v2 v4 v1 v3 v0 v1 v3 v1 v3 v5 v5 v4 GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN v6 v5 v4 v2 v0 v4 v0 v7 v4 v0 v2 v5 v1 v3 v5 v7 v1 v6 v2 v3 v1 v3 GL_QUADS GL_QUADS_STRIP GL_POLYGON

  31. 指令名稱 用途 glVertex*() 設定端點的座標 glColor*() 設定目前的繪圖顏色 glIndex*() 設定目前的繪圖索引色 glNormal*() 設定端點的法向量 glTexCoord*() 設定貼圖座標 glMultiTexCoord*ARB() 設定多重貼圖座標 glEdgeFlag*() 控制端線的繪製方式 glMaterial*() 設定材質的屬性 glArrayElement() 取出端點陣列的資料 glEvalCoord*(), glEvalPoint*() 産生座標值 glCallList(), glCallLists() 執行 display list(s) glBegin() 和 glEnd() 之間只可以擺下列的 OpenGL 指令:

  32. 設定/讀取 OpenGL 的狀態 • OpenGL 用一些內部的狀態變數(state variables)來開啟或關閉若干的高級高能。 • void glEnable (GLenum cap) • 開啟參數 cap 所代表的功能。 • void glDisable (GLenum cap) • 關閉參數 cap 所代表的功能。 • GLboolean glIsEnable (GLenum cap) • 檢驗cap 所代表的功能是否已經開啟。

  33. 若要取出狀態變數的值,我們可以依據其資料型態使用下列適當的函式:若要取出狀態變數的值,我們可以依據其資料型態使用下列適當的函式: • void glGetBooleanv (Glenum pname, GLboolean *params) • void glGetIntegerv (Glenum pname, GLint *params) • void glGetFloatv (Glenum pname, GLfloat *params) • void glGetDoublev (Glenum pname, GLdouble *params) • void glGetPointerv (Glenum pname, GLvoid *params) • 其中的第一個參數是狀態變數的符號名稱,如 GL_CURRENT_COLOR 代表儲存目前繪圖顏色的狀態變數。所以, • GLint params[4]; • glGetIntegerv (GL_CURRENT_COLOR, params); • 把目前的繪圖顏色取出存放在陣列 params 中。

  34. 設定圖形的屬性 • glPointSize() • glLineWidth() • glLineStipple()

  35. default antialiasing void glPointSize (GLfloat size) 設定端點的像素大小(預設值是 1.0)。參數 size不可以代入 0.0。端點有兩種顯示形狀:在預設的情況下, size 先被四捨五入成整數 n,然後端點被畫成 nn個像素的方點。若啟動平滑功能(antialiasing)的話, size 不會被四捨五入,而且端點被畫成近似圓的點。

  36. 啟動平滑繪點的功能: • glEnable(GL_POINT_SMOOTH); • 你可以用下列參數代入函式 glGetFloatv() 及來查詢 OpneGL 系統的能力: • GL_ALIASED_POINT_SIZE_RANGE • 點大小的允許範圍 • GL_SMOOTH_POINT_SIZE_RANGE • 平滑點大小的允許範圍 • GL_SMOOTH_POINT_SIZE_GRANULARITY • 平滑點大小的精確度

  37. glLineWidth(GLfloat width) 設定線段的寛度(預設值是 1.0 個像素)。同端點一樣,反鋸齒的平滑功能是否啟動會影響到線段的繪製方式。在預設的情況下, width 先被四捨五入成整數 n。斜率小於 1 的線,垂直厚度設為 n個像素,斜率大於 1 的線,則水平厚度設為 n個像素。若啟動平滑功能,則 width 不會被四捨五入成整數 n,同時線段的周圍用較暗的像素來達成平滑的效果。

  38. 平滑 line width = 2 非平滑 line width = 2

  39. 啟動平滑繪線的功能: • glEnable(GL_LINE_SMOOTH); • 你可以用下列參數代入函式 glGetFloatv() 及來查詢 OpneGL 系統的能力: • GL_ALIASED_LINE_WIDTH_RANGE • 線寛度大小的允許範圍 • GL_SMOOTH_LINE_WIDTH_RANGE • 平滑線寛度的允許範圍 • GL_SMOOTH_LINE_WIDTH_GRANULARITY • 平滑線寛度的精確度

  40. Pattern 十六進位 factor 樣式 0000000011111111 0x00FF 1 0000000011111111 0x00FF 2 0000110000001111 0x0C0F 1 1010101010101010 0xAAAA 1 glLineStipple(GLint factor, GLushort pattern) 這個函式可用來設定線段的樣式。使用這個函式之前,你必須呼叫 glEnable(GL_LINE_STIPPLE)來啟動這個功能。參數 pattern是一個 16-bit 的整數,用來定義線段的樣式,其中的 bits 由右至左地檢視,若為 1,則表示要畫點,若為 0 的話,則表示不要畫點。參數 factor控制樣式的放大倍數。

More Related