分享
 
 
 

利用VC+OpenGL实现几种特殊图形效果

王朝vc·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

[文章信息]

作者:

中国电波传播研究所青岛分所郎锐

时间:

2005-04-26

出处:

天极网

编辑:

方舟

[文章导读]

融合、雾化与反走样是OpenGL中的三种特殊效果处理方法

引言

融合(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)

通过指定参数sfactor和dfactor来分别指出计算源因子和目的因子的方式。具体取值可参见下表。在产生了融合因子值后,还需调用glEnable(GL_BLEND)和glDisable(GL_BLEND)来启用、关闭融合处理。

常数

相关因子

融合因子结果

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)

下面是应用了融合技术的一个简单例子,通过图1的绘制结果可以看出在启用了融合处理后在两个具有不同颜色方块的交叠部分颜色发生了变化,该区域即为融合所产生的结果:

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 有颜色方块的融合

雾化特效

雾化是一种模拟自然界中雾气对场景物体视觉效果产生影响的图形绘制技术。此技术从视点到物体逐渐将物体的绘制颜色淡化,直至背景色。通过雾化处理可较好的表现出物体到视点的距离感。虽然雾化的具体计算非常复杂,但在OpenGL中的使用却非常简单。首先调用glEnable(GL_FOG)以启用雾化处理,启用后离视点较远的物体开始淡化成雾的颜色。然后可通过glFog*()函数来选择控制雾的浓度和颜色的方程,具体形式为:

void glFog{if}[v](GLenum pname,TYPE param);

该函数设置了雾化参数和函数,在pname为GL_FOG MODE时,参数param可以为GL_EXP(指数)、GL_EXP2(指数平方)和GL_LINEAR(线性);如果参数pname为GL_FOG_DENSITY、GL_FOG_START或GL_FOG_END,参数param将分别指定在不同雾化数学模型下的不同计算公式参量;在参数pname为GL_FOG_COLOR时,param将为一个指向颜色向量的指针。最后,如果有必要,还可以调用函数glHint(GL_FOG_HINT)进一步指定雾化效果。下面给出实现雾化效果的部分具体示例代码及其绘制结果(图2):

图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);

参数target说明控制什么行为,具体的,GL_POINT_SMOOTH_HINT、GL_LINE_SMOOTH_HINT和GL_POLYGON_SMOOTH_HINT分别指定点、线和多边形的采样质量;GL_FOG_HINT指出雾化是按象素进行(GL_NICEST)还是按顶点进行(GL_FASTEST);GL_PERSPECTIVE_CORRECTION_HINT指定了颜色纹理插值的质量并可纠正由单纯线性插值所带来的一些视觉错误。参数hint可以是:GL_FASTEST(给出最有效的选择)、GL_NICEST(给出最高质量的选择)、GL_DONT_CARE(没有选择)。

虽然在OpenGL的颜色索引模式下也可以实现反走样,但仍建议在RGBA模式下进行。对图元进行反走样时也要先调用glEnable()函数启动反走样(其参数为GL_POINT、GL_LINE_SMOOTH或GL_POLYGON_SMOOTH)。如果是在RGBA模式下进行反走样,还必须与融合配合使用,通常使用GL_SRC_ALPHA和GL_ONE_MINUS_SRC_ALPHA分别作为源和目的因子。下面给出一段在RGBA模式下启用反走样绘制多面体的示例代码,从绘制结果(图3)可以明显看出在多边形的直线边界出现的锯齿得到了较好的平滑:

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 反走样多面体

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有