只有美九一个人

使用 OpenGL ES 和代码处理 FSGL 库的结果:

接下来我将描述它是如何编程的,以及如何解决各种有趣问题。

首先,我们将初始化 OpenGL ES 上下文,正如我在上一篇文章中所写的那样。此外,我们将仅考虑渲染和代码的简要描述。

黑客帝国正在注视着你

视频中 Miku 的这个形象由三角形组成。要在 OpenGL 中绘制三角形,需要指定坐标为 x、y、z 的三个点。在 OpenGL 上下文的 2D 坐标中。
由于我们需要绘制包含 3D 坐标的图形,因此需要使用投影矩阵。我们还需要旋转、放大或任何我们想要对模型执行的操作——为此,使用了模型矩阵。 OpenGL 中没有相机的概念;事实上,对象围绕静态相机旋转。为此,使用了视图矩阵

简化 OpenGL ES 的实现它不包含矩阵数据。您可以使用添加缺失功能的库,例如 GLM

着色器

为了允许开发人员以任何方式绘制任何内容,OpenGL ES 必须实现顶点和片段着色器。顶点着色器必须接收渲染坐标作为输入,使用矩阵执行转换,并将坐标传递给 gl_Position。片段或像素着色器 –已经绘制颜色/纹理、应用叠加等。

我用 GLSL 编写了着色器。在我当前的实现中,着色器作为 C 字符串直接内置到主应用程序代码中。

缓冲区

顶点缓冲区包含顶点(vertices)的坐标;该缓冲区还包含纹理的坐标以及着色器所需的其他数据。生成顶点缓冲区后,需要将指针绑定到顶点着色器的数据。这是通过 glVertexAttribPointer 命令完成的,您需要在其中指定元素数量、指向数据开头的指针以及用于遍历缓冲区的步长。在我的实现中,完成了像素着色器的顶点坐标和纹理坐标的绑定。不过,值得一提的是,数据(纹理坐标)到片段着色器的传输是通过顶点着色器进行的。为了实现这一点,使用variing声明坐标。

这样OpenGL就知道以什么顺序绘制三角形的点–您将需要一个索引缓冲区(索引)。索引缓冲区包含数组中的顶点编号;使用三个这样的索引,可以获得一个三角形。

纹理

首先您需要加载/生成 OpenGL 纹理。为此,我使用了 SDL_LoadBMP,纹理是从 bmp 文件加载的。不过,值得注意的是,只有 24 位 BMP 适合,并且其中的颜色不是按通常的 RGB 顺序存储,而是以 BGR 存储。即加载后需要将红色通道替换为蓝色通道
纹理坐标以以下格式指定: UV,即只需要传递两个坐标即可。纹理输出在片段着色器中完成。为此,您需要将纹理绑定到片段着色器中。

没什么多余的

因为,根据我们的指示,OpenGL 通过 2D 绘制 3D ——然后实现深度,并选择不可见的三角形–您需要使用剔除和深度缓冲区(Z-Buffer)。在我的实现中,我设法避免使用两个命令手动生成深度缓冲区:glEnable(GL_DEPTH_TEST);和选择 glEnable(GL_CULL_FACE);
另外一定要检查投影矩阵的近平面是否大于零,因为使用近平面的空值检查深度将不起作用。

渲染

要使用有意识的东西填充顶点缓冲区、索引缓冲区,例如 Miku 模型,您需要加载此模型。为此,我使用了 assimp 库。 Miku被放置在Wavefront OBJ格式文件中,使用assimp加载,并实现了assimp到顶点和索引缓冲区的数据转换。

渲染分几个阶段进行:

  1. 使用模型矩阵旋转来旋转 Miku
  2. 清除屏幕和深度缓冲区
  3. 使用 glDrawElements 命令绘制三角形。

下一阶段–使用 Emscripten 在 WebGL 中实现渲染。

源代码:
https://github.com/demensdeum/OpenGLES3-Experiments/tree/master/8-sdl-gles-obj-textured-assimp-miku
型号:
https://sketchfab.com/models/7310aaeb8370428e966bdcff414273e7

 

Leave a Comment

Your email address will not be published. Required fields are marked *