第三十六章 面剔除总结

本文详细介绍了OpenGL中的面剔除技术,通过开启`GL_CULL_FACE`节省片段着色器调用,以及如何调整顶点数据的环绕顺序。接着讲解了帧缓冲的概念,包括创建、绑定和检查完整性。同时阐述了帧缓冲对象的创建、附加纹理和渲染缓冲对象作为附件的过程,以及离屏渲染的应用。最后讨论了后期处理技术,如反相、灰度和核效果的实现。

面剔除:只绘制面向用户的面,背对用户的面进行丢弃。
OpenGL可以检查所有面向观察者的面,并渲染它们,而丢弃那些背向的面,节约片段着色器调用。用的是:顶点数据的环绕顺序

默认情况下,逆时针顶点所定义的三角形将会被处理为正向三角形。而且实际的环绕顺序是在光栅化阶段进行的,也就是顶点着色器运行之后,
这些顶点就是从观察者视角所见的了。则顺时针的1-2-3所形成的三角形是不可见面。这个功能默认是禁用的。
当然需要更新顶点数据,用逆时针环绕的顺序定义。启用面剔除方法如下:
glEnable(GL_CULL_FACE);
之后的代码实现中,所有的背向面都会被丢弃,只对类似立方体这样的封闭形状有效。

当然也可以只剔除正向面,而不是背向面:glCullFace(GL_FRONT);
有三个参数选项:
GL_BACK————只剔除背向面
GL_FRONT————只剔除正向面
GL_FRONT_AND_BAKC————剔除背向面和正向面
默认值是GL_BACK

也可以调用glFrontFace,来调整:顺时针的面定义为正向面
glFrontFace(GL_CCW);
默认值是GL_CCW————逆时针;GL_CW————顺时针。

下面看下帧缓冲相关内容:
前面看的都是屏幕缓冲,比如:颜色缓冲,深度缓冲,模板缓冲。
把上述的缓冲结合起来就叫做帧缓冲,被存储在内存中。允许定义自己的帧缓冲,也就是可以定义自己的颜色缓冲,深度缓冲和模板缓冲
默认的帧缓冲是创建窗口的时候就生成和配置的,GLFW做好了这些。

使用函数glGenFramebuffers创建一个帧缓冲对象:
unsigned int fbo;
glGenFramebuffers(1, &fbo);
再绑定为激活的帧缓冲:
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
绑定后,所有的读取和写入帧缓冲都会影响当前绑定的帧缓冲。也可以使用GL_READ_FRAMEBUFFER或GL_DRAW_FRAMEBUFFER,把帧缓冲分别绑定到读取或写入目标
补充:
GL_READ_FRAMEBUFFER的帧缓冲将会使用在所有像是glReadPixels的读取操作中,而绑定到GL_DRAW_FRAMEBUFFER的帧缓冲将会被用作渲染、清除等写入操作的目标。
大部分情况你都不需要区分它们,通常都会使用GL_FRAMEBUFFER,绑定到两个上。

一个完整的帧缓冲需要四个条件:
1.附加至少一个缓冲(颜色,深度,模板)
2.至少有一个颜色附件
3.所有的附件必须完整(保留内存)
4.每个缓冲都应该有相同的样本数

则,下面需要对帧缓冲创建一些附件,把附件附加到帧缓冲上。完成上述四个条件后,可以调用glCheckFramebufferStatus函数,用GL_FRAMEBUFFER为参数,
检查帧缓冲是否完整。如果返回值是GL_FRAMEBUFFER_COMPLETE,则帧缓冲是完整的。
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)

之后,所有的渲染操作将会渲染到当前绑定帧缓冲的附件中。但是,当前帧缓冲不是默认帧缓冲,渲染指令不会对窗口的视觉输出有啥影响。
由此可以得到一个新的概念:渲染到一个不同的帧缓冲被叫做 离屏渲染。要保证所有的渲染操作在主窗口有视觉效果,需要激活默认帧缓冲,绑定到0
glBindFramebuffer(GL_FRAMEBUFFER, 0);
在完成所有的帧缓冲操作之后,不要忘记删除这个帧缓冲对象:
glDeleteFramebuffers(1, &fbo);

当然,检查完整性之前,需要给帧缓冲附加一个附件。附件是一个内存位置,能够作为帧缓冲的一个缓冲,可以将其想象为一个图像。创建一个附件的话,有
两个选项:纹理 或者 渲染缓冲对象

下面分别看下两个选项,首先是纹理附件:
把一个纹理附加到帧缓冲的时候,所有渲染指令将会写到这个纹理中,就像是一个普通的颜色,深度或模板缓冲一样。
使用纹理的优点:所有渲染操作的结果将会被存储到一个纹理图像中,之后可以直接

### OpenGL剔除的概念和用法 #### 剔除的工作原理 在三维图形渲染中,许多多边形可能是不可见的,因为它们背对着观察者。为了提高性能并减少不必要的计算,OpenGL 提供了一种称为 **剔除** 的机制。该机制允许开发者指定哪些向应该被剔除(即不绘制)。这种优化基于这样一个事实:如果一个多边形的正朝向远离摄像机,则它的背必然朝向摄像机。 OpenGL 默认假设顶点顺序决定了多边形的方向性。例如,在默认情况下,顺时针排列的顶点定义了一个多边形的背[^1]。当启用剔除功能时,OpenGL 将自动检测这些不可见的表并将它们从渲染管线中移除。 #### 启用与禁用剔除 要控制剔除行为,可以使用 `glEnable` 和 `glDisable` 函数分别开启或关闭此功能: ```cpp // 开启剔除 glEnable(GL_CULL_FACE); // 关闭剔除 glDisable(GL_CULL_FACE); ``` #### 设置剔除模式 可以通过调用 `glCullFace` 来设置希望剔除的具体类型。常见的选项包括: - `GL_FRONT`: 剔除所有前。 - `GL_BACK`: 剔除所有后(这是最常用的设置)。 - `GL_FRONT_AND_BACK`: 同时剔除前后两。 示例代码如下所示: ```cpp // 只剔除 glCullFace(GL_BACK); ``` #### 定义顶点顺序规则 除了决定剔除哪一外,还需要告诉 OpenGL 如何判断某个属于“前”还是“后”。这由 `glFrontFace` 函数完成,支持两种参数值: - `GL_CCW`: 表明按逆时针方向环绕的多边形视为其正。 - `GL_CW`: 则表示顺时针环绕的多边形为其正。 典型配置如下: ```cpp // 设定逆时针为正 glFrontFace(GL_CCW); ``` #### 实际应用中的注意事项 尽管剔除能够显著提升效率,但在实际开发过程中需要注意一些细节问题。比如模型数据本身可能存在问题导致错误剔除;或者某些特殊效果确实需要保留双显示等情况都需要额外处理[^3]。 综上所述,合理运用 OpenGL 提供的剔除技术可以在不影响视觉质量的前提下大幅降低 GPU 负载,从而获得更流畅的游戏体验或其他高性能需求的应用场景表现。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值