前言
这篇做一些小优化,完善Renderer2D的API。
- 调整Run()方法的访问属性
- 纹理通过参数来控制缩放
- 支持创建旋转的矩形
代码优化
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();
}
如果运行正常,能看到下面
代码 & 总结
完整代码
总结
无