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模型,並且平滑的從乙個模型變換為另乙個模型。歡迎來到這激動人心的一課,在這一課裡,我們將介紹模型的變形。需要注意的是各個模型必須要有相同的頂點,才能一一對應,並應用變形。在這一課裡,我們同樣要教...