• HazelEngine 学习记录 - 2D Renderer Transforms and 2D Renderer Textures


    2D Renderer Transforms and 2D Renderer Textures

    在2D renderer 中,我们渲染的图元基本上全是矩形,加载纹理时,也是将对应的纹理贴到一个矩形内,本节就是实现了纹理在 2D renderer 中的加载以及进行了 shader 中 uniform 的设置从而控制图形的变换操作。

    由于我们之前没有给 shader.cpp 中添加设置 uniform 的接口,之前对 uniform 的设置是通过强制转换为 OpenGLShader 指针之后再进行的设置:

    std::dynamic_pointer_cast<OpenGLShader>(s_Data->FlatColorShader)->Bind();
    		std::dynamic_pointer_cast<OpenGLShader>(s_Data->FlatColorShader)->UploadUniformMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
    		std::dynamic_pointer_cast<OpenGLShader>(s_Data->FlatColorShader)->UploadUniformMat4("u_Transform", glm::mat4(1.0f));
    
    • 1
    • 2
    • 3

    所以在 shader 中添加对应的接口:

    		virtual void SetInt(const std::string& name, int value) = 0;
    		virtual void SetFloat3(const std::string& name, const glm::vec3& value) = 0;
    		virtual void SetFloat4(const std::string& name, const glm::vec4& value) = 0;
    		virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0;
    
    • 1
    • 2
    • 3
    • 4

    在 OpenGLShader 中实现:

    	void OpenGLShader::SetInt(const std::string& name, int value)
    	{
    		UploadUniformInt(name, value);
    	}
    
    	void OpenGLShader::SetFloat3(const std::string& name, const glm::vec3& value)
    	{
    		UploadUniformFloat3(name, value);
    	}
    
    	void OpenGLShader::SetFloat4(const std::string& name, const glm::vec4& value)
    	{
    		UploadUniformFloat4(name, value);
    	}
    
    	void OpenGLShader::SetMat4(const std::string& name, const glm::mat4& value)
    	{
    		UploadUniformMat4(name, value);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    然后之前用转换之后的指针进行设置 uniform 的代码可以换掉了:(这里添加了一个 Texture shader 用于 texture 加载)

    		s_Data->FlatColorShader->Bind();
    		s_Data->FlatColorShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
    
    		s_Data->TextureShader->Bind();
    		s_Data->TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    DrawQuad 函数中的也可以替换掉了,并且添加了 transform:

    void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color)
    	{
    		s_Data->FlatColorShader->Bind();
    		s_Data->FlatColorShader->SetFloat4("u_Color", color);
    
    		glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
    		s_Data->FlatColorShader->SetMat4("u_Transform", transform);
    
    		s_Data->QuadVertexArray->Bind();
    		RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后我们添加了用于绘制 texture 的 DrawQuad 函数:

    void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D>& texture)
    	{
    		DrawQuad({ position.x, position.y, 0.0f }, size, texture);
    	}
    
    	void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture2D>& texture)
    	{
    		s_Data->TextureShader->Bind();
    
    		glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
    		s_Data->TextureShader->SetMat4("u_Transform", transform);
    
    		texture->Bind();
    
    		s_Data->QuadVertexArray->Bind();
    		RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    然后进行测试,首先创建成员变量 m_CheckerboardTexture ,然后在 SandBox::OnAttach 函数中进行加载:

    	m_CheckerboardTexture = Hazel::Texture2D::Create("assets/textures/Checkerboard.png");
    
    • 1

    添加纹理坐标,然后添加布局和进行 texture 绑定:

    float squareVertices[5 * 4] = {
    			-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
    			 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
    			 0.5f,  0.5f, 0.0f, 1.0f, 1.0f,
    			-0.5f,  0.5f, 0.0f, 0.0f, 1.0f
    		};
    
    squareVB->SetLayout({
    			{ ShaderDataType::Float3, "a_Position" },
    			{ ShaderDataType::Float2, "a_TexCoord" }
    		});
    
    s_Data->TextureShader = Shader::Create("assets/shaders/Texture.glsl");
    		s_Data->TextureShader->Bind();
    		s_Data->TextureShader->SetInt("u_Texture", 0);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    绘制了三个矩形进行测试,其中一个使用纹理:

    	Hazel::Renderer2D::BeginScene(m_CameraController.GetCamera());
    	Hazel::Renderer2D::DrawQuad({ -1.0f, 0.0f }, { 0.8f, 0.8f }, { 0.8f, 0.2f, 0.3f, 1.0f });
    	Hazel::Renderer2D::DrawQuad({ 0.5f, -0.5f }, { 0.5f, 0.75f }, { 0.2f, 0.3f, 0.8f, 1.0f });
    	Hazel::Renderer2D::DrawQuad({ 0.0f, 0.0f, -0.1f }, { 10.0f, 10.0f }, m_CheckerboardTexture);
    	Hazel::Renderer2D::EndScene();
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后为了让 texture 显示在最底层,我们设置了其 z轴坐标为 -0.1,为了使设置生效,需要打开 OpenGL 的深度测试:

    //OpenGLRenderAPI::Init()
    glEnable(GL_DEPTH_TEST);
    
    • 1
    • 2

    之后运行,正常显示结果:

    在这里插入图片描述

  • 相关阅读:
    python控制负数以16进制整型格式输出
    2023年整理的自动化测试面试题及答案
    Vue结合Jquery 实现网页端数字键盘
    【PAT甲级】1077 Kuchiguse
    10.DesignForSymbols\CreatePad...
    SpringBoot整合Shiro(仅测试认证)
    java:逆序排序的三种方法
    阿里云轻量应用服务器流量价格表(计费/免费说明)
    【正点原子I.MX6U-MINI应用篇】8、嵌入式Linux网络通信socket编程
    golang监听rabbitmq消息队列任务断线自动重连接
  • 原文地址:https://blog.csdn.net/miyazono_/article/details/127838068