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; }效果则是完全透明的