openGL學習筆記四 : 關於顏色, 大小, 虛線, 多邊形反轉, 鏤空, 使用位元影像,opengl學習筆記
轉載請保留出處,,,,hushuai1992http://blog.csdn.net/u013642494/article/category/2675731
額, 這個標題我都不知道該怎麼起了, 如果沒有標題, 請不要在意這些細節。。。。。
我們看看上次我們畫的點、以及線, 我們似乎忘了說如何設定點的大小( 哦, 不對, 我似乎是說了後面來說的。。。。), 現在我們來看看
一 設定點的大小和線的粗細
void glPointSize (GLfloat size);//設定點的大小, 預設為一個像素
void glLineWidth (GLfloat width);//設定線的寬度
注意, 這兩個函數都要在glBegin()之前使用, 在glBegin()之後使用無效
而且必須要開啟反走樣(glEnable(GL_LINE_SMOOTH);)了之後才可以使用小數哦
看看代碼:
void display(){glClear( GL_COLOR_BUFFER_BIT);glPointSize( 20.0f);glBegin( GL_POINTS);glVertex2f( 0.0f, 0.0f);glEnd();glLineWidth( 5.0f);glBegin( GL_LINES);glVertex2f( -0.5f, -0.5f);glVertex2f( 1.0f, -0.5f);glEnd();glFinish();}
二 設定顏色
估計小夥伴們都猜到了吧
void glColor3f (GLfloat red, GLfloat green, GLfloat blue);//設定顏色
void glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);//設定顏色, 帶透明通道
不過這裡的參數不是[0,255], 而是[0,1]。線性映射等浮點值表示的最大值映射到1.0(全強度),和零映射到0.0(零點強度)。
void display(){glClear( GL_COLOR_BUFFER_BIT);glEnable(GL_BLEND); // 開啟混合glDisable(GL_DEPTH_TEST); // 關閉深度測試glBlendFunc(GL_SRC_ALPHA, GL_ONE); // 基於源象素alpha通道值的半透明混合函數glColor3f( 0.0f, 1.0f, 0.0f);glPointSize( 20.0f);glBegin( GL_POINTS);glVertex2f( 0.0f, 0.0f);glEnd();glColor4f( 1.0f, 0.0f, 0.0f, 0.5f);glLineWidth( 5.0f);glBegin( GL_LINES);glVertex2f( -0.5f, -0.5f);glVertex2f( 0.5f, 0.5f);glEnd();glFinish();}
小夥伴們都注意一下哈, 如果需要使用透明通道, 必須要開啟ALPHA混合器,並指定源與目標的混合方式。看這幾句代碼
glEnable(GL_BLEND); // 開啟混合glDisable(GL_DEPTH_TEST); // 關閉深度測試glBlendFunc(GL_SRC_ALPHA, GL_ONE); // 基於源象素alpha通道值的半透明混合函數
void glEnable(GLenum cap);//用來開啟各項功能
當然, 相對應的肯定就有關閉各項功能glDisable()
我們看看下面的參數
類型 |
值 |
說明 |
GL_ALPHA_TEST |
4864 |
根據函數glAlphaFunc的條件要求來決定圖形透明的層度是否顯示。具體參見glAlphaFunc |
GL_AUTO_NORMAL |
3456 |
執行後,圖形能把光反射到各個方向 |
GL_BLEND |
3042 |
啟用顏色混合。例如實現半透明效果 |
GL_CLIP_PLANE0 ~ GL_CLIP_PLANE5 |
12288 ~ 12283 |
根據函數glClipPlane的條件要求 啟用圖形切割管道。這裡指六種緩衝管道 |
GL_COLOR_LOGIC_OP |
3058 |
啟用每一像素的色彩為位邏輯運算 |
GL_COLOR_MATERIAL |
2930 |
執行後,圖形(材料)將根據光線的照耀進行反射。 反射要求由函數glColorMaterial進行設定。 |
GL_CULL_FACE |
2884 |
根據函數glCullFace要求啟用隱藏圖形材料的面。 |
GL_DEPTH_TEST |
2929 |
啟用深度測試。 根據座標的遠近自動隱藏被遮住的圖形(材料) |
GL_DITHER |
3024 |
啟用抖動 |
GL_FOG |
2912 |
霧化效果 例如距離越遠越模糊 |
GL_INDEX_LOGIC_OP |
3057 |
邏輯操作 |
GL_LIGHT0 ~ GL_LIGHT7 |
16384 ~ 16391 |
啟用0號燈到7號燈(光源) 光源要求由函數glLight函數來完成 |
GL_LIGHTING |
2896 |
啟用燈源 |
GL_LINE_SMOOTH |
2848 |
執行後,過慮線段的鋸齒 |
GL_LINE_STIPPLE |
2852 |
執行後,畫虛線 |
GL_LOGIC_OP |
3057 |
邏輯操作 |
GL_MAP1_COLOR_4 |
3472 |
根據函數Map1對貝賽爾曲線的設定, 啟用glEvalCoord1,glEvalMesh1,glEvalPoint1 產生RGBA曲線 |
GL_MAP1_INDEX |
3473 |
根據函數Map1對貝賽爾曲線的設定, 啟用glEvalCoord1,glEvalMesh1,glEvalPoint1 產生色彩索引曲線 |
GL_MAP1_NORMAL |
3474 |
根據函數Map1對貝賽爾曲線的設定, 啟用glEvalCoord1,glEvalMesh1,glEvalPoint1 產生法線 |
GL_MAP1_TEXTURE_COORD_1 |
3475 |
根據函數Map1對貝賽爾曲線的設定, 啟用glEvalCoord1,glEvalMesh1,glEvalPoint1 產生文理座標 |
GL_MAP1_TEXTURE_COORD_2 |
3476 |
根據函數Map1對貝賽爾曲線的設定, 啟用glEvalCoord1,glEvalMesh1,glEvalPoint1 產生文理座標 |
GL_MAP1_TEXTURE_COORD_3 |
3477 |
根據函數Map1對貝賽爾曲線的設定, 啟用glEvalCoord1,glEvalMesh1,glEvalPoint1 產生文理座標 |
GL_MAP1_TEXTURE_COORD_4 |
3478 |
根據函數Map1對貝賽爾曲線的設定, 啟用glEvalCoord1,glEvalMesh1,glEvalPoint1 產生文理座標 |
GL_MAP1_VERTEX_3 |
3479 |
根據函數Map1對貝賽爾曲線的設定, 啟用glEvalCoord1,glEvalMesh1,glEvalPoint1 在三維空間裡產生曲線 |
GL_MAP1_VERTEX_4 |
3480 |
根據函數Map1對貝賽爾曲線的設定, 啟用glEvalCoord1,glEvalMesh1,glEvalPoint1 在四維空間裡產生法線 |
GL_MAP2_COLOR_4 |
3504 |
根據函數Map2對貝賽爾曲線的設定, 啟用glEvalCoord2,glEvalMesh2,glEvalPoint2 產生RGBA曲線 |
GL_MAP2_INDEX |
3505 |
根據函數Map2對貝賽爾曲線的設定, 啟用glEvalCoord2,glEvalMesh2,glEvalPoint2 產生色彩索引 |
GL_MAP2_NORMAL |
3506 |
根據函數Map2對貝賽爾曲線的設定, 啟用glEvalCoord2,glEvalMesh2,glEvalPoint2 產生法線 |
GL_MAP2_TEXTURE_COORD_1 |
3507 |
根據函數Map2對貝賽爾曲線的設定, 啟用glEvalCoord2,glEvalMesh2,glEvalPoint2 產生紋理座標 |
GL_MAP2_TEXTURE_COORD_2 |
3508 |
根據函數Map2對貝賽爾曲線的設定, 啟用glEvalCoord2,glEvalMesh2,glEvalPoint2 產生紋理座標 |
GL_MAP2_TEXTURE_COORD_3 |
3509 |
根據函數Map2對貝賽爾曲線的設定, 啟用glEvalCoord2,glEvalMesh2,glEvalPoint2 產生紋理座標 |
GL_MAP2_TEXTURE_COORD_4 |
3510 |
根據函數Map2對貝賽爾曲線的設定, 啟用glEvalCoord2,glEvalMesh2,glEvalPoint2 產生紋理座標 |
GL_MAP2_VERTEX_3 |
3511 |
根據函數Map2對貝賽爾曲線的設定, 啟用glEvalCoord2,glEvalMesh2,glEvalPoint2 在三維空間裡產生曲線 |
GL_MAP2_VERTEX_4 |
3512 |
根據函數Map2對貝賽爾曲線的設定, 啟用glEvalCoord2,glEvalMesh2,glEvalPoint2 在三維空間裡產生曲線 |
GL_NORMALIZE |
2977 |
根據函數glNormal的設定條件,啟用法向量 |
GL_POINT_SMOOTH |
2832 |
執行後,過慮線點的鋸齒 |
GL_POLYGON_OFFSET_FILL |
32823 |
根據函數glPolygonOffset的設定,啟用面的深度位移 |
GL_POLYGON_OFFSET_LINE |
10754 |
根據函數glPolygonOffset的設定,啟用線的深度位移 |
GL_POLYGON_OFFSET_POINT |
10753 |
根據函數glPolygonOffset的設定,啟用點的深度位移 |
GL_POLYGON_SMOOTH |
2881 |
過慮圖形(多邊形)的鋸齒 |
GL_POLYGON_STIPPLE |
2882 |
執行後,多邊形為向量畫圖 |
GL_SCISSOR_TEST |
3089 |
根據函數glScissor設定,啟用圖形剪下 |
GL_STENCIL_TEST |
2960 |
開啟使用模板測試並且更新模版緩衝。參見glStencilFunc和glStencilOp. |
GL_TEXTURE_1D |
3552 |
啟用一維文理 |
GL_TEXTURE_2D |
3553 |
啟用二維文理 |
GL_TEXTURE_GEN_Q |
3171 |
根據函數glTexGen,啟用紋理處理 |
GL_TEXTURE_GEN_R |
3170 |
根據函數glTexGen,啟用紋理處理 |
GL_TEXTURE_GEN_S |
3168 |
根據函數glTexGen,啟用紋理處理 |
GL_TEXTURE_GEN_T |
3169 |
根據函數glTexGen,啟用紋理處理 |
這些東西會經常用到的。。。。。。。。
void glBlendFunc (GLenum sfactor, GLenum dfactor);//定義像素演算法
三 關於多邊形的正反面以及繪製方式
嗯 這個, 腫麼說呢, 還是先看代碼吧,,,直接講會很空洞滴。。。
void display(){glClear( GL_COLOR_BUFFER_BIT);glPolygonMode( GL_FRONT, GL_FILL);glPolygonMode( GL_BACK, GL_LINE);glFrontFace( GL_CCW);glBegin( GL_POLYGON);glVertex2f( -0.5f, -0.5f);glVertex2f( 0.0f, -0.5f);glVertex2f( 0.0f, 0.0f);glVertex2f( -0.5f, 0.0f);glEnd();glBegin( GL_POLYGON);glVertex2f( 0.0f, 0.0f);glVertex2f( 0.0f, 0.5f);glVertex2f( 0.5f, 0.5f);glVertex2f( 0.5f, 0.0f);glEnd();glFinish();}
我們慢慢來看,
void glPolygonMode(GLenum face,GLenum mode);
作用是控制多邊形的顯示方式
參數一:確定顯示模式將適用於物體的哪些部分,控制多邊形的正面和背面的繪圖模式
GL_FRONT表示顯示模式將適用於物體的前向面(也就是物體能看到的面)GL_BACK表示顯示模式將適用於物體的後向面(也就是物體上不能看到的面)GL_FRONT_AND_BACK表示顯示模式將適用於物體的所有面一般我們都是頂點以逆時針順序出現在螢幕上的面”為“正面”,另一個面即成為“反面”
參數二:確定選中的物體的面以何種方式顯示(顯示模式)
GL_LINE表示顯示線段,多邊形用輪廓顯示GL_FILL表示顯示面,多邊形採用填充形式
參見上面的兩個正方形
當然, 還有一個GL_POINT只顯示定點(估計也沒啥用。。。。。)
void glFrontFace(GLenum mode);
嗯, 這個函數的作用是設定正方形的正反面是如何決定的,
GL_CCW 表示視窗座標上投影多邊形的頂點順序為逆時針方向的表面為正面。GL_CW 表示頂點順序為順時針方向的表面為正面。預設的情況下是GL_CCW, 我們也來看看GL_CW的效果
對吧, 反轉了吧, 哦 對了這些函數也是要寫在glBegin()前面哦。。。。
四 剔除多邊形的表面
很多時候, 我們的東東會有前後遮擋的效果, 如果我們還是全部繪製了簡直就是在浪費資源嘛,,,,所以我們把那些被遮擋的多邊形可以剔除掉, 這樣可以大大的提升我們程式的運行效率,,,
還記得我們剛剛說的glEnable()嗎, 沒錯, 我們就要先使用他來開啟剔除功能, 然後再使用glCullFace()來進行剔除(參數也是正面, 反面, 全部),,,
剔除只是影響多邊形, 對點和直線沒有影響
代碼走起
glEnable(GL_CULL_FACE);glCullFace( GL_FRONT_AND_BACK);
五 虛線以及多邊形鏤空
嗯 老規矩了glEnable()開啟虛線, glLineStipple()設定虛線的顯示方式
void display( void){glClear( GL_COLOR_BUFFER_BIT);glEnable( GL_LINE_STIPPLE);glLineStipple( 2.0f, 0x0F0F);glLineWidth( 5.0f);glBegin( GL_LINES);glVertex2f( -0.5f, -0.5f);glVertex2f( 0.5f, 0.5f);glEnd();glFinish();}
void glLineStipple (GLint factor, GLushort pattern);
OpenGL中設定直線的當前點畫模式。pattern參數是由1或0組成的16位序列,它們根據需要進行重複,對一條特定的直線進行點畫處理。從這個模式的低位開始,一個像素一個像素的進行處理。如果模式中對應的位是1,就繪製這個像素,否則就不繪製。模式可以使用factor參數(表示重複因子)進行擴充,它與1和0的連續子序列相乘。因此,如果模式中出現了3個1,並且factor是2,那麼它們就擴充為6個連續的1。必須以GL_LINE_STIPPLE為參數調用glEnable()才能啟用直線點畫功能。為了禁用直線點畫功能,可以向glDisable()函數傳遞同一個參數。
就拿我們剛剛寫的0x0F0F(0000111100001111)來看, 如果第一個參數我們穿的是1, 那麼就從低位往高位(從右往左)進行繪製, 1表示繪製, 0表示不繪製,繪製結果就是【先繪製四個, 再空四個, 再繪製四個, 再空四個】 如果我們穿的參數是2那麼就是【先繪製八個, 再空八個, 再繪製八個, 再空八個】,以此類推。 看圖
再來說說多邊形的鏤空
也是使用glEnable()開啟鏤空,使用glPolygonStipple()設定鏤空模式, 先看代碼後解釋
這個數組是套用紅寶書上面的的, 如果要我自己寫一個出來, 我估計我會瘋掉的
GLubyte data[128] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, 0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20, 0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20, 0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC, 0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30, 0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0, 0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0, 0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30, 0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08, 0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08, 0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08, }; void display( void){glClear( GL_COLOR_BUFFER_BIT);glEnable( GL_POLYGON_STIPPLE);glPolygonStipple( data);glRectf( -0.5f, -0.5f, 0.0f, 0.0f);glFinish();}
哈哈, 有木有覺得很神奇,,,我們竟然畫了一堆蒼蠅在螢幕上, 其實我們的那個數組就是一個蒼蠅的映像。 我們來分析一下, 數組有128個位元組, 表示了一個32x32的矩陣型鏤空的資料。數組裡面的第一個位元組表示了左下方從左至右的8個像素是否鏤空, 以此類摧。。。
用這個圖可以表示出來
我們再來看看沒有鏤空的效果
就是這個吊樣子。。。。。
如果每次都讓我們程式來做這樣的數組, 我估計程式員真的會瘋掉吧, 我們來看看簡單的方法, 首先開啟你的畫板工具(就是電腦內建的那個 )隨便畫一幅畫, 儲存單色位元影像的bmp
好了, 我們現在來使用這張位元影像
void display( void){GLubyte data[128];FILE* fp;fp = fopen( "openGLTest.bmp", "rb");if ( !fp){exit( 0);}if ( fseek( fp, -(int)sizeof( data), SEEK_END)){exit( 0);}if ( !fread( data, sizeof( data), 1, fp)){exit( 0);}fclose( fp);glClear( GL_COLOR_BUFFER_BIT);glEnable( GL_POLYGON_STIPPLE);glPolygonStipple( data);glRectf( -0.5f, -0.5f, 0.0f, 0.0f);glFinish();}
是不是我們畫的圖片也載入出來了啊,,,,注意了, 圖片的位置一定要和執行檔案放在一塊啊, 畢竟人家是好基友嘛, 今天我們就到這裡了。。。
每天積累一點點, 總有一天你會成為大神的