游戏引擎从零开始(33)-2D渲染器支持旋转

前言

这篇做一些小优化,完善Renderer2D的API。

  1. 调整Run()方法的访问属性
  2. 纹理通过参数来控制缩放
  3. 支持创建旋转的矩形

代码优化

Run()方法设成private属性

当前的代码Run()函数在public下,可以被随意访问,这是不安全的。

但放到private下,main()函数就不能访问了,怎么办?

对main函数增加友元属性。

Sandbox/Hazel/src/Hazel/Core/Application.h

c++ 复制代码
...
// 1. 声明一个全局的main函数
// 注意!这里必须声明
int main(int argc, char** argv);

namespace Hazel{
class Application {
private:
    // 2. 优化,将Run()函数放到private下,不对外公开暴露
    void Run();

private:
    static Application* s_Instance;
    // 3. main通过friend的形式调用Run();
    friend int ::main(int argc, char** argv);
    ...
}

Renderer2D接口拓展&支持纹理缩放

用一个uniform代替之前写死的值,便于在代码里控制:

Sandbox/assets/shaders/Texture.glsl

c++ 复制代码
...
#type fragment
#version 330 core
layout(location = 0) out vec4 color;
in vec2 v_TexCoord;

uniform vec4 u_Color;
uniform float u_TilingFactor;
uniform sampler2D u_Texture;

void main()
{
	color = texture(u_Texture, v_TexCoord * u_TilingFactor) * u_Color;
}

shader里增加更新float的方法

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

c++ 复制代码
virtual void SetFloat(const std::string &name, const float value) = 0;

Sandbox/Hazel/src/Hazel/Platform/OpenGL/OpenGLShader.h

c++ 复制代码
void SetFloat(const std::string &name, const float value) override;

Sandbox/Hazel/src/Hazel/Platform/OpenGL/OpenGLShader.cpp

c++ 复制代码
void OpenGLShader::SetFloat(const std::string &name, const float value) {
    HZ_PROFILE_FUNCTION();
    UploadUniformFloat(name, value);
}

Renderer2D也一起更新接口,增加纹理缩放因子,支持旋转,整体有两组API,一组不带旋转,一组代旋转参数,其实也可以合并到一起:

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

c++ 复制代码
namespace Hazel {
    class Renderer2D {
    public:
        static void Init();
        static void Shutdown();
        static void BeginScene(const OrthographicCamera& camera);
        static void EndScene();
        // Primitives
        static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color);
        static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color);
        static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D>& texture,
                             float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
        static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture2D>& texture,
                             float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));

        static void DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color);
        static void DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color);
        static void DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture,float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
        static void DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture,float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
    };

}

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

c++ 复制代码
void Renderer2D::DrawQuad(const glm::vec2 &position, const glm::vec2 &size, const glm::vec4 &color) {
    DrawQuad({position.x, position.y, 0.0f}, size, color);
}
void Renderer2D::DrawQuad(const glm::vec3 &position, const glm::vec2 &size, const glm::vec4 &color) {
    HZ_PROFILE_FUNCTION();

    s_Data->TextureShader->SetFloat4("u_Color", color);
    s_Data->TextureShader->SetFloat("u_TilingFactor", 1.0f);
    s_Data->WhiteTexture->Bind();
    glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0), {size.x, size.y, 1.0f});
    s_Data->TextureShader->SetMat4("u_Transform", transform);
    s_Data->QuadVertexArray->Bind();
    RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
}

void Renderer2D::DrawQuad(const glm::vec2 &position, const glm::vec2 &size, const Ref<Texture2D> &texture, float tilingFactor, const glm::vec4& tintColor) {
    DrawQuad({position.x, position.y, 0.f}, size, texture, tilingFactor, tintColor);
}

void Renderer2D::DrawQuad(const glm::vec3 &position, const glm::vec2 &size, const Ref<Texture2D> &texture, float tilingFactor, const glm::vec4& tintColor) {
    HZ_PROFILE_FUNCTION();

    s_Data->TextureShader->Bind();
    s_Data->TextureShader->SetFloat4("u_Color", glm::vec4(1.0f));
    s_Data->TextureShader->SetFloat("u_TilingFactor", tilingFactor);
    texture->Bind();

    glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0), {size.x, size.y, 1.0f});
    s_Data->TextureShader->SetMat4("u_Transform", transform);

    s_Data->QuadVertexArray->Bind();
    RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
}

