基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(二十一)面剔除

Vries的教程是我看过的最好的可编程管线OpenGL教程,没有之一其原地址如下,https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/04%20Face%20culling/ 关于面剔除的详细知识了解请看原教程,本篇旨在对Vires基于visual studio平台的编程思想与c++代码做纯Qt平台的移植,代码移植顺序基本按照原教程顺序,并附加一些学习心得,重在记录自身学习之用

  •   Tip1:这节Vries没有提供源代码,因为代码没有新的内容,只是很简单的调换了下立方体的顶点数据顺序,与开启面剔除测试。
  •   Tip2:这节的Qt代码移植没有需要注意的地方,直接使用OpenGL原函数即可。

程序源代码链接:https://pan.baidu.com/s/1lZ40oN77BZdu8MEd04nVVw  提取码:3z5a

编译环境:Qt5.9.4

编译器:Desktop Qt5.9.4 MSVC2017 64bit

IDE:QtCreator

一.面剔除

  顾名思义,面剔除是将渲染时看不见的一些面进行丢弃,以此来节约资源的使用,以图1为例。

图1 正常渲染

  我们换成线框模式进行观察,普通渲染模式下的立方体是具有六个面的,如图2所示,当开启面剔除时,在这个观察视角下,看不见的背面等三个面会进行丢弃,不再显示,如图3所示。

图2 线框模式-正常渲染
图3 线框模式-剔除反面

二.环绕顺序

  面剔除是个很强大的功能与节约资源的办法,OpenGL依靠组成一个面的顶点环绕顺序,确立这个面在当前视角下是否看得见。它规定,所有从视角出发,顺时针顺序的面为不可见面(丢弃面),逆时针为可见面。

  看起来,这个顶点顺序很难控制,这里有一个窍门,每当生成一个面时,我们应该假设要生成的这个面正对着我们,然后总是以逆时针的顺序进行绘制,举例说明。

  生成A三角形时,用一些抽象思维,假设我们处于正对A三角形的方向O,这时以逆时针顺序1,2,3绘制这个三角形。绘制B三角形时,同样架设我们处于正对B三角形的方向O',同样以逆时针顺序1,2,3绘制三角形。

  好了,现在让我们的场景开始渲染,人眼处为我们的观察位置,在这个视角下,A三角形绘制顺序1,2,3,是逆时针的,可见。B三角形绘制顺序1,2,3,但在这个视角下,却是顺时针的,故不可见

  故我们如果需要开启面剔除,必须注意面的绘制顺序。

  这是Vries总结的立方体逆时针绘制顺序:

float vertices[] = {
    // positions        // textures        // normals
    //Back Face
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f,  0.0f,  0.0f, -1.0f, //bottom-left
     0.5f,  0.5f, -0.5f,  1.0f,  1.0f,  0.0f,  0.0f, -1.0f, //top-right
     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, -1.0f,
     0.5f,  0.5f, -0.5f,  1.0f,  1.0f,  0.0f,  0.0f, -1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f,  0.0f,  0.0f, -1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, -1.0f,

    //Front Face
    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  0.0f,  0.0f,  1.0f,
     0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
     0.5f,  0.5f,  0.5f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f,
     0.5f,  0.5f,  0.5f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f,
    -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  0.0f,  0.0f,  1.0f,

    //Left Face
    -0.5f,  0.5f,  0.5f,  1.0f,  1.0f, -1.0f,  0.0f,  0.0f,
    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f, -1.0f,  0.0f,  0.0f,
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,
    -0.5f, -0.5f,  0.5f,  1.0f,  0.0f, -1.0f,  0.0f,  0.0f,
    -0.5f,  0.5f,  0.5f,  1.0f,  1.0f, -1.0f,  0.0f,  0.0f,

    //Right Face
     0.5f,  0.5f,  0.5f,  1.0f,  1.0f,  1.0f,  0.0f,  0.0f,
     0.5f, -0.5f, -0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  1.0f,  0.0f,  0.0f,
     0.5f, -0.5f, -0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,
     0.5f,  0.5f,  0.5f,  1.0f,  1.0f,  1.0f,  0.0f,  0.0f,
     0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  1.0f,  0.0f,  0.0f,

    //Bottom Face
    -0.5f, -0.5f, -0.5f,  0.0f,  1.0f,  0.0f, -1.0f,  0.0f,
     0.5f, -0.5f, -0.5f,  1.0f,  1.0f,  0.0f, -1.0f,  0.0f,
     0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f, -1.0f,  0.0f,
     0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f, -1.0f,  0.0f,
    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  0.0f, -1.0f,  0.0f,
    -0.5f, -0.5f, -0.5f,  0.0f,  1.0f,  0.0f, -1.0f,  0.0f,

    //Top Face
    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,
     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
     0.5f,  0.5f, -0.5f,  1.0f,  1.0f,  0.0f,  1.0f,  0.0f,
     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,
    -0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  0.0f,  1.0f,  0.0f,
  };

三.函数

  与面剔除相关的由三个控制函数:

1.  glEnable(GL_CULL_FACE); 开启面剔除模式,该模式默认是关闭状态,

2.  glCullFace(GL_FRONT);设置剔除面为正向面,默认提出面为背向面

         该函数参数有三个选项:

         GL_BACK, 只剔除背向面

         GL_FRONT,只剔除正向面

         GL_FRONT_AND_BACK,剔除正向面和背向面

3.  glFrontFace(GL_CW); 设置顺时针顺序为正向面,默认逆时针GL_CCW为正向面。

图4 剔除正向面

猜你喜欢

转载自blog.csdn.net/z136411501/article/details/83479606