阅读:1387回复:0
OpenGL系列讲座(23)
5.3 雾
5.3.1 雾的概论和例程 雾化效果在当今的计算机图形学中应用极广,它不仅可以使场景中的物体看起来更加真 实,而且还可提高绘制速度。在很多情况下,计算机图像有时会出现不符合实际的精细和棱 角分明,上一节的反走样技术可以通过光顺着物体的边界反走样,使其看起来更真实,这一 节的雾化处理可以使物体看起来更加自然,即在雾中,离视点远的物体会变得模糊。 雾,是一个描述类似于大气效果的一般术语,在视景仿真中应用很广。它可以模拟烟雾 (haze)、薄雾(mist)、浓烟(smoke)和污染(pollution)等效果。当启动雾后,离视点较远的 物体开始淡化成雾的颜色,同时,雾的浓度可以控制,即随着距离的增加物体变淡的速率可 控,雾的颜色也可以任意设定。雾在两种颜色方式下都能使用。下面举出一个在RGBA方式下 使用雾的例程 fogrgb.c: 例 3-18 RGBA方式下雾化例程 fogrgb.c #include "glos.h" #include <GL/gl.h> #include <GL/glu.h> #include <math.h> #include <GL/glaux.h> #include <stdio.h> void myinit(void); void CALLBACK myReshape(GLsizei w, GLsizei h); void CALLBACK display(void); void myinit(void) { GLfloat mat_ambient[] = { 0.7, 0.6, 0.4, 1.00 }; GLfloat mat_diffuse[] = {0.7,0.0,0.99,1.0}; GLfloat mat_specular[] = { 1.0, 0.0, 1.0, 1.00 }; GLfloat mat_shininess[] = { 15.0 }; GLfloat position[] = { 5.0, 5.0, 5.0, 1.0 }; GLfloat fogColor[4] = {0.6, 0.6, 0.6, 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); glFrontFace (GL_CW); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_FOG); { glFogi (GL_FOG_MODE, GL_LINEAR); glFogfv (GL_FOG_COLOR, fogColor); glFogf (GL_FOG_START, 3.0); glFogf (GL_FOG_END,15.0); glHint (GL_FOG_HINT, GL_DONT_CARE); glClearColor(0.3, 0.3, 0.3, 1.0); } } void CALLBACK display(void) { 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(-0.5,-0.5,-7.0); auxSolidTorus(0.6,1.5); glPopMatrix(); glPushMatrix(); glTranslatef(2.0,0.8,-10.0); auxSolidTorus(0.6,1.5); glPopMatrix(); glFlush(); } void CALLBACK myReshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= (h*3)) glOrtho (-6.0, 6.0, -2.0*((GLfloat) h*3)/(GLfloat) w, 2.0*((GLfloat) h*3)/(GLfloat) w, 0.0, 10.0); else glOrtho (-6.0*(GLfloat) w/((GLfloat) h*3), 6.0*(GLfloat) w/((GLfloat) h*3), -2.0, 2.0, 0.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity (); } void main(void) { auxInitDisplayMode (AUX_SINGLE | AUX_RGBA); auxInitPosition (0, 0, 500, 400); auxInitWindow ("Fog_RGB_mode"); myinit(); auxReshapeFunc (myReshape); auxMainLoop(display); } 以上程序运行结果是显示三个不同远近的蓝紫色环形圈在雾中的效果,这里的雾化计算 采用线性方式(GL_LINEAR)。 图 3-5-5 雾化效果 5.3.2 雾化步骤 在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为雾方程中对应的density、start和end的值。缺省值为1、0、1。 在RGBA方式下,pname可以是GL_FOG_COLOR,此时参数param为指向含有RGBA值的向量指 针。同样,在颜色表方式下,pname相应值为GL_FOG_INDEX,其对应的param是雾的颜色索 引值。 三、若有必要,可用函数glHint(GL_FOG_HINT)提供一个值。 |
|
|