裁剪
- 只刷新屏幕上发生变化的部分可以提高渲染性能
- OpenGL中是允许将要进行渲染的窗口指定一个裁剪框
- 裁剪框与窗口大小可不一样(默认是同样大小且不会进行裁剪测试)
//使用时要开启裁剪测试函数
glEnable(GL_SCISSOR_TEST);
//关闭裁剪测试
glDisable(GL_SCISSOR_TEST);
//在执行渲染窗口中,被称为裁剪框的矩形是使用如下函数来指定窗口坐标(像素)的
glScissor(GLint x,GLint y,GLsizei width,GLsizei height);
*注意:*x和y是指定裁剪框左下角,width和height为裁剪框的相应尺寸
混合
- OpenGL渲染时会把颜色值放在颜色缓冲区,片段的深度是放在深度缓冲区的
- 当深度测试被关闭或者禁用时,新的颜色值就会直接覆盖颜色缓冲区中已经存在的其他值
- 当深度测试被打开或者启用时,新的颜色片段只有当它们比原来的值更接近临近的裁剪平面时才会替换原来的颜色片段
- 所以大多数情况下依赖于深度测试的结果:任何绘制操作不是被完全丢弃就是完全覆盖原来的颜色值
//若打开OpenGL的混合功能(如下函数),下层颜色值就不会被清除
glEnable(GL_BLEND);//开启后新旧颜色值在缓冲区中重新组合
组合颜色
- 目标颜色:已经存在颜色缓冲区中的颜色值
- 源颜色:作为当前渲染命令的结果进入缓冲区的颜色值
//当以上混合功能被启动时,源颜色值和目标颜色的组合方式由以下混合方程式控制的
Cf = (Cs * S) + (Cd * D);
1. Cf:最终计算的颜色
2. Cs:源颜色
3. Cd:目标颜色
4. S:源混合因子
5. D:目标混合因子
上述混合因子用以下函数设置的
glBlendFunc(GLenum S,GLenum D);(S和D都是枚举值)
截屏2020-07-23 16.26.34.png
注意:
颜色是用浮点数表述的(对它们加减甚至乘法也是完全合法的)
//混合函数组合例子
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
例如:如果颜色缓存区已经有一种颜⾊红色(1.0f,0.0f,0.0f,0.0f)即:⽬标颜色Cd,
如果在这上面⽤⼀种alpha为0.6的蓝色(0.0f,0.0f,1.0f,0.6f)
Cd (目标颜色) = (1.0f,0.0f,0.0f,0.0f);
Cs (源颜色) = (0.0f,0.0f,1.0f,0.6f);
S = 源alpha值 = 0.6f
D = 1 - 源alpha值= 1-0.6f = 0.4f
方程式Cf = (Cs * S) + (Cd * D)
等价于Cf = (Blue * 0.6f) + (Red * 0.4f)
最终的颜色:原先的红色(目标颜色)与后来的蓝色(源颜色)进行缩放后的组合,
且源颜色的alpha值越高,添加的源颜色成分就越多,目标颜色所保留的成分就越少
混合函数经常用于实现在其他一些不透明的物体前绘制一个透明物体的效果
改变混合方程式
- 默认混合方程式:Cf = (Cs * S) + (Cd * D)
//其实不止默认方程式,有五个不同的混合方程式可以选择,通过以下函数进行操作
glBlendEquation(GLenum mode);
如下图所示:
截屏2020-07-23 16.26.57.png
//除了用glBlendFunc来设置混合因子,还可以用如下函数更灵活的选择
glBlendFuncSeparate(GLenum strRGB,GLenum dstRGB ,GLenum strAlpha,GLenum dstAlpha);
1.strRGB: 源颜色的混合因⼦
2.dstRGB: ⽬标颜⾊的混合因⼦
3.strAlpha: 源颜⾊的Alpha因⼦
4.dstAlpha:目标颜⾊的Alpha因⼦
**注意:**
1.glBlendFunc函数指定了源和目标RGBA值的混合函数
2.glBlendFuncSeparate函数允许为RGB和alpha成分单独指定混合函数
常量混合颜⾊
默认初始化为⿊色(0.0f,0.0f,0.0f,0.0f),但可以用以下函数来修改。
void glBlendColor(GLclampf red ,GLclampf green ,GLclampf blue ,GLclampf alpha );
抗锯齿
- 锯齿:绝大多数情况下,一个独立的渲染片段将会映射到计算机屏幕上到一个像素(近似正方形的),通常可以相当清楚地看到二种颜色的分界
- 这种锯齿现象会彻底暴露出这个图像是计算机生成的,让人觉得很不自然,由此OpenGL混合功能就能抗锯齿,解决锯齿问题
//OpenGL使用混合功能来混合片段的颜色,即把像素的目标颜色与周围像素的颜色进行混合。
//(本质上来说:在任何图元的边缘上,像素颜色会稍微延伸到相邻的像素)
//开启抗锯齿(启用混合功能)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_MINUS_SRC_ALPHA);
//glEnable函数对点,直线和多边形(任何实心图元)进行抗锯齿处理
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);//对多边形处理还是比较复杂的,单独使用此方法效果并不好,大都被如下的多重采样方法所代替
多重采样
- 抗锯齿能够使多边形的边缘更为平滑,使渲染效果显得更为自然和逼真
- 但是多边形的平滑处理并没有在所有的平台上都得到实现,即使使用GL_POLYGON_SMOOTH也没有想象中的方便
- 抗锯齿处理是基于混合操作的,需要从前到后对所有的图元进行排序,但这是非常麻烦的
- 鉴于以上原因,OpenGL(1.3)新增了==多重采样==新特性来更方便的解决以上问题
- OpenGL实现支持这个特性就会添加一个额外的缓冲区其包含了颜色,深度和模版值的帧缓冲区
- 所有的图元在每个像素上都进行了多次采样,其结果就存储在这个缓冲区中
- 每次当这个像素进行更新时,这些采样值进行解析,以产生一个单独的值
注意:
以上处理会带来额外的内存和处理器开销,有可能对性能造成影响。因此,有些OpenGL实现可能并不支持多渲染环境中的多重采样
多重采样使用
- 为了进行多重采样,首先必须获得一个支持多重采样帧缓冲区的渲染环境(这在不同的平台中可能各不相同)
- 但是GLUT提供一个段位(GLUT_MULTISAMPLE),允许请求这种帧缓冲区
- 为了请求一个多重采样,完全颜色,带深度的双缓冲帧缓冲区,调用以下函数
gluInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
//打开多重采样
glEnable(GL_MULTISAMPLE);
//关闭多重采样
glDisable(GL_MULTISAMPLE);
注意:多重采样被启用时,点,直线和多边形的平滑特性都将被忽略(如果这些特性被启用的话),
就是说在使用多重采样时,不能同时使用点和直线点平滑处理。
在一种特定的OpenGL实现中,点和线如果采用平滑处理可能会比使用多重采样效果好(因此可以关闭多重采样)
glDisable(GL_MULTISAMPLE);
glEnable(GL_POINT_SMOOTH);
在绘制其他实心几何图形时再打开多重采样
glDisable(GL_POINT_SMOOTH);
glEnable(GL_MULTISAMPLE);
如果没有多重采样缓冲区,OpenGL就当作GL_MULTISAMPLE是被禁用的
打开或关闭不同的OpenGL特性将会修改驱动程序的内部状态,这种状态的改变可能会对渲染的性能造成影响。对性能非常敏感程序员常常会对所有绘图命令进行排序,这样需要相同状态的几何图形就可以一起绘制。这种状态排序是在游戏中常用的提高速度的方法之一
- 多重采样缓冲区在默认情况下使用片段点RGB值,并不包括颜色的alpha成分。可以通过调用glEnable(使用如下三个值之一)来修改这个行为
GL_SAMPLE_ALPHA_TO_COVERAGE //使用alpha值
GL_SAMPLE_ALPHA_TO_ON //将alpha值设置为1并使用
GL_SAMPLE_COVERAGE //使用glSampleConverage所设置的值
当使用最后一个时,glSampleConverage函数允许指定一个特定的值,它是与片段覆盖值进行按位与操作的结果
glSampleConverage(GLclampf value,GLboolean invert);
注:本文参考:OpenGL超级宝典第五版
网友评论