使用fog步骤:
1. enable. glEnable(GL_FOG); // 使用雾气
2. 设置雾气颜色。glFogfv(GL_FOG_COLOR, fogColor);
3. 设置雾气的模式. glFogi(GL_FOG_MODE, GL_EXP); // 还可以选择GL_EXP2或GL_LINEAR
4. 设置雾的密度. glFogf(GL_FOG_DENSITY, 0.35f); // GL_EXP/GL_EXP2 时有意义, GL_LINEAR时无意义
5. 设置雾气的开始位置。 glFogf(GL_FOG_START, 1.0f); //GL_LINEAR时有意义, GL_EXP/GL_EXP2 时有意义
6. 设置 雾气的结束位置。 glFogf(GL_FOG_END, 5.0f); //GL_LINEAR时有意义, GL_EXP/GL_EXP2 时有意义
7. glHint(GL_FOG_HINT, GL_DONT_CARE); // 设置系统如何计算雾气
glHint(GL_FOG_HINT, GL_DONT_CARE)确定了雾的渲染方式,使用GL_DONT_CARE是因为并不关心建议值。然而这里有一个用来解释关于这个项的不同值之间的区别:
- GK_DONT_CARE:让OPENGL自己来确定雾的渲染方式,每顶点或是每像素。
- GL_NICEST:对每一像素进行雾的渲染,它看起来是极棒的。
- GL_FASTEST:对每一顶点进行雾的渲染,它速度较快,但是不够美丽
- GL_EXP:简单渲染在屏幕上显示的雾的模式。它无法给予我们非常漂亮的雾的效果,但是却可以在古老的电脑上工作的很好。
- GL_EXP2:比1提高了一点,将渲染全屏幕的雾,然而她会给予场景更深的效果。
- GL_LINEAR:这是最好的雾的渲染模式,对象在雾中消隐的很好
GL_FOG_END的设置会影响你的glTranslatef的Z坐标,如果GL_FOG_END的值设置为5, 而glTranslatef的值设置为6,比5大,我曾经碰到过,纹理如何也不能显示,避免出现问题,最好GL_FOG_END的值要大于glTranslatef的Z值
____________————————————————————————————————————————————————
应用雾
雾是OpenGL支持的一种易于使用的特殊效果。在使用雾时,OpenGL把雾的颜色与完成所有其他颜色计算的几何图元进行混合。雾与几何图元的混合程度取决于几何图元离观察者的距离。雾可以使物体逐渐模糊最终消失在雾色里(就像在雾中远去的父亲的背影)。
在SetupRC函数中开启雾化效果。
glClearColor(fLowLight[0], fLowLight[1], fLowLight[2], fLowLight[3]); glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, fLowLight); glFogf(GL_FOG_START, 5.0f); glFogf(GL_FOG_END, 30.0f); glFogi(GL_FOG_MODE, GL_LINEAR);
开启和关闭雾化:
glEnable(GL_FOG); glDisable(GL_FOG);
设置雾化的参数使用glFog:
void glFogi(GLenum pname, GLint param);
void glFogf(GLenum pname, GLfloat param);
void glFogfv(GLenum pname, GLfloat *params);
void glFogiv(GLenum pname, GLint *params);
glFogfv(GL_FOG_COLOR, fLowLight); //设置雾的颜色与背景色相同
当使用GL_FOG_COLOR作为第一个参数时,后面的第二个参数是一个指定雾的颜色的数组。这里我们使用了与背景清除色相同的颜色。
glFogf(GL_FOG_START, 5.0f);
glFogf(GL_FOG_END, 30.0f);
这两行代码设置了雾化的范围,从哪里(离观察者多远)开始雾化,到哪结束(此过程逐渐加深雾色)。在GL_FOG_END指定的位置,物体完全雾化,物体的颜色跟雾的颜色是一样的。
雾化方程
glFogi(GL_FOG_MODE, GL_LINEAR); //使用哪一种雾化方程
雾化方程用于计算从起始到结束的雾化因子(0-1的范围)。OpenGl支持的雾化方程如下:
雾化模式 | 雾化方程 |
GL_LINEAR | f = (end – c) / (end – start) |
GL_EXP | f = exp(-d * c) |
GL_EXP2 | f = exp(-(d * c)2) |
在方程里,c是渲染片段离观察平面的距离,end是GL_FOG_END指定的距离。start是GL_FOG_START指定的距离。d是雾色的浓度。通过glFogf设置
glFogf(GL_FOG_DENSITY, 0.5f);
GL_FOG_START和GL_FOG_END只影响GL_LINEAR的雾化效果。GL_LINEAR(线性模式)是线性的直线,GL_EXP和GL_EXP2(指数模式)是两条特征曲线。如下图雾化浓度值为0.5的近似图:
在线性模式下,只需要提供一个距离视点的开始位置和结束位置。从开始位置到结束位置之间,雾的浓度越来越高,浓度的变化和距离成正比。在指数模式下,雾的浓度随着距离的增加呈指数增长。这种模式通常用来用于烟雾、烟幕等效果。
在计算片段到观察平面的距离有两种方式。一种(尤其是在NVIDIA的硬件上)计算真实的片段的深度。另一种(尤其是A卡上)使用顶点的距离和顶点之间的插值。前者称为片段雾,后者称为顶点雾。片段雾比顶点雾更为复杂,但它显示的效果更好。这两种都可以通过GL_FOG_HINT来设置效果。更好的效果需要更大的开销:
glHint(GL_FOG_HINT, GL_NICEST);
更快,但效果较差可以调用:
glHint(GL_FOG_HINT, GL_FASTEST);
具体的效果取决于实现。
雾坐标
我们不一定要OpenGL计算雾距离,也可以自己设置雾距离。通过手工调用glFogCoordf:
void glFogCoordf(GLfoat fFogDistance);
使用雾坐标的前提是,要调用下面的函数更改雾的来源:
glFogi(GL_FOG_COORD_SRC, GL_FOG_COORD);
打开OpenGl产生的雾值:
glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH);
在上一篇的代码的SetupRC中加入如下代码段:
glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, fLowLight); glFogf(GL_FOG_START, 0.5f); glFogf(GL_FOG_END, 30.0f); glFogi(GL_FOG_MODE, GL_LINEAR); glHint(GL_FOG_HINT, GL_NICEST); //开启最佳雾化效果
效果图如下:
OpenGL超级宝典 第4版 中文版PDF+英文版+源代码 见 http://www.linuxidc.com/Linux/2013-10/91413.htm
OpenGL编程指南(原书第7版)中文扫描版PDF 下载 http://www.linuxidc.com/Linux/2012-08/67925.htm
OpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htm
Ubuntu 13.04 安装 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htm
OpenGL三维球体数据生成与绘制【附源码】 http://www.linuxidc.com/Linux/2013-04/83235.htm
Ubuntu下OpenGL编程基础解析 http://www.linuxidc.com/Linux/2013-03/81675.htm
如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm
更多《OpenGL超级宝典学习笔记》相关知识 见 http://www.linuxidc.com/search.aspx?where=nkey&keyword=34581