]> git.localhorst.tv Git - blank.git/commitdiff
set and display block type labels
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 22 Jul 2015 10:28:25 +0000 (12:28 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 22 Jul 2015 10:39:33 +0000 (12:39 +0200)
16 files changed:
.gitmodules [new file with mode: 0644]
Makefile
TODO
assets [new submodule]
src/app/Application.cpp [deleted file]
src/app/Application.hpp
src/app/Assets.hpp [new file with mode: 0644]
src/app/app.cpp [new file with mode: 0644]
src/graphics/Font.hpp
src/graphics/render.cpp
src/ui/HUD.hpp
src/ui/Interface.hpp
src/ui/ui.cpp
src/world/BlockType.hpp
src/world/World.cpp
src/world/block.cpp

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..bde19f5
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "assets"]
+       path = assets
+       url = http://git.localhorst.tv/repo/blank-assets.git
index cfe9a2ccfd74129f3686ad7e2daccc4b214989b9..2a355cd9f45c0ab187a2e1f7e4dabff72dc75dba 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,9 @@ RELEASE_DIR := build/release
 TEST_DIR := build/test
 DIR := $(RELEASE_DIR) $(DEBUG_DIR) $(PROFILE_DIR) $(TEST_DIR) build
 
+ASSET_DIR := assets
+ASSET_DEP := $(ASSET_DIR)/.git
+
 LIB_SRC := $(wildcard $(SOURCE_DIR)/*/*.cpp)
 BIN_SRC := $(wildcard $(SOURCE_DIR)/*.cpp)
 SRC := $(LIB_SRC) $(BIN_SRC)
@@ -58,16 +61,16 @@ profile: $(PROFILE_BIN)
 
 tests: $(TEST_BIN)
 
-run: blank
+run: $(ASSET_DEP) blank
        ./blank
 
-gdb: blank.debug
+gdb: $(ASSET_DEP) blank.debug
        gdb ./blank.debug
 
-cachegrind: blank.profile
+cachegrind: $(ASSET_DEP) blank.profile
        valgrind ./blank.profile
 
-callgrind: blank.profile
+callgrind: $(ASSET_DEP) blank.profile
        valgrind --tool=callgrind \
                --branch-sim=yes --cacheuse=yes --cache-sim=yes \
                --collect-bus=yes --collect-systime=yes --collect-jumps=yes \
@@ -103,6 +106,10 @@ $(TEST_BIN): $(TEST_OBJ)
        @echo link: $@
        @$(LDXX) -o $@ $(CXXFLAGS) $(LDXXFLAGS) $(TESTLIBS) $(TEST_FLAGS) $^
 
+$(ASSET_DEP): .git/$(shell git symbolic-ref HEAD)
+       @git submodule update --init >/dev/null
+       @touch $@
+
 $(RELEASE_DIR)/%.o: $(SOURCE_DIR)/%.cpp | $(RELEASE_DIR)
        @mkdir -p "$(@D)"
        @echo compile: $@
diff --git a/TODO b/TODO
index e7b2f8f3b76e6157c6fba72f85b798e04f85ee92..9d43155a0d96e9b78ec394f0e16112e7e29f18b3 100644 (file)
--- a/TODO
+++ b/TODO
@@ -12,6 +12,11 @@ textures
 
        do I need to say anything? :)
 
+font colours
+
+       set font fg and bg colour as either uniform or vertex attribute
+       and lerp between them based on the texture's alpha component
+
 command line
 
        usefull for development and later on world administration
diff --git a/assets b/assets
new file mode 160000 (submodule)
index 0000000..7ac546c
--- /dev/null
+++ b/assets
@@ -0,0 +1 @@
+Subproject commit 7ac546c3310a3f147a889077dffa6919fad94be7
diff --git a/src/app/Application.cpp b/src/app/Application.cpp
deleted file mode 100644 (file)
index 80dee36..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-#include "Application.hpp"
-
-#include "../world/BlockType.hpp"
-#include "../world/Entity.hpp"
-
-#include <iostream>
-#include <stdexcept>
-
-
-namespace blank {
-
-Application::Application(const Config &config)
-: init_sdl()
-, init_img()
-, init_ttf()
-, init_gl(config.doublebuf, config.multisampling)
-, window()
-, ctx(window.CreateContext())
-, init_glew()
-, chunk_prog()
-, entity_prog()
-, cam()
-, world(config.world)
-, interface(config.interface, world)
-, test_controller(MakeTestEntity(world))
-, running(false) {
-       if (config.vsync) {
-               GLContext::EnableVSync();
-       }
-
-       glClearColor(0.0, 0.0, 0.0, 1.0);
-}
-
-Entity &Application::MakeTestEntity(World &world) {
-       Entity &e = world.AddEntity();
-       e.Name("test");
-       e.Position({ 0.0f, 0.0f, 0.0f });
-       e.Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
-       e.WorldCollidable(true);
-       e.SetShape(world.BlockTypes()[1].shape, { 1.0f, 1.0f, 0.0f });
-       e.AngularVelocity(glm::quat(glm::vec3{ 0.00001f, 0.000006f, 0.000013f }));
-       return e;
-}
-
-
-void Application::RunN(size_t n) {
-       Uint32 last = SDL_GetTicks();
-       for (size_t i = 0; i < n; ++i) {
-               Uint32 now = SDL_GetTicks();
-               int delta = now - last;
-               Loop(delta);
-               last = now;
-       }
-}
-
-void Application::RunT(size_t t) {
-       Uint32 last = SDL_GetTicks();
-       Uint32 finish = last + t;
-       while (last < finish) {
-               Uint32 now = SDL_GetTicks();
-               int delta = now - last;
-               Loop(delta);
-               last = now;
-       }
-}
-
-void Application::RunS(size_t n, size_t t) {
-       for (size_t i = 0; i < n; ++i) {
-               Loop(t);
-       }
-}
-
-
-void Application::Run() {
-       running = true;
-       Uint32 last = SDL_GetTicks();
-       window.GrabMouse();
-       while (running) {
-               Uint32 now = SDL_GetTicks();
-               int delta = now - last;
-               Loop(delta);
-               last = now;
-       }
-}
-
-void Application::Loop(int dt) {
-       HandleEvents();
-       Update(dt);
-       Render();
-}
-
-
-void Application::HandleEvents() {
-       SDL_Event event;
-       while (SDL_PollEvent(&event)) {
-               switch (event.type) {
-                       case SDL_KEYDOWN:
-                               interface.HandlePress(event.key);
-                               break;
-                       case SDL_KEYUP:
-                               interface.HandleRelease(event.key);
-                               break;
-                       case SDL_MOUSEBUTTONDOWN:
-                               interface.HandlePress(event.button);
-                               break;
-                       case SDL_MOUSEBUTTONUP:
-                               interface.HandleRelease(event.button);
-                               break;
-                       case SDL_MOUSEMOTION:
-                               interface.Handle(event.motion);
-                               break;
-                       case SDL_MOUSEWHEEL:
-                               interface.Handle(event.wheel);
-                               break;
-                       case SDL_QUIT:
-                               running = false;
-                               break;
-                       case SDL_WINDOWEVENT:
-                               switch (event.window.event) {
-                                       case SDL_WINDOWEVENT_FOCUS_GAINED:
-                                               window.GrabMouse();
-                                               break;
-                                       case SDL_WINDOWEVENT_FOCUS_LOST:
-                                               window.ReleaseMouse();
-                                               break;
-                                       case SDL_WINDOWEVENT_RESIZED:
-                                               cam.Viewport(event.window.data1, event.window.data2);
-                                               interface.Handle(event.window);
-                                               break;
-                                       default:
-                                               interface.Handle(event.window);
-                                               break;
-                               }
-                               break;
-                       default:
-                               break;
-               }
-       }
-}
-
-void Application::Update(int dt) {
-       interface.Update(dt);
-       test_controller.Update(dt);
-       world.Update(dt);
-}
-
-void Application::Render() {
-       GLContext::Clear();
-
-       chunk_prog.SetProjection(cam.Projection());
-       entity_prog.SetProjection(cam.Projection());
-
-       world.Render(chunk_prog, entity_prog);
-
-       interface.Render(entity_prog);
-
-       window.Flip();
-}
-
-}
index a3c62769164d9f5d7277aff0fb456caae0f5e1d2..ea7421161b9031e45aa9f54d78bff38c5be6db73 100644 (file)
@@ -1,14 +1,18 @@
 #ifndef BLANK_APP_APPLICATION_HPP_
 #define BLANK_APP_APPLICATION_HPP_
 
+#include "Assets.hpp"
 #include "init.hpp"
 #include "RandomWalk.hpp"
+#include "../graphics/BlendedSprite.hpp"
 #include "../graphics/BlockLighting.hpp"
 #include "../graphics/Camera.hpp"
 #include "../graphics/DirectionalLighting.hpp"
 #include "../ui/Interface.hpp"
 #include "../world/World.hpp"
 
+#include <SDL.h>
+
 
 namespace blank {
 
@@ -43,6 +47,7 @@ public:
 
        /// process all events in SDL's queue
        void HandleEvents();
+       void Handle(const SDL_WindowEvent &);
        /// integrate to the next step with dt milliseconds passed
        void Update(int dt);
        /// push the current state to display
@@ -58,8 +63,11 @@ private:
        Window window;
        GLContext ctx;
        InitGLEW init_glew;
+       Assets assets;
+
        BlockLighting chunk_prog;
        DirectionalLighting entity_prog;
+       BlendedSprite sprite_prog;
 
        Camera cam;
        World world;
diff --git a/src/app/Assets.hpp b/src/app/Assets.hpp
new file mode 100644 (file)
index 0000000..d9ab3d4
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef BLANK_APP_ASSETS_HPP_
+#define BLANK_APP_ASSETS_HPP_
+
+#include <string>
+
+
+namespace blank {
+
+class Font;
+
+class Assets {
+
+public:
+       explicit Assets(const std::string &base);
+
+       Font LoadFont(const std::string &name, int size) const;
+
+private:
+       std::string fonts;
+
+};
+
+}
+
+#endif
diff --git a/src/app/app.cpp b/src/app/app.cpp
new file mode 100644 (file)
index 0000000..9e83cd4
--- /dev/null
@@ -0,0 +1,193 @@
+#include "Application.hpp"
+#include "Assets.hpp"
+
+#include "../graphics/Font.hpp"
+#include "../world/BlockType.hpp"
+#include "../world/Entity.hpp"
+
+#include <iostream>
+#include <stdexcept>
+
+using std::string;
+
+
+namespace {
+
+string get_asset_path() {
+       char *base = SDL_GetBasePath();
+       string assets(base);
+       assets += "assets/";
+       SDL_free(base);
+       return assets;
+}
+
+}
+
+namespace blank {
+
+Application::Application(const Config &config)
+: init_sdl()
+, init_img()
+, init_ttf()
+, init_gl(config.doublebuf, config.multisampling)
+, window()
+, ctx(window.CreateContext())
+, init_glew()
+, assets(get_asset_path())
+, chunk_prog()
+, entity_prog()
+, sprite_prog()
+, cam()
+, world(config.world)
+, interface(config.interface, assets, world)
+, test_controller(MakeTestEntity(world))
+, running(false) {
+       if (config.vsync) {
+               GLContext::EnableVSync();
+       }
+
+       glClearColor(0.0, 0.0, 0.0, 1.0);
+}
+
+Entity &Application::MakeTestEntity(World &world) {
+       Entity &e = world.AddEntity();
+       e.Name("test");
+       e.Position({ 0.0f, 0.0f, 0.0f });
+       e.Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
+       e.WorldCollidable(true);
+       e.SetShape(world.BlockTypes()[1].shape, { 1.0f, 1.0f, 0.0f });
+       e.AngularVelocity(glm::quat(glm::vec3{ 0.00001f, 0.000006f, 0.000013f }));
+       return e;
+}
+
+
+void Application::RunN(size_t n) {
+       Uint32 last = SDL_GetTicks();
+       for (size_t i = 0; i < n; ++i) {
+               Uint32 now = SDL_GetTicks();
+               int delta = now - last;
+               Loop(delta);
+               last = now;
+       }
+}
+
+void Application::RunT(size_t t) {
+       Uint32 last = SDL_GetTicks();
+       Uint32 finish = last + t;
+       while (last < finish) {
+               Uint32 now = SDL_GetTicks();
+               int delta = now - last;
+               Loop(delta);
+               last = now;
+       }
+}
+
+void Application::RunS(size_t n, size_t t) {
+       for (size_t i = 0; i < n; ++i) {
+               Loop(t);
+       }
+}
+
+
+void Application::Run() {
+       running = true;
+       Uint32 last = SDL_GetTicks();
+       window.GrabMouse();
+       while (running) {
+               Uint32 now = SDL_GetTicks();
+               int delta = now - last;
+               Loop(delta);
+               last = now;
+       }
+}
+
+void Application::Loop(int dt) {
+       HandleEvents();
+       Update(dt);
+       Render();
+}
+
+
+void Application::HandleEvents() {
+       SDL_Event event;
+       while (SDL_PollEvent(&event)) {
+               switch (event.type) {
+                       case SDL_KEYDOWN:
+                               interface.HandlePress(event.key);
+                               break;
+                       case SDL_KEYUP:
+                               interface.HandleRelease(event.key);
+                               break;
+                       case SDL_MOUSEBUTTONDOWN:
+                               interface.HandlePress(event.button);
+                               break;
+                       case SDL_MOUSEBUTTONUP:
+                               interface.HandleRelease(event.button);
+                               break;
+                       case SDL_MOUSEMOTION:
+                               interface.Handle(event.motion);
+                               break;
+                       case SDL_MOUSEWHEEL:
+                               interface.Handle(event.wheel);
+                               break;
+                       case SDL_QUIT:
+                               running = false;
+                               break;
+                       case SDL_WINDOWEVENT:
+                               Handle(event.window);
+                               break;
+                       default:
+                               break;
+               }
+       }
+}
+
+void Application::Handle(const SDL_WindowEvent &event) {
+       switch (event.event) {
+               case SDL_WINDOWEVENT_FOCUS_GAINED:
+                       window.GrabMouse();
+                       break;
+               case SDL_WINDOWEVENT_FOCUS_LOST:
+                       window.ReleaseMouse();
+                       break;
+               case SDL_WINDOWEVENT_RESIZED:
+                       cam.Viewport(event.data1, event.data2);
+                       interface.Handle(event);
+                       break;
+               default:
+                       interface.Handle(event);
+                       break;
+       }
+}
+
+void Application::Update(int dt) {
+       interface.Update(dt);
+       test_controller.Update(dt);
+       world.Update(dt);
+}
+
+void Application::Render() {
+       GLContext::Clear();
+
+       chunk_prog.SetProjection(cam.Projection());
+       entity_prog.SetProjection(cam.Projection());
+
+       world.Render(chunk_prog, entity_prog);
+
+       interface.Render(entity_prog, sprite_prog);
+
+       window.Flip();
+}
+
+
+Assets::Assets(const string &base)
+: fonts(base + "fonts/") {
+
+}
+
+Font Assets::LoadFont(const string &name, int size) const {
+       string full = fonts + name + ".ttf";
+       return Font(full.c_str(), size);
+}
+
+}
index 2219452b86f8b71a11737402e508db5c2c802e4f..1d4ff17f619823b14efabe3fa8ac6a1a1452bee6 100644 (file)
@@ -11,6 +11,21 @@ class Texture;
 
 class Font {
 
+public:
+       enum FontStyle {
+               STYLE_NORMAL = TTF_STYLE_NORMAL,
+               STYLE_BOLD = TTF_STYLE_BOLD,
+               STYLE_ITALIC = TTF_STYLE_ITALIC,
+               STYLE_UNDERLINE = TTF_STYLE_UNDERLINE,
+               STYLE_STRIKE = TTF_STYLE_STRIKETHROUGH,
+       };
+       enum FontHinting {
+               HINT_NORMAL = TTF_HINTING_NORMAL,
+               HINT_LIGHT = TTF_HINTING_LIGHT,
+               HINT_MONO = TTF_HINTING_MONO,
+               HINT_NONE = TTF_HINTING_NONE,
+       };
+
 public:
        Font(const char *src, int size, long index = 0);
        ~Font();
@@ -22,6 +37,13 @@ public:
        Font &operator =(const Font &) = delete;
 
 public:
+       int Style() const noexcept;
+       void Style(int) const noexcept;
+       int Outline() const noexcept;
+       void Outline(int) noexcept;
+
+       int Hinting() const noexcept;
+       void Hinting(int) const noexcept;
        bool Kerning() const noexcept;
        void Kerning(bool) noexcept;
 
@@ -30,11 +52,15 @@ public:
        int Descent() const noexcept;
        int LineSkip() const noexcept;
 
+       const char *FamilyName() const noexcept;
+       const char *StyleName() const noexcept;
+
        bool HasGlyph(Uint16) const noexcept;
 
        glm::tvec2<int> TextSize(const char *) const;
 
        Texture Render(const char *, SDL_Color) const;
+       void Render(const char *, SDL_Color, Texture &) const;
 
 private:
        TTF_Font *handle;
index 3d0bbd47c6cf2e00feb6efb10798c22469a694a8..7e048408b5091239ca10e35e89a8dfe2fcec4035 100644 (file)
@@ -34,6 +34,31 @@ Font &Font::operator =(Font &&other) noexcept {
 }
 
 
+int Font::Style() const noexcept {
+       return TTF_GetFontStyle(handle);
+}
+
+void Font::Style(int s) const noexcept {
+       TTF_SetFontStyle(handle, s);
+}
+
+int Font::Outline() const noexcept {
+       return TTF_GetFontOutline(handle);
+}
+
+void Font::Outline(int px) noexcept {
+       TTF_SetFontOutline(handle, px);
+}
+
+
+int Font::Hinting() const noexcept {
+       return TTF_GetFontHinting(handle);
+}
+
+void Font::Hinting(int h) const noexcept {
+       TTF_SetFontHinting(handle, h);
+}
+
 bool Font::Kerning() const noexcept {
        return TTF_GetFontKerning(handle);
 }
@@ -60,6 +85,15 @@ int Font::LineSkip() const noexcept {
 }
 
 
+const char *Font::FamilyName() const noexcept {
+       return TTF_FontFaceFamilyName(handle);
+}
+
+const char *Font::StyleName() const noexcept {
+       return TTF_FontFaceStyleName(handle);
+}
+
+
 bool Font::HasGlyph(Uint16 c) const noexcept {
        return TTF_GlyphIsProvided(handle, c);
 }
@@ -74,16 +108,19 @@ glm::tvec2<int> Font::TextSize(const char *text) const {
 }
 
 Texture Font::Render(const char *text, SDL_Color color) const {
+       Texture tex;
+       return tex;
+}
+
+void Font::Render(const char *text, SDL_Color color, Texture &tex) const {
        SDL_Surface *srf = TTF_RenderUTF8_Blended(handle, text, color);
        if (!srf) {
                throw std::runtime_error(TTF_GetError());
        }
-       Texture tex;
        tex.Bind();
        tex.Data(*srf, false);
        tex.FilterLinear();
        SDL_FreeSurface(srf);
-       return tex;
 }
 
 
index ca6b7544a54ee9a15f7639bb2e1f6fba65376724..245d886e795ffaccf35b658e7fde710457d46d9d 100644 (file)
@@ -1,22 +1,26 @@
 #ifndef BLANK_UI_HUD_H_
 #define BLANK_UI_HUD_H_
 
+#include "../graphics/Texture.hpp"
 #include "../model/Model.hpp"
 #include "../model/OutlineModel.hpp"
+#include "../model/SpriteModel.hpp"
 
 #include <glm/glm.hpp>
 
 
 namespace blank {
 
+class BlendedSprite;
 class Block;
 class BlockTypeRegistry;
 class DirectionalLighting;
+class Font;
 
 class HUD {
 
 public:
-       explicit HUD(const BlockTypeRegistry &);
+       HUD(const BlockTypeRegistry &, const Font &);
 
        HUD(const HUD &) = delete;
        HUD &operator =(const HUD &) = delete;
@@ -26,14 +30,21 @@ public:
 
        void Display(const Block &);
 
-       void Render(DirectionalLighting &) noexcept;
+       void Render(DirectionalLighting &, BlendedSprite &) noexcept;
 
 private:
        const BlockTypeRegistry &types;
+       const Font &font;
 
        Model block;
        Model::Buffer block_buf;
        glm::mat4 block_transform;
+
+       Texture block_label;
+       SpriteModel label_sprite;
+       glm::mat4 label_transform;
+       SDL_Color label_color;
+
        bool block_visible;
 
        OutlineModel crosshair;
index a08a0bf5c6a3add3518ea571333bce3e44d6c212..88637c6adc368144b9825d411c03729b46cf9ba1 100644 (file)
@@ -4,6 +4,7 @@
 #include "HUD.hpp"
 #include "../app/FPSController.hpp"
 #include "../app/IntervalTimer.hpp"
+#include "../graphics/Font.hpp"
 #include "../model/geometry.hpp"
 #include "../model/OutlineModel.hpp"
 #include "../world/Block.hpp"
@@ -15,7 +16,9 @@
 namespace blank {
 
 class Chunk;
+class BlendedSprite;
 class DirectionalLighting;
+class Assets;
 class World;
 
 class Interface {
@@ -31,7 +34,7 @@ public:
                bool visual_disabled = false;
        };
 
-       Interface(const Config &, World &);
+       Interface(const Config &, const Assets &, World &);
 
        void HandlePress(const SDL_KeyboardEvent &);
        void HandleRelease(const SDL_KeyboardEvent &);
@@ -61,7 +64,7 @@ public:
 
        void Update(int dt);
 
-       void Render(DirectionalLighting &) noexcept;
+       void Render(DirectionalLighting &, BlendedSprite &) noexcept;
 
 private:
        void CheckAim();
@@ -69,6 +72,7 @@ private:
 private:
        World &world;
        FPSController ctrl;
+       Font font;
        HUD hud;
 
        Ray aim;
index 8ddd40c57fb8327a32c5097e890f5d4b6093e326..8e48f143b5c006f7aea3db4db9563b3c9cc05058 100644 (file)
@@ -1,11 +1,16 @@
 #include "HUD.hpp"
 #include "Interface.hpp"
 
+#include "../app/Assets.hpp"
 #include "../app/init.hpp"
+#include "../graphics/BlendedSprite.hpp"
 #include "../graphics/DirectionalLighting.hpp"
+#include "../graphics/Font.hpp"
 #include "../model/shapes.hpp"
 #include "../world/World.hpp"
 
+#include <algorithm>
+#include <cmath>
 #include <iostream>
 #include <glm/gtc/matrix_transform.hpp>
 #include <glm/gtx/io.hpp>
 
 namespace blank {
 
-HUD::HUD(const BlockTypeRegistry &types)
+HUD::HUD(const BlockTypeRegistry &types, const Font &font)
 : types(types)
+, font(font)
 , block()
 , block_buf()
 , block_transform(1.0f)
+, block_label()
+, label_sprite()
+, label_transform(1.0f)
+, label_color{0xFF, 0xFF, 0xFF, 0xFF}
 , block_visible(false)
 , crosshair()
 , crosshair_transform(1.0f)
 , near(100.0f)
 , far(-100.0f)
 , projection(glm::ortho(0.0f, 1.0f, 1.0f, 0.0f, near, far))
-, view(glm::translate(glm::mat4(1.0f), glm::vec3(-0.5f, -0.5f, 0))) {
+, view(1.0f) {
        block_transform = glm::translate(block_transform, glm::vec3(50.0f, 50.0f, 0.0f));
        block_transform = glm::scale(block_transform, glm::vec3(50.0f));
        block_transform = glm::rotate(block_transform, 3.5f, glm::vec3(1.0f, 0.0f, 0.0f));
@@ -48,7 +58,7 @@ void HUD::Viewport(float width, float height) noexcept {
 
 void HUD::Viewport(float x, float y, float width, float height) noexcept {
        projection = glm::ortho(x, width, height, y, near, far);
-       crosshair_transform = glm::translate(glm::mat4(1.0f), glm::vec3(width * 0.5f, height * 0.5f, 0.0f));
+       crosshair_transform = glm::translate(glm::vec3(width * 0.5f, height * 0.5f, 0.0f));
 }
 
 
@@ -58,32 +68,47 @@ void HUD::Display(const Block &b) {
        block_buf.Clear();
        type.FillModel(block_buf, b.Transform());
        block.Update(block_buf);
+
+       font.Render(type.label.c_str(), label_color, 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_visible = type.visible;
 }
 
 
-void HUD::Render(DirectionalLighting &program) noexcept {
-       program.SetLightDirection({ 1.0f, 3.0f, 5.0f });
+void HUD::Render(DirectionalLighting &world_prog, BlendedSprite &sprite_prog) noexcept {
+       world_prog.Activate();
+       world_prog.SetLightDirection({ 1.0f, 3.0f, 5.0f });
        // disable distance fog
-       program.SetFogDensity(0.0f);
+       world_prog.SetFogDensity(0.0f);
        GLContext::ClearDepthBuffer();
 
-       program.SetVP(view, projection);
+       world_prog.SetMVP(crosshair_transform, view, projection);
+       crosshair.Draw();
 
        if (block_visible) {
-               program.SetM(block_transform);
+               world_prog.SetM(block_transform);
                block.Draw();
-       }
 
-       program.SetM(crosshair_transform);
-       crosshair.Draw();
+               sprite_prog.Activate();
+               sprite_prog.SetMVP(label_transform, view, projection);
+               sprite_prog.SetTexture(block_label);
+               label_sprite.Draw();
+       }
 }
 
 
-Interface::Interface(const Config &config, World &world)
+Interface::Interface(const Config &config, const Assets &assets, World &world)
 : world(world)
 , ctrl(world.Player())
-, hud(world.BlockTypes())
+, font(assets.LoadFont("DejaVuSans", 16))
+, hud(world.BlockTypes(), font)
 , aim{{ 0, 0, 0 }, { 0, 0, -1 }}
 , aim_chunk(nullptr)
 , aim_block(0)
@@ -381,15 +406,16 @@ void Interface::CheckAim() {
 }
 
 
-void Interface::Render(DirectionalLighting &program) noexcept {
+void Interface::Render(DirectionalLighting &world_prog, BlendedSprite &sprite_prog) noexcept {
        if (config.visual_disabled) return;
 
        if (aim_chunk) {
-               program.SetM(outline_transform);
+               world_prog.Activate();
+               world_prog.SetM(outline_transform);
                outline.Draw();
        }
 
-       hud.Render(program);
+       hud.Render(world_prog, sprite_prog);
 }
 
 }
index 28f814b80d7245adf022f216689822b305c38142..caccb8f4b7ec237a014086195c6b065c875e2107 100644 (file)
@@ -20,6 +20,9 @@ struct BlockType {
        glm::vec3 color;
        glm::vec3 outline_color;
 
+       // a string to display to the user
+       std::string label;
+
        Block::Type id;
 
        // light level that blocks of this type emit
index d51520ef5b2828c1d22902e1e00902bccb504884..94cd092f88c03a7fd40562342231e06c6bb00dfc 100644 (file)
@@ -29,6 +29,7 @@ World::World(const Config &config)
 
        { // white block
                BlockType type(true, { 1.0f, 1.0f, 1.0f }, &blockShape);
+               type.label = "White Block";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -37,6 +38,7 @@ World::World(const Config &config)
        }
        { // white slab
                BlockType type(true, { 1.0f, 1.0f, 1.0f }, &slabShape);
+               type.label = "White Slab";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -45,6 +47,7 @@ World::World(const Config &config)
        }
        { // white stair
                BlockType type(true, { 1.0f, 1.0f, 1.0f }, &stairShape);
+               type.label = "White Stair";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -54,6 +57,7 @@ World::World(const Config &config)
 
        { // red block
                BlockType type(true, { 1.0f, 0.0f, 0.0f }, &blockShape);
+               type.label = "Red Block";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -62,6 +66,7 @@ World::World(const Config &config)
        }
        { // red slab
                BlockType type(true, { 1.0f, 0.0f, 0.0f }, &slabShape);
+               type.label = "Red Slab";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -70,6 +75,7 @@ World::World(const Config &config)
        }
        { // red stair
                BlockType type(true, { 1.0f, 0.0f, 0.0f }, &stairShape);
+               type.label = "Red Stair";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -79,6 +85,7 @@ World::World(const Config &config)
 
        { // green block
                BlockType type(true, { 0.0f, 1.0f, 0.0f }, &blockShape);
+               type.label = "Green Block";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -87,6 +94,7 @@ World::World(const Config &config)
        }
        { // green slab
                BlockType type(true, { 0.0f, 1.0f, 0.0f }, &slabShape);
+               type.label = "Green Slab";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -95,6 +103,7 @@ World::World(const Config &config)
        }
        { // green stair
                BlockType type(true, { 0.0f, 1.0f, 0.0f }, &stairShape);
+               type.label = "Green Stair";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -104,6 +113,7 @@ World::World(const Config &config)
 
        { // blue block
                BlockType type(true, { 0.0f, 0.0f, 1.0f }, &blockShape);
+               type.label = "Blue Block";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -112,6 +122,7 @@ World::World(const Config &config)
        }
        { // blue slab
                BlockType type(true, { 0.0f, 0.0f, 1.0f }, &slabShape);
+               type.label = "Blue Slab";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -120,6 +131,7 @@ World::World(const Config &config)
        }
        { // blue stair
                BlockType type(true, { 0.0f, 0.0f, 1.0f }, &stairShape);
+               type.label = "Blue Stair";
                type.block_light = true;
                type.collision = true;
                type.collide_block = true;
@@ -129,6 +141,7 @@ World::World(const Config &config)
 
        { // glowing yellow block
                BlockType type(true, { 1.0f, 1.0f, 0.0f }, &blockShape);
+               type.label = "Light";
                type.luminosity = 15;
                type.block_light = true;
                type.collision = true;
index 78aa9d8a30bdfe765983332247fc6bfddae92f7e..510771afdb2665a92b6ffab7bf83bd5801413d76 100644 (file)
@@ -77,6 +77,7 @@ BlockType::BlockType(bool v, const glm::vec3 &col, const Shape *s) noexcept
 : shape(s)
 , color(col)
 , outline_color(-1, -1, -1)
+, label("some block")
 , id(0)
 , luminosity(0)
 , visible(v)