《OpelGL编程指南第七版》第六章:混合、抗锯齿、雾和多边形(笔记)
《混合、抗锯齿、雾和多边形偏移》
标签(空格分隔): OpenGL编程指南第七版
6.1 混合
6.1.1 源因子与目标因子
void glBlendFunc(GLenum srcfactor GLenum destfactor);
void glBlenndFuncSeparate(GLenum srcRGB, GLenum destRBG, GLenum srcAlpha, GLenum destAlpha);
void glBlendColor(GLclampdf red, GLclampdf green, GLclampdf blue, GLclampdf alpha);
6.1.2 启用混合
glEnable(GL_BLEND);
6.1.3 使用混合方程式组合像素
void BlendEquation(GLenum mode);
void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
6.1.6 使用深度缓冲区进行三维混合
半透明物体绘图顺序将会极大地影响最终的结果。如果一个不透明的物体遮挡住了一个半透明的物体或者一个不透明的物体,就需要利用深度缓冲区消除这些距离更远的物体。但是吗,如果半透明物体更靠近观察点,就需要把它与位于它后面的不透明物体进行混合。
这个问题的解决方案是启用深度缓冲区。在绘制半透明物体时,让深度缓冲区处于只读状态(半透明间需要注意绘图顺序,由远及近)。
glDepthMask()传递GL_FALSE参数,深度缓冲区就设置为只读。
6.2 抗锯齿
void glHint(GLenum target, GLenum hint);对图像质量和渲染速度之间的权衡关系施加控制。
6.2.1 对点和直线进行抗锯齿处理
对点和直线进行抗锯齿处理的一种方法之一是使用glEnable()函数(GL_POINT_SMOOTH或GL_LINE_SMOOTH)启用抗锯齿。
RGBA模式下的抗锯齿
在RGB模式下,需要启用混合功能。最常用的混合因子是GL_SRC_ALPHA(源)和GL_ONE_MINUS_SRC_ALPHA(目标)。另外也可以使用GL_ONE来表示目标混合因子。
由于所执行的是混合操作(glEnable(GL_BLEND)),可能需要考虑渲染顺序。但是,在大多数情况下,可以忽略渲染顺序,它不会产生明显的不良效果。
颜色索引模式下的抗锯齿
6.2.2 使用多重采样对几何图元进行抗锯齿处理
多重采样特别适合对多边形的边缘进行抗锯齿处理,因为此时不需要进行排序
步骤:
- 获取支持多重采样的窗口
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_MUTISAMPLE); - 验证多重采样功能是否可用
如果查询状态变量GL_SAMPLE_BUFFERS返回的值是1,并且查询GL_SAMPLES返回的值大于1,就可以使用多重采样功能。
GLint bufs,samples;
glGetIntergerv(GL_SAMPLE_BUFFERS,&bufs);
glGetIntergerv(GL_SAMPLES,&samples); - 启用多重采样
glEnable(GL_MULTISAMPLE);
图片左侧抗锯齿,右侧不抗锯齿
alpha和多重采样
在默认情况下,多重采样计算的覆盖值是独立于alpha值的。但是,如果启用了下面这些特殊的模式,那么在计算片段的覆盖值时,就会考虑alpha值的因素。
- GL_SAMPLE_ALPHA_TO_COVERAGE:使用片段的alpha值来计算最终的覆盖值。
- GL_SAMPLE_ALPHA_TO_ONE:把片段的alpha值设置为1,然后在计算覆盖值时使用这个值。
- GL_SAMPLE_COVERAGE:使用glSampleCoverage()函数所设置的值,这个值与经过计算产生的覆盖值进行组合(使用AND操作)。另外,也可以通过在glSampleCoverage()函数中使用invert标志来反转这个模式。
void glSampleCoverage(GLclampf value, GLboolean invert);
6.2.3 对多边形进行抗锯齿处理
6.3 雾
雾是在执行了矩阵变换、光照和纹理之后才应用的。
6.3.1 使用雾
glEnable(GL_FOG);启用雾
GLfloat fogColor4 = { 0.5, 0.5, 0.5, 1.0 };
fogMode = GL_EXP;
glFogi(GL_FOG_MODE, fogMode);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.35);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 1.0);
glFogf(GL_FOG_END, 5.0);
6.3.2 雾方程式
void glFog{if}(GLenum pname, TYPE param);
void glFog{if}v(GLenum pname, TYPE* param);
RGBA模式下的雾
颜色索引模式下的雾
雾坐标
void glFogCoord{fd}(TYPE z);
void glFogCoord{fd}v(const TYPE* z);
此时,视点移动对物体指定雾坐标的顶点的雾效果没有影响。
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
6.4 点参数
点参数是一种自动、优雅的解决方案。它根据点和观察点的距离,对点的大小和亮度进行衰减。
void glPointParameter{if}(GLenum pname, GLfloat param);
void glPointParameter{if}v(GLenum panme, const TYPE* param);
6.5 多边形偏移
着重显示实心物体的边缘。
多边形偏移可也以用于在表面上生成贴花、使用隐藏直线消除来渲染图像。除了直线和多边形外,这个技巧也可以用于点图元。
使用glEnable()调用适当的参数(GL_POLYGON_OFFSET_FILL、GL_POLYGON_OFFSET_LINE、GL_POLYGON_OFFSET_POINT)来启用多边形偏移。还必须调用glPolygonMode()函数设置当前的多边形光栅化方法。
void glPolygonOffset(GLfloat factor, GLfloat units);
factor = 0.1f,units = 0.0f
factor = 0.1f,units = 536.0f
factor = 1.4f,units = 0.0f