【OpenGL】LearnOpenGL学习笔记15 - 面剔除

上接:https://blog.csdn.net/weixin_44506615/article/details/150637338?spm=1001.2014.3001.5501

完整代码:https://gitee.com/Duo1J/learn-open-gl | https://github.com/Duo1J/LearnOpenGL

面剔除 (Face Culling)

对于一个立方体来说,我们最多只能看见它的三个面,有时候甚至只有两个或一个

那么我们在绘制立方体时,完全可以不用绘制那些我们看不见的面,以此来提升渲染速度

如何确定一个面我们是否能够看见呢?对于立方体的一个面,它只有面向背向我们两种情况,一个面在面向我们的时候可以被看见,那么旋转到背后,这个面就是背向我们了,自然就可以将这个面剔除掉

那如何定义面向背向?

环绕顺序

当我们在定义一组三角形顶点的时候,我们会以特定的环绕顺序来定义它们。可能是顺时针 (Clockwise) ,也可能是逆时针 (Counter-clockwise) ,如下图所示 (图片来自于LearnOpenGL)

那我们只需要设定到底时顺时针还是逆时针是正面,在绘制时去判断顺序即可进行面剔除

面剔除

我们可以这样来开启和禁用面剔除

cpp 复制代码
glEnable(GL_CULL_FACE);
glDisable(GL_CULL_FACE);

glCullFace可以用来设定是要剔除正向面、背向面还是两面都剔除,默认为GL_BACK

cpp 复制代码
// 剔除背向面
glCullFace(GL_BACK);
指令 描述
GL_BACK 只剔除背向面
GL_FRONT 只剔除正向面
GL_FRONT_AND_BACK 剔除正向面和背向面

glFrontFace可以用来定义是顺时针还是逆时针为正向面,默认为GL_CCW

cpp 复制代码
// 逆时针为正向面 (Counter-clockwise)
glFrontFace(GL_CCW);
// 顺时针为正向面 (Clockwise)
glFrontFace(GL_CW);

我们先来看看剔除正向面的结果

cpp 复制代码
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glFrontFace(GL_CCW);

可以看到背包出现了多处镂空,并且右侧的草和窗户都不见了

移动相机可以看到草和窗户

接下来剔除背向面

cpp 复制代码
// 开启面剔除
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);

效果正常

移动相机到背包内,可以观察到镂空,并且窗户和草消失了

注意这里的窗户和草,我们都需要双面观察,所以需要在绘制这两种物体的时候关闭面剔除

cpp 复制代码
// ...

// 绘制草
glDisable(GL_CULL_FACE);
for (int i = 0; i < grassPositions.size(); ++i)
{
	glm::mat4 model = glm::mat4(1);
	model = glm::translate(model, grassPositions[i]);
	grassShader.SetMat4("model", model);
	glBindVertexArray(quadVAO);
	glDrawArrays(GL_TRIANGLES, 0, 6);
	glBindVertexArray(0);
}
glEnable(GL_CULL_FACE);

// ...

// 绘制窗户
glDisable(GL_CULL_FACE);
for (std::map<float, glm::vec3>::reverse_iterator it = sortedWindowPositions.rbegin();
	it != sortedWindowPositions.rend();
	++it)
{
	glm::mat4 model = glm::mat4(1);
	model = glm::translate(model, it->second);
	windowShader.SetMat4("model", model);
	glBindVertexArray(quadVAO);
	glDrawArrays(GL_TRIANGLES, 0, 6);
	glBindVertexArray(0);
}
glEnable(GL_CULL_FACE);

// ...
相关推荐
努力努力再努力FFF1 小时前
医生对AI辅助诊断感兴趣,作为临床人员该怎么了解和学习?
人工智能·学习
OBiO20132 小时前
Cell | 突破AAV载体容量限制!路中华/姜玉武/刘太安团队开发AAVLINK系统实现大基因递送
笔记
智者知已应修善业2 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
sakiko_3 小时前
UIKit学习笔记5-使用UITableView制作聊天页面
笔记·学习·swift·uikit
Alice-YUE4 小时前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript
北山有鸟4 小时前
修改源码法和插件法
嵌入式硬件·学习
richxu202510014 小时前
嵌入式学习之路->stm32篇->(14)通用定时器(上)
stm32·单片机·嵌入式硬件·学习
小陈phd5 小时前
TensorRT 入门完全指南(一)——从核心定义到生态工具全解析
人工智能·笔记
是上好佳佳佳呀5 小时前
【前端(十一)】JavaScript 语法基础笔记(多语言对比)
前端·javascript·笔记
qeen875 小时前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·