OpenGL Blend 和OpenGL中alpha测试GL_ALPHA_TEST

OpenGL Blend 和OpenGL中alpha测试GL_ALPHA_TEST

  像素的Alpha值可以用于混合操作

什么是混合呢?简单地说,就是当你透过一块红色的玻璃去看一个绿色的球时,此时就会发生颜色的混合现象,你看到的球的颜色将是两者的混合颜色。这在OpenGL里面有特殊的处理颜色混合的函数,比较常用GL_BLEND

要使用OpenGL的混合功能,调用:glEnable(GL_BLEND);// 开启混合模式

要关闭OpenGL的混合功能,调用:glDisable(GL_BLEND);// 禁用混合模式

切记:不用的时候要关闭

那么OpenGL的混合颜色是如何计算得来的?

      混合需要把原来的颜色和将要画上去的颜色找出来,经过某种方式处理后得到一种

的颜色。这里把将要画上去的颜色称为“源颜色”,把原来的颜色称为“目标颜色”。

OpenGL 会把源颜色和目标颜色各自取出,并乘以一个系数(源颜色乘以的系数称

为“源因子”,目标颜色乘以的系数称为“目标因子”),然后相加,这样就得到了新的

颜 色。

下面用数学公式来表达一下这个运算方式。

假设源颜色的四个分量(指红色,绿色,蓝色,alpha值)是 (Rs, Gs, Bs, As),目标

颜色的四个分量是(Rd, Gd, Bd, Ad),又设 源因子为(Sr, Sg, Sb, Sa),目标因子为

 (Dr, Dg, Db, Da)。则混合产生的新颜色可以表示为:

(Rs*Sr+Rd*Dr, Gs*Sg+Gd*Dg, Bs*Sb+Bd*Db, As*Sa+Ad*Da)

此外:   

 如果颜色的某一分量超过了1.0,则它会被自动截取为1.0,不需要考虑越界的

问题


源因子和目标因子是可以通过glBlendFunc函数来进行设置的。glBlendFunc有两个

参数,前者表示源因子,后者表示目标因子。这两个参数可以是多种值,下面介绍比

较常用的几种。


GL_ZERO:     表示使用0.0作为因子,实际上相当于不使用这种颜色参与混合运算。

GL_ONE:      表示使用1.0作为因子,实际上相当于完全的使用了这种颜色参与混合运算。
GL_SRC_ALPHA:表示使用源颜色的alpha值来作为因子。
GL_DST_ALPHA:表示使用目标颜色的alpha值来作为因子。
GL_ONE_MINUS_SRC_ALPHA:表示用1.0减去源颜色的alpha值来作为因子。
GL_ONE_MINUS_DST_ALPHA:表示用1.0减去目标颜色的alpha值来作为因子。


举例说明:

// 绘制树一种特殊的树(平面树旋转任何角度树的正面依然朝向你)
int MyDraw::DrawTree(float x, float y, float z)
{
	glPushAttrib(GL_CURRENT_BIT); // 保存现有颜色属性
	glPushMatrix(); // 压入栈可以不让其属性与上相同
	glTranslatef(x, y, z);
	glEnable(GL_TEXTURE_2D);// 开启纹理
	glEnable(GL_BLEND);// 开启混合模式
	// glBlendFunc有两个参数,前者表示源因子,后者表示目标因子
	// 混合需要把原来的颜色和将要画上去的颜色找出来,经过某种方式处理后得到一种新的颜色
	// 假设源颜色的四个分量(指红色,绿色,蓝色,alpha值)是 (Rs, Gs, Bs, As),
	// 目标颜色的四个分量是(Rd, Gd, Bd, Ad),又设源因子为(Sr, Sg, Sb, Sa),
	// 目标因子为 (Dr, Dg, Db, Da)。则混合产生的新颜色可以表示为:
	// (Rs*Sr + Rd*Dr, Gs*Sg + Gd*Dg, Bs*Sb + Bd*Db, As*Sa + Ad*Da)
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_ALPHA_TEST); // 启用Alpha测试 
	glAlphaFunc(GL_GREATER, 0.1);// 设置Alpha测试条件为大于0.0则通过即完全透明
	glBindTexture(GL_TEXTURE_2D, m_treeTex[0]);
	float length = 1.0, width = 0.0, height = 1.0;// 位置信息
	M3DMatrix44f modelMatrix;// 存储获得的模型矩阵
	glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);// 获得模型矩阵
	M3DVector3f xx = { modelMatrix[0], modelMatrix[4], modelMatrix[8] };// 获得右向量
	M3DVector3f zz = { modelMatrix[1], modelMatrix[5], modelMatrix[9] };// 获得向上的向量
	float h = 1.0;
	M3DVector3f temp; //临时向量
	M3DVector3f posi = { length, width, height };
	glBegin(GL_QUADS);//显示全部树
	m3dAddVector(temp, xx, zz);
	m3dScaleVector3(temp, -height);
	m3dAddVector(temp, temp, posi);
	glTexCoord2f(0.0, 0.0); glVertex3fv(temp);//左下点
	m3dSubVector(temp, xx, zz);
	m3dScaleVector3(temp, height);
	m3dAddVector(temp, temp, posi);
	glTexCoord2f(1.0, 0.0); glVertex3fv(temp);//右下点
	m3dAddVector(temp, xx, zz);
	m3dScaleVector3(temp, height);
	m3dAddVector(temp, temp, posi);
	glTexCoord2f(1.0, 1.0); glVertex3fv(temp);//右上点
	m3dSubVector(temp, zz, xx);
	m3dScaleVector3(temp, height);
	m3dAddVector(temp, temp, posi);
	glTexCoord2f(0.0, 1.0); glVertex3fv(temp);//左上点
	glEnd();
	glDisable(GL_BLEND);// 禁用混合模式
	glDisable(GL_TEXTURE_2D);// 关闭纹理
	glDisable(GL_ALPHA_TEST); // 禁用Alpha测试
	glPopAttrib(); // 属性矩阵出栈恢复
	glPopMatrix(); // 矩阵出栈恢复
	return 0;
}
效果则是完全透明的



你可能感兴趣的:(OpenGL Blend 和OpenGL中alpha测试GL_ALPHA_TEST)