我正在使用OpenGL加载位图来纹理3d网格。其中一些位图具有某些像素的alpha通道(透明度),我需要找出最佳方法
和
有没有人有这方面的好例子? OpenGL是否支持此功能?
答案 0 :(得分:5)
首先,通常最好将位图数据转换为32位,以便每个通道(R,G,B,A)获得8位。上传纹理时,请指定32位格式。
然后在渲染时,您需要glEnable(GL_BLEND);
并设置混合函数,例如:glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
。这告诉OpenGL使用纹理的alpha将纹理的RGB与背景的RGB混合。
如果您对3D对象执行此操作,您可能还需要关闭背面剔除(以便通过前面看到对象的背面)并将三角形从后向前排序(以便混合发生在正确的顺序)。
如果您的源位图是8位(即:使用指定为透明蒙版的一种颜色的调色板),那么将其转换为RGBA可能最容易,当颜色与透明度蒙版匹配时将alpha值设置为0
一些提示让事情(也许)看起来更好:
答案 1 :(得分:1)
如果您的像素图是8位单通道,则它们是灰度或使用调色板。您首先需要做的是将像素图数据转换为RGBA格式。为此,您需要分配一个足够大的缓冲区来容纳原始文件尺寸的4通道像素图。然后,对于像素图的每个像素,使用该像素的值作为调色板(查找表)的索引,并将该颜色值放入RGBA缓冲区中的相应像素中。完成后,使用 glTexImage2D 上传到OpenGL。
如果你的GPU支持片段着色器(非常可能),你可以在着色器中进行LUT转换:将8位pixmal上传为GL_RED或GL_LUMINANCE 2D纹理。并将调色板上传为1D 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缓冲区算法冲突,因此您必须从后到前对几何体进行排序才能使事物看起来正确。只要这会影响整体上的对象,这很简单,但如果需要对网格的每个帧进行排序,则会变得单调乏味。避免这种情况的一种方法是将网格划分为凸子网格(当然,凸起的网格已经无法进一步细分)。然后使用以下方法: