引言
融合(blending)、雾化(fog)与反走样(antialiasing)是OpenGL中的三种特殊效果处理方法。融合提供了一种透明或半透明显示的技术;雾化处理则根据物体距离视点的远近对其进行恰当的模糊处理;反走样则可减少在绘制离散化的图形时所产生的误差走样。
实现融合特效
融合可将两种颜色的R、G、B分量按一定比例混在一起形成一种新的颜色,RGBA颜色模式中的A即表示Alpha值,对应于颜色的混合比例。由于只有在RGBA模式中才能对A值进行说明,因此融合不能在颜色索引模式下使用。融合操作可通过源因子(Sr、Sg、Sb、Sa)与目的因子(Dr、Dg、Db、Da)计算锝出,融合结果为(Rs*Sr+Rd*Dr, Gs*Sg+Gd*Dg, Bs*Sb+Bd*Db, As*Sa+Ad*Da)每个元素值都在范围[0, 1]内。可以看出,融合处理的关键就是对融合因子(Sr,Sg,Sb,Sa)和(Dr,Dg,Db,Da)的设定。在OpenGL中,源因子和目的因子通过glBlendFunc()函数产生,其函数形式为:
void glBlendFunc(GLenum sfactor,GLenum dfactor) |
常数 | 相关因子 | 融合因子结果 |
GL_ZERO | 源因子或目的因子 | (0,0,0,0) |
GL_ONE | 源因子或目的因子 | (1,1,1,1) |
GL_DST_COLOR | 源因子 | (Rd,Gd,Bd,Ad) |
GL_SRC_COLOR | 目的因子 | (Rs,Gs,Bs,As) |
GL_ONE_MINUS_DST_COLOR | 源因子 | (1,1,1,1)-(Rd,Gd,Bd,Ad) |
GL_ONE_MINUS_SRC_COLOR | 目的因子 | (1,1,1,1)-(Rs,Gs,Bs,As) |
GL_SRC_ALPHA | 源因子或目的因子 | (As,As,As,As) |
GL_ONE_MINUS_SRC_ALPHA | 源因子或目的因子 | (1,1,1,1)-(As,As,As,As) |
GL_DST_ALPHA | 源因子或目的因子 | (Ad,Ad,Ad,Ad) |
GL_ONE_MINUS_DST_ALPHA | 源因子或目的因子 | (1,1,1,1)-(Ad,Ad,Ad,Ad) |
GL_SRC_ALPHA_SATURATE | 源因子 | (f,f,f,1); f=min(As,1-Ad) |
void CALLBACK Display() { glClear(GL_COLOR_BUFFER_BIT); // 清屏 glColor4f(0.0, 1.0, 0.0, 0.5); // 绘制矩形 glRectf(0.1, 0.1, 0.6, 0.6); glColor4f(1.0, 1.0, 0.0, 0.7); // 绘制矩形 glRectf(0.4, 0.3, 0.9, 0.8); glFlush(); // 强制绘图完成 } void Init() { glEnable (GL_BLEND); // 启用融合 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// 产生融合因子 glShadeModel (GL_FLAT); // 设置平面明暗处理 glClearColor (0.0, 0.0, 0.0, 0.0); // 清屏 } |
图1 有颜色方块的融合 |
void glFog{if}[v](GLenum pname,TYPE param); |
图2 雾化效果 |
void CALLBACK Display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清屏 glPushMatrix(); // 绘制近视点景物 glTranslatef(-3.0, -1.5, -2.0); auxSolidTorus(0.6, 1.5); glPopMatrix(); glPushMatrix(); // 绘制远视点景物 glTranslatef(2.0, 0.8, -10.0); auxSolidTorus(0.6, 1.5); glPopMatrix(); glFlush(); // 强制绘图完成 } void Init() { GLfloat mat_ambient[] = {0.7, 0.6, 0.0, 1.0}; // 设置光照模型 GLfloat mat_diffuse[] = {0.7, 0.6, 0.0, 1.0}; GLfloat mat_specular[] = {1.0, 0.0, 1.0, 1.0}; GLfloat mat_shininess[] = {50.0}; GLfloat position[] = {5.0, 5.0, 5.0, 1.0}; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glLightfv(GL_LIGHT0, GL_POSITION, position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glFrontFace(GL_CW); glEnable(GL_FOG); // 启用雾化处理 { glFogi(GL_FOG_MODE, GL_LINEAR); // 采用线性变化的雾化效果 GLfloat fogColor[] = {0.3, 0.3, 0.3, 1.0}; // 指定雾化颜色 glFogfv(GL_FOG_COLOR, fogColor); glFogf(GL_FOG_START, 3.0); // 指定按线性变化时计算公式的参量 glFogf(GL_FOG_END, 15.0); glHint(GL_FOG_HINT, GL_DONT_CARE); //规定雾化效果的质量 } } |
实现绘图反走样
由于在图形绘制到屏幕时,数字化的图像通过离散的象素点来表达,因此所绘制的图元将会在光滑的曲线上产生锯齿,这种锯齿即为走样。反走样也叫做反混淆,它将根据图元的象素区域来确定象素的颜色值,通过这种处理可在一定程度上消除锯齿的影响。在OpenGL中,可通过函数glHint()来对图像质量和绘制速度之间的权衡作一些控制,其函数形式为:
void glHint(GLenum target,GLenum hint); |
void CALLBACK Display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清屏 auxWireDodecahedron(1.0); // 绘制二十面体 glFlush(); // 强制绘图完成 } void Init() { glEnable(GL_LINE_SMOOTH); // 启用反走样 glEnable(GL_BLEND); // 启动融合 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// 产生融合因子 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);// 权衡图像质量与绘制速度 glLineWidth(2.0); // 线宽 glShadeModel(GL_FLAT); // 平面明暗处理 glClearColor(0.0, 0.0, 0.0, 0.0); // 清屏 glDepthFunc(GL_LESS); // 激活深度比较 glEnable(GL_DEPTH_TEST); } |
图3 反走样多面体 |
评论 {{userinfo.comments}}
{{child.content}}
{{question.question}}
提交