03、OpenGL隐藏面消除

在渲染过程中可能产生的问题

在绘制3D场景的时候,我们需要决定哪些部分是对观察者可见的,或者哪些部分是对观察者不可见的。不可见的部分,应该尽早的抛弃掉。例如一个不同的墙壁后,就不应该渲染。这种情况叫作隐藏面消除(Hidden surface elimination)

油画算法(基本不使用这种方法,也不推荐)

  • 先绘制场景中离观察者较远的物体,再绘制较劲的物体。
  • 例如下面的例子,绘制顺序:红色->黄色->灰色,即可解决隐藏面消除的问题
油画法.png

油画算法的弊端

  • 使用油画算法,只要将场景按照物理距离观察者的距离远近排序,由远及近的绘制即可。如果三个三角形是叠加的情况,油画算法将无法处理。
三角形叠加.png

正背面剔除

  • 解决问题
    • 如何告诉OpenGL 你绘制的图形,哪个面是正面,哪个面是背面?
    • 通过分析顶点数据的顺序。
  • 分析顶点顺序
分析顶点顺序.png
  • 正面/背面区分
    • 正面:按照逆时针顶点连接顺序的三角形面
    • 背面:按照顺时针顶点连接顺序的三角形面
  • 解析立方体中的正背面
正方体的正背面.png
  • 分析
    • 左侧三⻆形顶点顺序为: 1—> 2—> 3 ; 右侧三⻆形的顶点顺序为: 1—> 2—> 3 .
    • 当观察者在右侧时,则右边的三角形方向为逆时针方向则为正面,而左侧的三⻆形为顺时针则为背面
    • 当观察者在左侧时,则左边的三⻆形方向为逆时针方向则为正面,而右侧的三角形为顺时针则为背面
  • 总结
    • 正面和背面是有三角形的顶点定义顺序和观察者方向共同决定的.随着观察者的角度方向的改变,正面背⾯也会跟着改变

代码

  • 开启表⾯剔除(默认背⾯剔除)
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(逆时针顶点顺序的三角形)
  • 例如,剔除正⾯实现(1)
void glCullFace(GL_BACK); 
void glFrontFace(GL_CW);//修改顺时针顶点顺序的三角形为正面
  • 例如,剔除正⾯实现(2)
void glCullFace(GL_Front); 

你可能感兴趣的:(03、OpenGL隐藏面消除)