2011-06-20 32 views

回答

5

首先,通常最好將位圖數據轉換爲32位,以便每個通道(R,G,B,A)獲得8位。當你上傳紋理時,指定一個32位格式。

然後在渲染時,您需要glEnable(GL_BLEND);並設置混合函數,例如:glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);。這告訴OpenGL使用紋理的alpha來混合紋理的RGB和背景的紋理。

如果你正在對3D對象進行此操作,可能還需要關閉背面剔除(以便通過前方看到對象的背面)並將您的三角形背對背地排序(如此混合按照正確的順序發生)。

如果你的源位圖是8位的(即:使用一種顏色指定爲透明度蒙版),那麼最簡單的方法是將其轉換爲RGBA,當顏色與透明度相匹配時將alpha值設置爲0面具。

一些提示,以使事情(也許)更好看:

  • 你的alpha通道將是一個全有或全無(無論是爲0x00或0xFF的),因此適用於一些模糊算法得到更柔軟邊緣,如果這就是你在之後。
  • 對於alpha爲零(完全透明)的texels(紋理像素),將RGB顏色替換爲最接近的非透明紋理元素。當紋理座標被插值時,它們不會被混合到來自BMP的原始透明度顏色。
+0

@geofftnz呀。不幸的是,位圖是在我無法修改的檔案中,所以我需要像他們一樣處理它們。你能澄清一下我應該轉換爲RGBA嗎?謝謝! –

+0

你在說BMP文件嗎? – geofftnz

+0

是的。 8位bmp文件在我無法修改的檔案中,因此我需要按原樣加載它們。 –

1

如果你的像素圖是8位單通道,它們可能是灰度或使用調色板。你首先需要做的是將像素圖數據轉換成RGBA格式。爲此,您需要分配足夠大的緩衝區以容納原始文件尺寸的4通道像素圖。然後,對於像素圖的每個像素,將該像素的值用作調色板(查找表)中的索引,並將該顏色值放入RGBA緩衝區中的相應像素中。完成後,使用glTexImage2D上傳到OpenGL。

如果您的GPU支持片段着色器(很可能),您可以在着色器中執行LUT轉換:將8位pixma上傳爲GL_RED或GL_LUMINANCE 2D紋理。並將該調色板作爲一維GL_RGBA紋理上傳。然後,在片段着色器:

uniform sampler2D texture; 
uniform sampler1D palette_lut; 

void main() 
{ 
    float palette_index = texture2D(texture,gl_TexCoord[0].st).r; 
    vec4 color = texture1D(palette_lut, palette_index); 
    gl_FragColor = color; 
} 

與Z緩衝算法混合渲染衝突,因此必須將幾何排序後到前的事情以正確的樣子。只要這在整體上影響對象,這是相當簡單的,但是如果您需要對渲染每一幀的網格的面進行排序,則會變得乏味。一種避免這種情況的方法是將網格劃分爲凸面子網格(當然,已經凸出的網格已經不能被進一步細分)。然後使用下面的方法:

  • 啓用面剔除
  • 用於排序convex_submesh(網格,從遠到近):
    • 集合面剔除到面(即,背面獲取呈現)
    • render convex_submesh
    • 將臉部剔除爲返回臉部(即前端得到呈現)
    • 渲染convex_submesh再次