C++游戏引擎开发指南:使用OpenGL绘制三角形

C++游戏引擎开发指南:使用OpenGL绘制三角形

cpp-game-engine-book 从零编写游戏引擎教程 Writing a game engine tutorial from scratch cpp-game-engine-book 项目地址: https://gitcode.com/gh_mirrors/cp/cpp-game-engine-book

引言

在游戏引擎开发中,图形渲染是最基础也是最重要的功能之一。本文将基于一个C++游戏引擎项目,详细介绍如何使用OpenGL绘制一个彩色三角形。这个三角形绘制示例相当于图形编程界的"Hello World",是理解3D渲染管线的绝佳起点。

项目概述

本项目展示了一个完整的OpenGL三角形绘制流程,包含了从顶点数据定义到最终渲染的全部步骤。通过这个简单的例子,开发者可以学习到现代图形API的基本工作流程。

核心实现

1. 顶点数据定义

VertexData.h中,我们定义了三角形的三个顶点坐标和颜色:

static const glm::vec3 kPositions[3] = {
    glm::vec3{ -1.0f, -1.0f, 0.0f},  // 左下角顶点
    glm::vec3{  1.0f, -1.0f, 0.0f},  // 右下角顶点
    glm::vec3{   0.f,  1.0f, 0.0f}   // 顶部顶点
};

static const glm::vec4 kColors[3] = {
    glm::vec4{ 1.f, 0.f, 0.f ,1.f},  // 红色
    glm::vec4{ 0.f, 1.f, 0.f ,1.f},  // 绿色
    glm::vec4{ 0.f, 0.f, 1.f ,1.f}   // 蓝色
};

这里使用了GLM数学库中的向量类型来存储坐标和颜色数据。每个顶点包含:

  • 位置坐标(x,y,z)
  • 颜色值(r,g,b,a)

2. 着色器程序

着色器是运行在GPU上的小程序,控制图形渲染的不同阶段。在ShaderSource.h中定义了两个关键着色器:

顶点着色器
#version 110

uniform mat4 u_mvp;

attribute vec3 a_pos;
attribute vec4 a_color;

varying vec4 v_color;

void main()
{
    gl_Position = u_mvp * vec4(a_pos, 1.0);
    v_color = a_color;
}

顶点着色器的主要功能:

  1. 接收顶点位置(a_pos)和颜色(a_color)属性
  2. 应用模型-视图-投影矩阵(u_mvp)变换
  3. 将颜色数据传递给片段着色器
片段着色器
#version 110

varying vec4 v_color;

void main()
{
    gl_FragColor = v_color;
}

片段着色器简单地将插值后的颜色输出到屏幕。

3. 主程序流程

main.cpp中的主逻辑分为几个关键步骤:

3.1 OpenGL初始化
void init_opengl()
{
    // 初始化GLFW
    glfwSetErrorCallback(error_callback);
    if (!glfwInit()) exit(EXIT_FAILURE);

    // 设置OpenGL版本
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);

    // 创建窗口
    window = glfwCreateWindow(960, 640, "Triangle Example", NULL, NULL);
    if (!window) {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    // 设置当前上下文
    glfwMakeContextCurrent(window);
    gladLoadGL(glfwGetProcAddress);
    glfwSwapInterval(1);
}
3.2 着色器编译与链接
void compile_shader()
{
    // 顶点着色器
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
    glCompileShader(vertex_shader);

    // 片段着色器
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
    glCompileShader(fragment_shader);

    // 创建并链接程序
    program = glCreateProgram();
    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glLinkProgram(program);
}
3.3 渲染循环
while (!glfwWindowShouldClose(window))
{
    // 清除缓冲区
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glClearColor(49.f/255,77.f/255,121.f/255,1.f);

    // 坐标系变换
    glm::mat4 model = ...; // 模型变换
    glm::mat4 view = ...;  // 视图变换
    glm::mat4 projection = ...; // 投影变换
    glm::mat4 mvp = projection * view * model;

    // 使用着色器程序
    glUseProgram(program);
    {
        // 设置顶点属性
        glEnableVertexAttribArray(vpos_location);
        glVertexAttribPointer(vpos_location, 3, GL_FLOAT, false, sizeof(glm::vec3), kPositions);

        glEnableVertexAttribArray(vcol_location);
        glVertexAttribPointer(vcol_location, 3, GL_FLOAT, false, sizeof(glm::vec4), kColors);

        // 上传MVP矩阵
        glUniformMatrix4fv(mvp_location, 1, GL_FALSE, &mvp[0][0]);

        // 绘制三角形
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }

    // 交换缓冲区
    glfwSwapBuffers(window);
    glfwPollEvents();
}

关键概念解析

1. 坐标系变换

在3D图形编程中,我们需要通过一系列矩阵变换将物体从模型空间转换到屏幕空间:

  1. 模型变换:控制物体在场景中的位置、旋转和缩放
  2. 视图变换:模拟相机的位置和方向
  3. 投影变换:将3D坐标映射到2D屏幕

这些变换通过矩阵乘法组合成最终的MVP矩阵。

2. 顶点属性

顶点可以包含多种属性,如位置、颜色、纹理坐标等。在OpenGL中,我们需要:

  1. 启用顶点属性
  2. 指定属性数据的格式和位置
  3. 在着色器中声明对应的属性变量

3. 渲染管线

现代图形API的渲染流程大致如下:

  1. 顶点数据输入
  2. 顶点着色器处理
  3. 图元装配
  4. 光栅化
  5. 片段着色器处理
  6. 深度测试/混合等后期处理
  7. 写入帧缓冲区

扩展思考

  1. 性能优化:可以使用顶点缓冲对象(VBO)来提升渲染效率
  2. 着色器扩展:可以添加光照、纹理等效果
  3. 几何体扩展:可以绘制更复杂的多边形或3D模型

总结

通过这个简单的三角形绘制示例,我们学习了OpenGL渲染的基本流程,包括:

  • 顶点数据定义
  • 着色器编写与编译
  • 坐标系变换
  • 渲染循环实现

这是理解现代图形编程的重要第一步,为后续开发更复杂的渲染功能奠定了基础。

cpp-game-engine-book 从零编写游戏引擎教程 Writing a game engine tutorial from scratch cpp-game-engine-book 项目地址: https://gitcode.com/gh_mirrors/cp/cpp-game-engine-book

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

范垣楠Rhoda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值