Improve 2D Rendering
本节主要是给Renderer2D中添加一些其他的API来让其功能更加丰富,首先为了能够在shader中进行Float的设置,先在shader.h
中添加了如下API:
virtual void SetFloat(const std::string& name, float value) = 0;
然后在OpenGLShader中实现:
//OpenGLShader.h
virtual void SetFloat(const std::string& name, float value) override;
//OpenGL Shader.cpp
void OpenGLShader::SetFloat(const std::string& name, float value)
{
HZ_PROFILE_FUNCTION();
UpLoadUniformFloat(name, value);
}
void OpenGLShader::UpLoadUniformFloat(const std::string& name, float value)
{
GLint location = glGetUniformLocation(m_RendererID, name.c_str());
glUniform1f(location, value);
}
现在可以通过SetFloat
函数来实现全局变量Float的设置了。
本节中,添加了用于绘制旋转矩形的函数,分别给出了绘制Texture版本和Color版本:
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<Texture>& 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<Texture>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
绘制带纹理的矩形这部分还添加了两个参数 tilingFactor和tintColor分别用于控制纹理坐标的缩放比例和默认没有纹理时候输出的颜色。具体函数实现如下:
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);
//Bind white texture here
s_Data->WhiteTexture->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();
RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
}
void Renderer2D::DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<Texture>& texture, float tilingFactor, const glm::vec4& tintColor)
{
DrawRotatedQuad({ position.x, position.y, 0.0f }, size, rotation, texture, tilingFactor);
}
void Renderer2D::DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const Ref<Texture>& 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);
texture->Bind();
s_Data->QuadVertexArray->Bind();
RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
}
同样的,给之前的DrawQuad
函数也添加进这两个默认参数:
static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture>& 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<Texture>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture>& texture, float tilingFactor, const glm::vec4& tintColor)
{
DrawQuad({ position.x, position.y, 0.0f }, size, texture, tilingFactor);
}
void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture>& 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::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);
}
shader中添加tilingFactor进行控制:
uniform float u_TilingFactor;
void main()
{
color = texture(u_Texture, v_TexCoord * u_TilingFactor) * u_Color;
}
画两个旋转后的矩形测试一下
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.75f }, { m_FlatColor, 1.0f });
Hazel::Renderer2D::DrawQuad({ 0.2f, 0.5f, -0.1f }, { 10.f, 10.f }, m_Texture, 10.0f, glm::vec4(1.0f, 0.9f, 0.9f, 1.0f));
Hazel::Renderer2D::EndScene();