NeHe OpenGL第八課 混合

2021-05-26 16:26:35 字數 2193 閱讀 1460

nehe opengl第八課:混合

混合:在這一課裡,我們在紋理的基礎上加上了混合,它看起具有透明的效果,當然解釋它不是那麼容易,當希望你喜歡它。

簡單的透明

opengl中的絕大多數特效都與某些型別的(色彩)混合有關。混色的定義為,將某個象素的顏色和已繪製在螢幕上與其對應的象素顏色相互結合。至於如何結合這兩個顏色則依賴於顏色的alpha通道的分量值,以及/或者所使用的混色函式。alpha通常是位於顏色值末尾的第4個顏色組成分量。前面這些課我們都是用gl_rgb來指定顏色的三個分量。相應的gl_rgba可以指定alpha分量的值。更進一步,我們可以使用glcolor4f()來代替glcolor3f()。

絕大多數人都認為alpha分量代表材料的透明度。這就是說,alpha值為0.0時所代表的材料是完全透明的。alpha值為1.0時所代表的材料則是完全不透明的。 

混色的公式

若您對數學不感冒,而只想看看如何實現透明,請跳過這一節。若您想深入理解(色彩)混合的工作原理,這一節應該適合您吧。『譯者注:其實並不難^-^。原文中的公式如下,cker再嘮叨一下吧。其實混合的基本原理是就將要分色的影象各象素的顏色以及背景顏色均按照rgb規則各自分離之後,根據-影象的rgb顏色分量*alpha值+背景的rgb顏色分量*(1-alpha值)-這樣乙個簡單公式來混合之後,最後將混合得到的rgb分量重新合併。』

公式如下:

(rs sr + rd dr, gs sg + gd dg, bs sb + bd db, as sa + ad da)

opengl按照上面的公式計算這兩個象素的混色結果。小寫的s和r分別代表源象素和目標象素。大寫的s和d則是相應的混色因子。這些決定了您如何對這些象素混色。絕大多數情況下,各顏色通道的alpha混色值大小相同,這樣對源象素就有 (as, as, as, as),目標象素則有1, 1, 1, 1) - (as, as, as, as)。上面的公式就成了下面的模樣:

(rs as + rd (1 - as), gs as + gd (1 - as), bs as + bs (1 - as), as as + ad (1 - as))

這個公式會生成透明/半透明的效果。

opengl中的混色

在opengl中實現混色的步驟類似於我們以前提到的opengl過程。接著設定公式,並在繪製透明物件時關閉寫深度快取。因為我們想在半透明的圖形背後繪製 物件。這不是正確的混色方法,但絕大多數時候這種做法在簡單的專案中都工作的很好。

rui martins 的補充: 正確的混色過程應該是先繪製全部的場景之後再繪製透明的圖形。並且要按照與深度快取相反的次序來繪製(先畫最遠的物體)。

考慮對兩個多邊形(1和2)進行alpha混合,不同的繪製次序會得到不同的結果。(這裡假定多邊形1離觀察者最近,那麼正確的過程應該先畫多邊形2,再畫多邊形1。正如您再現實中所見到的那樣,從這兩個《透明的》多邊形背後照射來的光線總是先穿過多邊形2,再穿過多邊形1,最後才到達觀察者的眼睛。)

在深度快取啟用時,您應該將透明圖形按照深度進行排序,並在全部場景繪製完畢之後再繪製這些透明物體。否則您將得到不正確的結果。我知道某些時候這樣做是很令人痛苦的,但這是正確的方法。

我們將使用第七課的**。一開始先在**開始處增加兩個新的變數。出於清晰起見,我重寫了整段**。

bool    blend;      // 是否混合?

bool bp;      // b 鍵按下了麼?

然後往下移動到 loadgltextures() 這裡。找到" if (textureimage[0]=loadbmp("data/crate.bmp")) "這一行。我們現在使用有色玻璃紋理來代替上一課中的木箱紋理。  

if (textureimage[0]=loadbmp("data/glass.bmp")) // 載入玻璃位圖

在initgl()**段加入以下兩行。第一行以全亮度繪製此物體,並對其進行50%的alpha混合(半透明)。當混合選項開啟時,此物體將會產生50%的透明效果。第二行設定所採用的混合型別。

rui martins 的補充: alpha通道的值為 0.0意味著物體材質是完全透明的。1.0 則意味著完全不透明。   

glcolor4f(1.0f,1.0f,1.0f,0.5f);   // 全亮度, 50% alpha 混合

glblendfunc(gl_src_alpha,gl_one);  // 基於源象素alpha通道值的半透明混合函式

在接近第七課結尾處的地方找到下面的**段。  

if (keys[vk_left])    // left方向鍵按下了麼?

NeHe OpenGL第八課 混合

第八課 混合 混合 在這一課裡,我們在紋理的基礎上加上了混合,它看起具有透明的效果,當然解釋它不是那麼容易,當希望你喜歡它。簡單的透明 opengl中的絕大多數特效都與某些型別的 色彩 混合有關。混色的定義為,將某個象素的顏色和已繪製在螢幕上與其對應的象素顏色相互結合。至於如何結合這兩個顏色則依賴於...

第八課 混合

第八課 混合 opengl中的混色 在opengl中實現混色的步驟類似於我們以前提到的opengl過程。接著設定公式,並在繪製透明物件時關閉寫深度快取。因為我們想在半透明的圖形背後繪製 物件。這不是正確的混色方法,但絕大多數時候這種做法在簡單的專案中都工作的很好。rui martins 的補充 正確...

第八課 陣列

1 宣告 int arr string str 2 分配空間 arr new int 5 3 宣告同時分配記憶體 int arr new int 5 4 初始化 int arr new int 5 int arr2 1 宣告 int arr string str 2 分配空間 1 直接為每一維分配空...