Skip to content

Commit

Permalink
Added TextComponent with some more text params
Browse files Browse the repository at this point in the history
- Also fixed BoxColliders not rendering correctly with physics visualization turned on when offsets were used (thanks VagueLobster for the fix)
  • Loading branch information
TheCherno committed Feb 27, 2023
1 parent d32b9a2 commit be419f6
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 105 deletions.
4 changes: 3 additions & 1 deletion Hazel/src/Hazel/ImGui/ImGuiBuild.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "hzpch.h"

#include <misc/cpp/imgui_stdlib.cpp>

#define IMGUI_IMPL_OPENGL_LOADER_GLAD
#include <examples/imgui_impl_opengl3.cpp>
#include <examples/imgui_impl_glfw.cpp>
#include <examples/imgui_impl_glfw.cpp>
57 changes: 41 additions & 16 deletions Hazel/src/Hazel/Renderer/Renderer2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ namespace Hazel {
DrawQuad(transform, src.Color, entityID);
}

void Renderer2D::DrawString(const std::string& string, Ref<Font> font, const glm::mat4& transform, const glm::vec4& color)
void Renderer2D::DrawString(const std::string& string, Ref<Font> font, const glm::mat4& transform, const TextParams& textParams, int entityID)
{
const auto& fontGeometry = font->GetMSDFData()->FontGeometry;
const auto& metrics = fontGeometry.getMetrics();
Expand All @@ -561,7 +561,8 @@ namespace Hazel {
double x = 0.0;
double fsScale = 1.0 / (metrics.ascenderY - metrics.descenderY);
double y = 0.0;
float lineHeightOffset = 0.0f;

const float spaceGlyphAdvance = fontGeometry.getGlyph(' ')->getAdvance();

for (size_t i = 0; i < string.size(); i++)
{
Expand All @@ -572,18 +573,38 @@ namespace Hazel {
if (character == '\n')
{
x = 0;
y -= fsScale * metrics.lineHeight + lineHeightOffset;
y -= fsScale * metrics.lineHeight + textParams.LineSpacing;
continue;
}

if (character == ' ')
{
float advance = spaceGlyphAdvance;
if (i < string.size() - 1)
{
char nextCharacter = string[i + 1];
double dAdvance;
fontGeometry.getAdvance(dAdvance, character, nextCharacter);
advance = (float)dAdvance;
}

x += fsScale * advance + textParams.Kerning;
continue;
}

if (character == '\t')
{
// NOTE(Yan): is this right?
x += 4.0f * (fsScale * spaceGlyphAdvance + textParams.Kerning);
continue;
}

auto glyph = fontGeometry.getGlyph(character);
if (!glyph)
glyph = fontGeometry.getGlyph('?');
if (!glyph)
return;

if (character == '\t')
glyph = fontGeometry.getGlyph(' ');

double al, ab, ar, at;
glyph->getQuadAtlasBounds(al, ab, ar, at);
glm::vec2 texCoordMin((float)al, (float)ab);
Expand All @@ -605,27 +626,27 @@ namespace Hazel {

// render here
s_Data.TextVertexBufferPtr->Position = transform * glm::vec4(quadMin, 0.0f, 1.0f);
s_Data.TextVertexBufferPtr->Color = color;
s_Data.TextVertexBufferPtr->Color = textParams.Color;
s_Data.TextVertexBufferPtr->TexCoord = texCoordMin;
s_Data.TextVertexBufferPtr->EntityID = 0; // TODO
s_Data.TextVertexBufferPtr->EntityID = entityID;
s_Data.TextVertexBufferPtr++;

s_Data.TextVertexBufferPtr->Position = transform * glm::vec4(quadMin.x, quadMax.y, 0.0f, 1.0f);
s_Data.TextVertexBufferPtr->Color = color;
s_Data.TextVertexBufferPtr->Color = textParams.Color;
s_Data.TextVertexBufferPtr->TexCoord = { texCoordMin.x, texCoordMax.y };
s_Data.TextVertexBufferPtr->EntityID = 0; // TODO
s_Data.TextVertexBufferPtr->EntityID = entityID;
s_Data.TextVertexBufferPtr++;

s_Data.TextVertexBufferPtr->Position = transform * glm::vec4(quadMax, 0.0f, 1.0f);
s_Data.TextVertexBufferPtr->Color = color;
s_Data.TextVertexBufferPtr->Color = textParams.Color;
s_Data.TextVertexBufferPtr->TexCoord = texCoordMax;
s_Data.TextVertexBufferPtr->EntityID = 0; // TODO
s_Data.TextVertexBufferPtr->EntityID = entityID;
s_Data.TextVertexBufferPtr++;

s_Data.TextVertexBufferPtr->Position = transform * glm::vec4(quadMax.x, quadMin.y, 0.0f, 1.0f);
s_Data.TextVertexBufferPtr->Color = color;
s_Data.TextVertexBufferPtr->Color = textParams.Color;
s_Data.TextVertexBufferPtr->TexCoord = { texCoordMax.x, texCoordMin.y };
s_Data.TextVertexBufferPtr->EntityID = 0; // TODO
s_Data.TextVertexBufferPtr->EntityID = entityID;
s_Data.TextVertexBufferPtr++;

s_Data.TextIndexCount += 6;
Expand All @@ -637,12 +658,16 @@ namespace Hazel {
char nextCharacter = string[i + 1];
fontGeometry.getAdvance(advance, character, nextCharacter);

float kerningOffset = 0.0f;
x += fsScale * advance + kerningOffset;
x += fsScale * advance + textParams.Kerning;
}
}
}

void Renderer2D::DrawString(const std::string& string, const glm::mat4& transform, const TextComponent& component, int entityID)
{
DrawString(string, component.FontAsset, transform, { component.Color, component.Kerning, component.LineSpacing }, entityID);
}

float Renderer2D::GetLineWidth()
{
return s_Data.LineWidth;
Expand Down
9 changes: 8 additions & 1 deletion Hazel/src/Hazel/Renderer/Renderer2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ namespace Hazel {

static void DrawSprite(const glm::mat4& transform, SpriteRendererComponent& src, int entityID);

static void DrawString(const std::string& string, Ref<Font> font, const glm::mat4& transform, const glm::vec4& color);
struct TextParams
{
glm::vec4 Color{ 1.0f };
float Kerning = 0.0f;
float LineSpacing = 0.0f;
};
static void DrawString(const std::string& string, Ref<Font> font, const glm::mat4& transform, const TextParams& textParams, int entityID = -1);
static void DrawString(const std::string& string, const glm::mat4& transform, const TextComponent& component, int entityID = -1);

static float GetLineWidth();
static void SetLineWidth(float width);
Expand Down
12 changes: 11 additions & 1 deletion Hazel/src/Hazel/Scene/Components.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "SceneCamera.h"
#include "Hazel/Core/UUID.h"
#include "Hazel/Renderer/Texture.h"
#include "Hazel/Renderer/Font.h"

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
Expand Down Expand Up @@ -160,6 +161,15 @@ namespace Hazel {
CircleCollider2DComponent(const CircleCollider2DComponent&) = default;
};

struct TextComponent
{
std::string TextString;
Ref<Font> FontAsset = Font::GetDefault();
glm::vec4 Color{ 1.0f };
float Kerning = 0.0f;
float LineSpacing = 0.0f;
};

template<typename... Component>
struct ComponentGroup
{
Expand All @@ -169,6 +179,6 @@ namespace Hazel {
ComponentGroup<TransformComponent, SpriteRendererComponent,
CircleRendererComponent, CameraComponent, ScriptComponent,
NativeScriptComponent, Rigidbody2DComponent, BoxCollider2DComponent,
CircleCollider2DComponent>;
CircleCollider2DComponent, TextComponent>;

}
110 changes: 26 additions & 84 deletions Hazel/src/Hazel/Scene/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,17 @@ namespace Hazel {
}
}

// Draw text
{
auto view = m_Registry.view<TransformComponent, TextComponent>();
for (auto entity : view)
{
auto [transform, text] = view.get<TransformComponent, TextComponent>(entity);

Renderer2D::DrawString(text.TextString, transform.GetTransform(), text, (int)entity);
}
}

Renderer2D::EndScene();
}

Expand Down Expand Up @@ -386,7 +397,7 @@ namespace Hazel {
auto& bc2d = entity.GetComponent<BoxCollider2DComponent>();

b2PolygonShape boxShape;
boxShape.SetAsBox(bc2d.Size.x * transform.Scale.x, bc2d.Size.y * transform.Scale.y);
boxShape.SetAsBox(bc2d.Size.x * transform.Scale.x, bc2d.Size.y * transform.Scale.y, b2Vec2(bc2d.Offset.x, bc2d.Offset.y), 0.0f);

b2FixtureDef fixtureDef;
fixtureDef.shape = &boxShape;
Expand Down Expand Up @@ -448,90 +459,16 @@ namespace Hazel {
}
}

Renderer2D::DrawString("Cherno", Font::GetDefault(), glm::mat4(1.0f), glm::vec4(1.0f));
Renderer2D::DrawString(
R"(
// MSDF text shader
#type vertex
#version 450 core
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec4 a_Color;
layout(location = 2) in vec2 a_TexCoord;
layout(location = 3) in int a_EntityID;
layout(std140, binding = 0) uniform Camera
{
mat4 u_ViewProjection;
};
struct VertexOutput
{
vec4 Color;
vec2 TexCoord;
};
layout (location = 0) out VertexOutput Output;
layout (location = 2) out flat int v_EntityID;
void main()
{
Output.Color = a_Color;
Output.TexCoord = a_TexCoord;
v_EntityID = a_EntityID;
gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
}
#type fragment
#version 450 core
layout(location = 0) out vec4 o_Color;
layout(location = 1) out int o_EntityID;
struct VertexOutput
{
vec4 Color;
vec2 TexCoord;
};
layout (location = 0) in VertexOutput Input;
layout (location = 2) in flat int v_EntityID;
layout (binding = 0) uniform sampler2D u_FontAtlas;
float screenPxRange() {
const float pxRange = 2.0; // set to distance field's pixel range
vec2 unitRange = vec2(pxRange)/vec2(textureSize(u_FontAtlas, 0));
vec2 screenTexSize = vec2(1.0)/fwidth(Input.TexCoord);
return max(0.5*dot(unitRange, screenTexSize), 1.0);
}
float median(float r, float g, float b) {
return max(min(r, g), min(max(r, g), b));
}
// Draw text
{
auto view = m_Registry.view<TransformComponent, TextComponent>();
for (auto entity : view)
{
auto [transform, text] = view.get<TransformComponent, TextComponent>(entity);

void main()
{
vec4 texColor = Input.Color * texture(u_FontAtlas, Input.TexCoord);
vec3 msd = texture(u_FontAtlas, Input.TexCoord).rgb;
float sd = median(msd.r, msd.g, msd.b);
float screenPxDistance = screenPxRange()*(sd - 0.5);
float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0);
if (opacity == 0.0)
discard;
vec4 bgColor = vec4(0.0);
o_Color = mix(bgColor, Input.Color, opacity);
if (o_Color.a == 0.0)
discard;
o_EntityID = v_EntityID;
}
)"
, Font::GetDefault(), glm::mat4(1.0f), glm::vec4(1.0f));
Renderer2D::DrawString(text.TextString, transform.GetTransform(), text, (int)entity);
}
}

Renderer2D::EndScene();
}
Expand Down Expand Up @@ -599,4 +536,9 @@ void main()
{
}

template<>
void Scene::OnComponentAdded<TextComponent>(Entity entity, TextComponent& component)
{
}

}
26 changes: 26 additions & 0 deletions Hazel/src/Hazel/Scene/SceneSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,21 @@ namespace Hazel {
out << YAML::EndMap; // CircleCollider2DComponent
}

