文章目录
第四章 颜色、像素和帧缓存
4.6 逐图元的反走样
- 当我们实现反走样的时候,OpenGL会根据屏幕上每个像素块所覆盖的范围来计算每个片元的覆盖值;OpenGL会将片元alpha值与这个覆盖值相乘;然后我们就可以使用alpha值来实现片元与帧缓存中已有像素的融合操作了
- 覆盖值计算的细节非常复杂,我们可以使用glHint()来进行进一步的控制,在图像质量和速度上做出权衡
- void glHint(GLenum target, GLenum hint) 控制OpenGL的一些具体特性;target用来设置要控制的特性类型,可用的值见下表;
target可选枚举 | 描述 |
---|---|
GL_LINE_SMOOTH_HINT | 线的反走样质量 |
GL_POLYGON_SMOOTH_HINT | 多边形边的反走样质量 |
GL_TEXTURE_COMPRESSION_HINT | 纹理图像压缩的质量和性能 |
GL_FRAGMENT_SHADER_DERIVATIVE_HINT | 片元处理内置函数的导数精度,包括dFdx、fwidth |
hint可以设置的值如下:
hint可选枚举 | 描述 |
---|---|
GL_FASTEST | 使用效率最好的方式 |
GL_NICEST | 使用质量最高的方式 |
GL_DONT_CARE | 没有偏好 |
- 如果程序十分需要多重采样的效果,那么对线段和多边形反走样的另一种方法就是通过glEnable()开启反走样,然后将GL_LINE_SMOOTH或者GL_POLYGON_SMOOTH作为参数传入
4.6.1 线段的反走样
-
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); -
首先要开启混合;混合参数通常可以设置为GL_SRC_ALPHA(源)和GL_ONE_MINUS_SRC_ALPHA(目标);或者也可使用GL_ONE作为目标参数,这样线段相交的地方会更亮;
-
如果用的alpha值足够高,那么反走样效果非常明显
-
当设置使用混合时,需要考虑好渲染的顺序
4.6.2 多边形的反走样
- 通过glEnable(GL_POLYGON_SMOOTH)开启多边形的反走样
- 如果需要可以设置GL_POLYGON_SMOOTH_HINT的质量值
- 混合参数为GL_SRC_ALPHA_SATURATE(源)和GL_ONE(目标)
- 对场景中的多边形排序,确保他们是从前往后的顺序后再做渲染
- 如果要保证混合和反走样的正确性,那么我们也许需要禁止深度测试
4.7 帧缓存对象
- 在此之前,所有有关缓存的讨论都是集中在窗口系统的缓存,也就是调用glutCreateWindow()这样的函数得到的缓存
- 在不同的缓存之间大量的迁移数据,这就是帧缓存对象存在的意义
- 通过帧缓存对象,我们可以创建自己的帧缓存,并且将他们绑定到渲染缓存上,将数据拷贝的消耗最小化,同时对性能进行优化
- 帧缓存对象对于离屏渲染技术、纹理贴图的更新,以及缓存乒乓技术的实现非常有意义
- 窗口系统所提供的帧缓存是唯一可以被图形服务器的显示系统所识别的帧缓存,也就是说我们在屏幕上看到的只能是这个缓存(窗口系统的帧缓存与应用程序中创建的帧缓存区别一)
- 区别二:窗口系统的帧缓存有自己的缓存对象–颜色、深度和模板,它们都诞生于窗口创建时;当创建一个应用程序管理的帧缓存对象时,还需要创建额外的渲染缓存,并且于帧缓存对象相关联
- void glGenFramebuffers(GLsizei n, GLuint* ids) 分配n个未使用的帧缓存对象名称,并且将它们存储到ids中
- void glBindFramebuffer(GLenum target, GLuint framebuffer) 当第一次调用它来绑定某个帧缓存时,他会分配这个对象的存储空间并且将其初始化;此后再次调用这个函数时,会将给定的帧缓存对象绑定为当前激活的状态;target可取的值如下:
target可取的值 | 描述 |
---|---|
GL_DRAW_FRAMEBUFFER | 设置为绘制时的目标帧缓存 |
GL_READ_FRAMEBUFFER | 设置为读取操作的数据源 |
GL_FRAMEBUFFER | 设置的帧缓存可读也可写 |