void Renderer2D::DrawRotatedQuad(const glm::vec2 &position, const glm::vec2 &size, float rotation,
                                 const glm::vec4 &color) {
    DrawRotatedQuad({position.x, position.y, 0.0f}, size, rotation, color);
}

void Renderer2D::DrawRotatedQuad(const glm::vec3 &position, const glm::vec2 &size, float rotation,
                                 const glm::vec4 &color) {
    HZ_PROFILE_FUNCTION();

    s_Data->TextureShader->SetFloat4("u_Color", color);
    s_Data->TextureShader->SetFloat("u_TilingFactor", 1.0f);
    s_Data->WhiteTexture->Bind();

    glm::mat4 transform = glm::translate(glm::mat4(1.0f), position)
            * glm::rotate(glm::mat4(1.0), rotation, {0.0f, 0.0f, 1.0f})
            * glm::scale(glm::mat4(1.0f), {size.x, size.y, 1.0f});
    s_Data->TextureShader->SetMat4("u_Transform", transform);
    RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
}

void Renderer2D::DrawRotatedQuad(const glm::vec2 &position, const glm::vec2 &size, float rotation,
                                 const Ref<Texture2D> &texture, float tilingFactor, const glm::vec4 &tintColor) {
    DrawRotatedQuad({position.x, position.y, 0.0f}, size, rotation, texture, tilingFactor, tintColor);
}

void Renderer2D::DrawRotatedQuad(const glm::vec3 &position, const glm::vec2 &size, float rotation,
                                 const Ref<Texture2D> &texture, float tilingFactor, const glm::vec4 &tintColor) {
    HZ_PROFILE_FUNCTION();

    s_Data->TextureShader->SetFloat4("u_Color", tintColor);
    s_Data->TextureShader->SetFloat("u_TilingFactor", tilingFactor);
    texture->Bind();

    glm::mat4 transform = glm::translate(glm::mat4(1.0f), position)
            * glm::rotate(glm::mat4(1.0f), rotation, {0.0f, 0.0f, 1.0f})
            * glm::scale(glm::mat4(1.0f), {size.x, size.y, 1.0f});

    s_Data->TextureShader->SetMat4("u_Transform", transform);
    s_Data->QuadVertexArray->Bind();
}

更新Sandbox2D

Sandbox/src/Sandbox2D.cpp

c++ 复制代码
{
    HZ_PROFILE_SCOPE("Renderer Draw");
    Hazel::Renderer2D::BeginScene(m_CameraController.GetCamera());
    Hazel::Renderer2D::DrawRotatedQuad({-1.0f, 0.0f}, {0.8f, 0.8f}, glm::radians(-45.0f), {0.8f, 0.2f, 0.3f, 1.0f});
    Hazel::Renderer2D::DrawQuad({0.5f, -0.5f}, {0.5f, 0.5f}, {0.2f, 0.3f, 0.8f, 1.0f});
    Hazel::Renderer2D::DrawQuad({0.0f, 0.0f, -0.1f}, {5.f, 5.f}, m_CheckerboardTexture, 10.0f);
    Hazel::Renderer2D::EndScene();
}

如果运行正常,能看到下面

代码 & 总结

完整代码

github.com/summer-go/H...

总结

相关推荐
一名用户4 小时前
unity实现自定义粒子系统
c#·unity3d·游戏开发
技术小甜甜2 天前
【Blender Texture】【游戏开发】高质感 Blender 4K 材质资源推荐合集 —— 提升场景真实感与美术表现力
blender·游戏开发·材质·texture
Thomas游戏开发2 天前
Unity3D TextMeshPro终极使用指南
前端·unity3d·游戏开发
Thomas游戏开发3 天前
Unity3D 逻辑代码性能优化策略
前端框架·unity3d·游戏开发
byxdaz4 天前
Qt OpenGL 3D 编程入门
qt·opengl
Thomas游戏开发4 天前
Unity3D HUD高性能优化方案
前端框架·unity3d·游戏开发
陈哥聊测试5 天前
游戏公司如何同时管好上百个游戏项目?
游戏·程序员·游戏开发
byxdaz6 天前
Qt OpenGL 相机实现
opengl
一名用户6 天前
unity随机生成未知符号教程
c#·unity3d·游戏开发
Be_Somebody11 天前
计算机图形学——Games101深度解析_第二章
游戏开发·计算机图形学·games101