40
Introduction to OpenGL (2) 靜靜靜靜靜靜靜 靜靜靜 靜靜靜 2001-2008 Red Book 靜靜靜

Introduction to OpenGL (2)

  • Upload
    pepper

  • View
    87

  • Download
    0

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Introduction to OpenGL (2)

Introduction to OpenGL (2)

靜宜大學資工系蔡奇偉 副教授2001-2008

Red Book 第二章

Page 2: Introduction to OpenGL (2)

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

Page 3: Introduction to OpenGL (2)

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 個浮點數組成的陣列 */

Page 4: Introduction to OpenGL (2)

字尾 資料型態 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 為結尾。

Page 5: Introduction to OpenGL (2)

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

Page 6: Introduction to OpenGL (2)

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

Page 7: Introduction to OpenGL (2)

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 ();}

Page 8: Introduction to OpenGL (2)

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);}

Page 9: Introduction to OpenGL (2)

/* * 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. */}

Page 10: Introduction to OpenGL (2)

GLUT 初始化函式

glutInit (int *argc, char ** argv)

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

Page 11: Introduction to OpenGL (2)

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

Page 12: Introduction to OpenGL (2)

glutInitWindowSize (int width, int height)

glutInitWindowPosition (int x, int y)

設定視窗在螢幕上的初始位置為 (x, y) 像素。glutCreateWindow (char *name)

建立和顯示最上層的視窗並把視窗的標題設成 name 。

設定視窗的初始大小為 width x height 像素。

Page 13: Introduction to OpenGL (2)

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

Page 14: Introduction to OpenGL (2)

取出下一個事件判斷是何事件

front rear

event queue

e1 e2 en

呼叫該事件的處理函式

eventloop

加入新事件

Page 15: Introduction to OpenGL (2)

GLUT callback 函式GLUT 利用 callback 函式的機制來註冊事件處理函式。 GLUT 提供了一些函式來設定事件處理函式。

glutDisplayFunc (void (*func)(void))

設定 func 為處理視窗內容變動事件的函式。我們必須把所有繪製視窗內容的程式碼寫在函式 func 之中。

Page 16: Introduction to OpenGL (2)

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) 是按鍵時滑鼠所在的座標。

Page 17: Introduction to OpenGL (2)

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 為處理「空事件(即無任何事件發生)」的函式。

Page 18: Introduction to OpenGL (2)

glutTimerFunc (insigned int msec, void (*func)(int value ), int value )

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

Page 19: Introduction to OpenGL (2)

void glutMainLoop (void)

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

Page 20: Introduction to OpenGL (2)

清除視窗的內容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 用來設定透明度。

Page 21: Introduction to OpenGL (2)

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)

註:不同的緩衝區需要用不同的函式(上表的右方)來設定清除值。

Page 22: Introduction to OpenGL (2)

範例:glClearColor(0.0, 0.0, 0.0, 0.0);glClearDepth(1.0);glClear(GL_COLOR_BUFFER_BIT |

GL_DEPTH_BUFFER_BIT);

Page 23: Introduction to OpenGL (2)

設定目前的繪圖顏色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 */

Page 24: Introduction to OpenGL (2)

常見的顏色值color name Red Green Blue

black 0.0 0.0 0.0

red 1.0 0.0 0.0

green 0.0 1.0 0.0

yellow 1.0 1.0 0.0

blue 0.0 0.0 1.0

magenta 1.0 0.0 1.0

cyan 0.0 1.0 1.0

dark gray 0.25 0.25 0.25

light gray 0.75 0.75 0.75

brown 0.6 0.4 0.12

pumpkin orange 0.98 0.625 0.12

pastel pink 0.98 0.04 0.7

Barney purple 0.6 0.4 0.7

white 1.0 1.0 1.0

Page 25: Introduction to OpenGL (2)

glFlush() 和 glFinish()

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

Page 26: Introduction to OpenGL (2)

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

Page 27: Introduction to OpenGL (2)

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);

