From 50f35affb16c78bd3d0b420f5ba37d74fcac391f Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 28 Jul 2015 13:10:59 +0200 Subject: [PATCH 1/1] combine text handling stuff into a class --- TODO | 5 +-- src/app/app.cpp | 1 - src/graphics/Text.hpp | 79 +++++++++++++++++++++++++++++++++++++++ src/graphics/Viewport.hpp | 11 ++++-- src/graphics/align.hpp | 52 ++++++++++++++++++++++++++ src/graphics/render.cpp | 42 +++++++++++++++++++++ src/graphics/viewport.cpp | 24 ++++++++++-- src/ui/HUD.hpp | 7 +--- src/ui/Interface.hpp | 9 +---- src/ui/ui.cpp | 66 ++++++++++++-------------------- 10 files changed, 230 insertions(+), 66 deletions(-) create mode 100644 src/graphics/Text.hpp create mode 100644 src/graphics/align.hpp diff --git a/TODO b/TODO index 49fac3b..8cea292 100644 --- a/TODO +++ b/TODO @@ -14,9 +14,8 @@ textures font rendering - should combine all that's needed to render a text into some struct - also, with background nw being a thing, a padding might be nice - or could separate bg from fg rendering + with background now being a thing, a padding might be nice + that or maybe separate bg from fg rendering it may also be feasible to get rid of SDL_ttf and use freetype directly to eliminate the unneccessary surface creation diff --git a/src/app/app.cpp b/src/app/app.cpp index 8577e45..1c4b4db 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -145,7 +145,6 @@ void Application::Handle(const SDL_WindowEvent &event) { break; case SDL_WINDOWEVENT_RESIZED: viewport.Resize(event.data1, event.data2); - interface.Resize(viewport); break; default: break; diff --git a/src/graphics/Text.hpp b/src/graphics/Text.hpp new file mode 100644 index 0000000..5d7a8b3 --- /dev/null +++ b/src/graphics/Text.hpp @@ -0,0 +1,79 @@ +#ifndef BLANK_GRAPHICS_TEXT_HPP_ +#define BLANK_GRAPHICS_TEXT_HPP_ + +#include "align.hpp" +#include "Texture.hpp" +#include "../model/SpriteModel.hpp" + +#include +#include + + +namespace blank { + +class Font; +class Viewport; + +class Text { + +public: + Text() noexcept; + + void Set(const Font &, const char *); + void Set(const Font &f, const std::string &s) { + Set(f, s.c_str()); + } + + void Position(const glm::vec3 &p) noexcept { + pos = p; + } + void Position( + const glm::vec3 &p, + Gravity g + ) noexcept { + pos = p; + grav = g; + pivot = g; + dirty = true; + } + void Position( + const glm::vec3 &p, + Gravity g, + Gravity pv + ) noexcept { + pos = p; + grav = g; + pivot = pv; + dirty = true; + } + + void Foreground(const glm::vec4 &col) noexcept { fg = col; } + void Background(const glm::vec4 &col) noexcept { bg = col; } + + void Render(Viewport &) noexcept; + + void Show() noexcept { visible = true; } + void Hide() noexcept { visible = false; } + void Toggle() noexcept { visible = !visible; } + bool Visible() const noexcept { return visible; } + +private: + void Update(); + +private: + Texture tex; + SpriteModel sprite; + glm::vec4 bg; + glm::vec4 fg; + glm::vec2 size; + glm::vec3 pos; + Gravity grav; + Gravity pivot; + bool dirty; + bool visible; + +}; + +} + +#endif diff --git a/src/graphics/Viewport.hpp b/src/graphics/Viewport.hpp index d64e580..0bd6e89 100644 --- a/src/graphics/Viewport.hpp +++ b/src/graphics/Viewport.hpp @@ -1,6 +1,7 @@ #ifndef BLANK_GRAPHICS_VIEWPORT_HPP_ #define BLANK_GRAPHICS_VIEWPORT_HPP_ +#include "align.hpp" #include "BlendedSprite.hpp" #include "BlockLighting.hpp" #include "Camera.hpp" @@ -8,7 +9,6 @@ #include "DirectionalLighting.hpp" #include -#include namespace blank { @@ -41,6 +41,11 @@ public: void Clear() noexcept; void ClearDepth() noexcept; + void SetCursor(const glm::vec3 &); + void SetCursor(const glm::vec3 &, Gravity = Gravity::NORTH_WEST); + void MoveCursor(const glm::vec3 &); + const glm::mat4 &Cursor() const noexcept { return cursor; } + BlockLighting &ChunkProgram() noexcept; DirectionalLighting &EntityProgram() noexcept; DirectionalLighting &HUDProgram() noexcept; @@ -50,14 +55,12 @@ public: const glm::mat4 &Perspective() const noexcept { return cam.Projection(); } const glm::mat4 &Ortho() const noexcept { return canv.Projection(); } - const glm::mat4 &CenterTransform() const noexcept { return center; } private: - SDL_GLContext ctx; Camera cam; Canvas canv; - glm::mat4 center; + glm::mat4 cursor; BlockLighting chunk_prog; DirectionalLighting entity_prog; diff --git a/src/graphics/align.hpp b/src/graphics/align.hpp new file mode 100644 index 0000000..1e18f35 --- /dev/null +++ b/src/graphics/align.hpp @@ -0,0 +1,52 @@ +#ifndef BLANK_GRAPHICS_ALIGN_HPP_ +#define BLANK_GRAPHICS_ALIGN_HPP_ + +#include + + +namespace blank { + +enum class Align { + LEFT, + CENTER, + RIGHT, +}; + +enum class Gravity { + NORTH_WEST, + NORTH, + NORTH_EAST, + WEST, + CENTER, + EAST, + SOUTH_WEST, + SOUTH, + SOUTH_EAST, +}; + +inline Align get_x(Gravity g) noexcept { + return Align(int(g) % 3); +} + +inline Align get_y(Gravity g) noexcept { + return Align(int(g) / 3); +} + +inline Gravity get_gravity(Align x, Align y) noexcept { + return Gravity(int(y) * 3 + int(x)); +} + +inline glm::vec2 align( + Gravity g, + const glm::vec2 &size, + const glm::vec2 &offset = glm::vec2(0.0f, 0.0f) +) { + return glm::vec2( + size.x * 0.5 * int(get_x(g)) + offset.x, + size.y * 0.5 * int(get_y(g)) + offset.y + ); +} + +} + +#endif diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 1dc9b2b..1a6d1ab 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -1,6 +1,9 @@ +#include "BlendedSprite.hpp" #include "Font.hpp" #include "Format.hpp" +#include "Text.hpp" #include "Texture.hpp" +#include "Viewport.hpp" #include #include @@ -155,6 +158,45 @@ void Format::ReadPixelFormat(const SDL_PixelFormat &fmt) { } +Text::Text() noexcept +: tex() +, sprite() +, bg(1.0f, 1.0f, 1.0f, 0.0f) +, fg(1.0f, 1.0f, 1.0f, 1.0f) +, size(0.0f) +, pos(0.0f) +, grav(Gravity::NORTH_WEST) +, pivot(Gravity::NORTH_WEST) +, dirty(false) +, visible(false) { + +} + +void Text::Set(const Font &font, const char *text) { + font.Render(text, tex); + size = font.TextSize(text); + dirty = true; +} + +void Text::Update() { + sprite.LoadRect(size.x, size.y, align(pivot, size)); + dirty = false; +} + +void Text::Render(Viewport &viewport) noexcept { + if (dirty) { + Update(); + } + BlendedSprite &prog = viewport.SpriteProgram(); + viewport.SetCursor(pos, grav); + prog.SetM(viewport.Cursor()); + prog.SetTexture(tex); + prog.SetBG(bg); + prog.SetFG(fg); + sprite.Draw(); +} + + Texture::Texture() : handle(0) , width(0) diff --git a/src/graphics/viewport.cpp b/src/graphics/viewport.cpp index 0607380..e6ac768 100644 --- a/src/graphics/viewport.cpp +++ b/src/graphics/viewport.cpp @@ -76,7 +76,7 @@ void Canvas::UpdateProjection() noexcept { Viewport::Viewport() : cam() , canv() -, center(1.0f) +, cursor(1.0f) , chunk_prog() , entity_prog() , sprite_prog() @@ -128,8 +128,6 @@ void Viewport::Resize(int w, int h) noexcept { cam.Aspect(fw, fh); canv.Resize(fw, fh); - center = glm::translate(glm::vec3(fw * 0.5f, fh * 0.5f, 0.0f)); - chunk_prog.SetProjection(Perspective()); if (active_prog == HUD) { entity_prog.SetProjection(Ortho()); @@ -148,6 +146,26 @@ void Viewport::ClearDepth() noexcept { } +void Viewport::SetCursor(const glm::vec3 &pos) { + cursor[3].x = pos.x; + cursor[3].y = pos.y; + cursor[3].z = pos.z; +} + +void Viewport::SetCursor(const glm::vec3 &pos, Gravity grav) { + glm::vec2 p(align(grav, canv.Size(), glm::vec2(pos) + canv.Offset())); + cursor[3].x = p.x; + cursor[3].y = p.y; + cursor[3].z = pos.z; +} + +void Viewport::MoveCursor(const glm::vec3 &d) { + cursor[3].x += d.x; + cursor[3].y += d.y; + cursor[3].z += d.z; +} + + BlockLighting &Viewport::ChunkProgram() noexcept { if (active_prog != CHUNK) { chunk_prog.Activate(); diff --git a/src/ui/HUD.hpp b/src/ui/HUD.hpp index 55f3afb..47e0fd4 100644 --- a/src/ui/HUD.hpp +++ b/src/ui/HUD.hpp @@ -1,10 +1,9 @@ #ifndef BLANK_UI_HUD_H_ #define BLANK_UI_HUD_H_ -#include "../graphics/Texture.hpp" +#include "../graphics/Text.hpp" #include "../model/Model.hpp" #include "../model/OutlineModel.hpp" -#include "../model/SpriteModel.hpp" #include @@ -36,9 +35,7 @@ private: Model::Buffer block_buf; glm::mat4 block_transform; - Texture block_label; - SpriteModel label_sprite; - glm::mat4 label_transform; + Text block_label; bool block_visible; diff --git a/src/ui/Interface.hpp b/src/ui/Interface.hpp index 1e2e883..d6c3019 100644 --- a/src/ui/Interface.hpp +++ b/src/ui/Interface.hpp @@ -5,6 +5,7 @@ #include "../app/FPSController.hpp" #include "../app/IntervalTimer.hpp" #include "../graphics/Font.hpp" +#include "../graphics/Text.hpp" #include "../model/geometry.hpp" #include "../model/OutlineModel.hpp" #include "../world/Block.hpp" @@ -42,8 +43,6 @@ public: void HandleRelease(const SDL_MouseButtonEvent &); void Handle(const SDL_MouseWheelEvent &); - void Resize(const Viewport &); - void FaceBlock(); void TurnBlock(); @@ -87,11 +86,7 @@ private: OutlineModel outline; glm::mat4 outline_transform; - bool show_counter; - Texture counter_tex; - SpriteModel counter_sprite; - glm::mat4 counter_transform; - float counter_x; + Text counter_text; Config config; diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index ee26989..e3ddf10 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -26,8 +26,6 @@ HUD::HUD(const BlockTypeRegistry &types, const Font &font) , block_buf() , block_transform(1.0f) , block_label() -, label_sprite() -, label_transform(1.0f) , block_visible(false) , crosshair() { block_transform = glm::translate(block_transform, glm::vec3(50.0f, 50.0f, 0.0f)); @@ -44,6 +42,14 @@ HUD::HUD(const BlockTypeRegistry &types, const Font &font) }); crosshair.colors.resize(4, { 10.0f, 10.0f, 10.0f }); crosshair.Invalidate(); + + block_label.Position( + glm::vec3(50.0f, 85.0f, 0.0f), + Gravity::NORTH_WEST, + Gravity::NORTH + ); + block_label.Foreground(glm::vec4(1.0f)); + block_label.Background(glm::vec4(0.5f)); } @@ -54,14 +60,7 @@ void HUD::Display(const Block &b) { type.FillModel(block_buf, b.Transform()); block.Update(block_buf); - font.Render(type.label.c_str(), block_label); - glm::vec2 size(font.TextSize(type.label.c_str())); - label_sprite.LoadRect(size.x, size.y); - label_transform = glm::translate(glm::vec3( - std::max(5.0f, 50.0f - std::round(size.x * 0.5f)), - 70.0f + size.y, - 0.75f - )); + block_label.Set(font, type.label); block_visible = type.visible; } @@ -76,20 +75,15 @@ void HUD::Render(Viewport &viewport) noexcept { world_prog.SetFogDensity(0.0f); viewport.EnableInvertBlending(); - world_prog.SetM(viewport.CenterTransform()); + viewport.SetCursor(glm::vec3(0.0f), Gravity::CENTER); + world_prog.SetM(viewport.Cursor()); crosshair.Draw(); if (block_visible) { viewport.DisableBlending(); world_prog.SetM(block_transform); block.Draw(); - - BlendedSprite &sprite_prog = viewport.SpriteProgram(); - sprite_prog.SetM(label_transform); - sprite_prog.SetTexture(block_label); - sprite_prog.SetFG(glm::vec4(1.0f)); - sprite_prog.SetBG(glm::vec4(0.5f)); - label_sprite.Draw(); + block_label.Render(viewport); } } @@ -110,11 +104,7 @@ Interface::Interface( , aim_normal() , outline() , outline_transform(1.0f) -, show_counter(false) -, counter_tex() -, counter_sprite() -, counter_transform(1.0f) -, counter_x(935.0f) +, counter_text() , config(config) , place_timer(256) , remove_timer(256) @@ -122,6 +112,10 @@ Interface::Interface( , selection(1) , fwd(0) , rev(0) { + counter_text.Hide(); + counter_text.Position(glm::vec3(-25.0f, 25.0f, 0.0f), Gravity::NORTH_EAST); + counter_text.Foreground(glm::vec4(1.0f)); + counter_text.Background(glm::vec4(0.5f)); hud.Display(selection); } @@ -286,7 +280,8 @@ void Interface::Print(const Block &block) { } void Interface::ToggleCounter() { - if ((show_counter = !show_counter)) { + counter_text.Toggle(); + if (counter_text.Visible()) { UpdateCounter(); } } @@ -295,14 +290,7 @@ void Interface::UpdateCounter() { std::stringstream s; s << std::setprecision(3) << counter.AvgRunning() << "ms"; std::string text = s.str(); - font.Render(text.c_str(), counter_tex); - glm::vec2 size(font.TextSize(text.c_str())); - counter_sprite.LoadRect(size.x, size.y); - counter_transform = glm::translate(glm::vec3( - counter_x - size.x, - 25.0f, - 0.75f - )); + counter_text.Set(font, text); } @@ -388,11 +376,6 @@ void Interface::SelectPrevious() { } -void Interface::Resize(const Viewport &viewport) { - counter_x = viewport.Width() - 25.0f; -} - - void Interface::Update(int dt) { ctrl.Velocity(glm::vec3(fwd - rev) * config.move_velocity); ctrl.Update(dt); @@ -413,7 +396,7 @@ void Interface::Update(int dt) { CheckAim(); } - if (show_counter && counter.Changed()) { + if (counter_text.Visible() && counter.Changed()) { UpdateCounter(); } } @@ -441,11 +424,8 @@ void Interface::Render(Viewport &viewport) noexcept { outline.Draw(); } - if (show_counter) { - BlendedSprite &sprite_prog = viewport.SpriteProgram(); - sprite_prog.SetM(counter_transform); - sprite_prog.SetTexture(counter_tex); - counter_sprite.Draw(); + if (counter_text.Visible()) { + counter_text.Render(viewport); } hud.Render(viewport); -- 2.39.2