OpenGL 融合和透明

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:定义将已经并且覆盖的绘制物体颜色在最后结果中所占比例,称为目的因子。
OpenGL 融合和透明_第1张图片 OpenGL 融合和透明_第2张图片

下面附上,我今天绘制一些代码:
绘制水面函数:
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);
	
}

程序运行截图:
OpenGL 融合和透明_第3张图片


2.复杂的透明

OpenGL 融合和透明_第4张图片


这部分我也不太懂,暂时用不到;以后有时间在细谈,只做了一个简单的例子,可以把水壶实现部分透明:
附上代码:
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);
	
}

恩,大概就是这样,我把水面暂时屏蔽了,可以看到这样的效果,有兴趣的同学可以再研究:
OpenGL 融合和透明_第5张图片

你可能感兴趣的:(OpenGL)