其实这是个滞后话题了事实上应该在光照节就应该详述但是光照内容本来就多所以当时并没有再牵涉此内容
在我们填充 3维物体时和平面绘制区别牵涉到了前面物体遮挡后面物体问题假如没有个很好内置机制我们就只能通过记住每个物体Z轴(其实也不定是Z轴看当时观察方向)然后按顺序将远物体先绘制然后再绘制离我们近通过这种方式可以让离我们近物体绘制在后面覆盖掉远物体
当然假如觉得不麻烦话这样做倒也不是不行但是假如这些事情是由硬件实现话效率可是会上个层次所以OpenGL 也提供了此思路方法被称作深度测试(Depth Test)使用思路方法那是相当简单仅仅需要通过glEnable启用就可以了我们现在看看使用前后区别
我们通过以下绘制大小两个球
void DrawBigRedSphere
{
GLfloat mat_specular = { 1.0, 0.0, 0.0, 1.0 };
GLfloat mat_shininess = { 50.0 };
GLfloat mat_ambient = { 1.0, 0.0, 0.0, 1.0 };
GLfloat mat_dfuse = { 1.0, 0.0, 0.0, 1.0 };
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_dfuse);
glutSolidSphere(0.5, 32, 32);
}
void DrawSmallBlueSphere
{
GLfloat mat_specular = { 0.0, 0.0, 1.0, 1.0 };
GLfloat mat_shininess = { 50.0 };
GLfloat mat_ambient = { 0.0, 0.0, 1.0, 1.0 };
GLfloat mat_dfuse = { 0.0, 0.0, 1.0, 1.0 };
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_dfuse);
glutSolidSphere(0.3, 32, 32);
}
DrawBigRedSphere绘制是大红球DrawSmallBlueSphere绘制是小蓝球绘制时候都采用默认坐标即绘制在屏幕中央并且Z轴也不动那么从理论上来讲大球会包含小球小球就被大球遮掩了我们显示要应该也是这种效果
看下未开启深度测试情况下情况我们先绘制大球再绘制小球和用相反顺序再绘制情形:
代码如下:
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix;
glTranslatef(-0.5, 0.0, 0.0);
DrawBigRedSphere;
DrawSmallBlueSphere;
glPopMatrix;
glPushMatrix;
glTranslatef(0.5, 0.0, 0.0);
DrawSmallBlueSphere;
DrawBigRedSphere;
glPopMatrix;
glFlush;
}
我们会观察到很明显绘制顺序导致问题左边图先绘制大球再绘制小球小篮球竟然覆盖掉了应该在其外部红球实际使用中我们可以都自己判断然后用右边正确绘制方式随着图形增多会增加定计算量OpenGL提供深度测试就是为我们提供了更简便高效方式事实上由于 OpenGL使用方式可以在测试后直接绘制出最终图形而忽略绘制被覆盖掉图形效率上比覆盖绘制会更高些(需要硬件支持)
上述代码仅仅需要添加行
glEnable(GL_DEPTH_TEST);
以启用深度测试效果大不样:
天下至简的事莫过于此
雾
扇子驱不散大雾 -- 阿拉伯谚语
像云像雾又像风 -- 某电视剧名
雾作为种常见天气现象OpenGL中有所模拟体现也算是正常但是在OpenGL中雾作用却又不止这些事实上雾效果还用于实现模糊效果用于有关模拟模糊薄雾烟污染
使用步骤非常简单如OpenGL惯例首先通过glEnable开启然后又有个glFog*这个用于设置雾效果可以使用呵呵OpenGL学多了会发现除了概念不样基本上使用步骤都差不多开始觉得OpenGL这种个通过pname参数去决定作用方式不太符合好API设计哲学(可以参考设计Qt风格CAPI【转】)但是想来API设计还不定有绝对意义上好坏这样设计倒是在定程度上减少了API数量并且查找时会稍微方便点虽然同时增加了查文档看参数作用负担这些又是题外话了
首先看没有雾效果时我用OpenGL绘制3个红球红球Z轴是依次向内
主要代码如下:
void DrawRedSphere
{
GLfloat mat_specular = { 1.0, 0.0, 0.0, 1.0 };
GLfloat mat_shininess = { 50.0 };
GLfloat mat_ambient = { 1.0, 0.0, 0.0, 1.0 };
GLfloat mat_dfuse = { 1.0, 0.0, 0.0, 1.0 };
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_dfuse);
glutSolidSphere(0.25, 32, 32);
}
//这里进行所有绘图工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix;
glTranslatef(-0.75, 0.0, 0.0);
DrawRedSphere;
glPopMatrix;
glPushMatrix;
glTranslatef(0.0, 0.0, -1.0);
DrawRedSphere;
glPopMatrix;
glPushMatrix;
glTranslatef(0.75, 0.0, -2.0);
DrawRedSphere;
glPopMatrix;
glFlush;
}
图片看不清楚?请点击这里查看原图(大图)
从图形上效果上看不出Z轴变化使用是正投影方式现在我们启用雾效果来试下
添加进如下语句:
glEnable(GL_FOG);
GLfloat fogColor[4] = {1.0, 1.0, 1.0, 1.0};
glFogi (GL_FOG_MODE, GL_EXP);
glFogfv (GL_FOG_COLOR, fogColor);
glFogf (GL_FOG_DENSITY, 0.5);
效果如下:
图片看不清楚?请点击这里查看原图(大图)
雾颜色为白色第3个红球基本上已经全白了大家可以调整上述代码中参数以获取区别效果
比如说偏蓝色雾:
glEnable(GL_FOG);
GLfloat fogColor[4] = {0.0, 0.0, 0.5, 1.0};
glFogi (GL_FOG_MODE, GL_EXP);
glFogfv (GL_FOG_COLOR, fogColor);
glFogf (GL_FOG_DENSITY, 0.5);
图片看不清楚?请点击这里查看原图(大图)
主要其实也就个glFog*但是参数那是相当多啊留待大家自己尝试了
OpenGL Reference Manual:
glFog — specy fog parameters
C Specication
void glFogf( GLenum pname,
GLfloat param);
void glFogi( GLenum pname,
GL param);
Parameters
pname
Species a single-valued fog parameter.
GL_FOG_MODE,
GL_FOG_DENSITY,
GL_FOG_START,
GL_FOG_END,
GL_FOG_INDEX, and
GL_FOG_COORD_SRC
are accepted.
param
Species the value that pname will be to.
C Specication
void glFogfv( GLenum pname,
const GLfloat * params);
void glFogiv( GLenum pname,
const GL * params);
Parameters
pname
Species a fog parameter.
GL_FOG_MODE,
GL_FOG_DENSITY,
GL_FOG_START,
GL_FOG_END,
GL_FOG_INDEX,
GL_FOG_COLOR, and
GL_FOG_COORD_SRC
are accepted.
params
Species the value or values to be assigned to pname.
GL_FOG_COLOR requires an .gif' /> of four values.
All other parameters accept an .gif' /> containing only a single value.
Description
Fog is initially disabled.
While enabled, fog affects rasterized geometry,
bitmaps, and pixel blocks, but not buffer clear operations. To enable
and disable fog, call glEnable and glDisable with argument
GL_FOG.
glFog assigns the value or values in params to the fog parameter
specied by pname.
The following values are accepted for pname:
GL_FOG_MODE
params is a single eger or floating-po value that species
the equation to be used to compute the fog blend factor,
f.
Three symbolic constants are accepted:
GL_LINEAR,
GL_EXP,
and GL_EXP2.
The equations corresponding to these symbolic constants are d below.
The initial fog mode is GL_EXP.
GL_FOG_DENSITY
params is a single eger or floating-po value that species
density,
the fog density used in both exponential fog equations.
Only nonnegative densities are accepted.
The initial fog density is 1.
GL_FOG_START
params is a single eger or floating-po value that species
start,
the near distance used in the linear fog equation.
The initial near distance is 0.
GL_FOG_END
params is a single eger or floating-po value that species
end,
the far distance used in the linear fog equation.
The initial far distance is 1.
GL_FOG_INDEX
params is a single eger or floating-po value that species
i
f
,
the fog color index.
The initial fog index is 0.
GL_FOG_COLOR
params contains four eger or floating-po values that specy
C
f
,
the fog color.
Integer values are mapped linearly such that the most positive representable
value maps to 1.0,
and the most negative representable value maps to
-1.0
.
Floating-po values are mapped directly.
After conversion,
all color components are clamped to the range
0
1
.
The initial fog color is (0, 0, 0, 0).
GL_FOG_COORD_SRC
params contains either of the following symbolic constants:
GL_FOG_COORD or GL_FRAGMENT_DEPTH. GL_FOG_COORD
species that the current fog coordinate should be used as distance value
in the fog color computation. GL_FRAGMENT_DEPTH species that the
current fragment depth should be used as distance value in the fog
computation.
最新评论