返回

OpenGL学习之路:第11章 - GLSL 顶点/片段着色器绘制纹理立方体

IOS

GLSL 顶点/片段着色器绘制纹理立方体:开启 3D 图形的新篇章

简介

在上一章中,我们探索了 OpenGL 的基本光照和材质技术,绘制了一个带有光照效果的 3D 场景。在这个激动人心的旅程中,我们将更深入地研究 OpenGL 的着色语言 (GLSL),重点关注如何使用 GLSL 顶点和片段着色器绘制一个带纹理的立方体。准备好踏上探索 3D 图形的新篇章了吗?

环境设置:搭建舞台

创建窗口和上下文

就像任何舞台剧一样,我们的 3D 场景也需要一个窗口和一个上下文。在这里,我们将遵循上章中的步骤来创建这个基础。

加载着色器程序:定义规则

接下来,我们需要加载并创建着色器程序,它定义了将 3D 场景转化为屏幕像素的规则。我们将使用一个顶点着色器和一个片段着色器,分别负责处理顶点位置和纹理信息。

顶点着色器:

attribute vec3 aPos; // 顶点位置
attribute vec2 aTexCoords; // 纹理坐标
varying vec2 vTexCoords; // 片段着色器中使用的纹理坐标

void main() {
    gl_Position = vec4(aPos, 1.0f); // 设置顶点位置
    vTexCoords = aTexCoords; // 传递纹理坐标
}

片段着色器:

varying vec2 vTexCoords; // 从顶点着色器接收纹理坐标
uniform int texture_diffuse1; // 扩散纹理(我们的图片)

void main() {
    gl_FragColor = texture2D(texture_diffuse1, vTexCoords); // 根据纹理坐标设置片段颜色
}

启用顶点和纹理数据:连接组件

有了着色器程序后,我们需要启用顶点和纹理数据,就像连接舞台上的所有组件一样。

准备数据:搭建场景

顶点数据:立方体的形状

为了绘制一个立方体,我们需要一个包含顶点位置和纹理坐标的顶点缓冲对象 (VBO)。以下是立方体顶点的详细信息:

float cube_vertex[] = {
    // 位置                   纹理
    // 前面
    -0.5f, -0.5f, 0.5f,  0.0f, 0.0f,
     0.5f, -0.5f, 0.5f,  1.0f, 0.0f,
     0.5f,  0.5f, 0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f, 0.5f,  0.0f, 1.0f,

    // 后面
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
     0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,

    // 上面
    -0.5f,  0.5f, 0.5f,  0.0f, 0.0f,
     0.5f,  0.5f, 0.5f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,

    // 下面
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
     0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
     0.5f, -0.5f, 0.5f,  1.0f, 1.0f,
    -0.5f, -0.5f, 0.5f,  0.0f, 1.0f,

    // 右面
    0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
    0.5f,  0.5f, -0.5f,  1.0f, 0.0f,
    0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
    0.5f, -0.5f,  0.5f,  0.0f, 1.0f,

    //  left
    -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
};

缓冲对象:存储顶点

现在,我们需要创建一个 VBO 并将顶点数据复制到缓冲区中,就像将道具放到舞台后面一样。

准备纹理:添加色彩

就像给舞台增添色彩一样,我们需要加载纹理图片并创建一个纹理对象,给我们的立方体增添一些生机。

3D 转换:定位相机

最后,我们需要设置 3D 转换矩阵,就像设置舞台上的聚光灯一样。这将帮助我们确定相机的角度和位置。

绘制立方体:让表演开始

经过精心准备,现在是时候让我们的立方体在舞台上闪耀了。我们将通过以下步骤来绘制它:

  1. 绑定纹理
  2. 激活着色器程序
  3. 设置统一变量
  4. 绑定顶点数组对象 (VAO)
  5. 绘制立方体

常见问题解答

  1. 为什么我的立方体是黑色的?

    • 确保已启用纹理映射并已正确加载和绑定纹理。
  2. 为什么我的立方体变形了?

    • 检查顶点数据是否正确,并且顶点着色器正确地设置了位置。
  3. 如何更改立方体的纹理?

    • 重新加载纹理图片并更新纹理对象,然后重新绑定它。
  4. 如何让立方体旋转?

    • 在渲染循环中更新模型矩阵,以旋转立方体。
  5. 我可以使用键盘或鼠标控制立方体吗?

    • 通过添加用户输入处理程序来监听键盘或鼠标事件,并相应地更新立方体的转换。

结论

恭喜!你已经掌握了使用 GLSL 顶点和片段着色器绘制纹理立方体的艺术。通过这个过程,你不仅深入了解了 3D 图形,还提高了编程技能。现在,你可以放飞你的想象力,创造出更复杂、更引人入胜的 3D 场景。继续探索 OpenGL 的世界,发挥你的创造力,让你的 3D 世界栩栩如生!