NeHe OpenGL教程 (二十)

2021-05-01 23:49:32 字數 3927 閱讀 5404

20課

蒙板:到目前為止你已經學會如何使用alpha混合,把乙個透明物體渲染到螢幕上了,但有的使用它看起來並不是那麼的復合你的心意。使用蒙板技術,將會按照你蒙板的位置精確的繪製。

歡迎來到第20課的教程,*.bmp影象被給各種作業系統所支援,因為它簡單,所以可以很輕鬆的作為紋理載入它。知道現在,我們在把影象載入到螢幕上時沒有擦除背景色,因為這樣簡單高效。但是效果並不總是很好。

大部分情況下,把紋理混合到螢幕,紋理不是太少就是太多。當使用精靈時,我不希望背景從精靈的縫隙中透出光來;但在顯示文字時,你希望文字的間隙可以顯示背景色。

由於以上原因,我們需要使用「掩模」。使用「掩模」需要兩個步驟,首先我們在場景上放置黑白相間的紋理,白色代表透明部分,黑色代表不透明部分。接著我們使用一種特殊的混合方式,只有在黑色部分上的紋理才會顯示在場景中。

我只重寫那些改變的地方,如果你做好了學習的準備,我們就上路吧。

在這個程式裡,我們使用7個全域性變數。變數masking為乙個布林值,標誌是否使用「掩模」。變數mp標誌鍵m是否按下,變數sp標誌空格是否按下。

接著我們建立儲存5個紋理標誌的陣列,loop為迴圈變數。變數roll使得紋理沿螢幕滾動。

bool    masking=true;                    // 是否使用「掩模」

bool    mp;                        // 鍵m是否按下

bool    sp;                        // 空格是否按下

bool    scene;                        // 繪製那乙個場景

gluint    texture[5];                    // 儲存5個紋理標誌

gluint    loop;                        // 迴圈變數

glfloat    roll;                        // 滾動紋理

載入紋理**基本沒變,只是這裡我們需要載入5個紋理 

int loadgltextures()                       

}for (loop=0; loop<5; loop++)                   

free(textureimage[loop]);            }}

return status;                       

}改變視窗大小和初始化opengl的函式沒有變化

現在到了最有趣的繪製部分了,我們從清楚背景色開始,接著把物體移入螢幕2個單位。 

int drawglscene(glvoid)       

現在我們檢查繪製那乙個層,如果為true繪製第二個層,否則繪製第乙個層 

if (scene)   

當我們把「掩模」繪製到螢幕上後,接著我們變換混合係數。這次我們告訴opengl把任何黑色部分對應的畫素複製到螢幕,這樣看起來紋理就像被鏤空一樣帖子螢幕上。

注意,我們在變換了混合模式後在選擇的紋理。

如果我們沒有使用「掩模」,我們的影象將與螢幕顏色混合。

glblendfunc(gl_one, gl_one);                // 把紋理2複製到螢幕

glbindtexture(gl_texture_2d, texture[4]);            // 選擇第二個紋理

glbegin(gl_quads);                        // 繪製四邊形

gltexcoord2f(0.0f, 0.0f); glvertex3f(-1.1f, -1.1f,  0.0f);   

gltexcoord2f(1.0f, 0.0f); glvertex3f( 1.1f, -1.1f,  0.0f);   

gltexcoord2f(1.0f, 1.0f); glvertex3f( 1.1f,  1.1f,  0.0f);   

gltexcoord2f(0.0f, 1.0f); glvertex3f(-1.1f,  1.1f,  0.0f);   

glend();                       

}繪製第一層影象 

else                                   

當我們把「掩模」繪製到螢幕上後,接著我們變換混合係數。這次我們告訴opengl把任何黑色部分對應的畫素複製到螢幕,這樣看起來紋理就像被鏤空一樣帖子螢幕上。

注意,我們在變換了混合模式後在選擇的紋理。

