当甜甜圈旋转时,甜甜圈不在完整,有一部分变成了黑色。这是因为我们绘制的甜甜圈是3D图形,观察者最多只能看到正视的3个面。背面的观察者看不到的。旋转时OpenGL不知道该显示哪些界面,导致本来是观察者不应该看到且该丢弃部分,不仅看到了,而且没有将隐藏部分丢弃。也就出现了上面现象。
1、隐藏面消除
绘制3D图形时,我们针对的部分其实观察者可见的部分。对于观察者不可见的部分可以丢弃,应及早丢弃不进行绘制。这种情况叫做”隐藏面消除”(Hidden surface elimination)。
例:一个正方体,无论你从那个角度观察,最多只能看到3个面,至少有一个面是无法看到的。对于无法看到的面直接丢弃不进行绘制,也可以提高性能(节约片元着色器性能,提高超过50%)。
2、正背面剔除
2.1区分正背面
分析顶点顺序:OpenGL中默认顶点按照逆时针顺序链接的面为正面,顶点顺时针连接的面为背面(图2.1)。
GLfloat vertices[] = {
//顺时针
vertices[0], // vertex A
vertices[1], // vertex C
vertices[2], // vertex B
// 逆时针
vertices[0], // vertex A
vertices[2], // vertex B
vertices[1] // vertex C
};
图2.1
立方体图形分析(图2.2)
图2.2
- 左侧三角形顶点连接顺序为A->B->C,右侧三角形顶点连接顺序为A->B->C
- 当观察者在右侧时,右边的正方形是逆时针为正面,左侧为顺时针为背面
- 当观察者在左侧时,右边的正方形是顺时针为背面,左侧为逆时针为正面
- 正面和背面是由三角形顶点定义顺序和观察者的方位共同决定的,随着观察者方位的变化,正背面也随之改变。
也可以修改OpenGL默认的逆时针为正面顺时针为背面的规则。
一但修改整个项目都将以修改后的规则进行正背面的判断,所以最好不进行修改。
glFrontFace(GL_CW);
GL_CW:设置OpenGL 顺时针环绕的多边形为正⾯。
GL_CCW:设置OpenGL 逆时针环绕的多边形为正面。
正背面剔除的设置
- 开启表面剔除(默认背面剔除)
void glEnable(GL_CULL_FACE); - 关闭表面剔除
void glDisable(GL_CULL_FACE); - 选择剔除面(正面/背面)
void glCullFace(GLenum mode);
mode: GL_FRONT,GL_BACK,GL_FRONT_AND_BACK ,默认GL_BACK - 指定正背面
void glFrontFace(GLenum mode);
mode参数为:GL_CW(顺时针)、GL_CCW(逆时针)。默认值:GL_CCW(逆时针为正面)。
//开启表面剔除(默认背面剔除)
glEnable(GL_CULL_FACE);
//关闭表面剔除(默认背面剔除)
glDisable(GL_CULL_FACE);
//选择剔除那个面(正面/背面)
// mode参数为: GL_FRONT, GL_BACK, GL_FRONT_AND_BACK,默认GL_BACK
glCullFace(GLenum mode);
//用户指定绕序那个为正面
//mode参数为: GL_CW(顺时针), GL_CCW(逆时针),默认值:GL_CCW
glFrontFace(GL enum mode);
//剔除正面实现
glCullFace(GL_BACK);
glFrontFace(GL_CW); //顺时针为正面
//剔除正面实现
glCullFace(GL_FRONT);
glFrontFace(GL_CCW);//逆时针为正面
开启表面剔除在效果完整Demo
网友评论