Page 28: Introduction to OpenGL (2)

由端點組成的基本圖形我們可以用下面的結構來繪製 OpenGL 的基本圖形:

glBegin(type);

/* 一連串的 glVertex*() 的呼叫 */

glEnd();

其中 glBegin 函式的參數 type 用來指定所需的圖形,它的可能值與相對的圖形如底下幾頁所示。

Page 29: Introduction to OpenGL (2)

v0 v2 v4

v1 v3 v5

GL_POINTS

v0 v2 v4

v1 v3 v5

GL_LINES

v0 v2 v4

v1 v3 v5

GL_LINE_STRIP

v0 v2 v4

v1 v3 v5

GL_LINE_LOOP

Page 30: Introduction to OpenGL (2)

v0 v2 v4

v1 v3 v5

GL_TRIANGLES

v0 v2 v4

v1 v3 v5

GL_TRIANGLE_STRIP

v1v2

v4

v0

v3

GL_TRIANGLE_FAN

v0 v2

v4

v1 v3

v5

GL_QUADS

v6

v7v0

v2 v4

v1 v3

v5

GL_QUADS_STRIP

v7

v6 v0

v5

v4

v1v2

v3

GL_POLYGON

Page 31: Introduction to OpenGL (2)

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

Page 32: Introduction to OpenGL (2)

設定 / 讀取 OpenGL 的狀態OpenGL 用一些內部的狀態變數( state variables )來開啟或關閉若干的高級高能。void glEnable (GLenum cap)

開啟參數 cap 所代表的功能。void glDisable (GLenum cap)關閉參數 cap 所代表的功能。

GLboolean glIsEnable (GLenum cap)檢驗 cap 所代表的功能是否已經開啟。

Page 33: Introduction to OpenGL (2)

若要取出狀態變數的值,我們可以依據其資料型態使用下列適當的函式: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 中。

Page 34: Introduction to OpenGL (2)

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

Page 35: Introduction to OpenGL (2)

void glPointSize (GLfloat size)

設定端點的像素大小(預設值是 1.

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

default

antialiasing

Page 36: Introduction to OpenGL (2)

啟動平滑繪點的功能:glEnable(GL_POINT_SMOOTH);

你可以用下列參數代入函式 glGetFloatv() 及來查詢 OpneGL 系統的能力:GL_ALIASED_POINT_SIZE_RANGE

點大小的允許範圍GL_SMOOTH_POINT_SIZE_RANGE平滑點大小的允許範圍

GL_SMOOTH_POINT_SIZE_GRANULARITY平滑點大小的精確度

Page 37: Introduction to OpenGL (2)

glLineWidth(GLfloat width)

設定線段的寛度(預設值是 1.0 個像素)。同端點一樣,反鋸齒的平滑功能是否啟動會影響到線段的繪製方式。在預設的情況下, width 先被四捨五入成整數 n 。斜率小於 1 的線,垂直厚度設為 n 個像素,斜率大於 1

的線,則水平厚度設為 n 個像素。若啟動平滑功能,則 width 不會被四捨五入成整數 n ,同時線段的周圍用較暗的像素來達成平滑的效果。

Page 38: Introduction to OpenGL (2)

非平滑line width = 2

平滑line width = 2

Page 39: Introduction to OpenGL (2)

啟動平滑繪線的功能:glEnable(GL_LINE_SMOOTH);

你可以用下列參數代入函式 glGetFloatv() 及來查詢 OpneGL 系統的能力:GL_ALIASED_LINE_WIDTH_RANGE

線寛度大小的允許範圍GL_SMOOTH_LINE_WIDTH_RANGE平滑線寛度的允許範圍

GL_SMOOTH_LINE_WIDTH_GRANULARITY平滑線寛度的精確度

Page 40: Introduction to OpenGL (2)

glLineStipple(GLint factor, GLushort pattern)

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

0000000011111111 0x00FF 2

0000110000001111 0x0C0F 1

1010101010101010 0xAAAA 1