if (entity.HasComponent<TextComponent>())
{
out << YAML::Key << "TextComponent";
out << YAML::BeginMap; // TextComponent

auto& textComponent = entity.GetComponent<TextComponent>();
out << YAML::Key << "TextString" << YAML::Value << textComponent.TextString;
// TODO: textComponent.FontAsset
out << YAML::Key << "Color" << YAML::Value << textComponent.Color;
out << YAML::Key << "Kerning" << YAML::Value << textComponent.Kerning;
out << YAML::Key << "LineSpacing" << YAML::Value << textComponent.LineSpacing;

out << YAML::EndMap; // TextComponent
}

out << YAML::EndMap; // Entity
}

Expand Down Expand Up @@ -562,6 +577,17 @@ namespace Hazel {
cc2d.Restitution = circleCollider2DComponent["Restitution"].as<float>();
cc2d.RestitutionThreshold = circleCollider2DComponent["RestitutionThreshold"].as<float>();
}

auto textComponent = entity["TextComponent"];
if (textComponent)
{
auto& tc = deserializedEntity.AddComponent<TextComponent>();
tc.TextString = textComponent["TextString"].as<std::string>();
// tc.FontAsset // TODO
tc.Color = textComponent["Color"].as<glm::vec4>();
tc.Kerning = textComponent["Kerning"].as<float>();
tc.LineSpacing = textComponent["LineSpacing"].as<float>();
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions Hazelnut/src/EditorLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,10 +577,11 @@ namespace Hazel {
glm::vec3 translation = tc.Translation + glm::vec3(bc2d.Offset, 0.001f);
glm::vec3 scale = tc.Scale * glm::vec3(bc2d.Size * 2.0f, 1.0f);

glm::mat4 transform = glm::translate(glm::mat4(1.0f), translation)
glm::mat4 transform = glm::translate(glm::mat4(1.0f), tc.Translation)
* glm::rotate(glm::mat4(1.0f), tc.Rotation.z, glm::vec3(0.0f, 0.0f, 1.0f))
* glm::translate(glm::mat4(1.0f), glm::vec3(bc2d.Offset, 0.001f))
* glm::scale(glm::mat4(1.0f), scale);

Renderer2D::DrawRect(transform, glm::vec4(0, 1, 0, 1));
}
}
Expand Down
10 changes: 10 additions & 0 deletions Hazelnut/src/Panels/SceneHierarchyPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <imgui/imgui.h>
#include <imgui/imgui_internal.h>
#include <imgui/misc/cpp/imgui_stdlib.h>

#include <glm/gtc/type_ptr.hpp>

Expand Down Expand Up @@ -247,6 +248,7 @@ namespace Hazel {
DisplayAddComponentEntry<Rigidbody2DComponent>("Rigidbody 2D");
DisplayAddComponentEntry<BoxCollider2DComponent>("Box Collider 2D");
DisplayAddComponentEntry<CircleCollider2DComponent>("Circle Collider 2D");
DisplayAddComponentEntry<TextComponent>("Text Component");

ImGui::EndPopup();
}
Expand Down Expand Up @@ -474,6 +476,14 @@ namespace Hazel {
ImGui::DragFloat("Restitution Threshold", &component.RestitutionThreshold, 0.01f, 0.0f);
});

DrawComponent<TextComponent>("Text Renderer", entity, [](auto& component)
{
ImGui::InputTextMultiline("Text String", &component.TextString);
ImGui::ColorEdit4("Color", glm::value_ptr(component.Color));
ImGui::DragFloat("Kerning", &component.Kerning, 0.025f);
ImGui::DragFloat("Line Spacing", &component.LineSpacing, 0.025f);
});

}

template<typename T>
Expand Down

0 comments on commit be419f6

Please sign in to comment.