OpenGL學習 點 直線 多邊形

2021-09-06 22:13:48 字數 3899 閱讀 8555

上一課中,我們學習了如何繪製幾何圖形,但大家如果多寫幾個程式,就會發現其實還是有些鬱悶之處。例如:點太小,難以看清楚;直線也太細,不舒服;或者想畫虛線,但不知道方法只能用許多短直線,甚至用點組合而成。

這些問題將在本課中被解決。

下面就點、直線、多邊形分別討論。

1、關於點

點的大小預設為1個畫素,但也可以改變之。改變的命令為glpointsize,其函式原型如下:

void glpointsize(glfloat size);

size必須大於0.0f,預設值為1.0f,單位為「畫素」。

注意:對於具體的opengl實現,點的大小都有個限度的,如果設定的size超過最大值,則設定可能會有問題。

例子:

void mydisplay(void

)

2、關於直線

(1)直線可以指定寬度:

void gllinewidth(glfloat width);其用法跟glpointsize類似。

(2)畫虛線。

首先,使用glenable(gl_line_stipple);來啟動虛線模式(使用gldisable(gl_line_stipple)可以關閉之)。

然後,使用gllinestipple來設定虛線的樣式。

void gllinestipple(glint factor, glushort pattern);

pattern是由1和0組成的長度為16的序列,從最低位開始看,如果為1,則直線上接下來應該畫的factor個點將被畫為實的;如果為0,則直線上接下來應該畫的factor個點將被畫為虛的。

以下是一些例子:

void mydisplay(void

)

3、關於多邊形

多邊形的內容較多,我們將講述以下四個方面。

(1)多邊形的兩面以及繪製方式。

雖然我們目前還沒有真正的使用三維座標來畫圖,但是建立一些三維的概念還是必要的。

從三維的角度來看,乙個多邊形具有兩個面。每乙個面都可以設定不同的繪製方式:填充、只繪製邊緣輪廓線、只繪製頂點,其中「填充」是預設的方式。可以為兩個面分別設定不同的方式。

glpolygonmode(gl_front, gl_fill);            //

設定正面為填充方式

glpolygonmode(gl_back, gl_line);

//設定反面為邊緣繪製方式

glpolygonmode(gl_front_and_back, gl_point);

//設定兩面均為頂點繪製方式

(2)反轉

一般約定為「頂點以逆時針順序出現在螢幕上的面」為「正面」,另乙個麵即成為「反面」。生活中常見的物體表面,通常都可以用這樣的「正面」和「反面」,「合理的」被表現出來(請找乙個比較透明的礦泉水瓶子,在正對你的一面沿逆時針畫乙個圓,並標明畫的方向,然後將背面轉為正面,畫乙個類似的圓,體會一下「正面」和「反面」。你會發現正對你的方向,瓶的外側是正面,而背對你的方向,瓶的內側才是正面。正對你的內側和背對你的外側則是反面。這樣一來,同樣屬於「瓶的外側」這個表面,但某些地方算是正面,某些地方卻算是反面了)。

但也有一些表面比較特殊。例如「麥比烏斯帶」(請自己google一下),可以全部使用「正面」或全部使用「背面」來表示。

可以通過glfrontface函式來交換「正面」和「反面」的概念。

glfrontface(gl_ccw);   // 設定ccw方向為「正面」,ccw即counterclockwise,逆時針

glfrontface(gl_cw);    // 設定cw方向為「正面」,cw即clockwise,順時針

下面是乙個示例程式,請用它替換第一課中的mydisplay函式,並將glfrontface(gl_ccw)修改為glfrontface(gl_cw),並觀察結果的變化。

void mydisplay(void

)

(3)剔除多邊形表面

在三維空間中,乙個多邊形雖然有兩個面,但我們無法看見背面的那些多邊形,而一些多邊形雖然是正面的,但被其他多邊形所遮擋。如果將無法看見的多邊形和可見的多邊形同等對待,無疑會降低我們處理圖形的效率。在這種時候,可以將不必要的面剔除。

首先,使用glenable(gl_cull_face);來啟動剔除功能(使用gldisable(gl_cull_face)可以關閉之)