如果我們沒有使用「掩模」,我們的影象將與螢幕顏色混合。

glblendfunc(gl_one, gl_one);                    // 把紋理1複製到螢幕

glbindtexture(gl_texture_2d, texture[2]);                // 選擇第乙個紋理

glbegin(gl_quads);                            // 開始繪製四邊形

gltexcoord2f(roll+0.0f, 0.0f); glvertex3f(-1.1f, -1.1f,  0.0f);   

gltexcoord2f(roll+4.0f, 0.0f); glvertex3f( 1.1f, -1.1f,  0.0f);   

gltexcoord2f(roll+4.0f, 4.0f); glvertex3f( 1.1f,  1.1f,  0.0f);   

gltexcoord2f(roll+0.0f, 4.0f); glvertex3f(-1.1f,  1.1f,  0.0f);   

glend();           

}接下來啟用深度測試,禁用混合。 

glenable(gl_depth_test);                            // 啟用深度測試

gldisable(gl_blend);                            // 禁用混合

最後增加roll變數,如果大於1,把它的值減1。 

roll+=0.002f;                                // 增加紋理滾動變數

if (roll>1.0f)                                // 大於1則減1

return true;                                // 成功返回

}函式killglwindow(), createglwindow() 和 wndproc() 沒有改變。

接下來在wwinmain,我們新增鍵盤控制函式。我們檢查空格是否按下,如果是則設定sp變數為true,sp變數用來切換場景。 

if (keys[' '] && !sp)                // 空格鍵是否被按下?

如果空格鍵釋放,記錄下來 

if (!keys[' '])                    // 如果空格鍵釋放,記錄下來

我們檢查m鍵是否按下,如果是則設定mp變數為true,sp變數用來切換是否使用「掩模」 

if (keys['m'] && !mp)                // m鍵是否被按下

如果m鍵釋放,記錄下來 

if (!keys['m'])                    // 如果m鍵釋放,記錄下來

eric desrosiers指出,你也可以在載入的時候測試*.bmp影象中的每乙個畫素,如果你你想要透明的結果,你可以把顏色的alpha設定為0。對於其他的顏色,你可以把alpha設定為1。這個方法也能達到同樣的效果,但需要一些額外的**。

在這課裡,我們給你演示了乙個簡單的例子,它能高效的繪製一部分紋理而不使用alpha值。

謝謝rob santa的想法和例子程式,我從沒想到過這種方法。

我希望你喜歡這個教程,如果你在理解上有任何問題或找到了任何錯誤,請我知道,我想做最好的教程,你的反饋是非常重要的。

NeHe OpenGL教程 (十二)

第12課 顯示列表 想知道如何加速你的opengl程式麼?這一課將告訴你如何使用opengl的顯示列表,它通過預編譯opengl命令來加速你的程式,並可以為你省去很多重複的 這次我將教你如何使用顯示列表,顯示列表將加快程式的速度,而且可以減少 的長度。當你在製作遊戲裡的小行星場景時,每一層上至少需要...

NeHe OpenGL教程 (十六)

第16課 霧 這一課是基於第7課的 的,你將學會三種不同的霧的計算方法,以及怎樣設定霧的顏色和霧的範圍。這篇教程由chris aliotta編寫。你想給你的opengl程式新增霧效?我將在這篇教程中教你如何去做。這是我第一次寫教程,我也只是opengl c 程式設計的新手,所以如果你發現了什麼錯誤請...

NeHe OpenGL第二十五課 變形

nehe opengl第二十五課 變形 變形和從檔案中載入3d物體 在這一課中,你將學會如何從檔案載入3d模型,並且平滑的從乙個模型變換為另乙個模型。歡迎來到這激動人心的一課,在這一課裡,我們將介紹模型的變形。需要注意的是各個模型必須要有相同的頂點,才能一一對應,並應用變形。在這一課裡,我們同樣要教...