OpenGL入門學習——第二課 繪製幾何圖形

本次課程所要講的是繪製簡單的幾何圖形,在實際繪製之前,讓我們先熟悉一些概念。


一、點、直線和多邊形
我們知道數學(具體的說,是幾何學)中有點、直線和多邊形的概念,但這些概念在計算機中會有所不同。
數學上的點,只有位置,沒有大小。但在計算機中,無論計算精度如何提高,始終不能表示一個無窮小的點。另一方面,無論圖形輸出設備(例如,顯示器)如何精確,始終不能輸出一個無窮小的點。一般情況下,OpenGL中的點將被畫成單個的像素(像素的概念,請自己搜索之~),雖然它可能足夠小,但並不會是無窮小。同一像素上,OpenGL可以繪製許多座標只有稍微不同的點,但該像素的具體顏色將取決於OpenGL的實現。當然,過度的注意細節就是鑽牛角尖,我們大可不必花費過多的精力去研究“多個點如何畫到同一像素上”。
同樣的,數學上的直線沒有寬度,但OpenGL的直線則是有寬度的。同時,OpenGL的直線必須是有限長度,而不是像數學概念那樣是無限的。可以認爲,OpenGL的“直線”概念與數學上的“線段”接近,它可以由兩個端點來確定。
多邊形是由多條線段首尾相連而形成的閉合區域。OpenGL規定,一個多邊形必須是一個“凸多邊形”(其定義爲:多邊形內任意兩點所確定的線段都在多邊形內,由此也可以推導出,凸多邊形不能是空心的)。多邊形可以由其邊的端點(這裏可稱爲頂點)來確定。(注意:如果使用的多邊形不是凸多邊形,則最後輸出的效果是未定義的——OpenGL爲了效率,放寬了檢查,這可能導致顯示錯誤。要避免這個錯誤,儘量使用三角形,因爲三角形都是凸多邊形)

可以想象,通過點、直線和多邊形,就可以組合成各種幾何圖形。甚至於,你可以把一段弧看成是很多短的直線段相連,這些直線段足夠短,以至於其長度小於一個像素的寬度。這樣一來弧和圓也可以表示出來了。通過位於不同平面的相連的小多邊形,我們還可以組成一個“曲面”。

二、在OpenGL中指定頂點
由以上的討論可以知道,“點”是一切的基礎。
如何指定一個點呢?OpenGL提供了一系列函數。它們都以glVertex開頭,後面跟一個數字和1~2個字母。例如:
glVertex2d
glVertex2f
glVertex3f
glVertex3fv
等等。
數字表示參數的個數,2表示有兩個參數,3表示三個,4表示四個(我知道有點羅嗦~)。
字母表示參數的類型,s表示16位整數(OpenGL中將這個類型定義爲GLshort),
i表示32位整數(OpenGL中將這個類型定義爲GLint和GLsizei),
f表示32位浮點數(OpenGL中將這個類型定義爲GLfloat和GLclampf),
d表示64位浮點數(OpenGL中將這個類型定義爲GLdouble和GLclampd)。
v表示傳遞的幾個參數將使用指針的方式,見下面的例子。
這些函數除了參數的類型和個數不同以外,功能是相同的。例如,以下五個代碼段的功能是等效的:
(一)glVertex2i(1, 3);
(二)glVertex2f(1.0f, 3.0f);
(三)glVertex3f(1.0f, 3.0f, 0.0f);
(四)glVertex4f(1.0f, 3.0f, 0.0f, 1.0f);
(五)GLfloat VertexArr3[] = {1.0f, 3.0f, 0.0f};
glVertex3fv(VertexArr3);
以後我們將用glVertex*來表示這一系列函數。
注意:OpenGL的很多函數都是採用這樣的形式,一個相同的前綴再加上參數說明標記,這一點會隨着學習的深入而有更多的體會。

三、開始繪製
假設現在我已經指定了若干頂點,那麼OpenGL是如何知道我想拿這些頂點來幹什麼呢?是一個一個的畫出來,還是連成線?或者構成一個多邊形?或者做其它什麼事情?
爲了解決這一問題,OpenGL要求:指定頂點的命令必須包含在glBegin函數之後,glEnd函數之前(否則指定的頂點將被忽略)。並由glBegin來指明如何使用這些點。
例如我寫:
glBegin(GL_POINTS);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.0f);
glEnd();
則這兩個點將分別被畫出來。如果將GL_POINTS替換成GL_LINES,則兩個點將被認爲是直線的兩個端點,OpenGL將會畫出一條直線。
我們還可以指定更多的頂點,然後畫出更復雜的圖形。
另一方面,glBegin支持的方式除了GL_POINTS和GL_LINES,還有GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN等,每種方式的大致效果見下圖:


聲明:該圖片來自www.opengl.org,該圖片是《OpenGL編程指南》一書的附圖,由於該書的舊版(第一版,1994年)已經流傳於網絡,我希望沒有觸及到版權問題。

我並不準備在glBegin的各種方式上大作文章。大家可以自己嘗試改變glBegin的方式和頂點的位置,生成一些有趣的圖案。

程序代碼:

void myDisplay(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin( /* 在這裏填上你所希望的模式 */ );
        /* 在這裏使用glVertex*系列函數 */
        /* 指定你所希望的頂點位置 */
	glEnd();
	glFlush();
}

把這段代碼改成你喜歡的樣子,然後用它替換第一課中的myDisplay函數,編譯後即可運行。


三個例子

例一、畫一個圓

例二、畫一個五角星

例三、畫出正弦函數的圖形


小結
本課講述了點、直線和多邊形的概念,以及如何使用OpenGL來描述點,並使用點來描述幾何圖形。
大家可以發揮自己的想象,畫出各種幾何圖形,當然,也可以用GL_LINE_STRIP把很多位置相近的點連接起來,構成函數圖象。如果有興趣,也可以去找一些圖象比較美觀的函數,自己動手,用OpenGL把它畫出來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章