然後,使用glcullface來進行剔除。

glcullface的引數可以是gl_front,gl_back或者gl_front_and_back,分別表示剔除正面、剔除反面、剔除正反兩面的多邊形。

注意:剔除功能只影響多邊形,而對點和直線無影響。例如,使用glcullface(gl_front_and_back)後,所有的多邊形都將被剔除,所以看見的就只有點和直線。

(4)鏤空多邊形

直線可以被畫成虛線,而多邊形則可以進行鏤空。

首先,使用glenable(gl_polygon_stipple);來啟動鏤空模式(使用gldisable(gl_polygon_stipple)可以關閉之)。

然後,使用glpolygonstipple來設定鏤空的樣式。

void glpolygonstipple(const glubyte *mask);

其中的引數mask指向乙個長度為128位元組的空間,它表示了乙個32*32的矩形應該如何鏤空。其中:第乙個位元組表示了最左下方的從左到右(也可以是從右到左,這個可以修改)8個畫素是否鏤空(1表示不鏤空,顯示該畫素;0表示鏤空,顯示其後面的顏色),最後乙個位元組表示了最右上方的8個畫素是否鏤空。

但是,如果我們直接定義這個mask陣列,像這樣:

static glubyte mask[128] =;

這樣一堆資料非常缺乏直觀性,我們需要很費勁的去分析,才會發現它表示的竟然是乙隻蒼蠅。

如果將這樣的資料儲存成,並用專門的工具進行編輯,顯然會方便很多。下面介紹如何做到這一點。

首先,用windows自帶的畫筆程式新建一副,取名為mask.bmp,注意儲存時,應該選擇「單色位圖」。在「圖象」->「屬性」對話方塊中,設定的高度和寬度均為32。

然後,就可以使用以下**來獲得這個mask陣列了。

static glubyte mask[128

];file *fp;

fp = fopen("

mask.bmp

", "rb"

);if( !fp )

exit(0);

//移動檔案指標到這個位置,使得再讀sizeof(mask)個位元組就會遇到檔案結束

//注意-(int)sizeof(mask)雖然不是什麼好的寫法,但這裡它確實是正確有效的

//如果直接寫-sizeof(mask)的話,因為sizeof取得的是乙個無符號數,取負號會有問題

if( fseek(fp, -(int)sizeof

(mask), seek_end) )

exit(0);

//讀取sizeof(mask)個位元組到mask

if( !fread(mask, sizeof(mask), 1

, fp) )

exit(0);

fclose(fp);

說明:繪製虛線時可以設定factor因子,但多邊形的鏤空無法設定factor因子。請用滑鼠改變視窗的大小,觀察鏤空效果的變化情況。

#include #include 

void mydisplay(void

)

小結本課學習了繪製幾何圖形的一些細節。

點可以設定大小。直線可以設定寬度;可以將直線畫成虛線。

多邊形的兩個面的繪製方法可以分別設定;在三維空間中,不可見的多邊形可以被剔除;可以將填充多邊形繪製成鏤空的樣式。

了解這些細節會使我們在一些圖象繪製中更加得心應手。

另外,把一些資料寫到程式之外的檔案中,並用專門的工具編輯之,有時可以顯得更方便。

OpenGL 多邊形偏移

include gltools.h include glshadermanager.h include else define freeglut static include endif gluint list glint spinx 0 glint spiny 0 glfloat tdist 0....

OpenGL學習筆記四(多邊形)

在qt中的opengl模組中,使用opengl是比較簡單的,只需要在你建立的專案中新增 qopenglwidget 和qopenglfunctions就可以使用opengl基本上所有的功能。include include 在qt中使用opengl繪製點線也非常簡單。在開始繪製點線之前有幾個函式是必須...

OpenGL 多邊形的鏤空

1.凸多邊形的定義是多邊形的內角均小於180 2.多邊形可以設定鏤空效果,使用glenable gl polygon stipple 開啟鏤空模式,之後使用glpolygonstipple 設定鏤空基本圖案。void glpolygonstipple const glubyte mask mask是...