游戏引擎从零开始(21)-移动物体

移动物体

物体在空间中的坐标变换简称mvp(model、view、projection),前面两章讲了vp,这章补上model变换。

目标是通过移动矩形坐标,复制出一个蓝色的棋盘图案,如下图所示:

拓展Renderer接口

在当前代码的基础上,稍作调整,就能实现棋盘效果。

拓展Renderer接口

Renderer->Submit接口增加移动的transform矩阵,在实现里将transform矩阵设置到shader中

Sandbox/Hazel/src/Hazel/Renderer/Renderer.h

c++ 复制代码
static void Submit(const std::shared_ptr<Shader>& shader, const std::shared_ptr<VertexArray>& vertexArray,
                   const glm::mat4& transform = glm::mat4(1.0f));

Sandbox/Hazel/src/Hazel/Renderer/Renderer.cpp

c++ 复制代码
void Renderer::Submit(const std::shared_ptr<Shader>& shader, const std::shared_ptr<VertexArray> &vertexArray, const glm::mat4& transform) {
    shader->Bind();
    shader->UploadUniformMat4("u_ViewProjection", s_SceneData->ViewProjectionMatrix);
    shader->UploadUniformMat4("u_Transform", transform);
    vertexArray->Bind();
    RenderCommand::DrawIndexed(vertexArray);
}

绘制棋盘

修改ExampleLayer中的demo,将之前的矩形背景缩小到0.1,然后在for循环中生成10 * 10的方格矩阵。

Sandbox/src/SandBoxApp.cpp

c++ 复制代码
...
// -----------------矩形--------------------
// 注意矩形,顶点按照逆时针排列
float squareVertices[3*4] = {
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f,
        0.5f, 0.5f, 0.0f,
        -0.5f, 0.5f, 0.0f
};

...

// 拓展vertexSrc,增加u_Transform字段,
// 乘到a_Position左边,这就是标准的mvp变换矩阵
std::string vertexSrc = R"(
    #version 330 core
    ...
    out vec3 v_Position;
    out vec4 v_Color;
    void main()
    {
        v_Position = a_Position;
        v_Color = a_Color;
        gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);
    }
)";

...

std::string blueShaderVertexSrc = R"(
    #version 330 core
    layout(location = 0) in vec3 a_Position;
    uniform mat4 u_ViewProjection;
    uniform mat4 u_Transform;
    out vec3 v_Position;
    void main() {
        v_Position = a_Position;
        gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);
    }
)";

绘制棋盘

c++ 复制代码
...
Hazel::Renderer::BeginScene(m_Camera);

static glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
for (int y = 0; y < 20; y++) {
    for (int x = 0; x < 20; x++) {
        glm::vec3 pos(x * 0.11f, y * 0.11f, 0.0f);
        glm::mat4 transfrom = glm::translate(glm::mat4(1.0f), pos) * scale;
        Hazel::Renderer::Submit(m_BlueShader, m_SquareVA, transfrom);
    }
}

//        Hazel::Renderer::Submit(m_BlueShader,m_SquareVA);
Hazel::Renderer::Submit(m_Shader, m_VertexArray);

Hazel::Renderer::EndScene();
...

完整代码 & 总结

完整代码:
github.com/summer-go/H...

得益于前面花了很多时间做基础的能力建设,对渲染API做了合理的封装,现在绘制一个棋盘,只需要一个for循环即可。

当前的代码离完整的引擎还有很远的距离,但是已经有引擎的雏形了。

相关推荐
大白的编程日记.27 分钟前
【计算机基础理论知识】C++篇(二)
开发语言·c++·学习
C语言小火车33 分钟前
野指针:C/C++内存管理的“幽灵陷阱”与系统化规避策略
c语言·c++·学习·指针
凤年徐42 分钟前
【数据结构】时间复杂度和空间复杂度
c语言·数据结构·c++·笔记·算法
踏莎行hyx1 小时前
使用langchain连接llama.cpp部署的本地deepseek大模型开发简单的LLM应用
c++·ai·langchain·大模型·llama.cpp·deepseek
山河木马1 小时前
前端学C++可太简单了:双冒号 :: 操作符
前端·javascript·c++
乌萨奇也要立志学C++2 小时前
【C++详解】STL-list模拟实现(深度剖析list迭代器,类模板未实例化取嵌套类型问题)
c++·list
闻缺陷则喜何志丹2 小时前
【前缀和 BFS 并集查找】P3127 [USACO15OPEN] Trapped in the Haybales G|省选-
数据结构·c++·前缀和·宽度优先·洛谷·并集查找
序属秋秋秋4 小时前
《C++初阶之内存管理》【内存分布 + operator new/delete + 定位new】
开发语言·c++·笔记·学习
十秒耿直拆包选手11 小时前
Qt:主窗体(QMainwindow)初始化注意事项
c++·qt
霖0013 小时前
C++学习笔记三
运维·开发语言·c++·笔记·学习·fpga开发