裁剪
在OpenGL中提⾼渲染效率的⼀种⽅式。只刷新屏幕上发⽣变化的部分。
- 基本原理
用于渲染时限制绘制区域,通过此技术可以在屏幕(帧缓冲)指定一个矩形区域。启用剪裁测试之后,不在此矩形区域内的片元被丢弃,只有在此矩形区域内的⽚元才有可能进入帧缓冲。因此,实际达到的效果就是在屏幕上开辟了一个⼩窗口,可以在其中进⾏指定内容的绘制。
//1 开启裁剪测试
glEnable(GL_SCISSOR_TEST);
//2.关闭裁剪测试
glDisable(GL_SCISSOR_TEST);
//3.指定裁剪窗⼝
//x,y:指定裁剪框左下⻆位置; width,height:指定裁剪尺⼨
void glScissor(Glint x, Glint y, GLSize width, GLSize height);
- 窗口
显示界面。就相当于iOS里面的window。 - 视口
窗口中⽤来显示图形的一块矩形区域,它可以和窗⼝等⼤,也可以⽐窗口⼤或者小。只有绘
制在视口区域中的图形才能被显示,如果图形有一部分超出了视口区域,那么那一部分是看
不到的。通过glViewport()函数设置。就相当于View。 - 裁剪区域(平⾏投影)
视口矩形区域的最小最大x坐标(left,right)和最小最⼤y坐标 (bottom,top),⽽不是窗口的最
小最大x坐标和y坐标。通过glOrtho()函数设置,这个函数还需指定最近最远z坐标,形成一
个立体的裁剪区域。 就相当于设置一个frame。
混合
当开启深度测试后,两个重叠的图层中,如果有一个图层是半透明的,另一个是非半透明,此时就不能通过深度值比较,来进行颜色值的覆盖,而是需要将两个颜色进行混合,然后存入颜色缓冲区
针对不同需求,颜色混合的使用方式有两种
- 开关方式
用于单纯的将两个图层重叠时进行颜色混合,这种混合并不能解决颜色的混合。在固定着色器和可编程着色器都可以使用这种方式
//开启,
glEnable(GL_BlEND);
//关闭
glDisable(GL_BlEND);
- 开关方式 + 混合方程式
用于处理类似滤镜效果的场景,简单描述就是将需要处理的图片颜色和图片上覆盖的半透明颜色进行混合 即 两股颜色混合,此时如果只是单纯的开关方式,已经不能满足我们的需求,需要借助混合方程式,来实现两股颜色的混合。一般是在可编程着色器中片元着色器中使用。
//开启,
glEnable(GL_BlEND);
//设置混合因子--默认值是 GL_SRC_ALPHA 和 GL_ONE_MINUS_SRC_ALPHA
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
//关闭
glDisable(GL_BlEND);
- ⽬标颜色:已经存储在颜色缓存区的颜色值 (已经存在的颜色,旧颜色)
- 源颜色:作为当前渲染命令结果进入颜色缓存区的颜⾊值 (新进来的颜色 ,新颜色)
当混合功能被开启时,源颜色和⽬标颜色的组合方式是混合方程式控制的。在默认情况下,混合方程式如下所示:
//Cf: 最终计算参数的颜⾊
//Cs: 源颜⾊
//Cd: 目标颜⾊
//S: 源混合因⼦,源Alpha混合因子
//D: ⽬标混合因⼦,⽬标Alpha混合因子
Cf = (Cs * S) + (Cd * D);
混合方程式
OpenGL有5个不同的方程式进行选择。
glbBlendEquation(GLenum mode);
模式 | 函数 |
---|---|
GL_FUNC_ADD | Cf = (Cs * S) + (Cd * D) |
GL_FUNC_SUBTRACT | Cf = (Cs * S) - (Cd * D) |
GL_FUNC_REVERSE_SUBTRACT | Cf = (Cd * D) - (Cs * S) |
GL_MIN | Cf = min(Cs, Cd) |
GL_MAX | Cf = max(Cs, Cd) |
设置混合因⼦
//S:源混合因⼦
//D:⽬标混合因子
glBlendFunc(GLenum S, GLenum D);
函数 | RGB混合因子 | Alpha混合因子 |
---|---|---|
GL_ZERO | (0, 0, 0) | 0 |
GL_ONE | (1, 1, 1) | 1 |
GL_SRC_COLOR | (Rs, Gs, Bs) | As |
GL_ONE_MINUS_SCR_COLOR | (1, 1, 1) - (Rs, Gs, Bs) | 1 - As |
GL_DST_COLOR | (Rd, Gd, Bd) | Ad |
GL_ONE_MINUS_DST_COLOR | (1, 1, 1) - (Rd, Gd, Bd) | 1 - Ad |
GL_SRC_ALPHA | (As, As, As) | As |
GL_ONE_MINUS_SCR_ALPHA | (1, 1, 1) - (As, As, As) | 1- As |
GL_DST_ALPHA | (Ad, Ad, Ad) | Ad |
GL_ONE_MINUS_DST_ALPHA | (1, 1, 1) - (Ad, Ad, Ad) | 1- Ad |
GL_CONSTANT_COLOR | (Rc, Gc, Bc) | Ac |
GL_ONE_MINUS_CONSTANT_ALPHA | (1, 1, 1) - (Ac, Ac, Ac) | 1- Ac |
GL_CONSTANT_ALPHA | (Ac, Ac, Ac) | Ac |
GL_ONE_MINUS_CONSTANT_ALPHA | (1, 1, 1) - (Ac, Ac, Ac) | 1- Ac |
GL_SRC_ALPHA_SATURATE | (f, f, f)* f = min(As, 1 - Ad) | 1 |
表中R、G、B、A 分别代表 红、绿、蓝、Alpha
表中下标S、D,分别代表源、⽬标
表中C 代表常量颜⾊(默认⿊色)
默认初始化为⿊色(0, 0, 0, 0),通过下面的函数可以修改这个颜色。
void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );
glBlendFuncSeparate函数
除了能使⽤OpenGL内置的混合因⼦,还可以有更灵活的选择
//strRGB: 源颜色的混合因⼦
//dstRGB: 目标颜⾊的混合因⼦
//strAlpha: 源颜⾊的Alpha因⼦
//dstAlpha: 目标颜⾊的Alpha因⼦
void glBlendFuncSeparate(GLenum strRGB, GLenum dstRGB , GLenum strAlpha, GLenum dstAlpha);
总结
- 在颜色缓冲区中,每个像素点只能存储一种颜色
- 颜色混合主要用于实现在不透明物体前绘制透明物体的效果
- 只有上面图层是透明时,才需要开启颜色混合,如果不是,则没有必要开启颜色混合
- 绘制完成后,需要关闭混合功能,通过glDisable关闭,如果不关闭,会对其他项目造成影响,混合的开启是针对全局的,并不单单只是这个项目
网友评论