OpenGL 融合和透明
前言:上午一直处于浑噩状态,刷一下四个小时就没了。就这样看着电脑,“思考人生”!
1.OpenGL颜色的融合
OpenGL融合是一种基本的图形图像处理技术。所谓融合处理,实际上是通过两种颜色的混合(Blending)来完成特殊颜色的绘制或透明物体的绘制;说白了就是两种颜色进行叠合,产生一种新颜色。
在运用深度缓存时,为了产生更加自然效果,通常是前面的物体遮住后面的物体来显示。当需要看到后面的物体时,或者停用深度缓存,绘制后面的物体;或者是前面的物体变成部分透明。
基于以上思路,融合至少有两种:
一种是屏蔽掉深度缓存的记忆,完成绘制后面的物体;另一种是利用颜色的透明方法;
融合效果通过绘制颜色体现,例如我在绘制水面颜色时,使用:
glColor4f(0.0f,0.5f,1.0f,0.3f);
前三个参数代表颜色,最后一位是Alpha值;值越大,物体越不透明,范围在[0.0,1.0]之间。
启动和关闭融合:
glEnable(GL_BLEND);
glDisable(GL_BLEND);
void glBlendFunc(GLenum s,GLenum d);
GLenum s:定义将要绘制的物体颜色在最后结果中所占比例,称为源因子;
GLenum d:定义将已经并且覆盖的绘制物体颜色在最后结果中所占比例,称为目的因子。
下面附上,我今天绘制一些代码:
绘制水面函数:
void CStepinGLView::DrawWater(void)
{
glEnable(GL_BLEND); //启用融合
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); //定义源因子与目的因子
glColor4f(0.0f,0.5f,1.0f,0.3f); //水面接近背景色,稍亮 Alpha为0.3
glPushMatrix();
glBegin(GL_QUAD_STRIP); //用一个矩形区域代表水面
glVertex3f(-1.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f,0.0f);
glVertex3f(1.0f,1.0f,0.0f);
glVertex3f(1.0f,-1.0f,0.0f);
glEnd();
glPopMatrix();
glDisable(GL_BLEND) ;
}
绘制函数:
void CStepinGLView::DrawScene(void)
{
//移动物体到显示区
glTranslatef(0.0f,0.0f,-7.0f);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
//视角变换
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,3.0,7.0, 0.0,0.0,0.0, 0.0,1.0,0.0);/*前三个参数是眼睛的位置,中间三个参数是物体所在的位置,后面三个参数表示向量,头顶朝上的方向*/
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glPushMatrix();
LightM();
glPopMatrix();
glPushMatrix();
glColor3f(0.5f, 0.25f, 0.0f);
glRotatef(rtri,0.0f,0.1f,0.0f);
glScalef(0.5f,0.5f,0.5f);
glShadeModel(GL_SMOOTH);
glutSolidTeapot(0.5f);
glPopMatrix();
glPushMatrix(); //绘制水面 ,最后绘制
glRotated(-65,1.0,0.0,0.0);//稍微倾斜
DrawWater();
glPopMatrix();
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
}
程序运行截图:
2.复杂的透明
这部分我也不太懂,暂时用不到;以后有时间在细谈,只做了一个简单的例子,可以把水壶实现部分透明:
附上代码:
void CStepinGLView::DrawScene(void)
{
//移动物体到显示区
glTranslatef(0.0f,0.0f,-7.0f);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
//视角变换
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,3.0,7.0, 0.0,0.0,0.0, 0.0,1.0,0.0);/*前三个参数是眼睛的位置,中间三个参数是物体所在的位置,后面三个参数表示向量,头顶朝上的方向*/
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glPushMatrix();
LightM();
glPopMatrix();
glPushMatrix();
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glColor3f(0.5f, 0.25f, 0.0f);
glRotatef(rtri,0.0f,0.1f,0.0f);
glScalef(0.5f,0.5f,0.5f);
glShadeModel(GL_SMOOTH);
glutSolidTeapot(0.5f);
glPopMatrix();
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glPushMatrix(); //绘制水面 ,最后绘制
glRotated(-65,1.0,0.0,0.0);//稍微倾斜
DrawWater();
glPopMatrix();
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
}
恩,大概就是这样,我把水面暂时屏蔽了,可以看到这样的效果,有兴趣的同学可以再研究: