由上面俩张图我们有一点困惑,为什么会出现这种情况呢??
首先作者是用默认光源着色器(见下方代码)进行操作的,光打到的地方称为阳面,没有打到的地方称为暗面,但是我们一旋转,OpenGL就懵了,不知道该显示哪个面,于是就都显示了,正常情况下,我们看一个立体总有一部分看不到,但是现在却不是了,那我们可以尝试解决一下。
shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vRad);
油画算法:
如图所示,油画算法是先绘制远的红色方块,再绘制比较近的黄色方块,最后绘制近的灰色方块,这样就可以消除暗面显示了,但是它有一个弊端👇
这张图没有先后顺序,油画算法,也不行了,于是引入了新的概念:正背面剔除
正背面剔除(Fuce Culling)
正背面剔除是什么呢?我们可以这样理解,我们看一个3D图形时,是不可能全部面都能看到的,于是我们假设看不到的那个面没有绘制,当我们换个面看时,再绘制出来,这样做能够大大的提高效率,对吧,而为什么叫正背面剔除,而不是莫一面剔除呢?我们首先要搞清楚什么叫正背面,如下图
逆时针链接绘制的是正面;
顺时针连接绘制的是背面;
我们看3D图形时,看到正面,那我们可以先不绘制背面,看到背面也一样,所以叫正背面剔除。而这些事是由OpenGL自己判断,你只要负责是否开启正背面剔除这个决定就行了。
而如何开启呢?首先我们要在Mian函数里面注册,右击函数,同时还要定义一个全局变量
int iDepth = 0; //开启深度测试
int iCull = 0; //开始正背面剔除
glutCreateMenu(ProcessMenu); //注册函数
然后调用这个函数:
void ProcessMenu(int value){
switch (value) {
case 1:
iDepth = !iDepth; //深度测试
break;
case 2:
iCull = !iCull; //正背面剔除
default:
break;
}
//一定要重绘
glutPostRedisplay();
}
光调用不实现可不行啊于是,我们可以去RenderScene
中实现
if (iCull) {
//开启正背面剔除
glEnable(GL_CULL_FACE);
//下面俩行代码可以不用敲,第一个是告诉OpenGL哪个是正面,第二个是要剔除哪面
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
}else{
glDisable(GL_CULL_FACE); //关闭正背面剔除
}
到此正背面剔除就完成了