Skip to content

Commit

Permalink
[Text] Now uses a VBO to display characters.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unarelith committed Mar 4, 2020
1 parent 896460c commit be86e66
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 66 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ This list is non exhaustive.
- Particle system
- Fluid propagation
- Player model display (currently displaying an ugly box)
- Day/night cycle with sun/moon display
- Day/night cycle with sun/moon display ([#73](https://github.com/Unarelith/OpenMiner/issues/73))
- Real worldgen (seed-based, biomes, cave tunnels)
- Entities (block drops, mobs, etc...)
- Clouds ([#52](https://github.com/Unarelith/OpenMiner/pull/52))
Expand Down
11 changes: 0 additions & 11 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@ TODO

# Issues

• DONE: Blocks can be placed inside the player (check for AABB?)
• DONE: Sometimes it’s possible to aim between two blocks and right-clicking will replace one
• TODO: GUI scale issues
◦ TODO: `HUD` doesn’t update when GUI scale is changed
◦ TODO: `SettingsMenuState` should update scaling when the setting is changed
◦ DONE: All Lua-defined GUI are not scaled correctly with lower GUI scale settings
◦ DONE: Send client screen size and GUI scale to server
◦ TODO: Trees should block light
• TODO: Blocks can be accessed from outside the world (will need a refactoring)
• TODO: Collisions are fucked up with blocks placed at `x = -1` from `x = 0`
Expand All @@ -27,13 +23,6 @@ TODO
→ Maybe this is the way to add custom vertex attributes while having default ones? Check 3dee
→ Or maybe it would be better to use a VAO in `GameKit`

# GUI

• DONE: Implement `PlayerInventoryWidget` completely in Lua
• DONE: Implement `PlayerCraftingWidget` completely in Lua
• DONE: Implement `FurnaceWidget` completely in Lua
◦ DONE: Add a `ProgressBarWidget`

# Menus

• TODO: World loading/saving
Expand Down
12 changes: 12 additions & 0 deletions client/source/gui/Font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ Font::Font(const std::string &textureName, const std::string &configPath)
parseConfig(configPath);
}

gk::Vector2f Font::getTexCoords(u8 c, u8 x, u8 y) const {
u8 tileX = c % (m_texture.getSize().x / m_width);
u8 tileY = c / (m_texture.getSize().x / m_width);

gk::Vector2f texCoords{
(tileX + x) * m_width / (float)m_texture.getSize().x,
(tileY + y) * m_height / (float)m_texture.getSize().y
};

return texCoords;
}

void Font::parseConfig(const std::string &configPath) {
std::ifstream file(configPath);

Expand Down
9 changes: 7 additions & 2 deletions client/source/gui/Font.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

#include <string>

#include <gk/core/IntTypes.hpp>
#include <gk/core/Vector2.hpp>

namespace gk {
class Texture;
Expand All @@ -39,7 +39,10 @@ class Font {
public:
Font(const std::string &textureName, const std::string &configPath);

u8 getCharWidth(u8 c) { return m_charWidth[c]; }
gk::Vector2f getTexCoords(u8 c, u8 x, u8 y) const;

u8 getCharWidth(u8 c) const { return m_charWidth[c]; }
gk::Vector2i getTileSize() const { return {m_width, m_height}; }

const std::string &textureName() const { return m_textureName; } // FIXME: Will be removed later
const gk::Texture &texture() const { return m_texture; }
Expand All @@ -51,6 +54,8 @@ class Font {
gk::Texture &m_texture;

u8 m_charWidth[256];
u8 m_width = 8; // FIXME: Hardcoded value
u8 m_height = 8; // FIXME: Hardcoded value
};

#endif // FONT_HPP_
112 changes: 86 additions & 26 deletions client/source/gui/Text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*
* =====================================================================================
*/
#include <gk/gl/Texture.hpp>
#include <gk/resource/ResourceHandler.hpp>

#include "Color.hpp"
Expand All @@ -37,78 +38,137 @@ Text::Text() : m_font(gk::ResourceHandler::getInstance().get<Font>("font-ascii")
void Text::setText(const std::string &text) {
if (m_text != text) {
m_text = text;
updateTextSprites();
m_isUpdateNeeded = true;
}
}

void Text::setColor(const gk::Color &color) {
if (m_color != color) {
m_color = color;
updateTextSprites();
m_isUpdateNeeded = true;
}
}

void Text::setPadding(int x, int y) {
if (m_padding.x != x || m_padding.y != y) {
m_padding.x = x;
m_padding.y = y;
m_isUpdateNeeded = true;
}
}

void Text::setMaxLineLength(unsigned int maxLineLength) {
if (m_maxLineLength != maxLineLength) {
m_maxLineLength = maxLineLength;
m_isUpdateNeeded = true;
}
}

void Text::draw(gk::RenderTarget &target, gk::RenderStates states) const {
if (m_isUpdateNeeded) {
updateVertexBuffer();
m_isUpdateNeeded = false;
}

if (m_verticesCount == 0) return;

states.transform *= getTransform();

target.draw(m_background, states);

states.transform.translate(m_padding.x, m_padding.y);
states.texture = &m_font.texture();
states.vertexAttributes = gk::VertexAttribute::Only2d;

for(const gk::Sprite &sprite : m_textSprites) {
target.draw(sprite, states);
}
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);

target.draw(m_vbo, GL_TRIANGLES, 0, m_verticesCount, states);
}

// FIXME: USE A VBO INSTEAD
void Text::updateTextSprites() {
m_textSprites.clear();
void Text::updateVertexBuffer() const {
if (!m_isUpdateNeeded) return;

unsigned int x = 0;
unsigned int y = 0;
unsigned int maxX = 0;
std::vector<gk::Vertex> vertices;

u32 x = 0;
u32 y = 0;
u32 maxX = 0;
gk::Color color = gk::Color{70, 70, 70, 255};
for(char c : m_text) {
if (c == '\n' || (m_maxLineLength && x + m_font.getCharWidth(c) >= m_maxLineLength)) {
y += 9;
y += m_font.getTileSize().y + 1;
x = 0;
continue;
}

gk::Sprite sprite{m_font.textureName(), 8, 8};
sprite.setCurrentFrame(c);
sprite.setPosition(x + 1, y + 1, 0);
sprite.setColor(color);
m_textSprites.emplace_back(std::move(sprite));
addCharacter(x + 1, y + 1, color, c, vertices);

x += m_font.getCharWidth(c);
}

x = 0;
y = 0;
color = m_color;
for(char c : m_text) {
if (c == '\n' || (m_maxLineLength && x + m_font.getCharWidth(c) >= m_maxLineLength)) {
maxX = std::max(x, maxX);
y += 9;
y += m_font.getTileSize().y + 1;
x = 0;
continue;
}

gk::Sprite sprite{m_font.textureName(), 8, 8};
sprite.setCurrentFrame(c);
sprite.setPosition(x, y, 0);
if (c == '[')
color = Color::Blue;
sprite.setColor(color);
m_textSprites.emplace_back(std::move(sprite));

addCharacter(x, y, color, c, vertices);

x += m_font.getCharWidth(c);
}

m_verticesCount = vertices.size();

gk::VertexBuffer::bind(&m_vbo);
m_vbo.setData(sizeof(gk::Vertex) * m_verticesCount, vertices.data(), GL_DYNAMIC_DRAW);
gk::VertexBuffer::bind(nullptr);

m_size.x = std::max(x, maxX);
m_size.y = y + 9;
m_size.y = y + m_font.getTileSize().y + 1;

unsigned int backgroundX = std::max<int>(m_background.getSize().x, m_size.x + m_padding.x);
unsigned int backgroundY = std::max<int>(m_background.getSize().y, m_size.y + m_padding.y);
u32 backgroundX = std::max<s32>(m_background.getSize().x, m_size.x + m_padding.x);
u32 backgroundY = std::max<s32>(m_background.getSize().y, m_size.y + m_padding.y);

m_background.setSize(backgroundX, backgroundY);
}

void Text::addCharacter(u32 x, u32 y, const gk::Color &color, u8 c, std::vector<gk::Vertex> &vertices) const {
static const u8 coords[6][2] = {
{1, 0},
{0, 0},
{1, 1},

{1, 1},
{0, 0},
{0, 1},
};

for (int i = 0 ; i < 6 ; ++i) {
vertices.emplace_back();
gk::Vertex &vertex = vertices.back();

vertex.coord3d[0] = x + coords[i][0] * m_font.getTileSize().x;
vertex.coord3d[1] = y + coords[i][1] * m_font.getTileSize().y;
vertex.coord3d[2] = 0;
vertex.coord3d[3] = -1;

vertex.color[0] = color.r;
vertex.color[1] = color.g;
vertex.color[2] = color.b;
vertex.color[3] = color.a;

gk::Vector2f texCoords = m_font.getTexCoords(c, coords[i][0], coords[i][1]);
vertex.texCoord[0] = texCoords.x;
vertex.texCoord[1] = texCoords.y;
}
}

22 changes: 14 additions & 8 deletions client/source/gui/Text.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
#define TEXT_HPP_

#include <string>
#include <vector>

#include <gk/gl/Vertex.hpp>
#include <gk/graphics/RectangleShape.hpp>
#include <gk/graphics/Sprite.hpp>

class Font;

Expand All @@ -49,28 +50,33 @@ class Text : public gk::Drawable, public gk::Transformable {
void setBackgroundColor(const gk::Color &color) { m_background.setFillColor(color); }
void setBackgroundSize(unsigned int width, unsigned int height) { m_background.setSize(width, height); }

void setPadding(int x, int y) { m_padding.x = x; m_padding.y = y; updateTextSprites(); }
void setPadding(int x, int y);

void setMaxLineLength(unsigned int maxLineLength) { m_maxLineLength = maxLineLength; updateTextSprites(); }
void setMaxLineLength(u32 maxLineLength);

void updateVertexBuffer() const;

private:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;

void updateTextSprites();
void addCharacter(u32 x, u32 y, const gk::Color &color, u8 c, std::vector<gk::Vertex> &vertices) const;

std::string m_text;
std::vector<gk::Sprite> m_textSprites;

Font &m_font;

gk::Vector2i m_size;
gk::VertexBuffer m_vbo;
mutable u32 m_verticesCount = 0;
mutable bool m_isUpdateNeeded = true;

mutable gk::Vector2i m_size;
gk::Vector2i m_padding{0, 0};

gk::Color m_color = gk::Color::White;

gk::RectangleShape m_background;
mutable gk::RectangleShape m_background;

unsigned int m_maxLineLength = 0;
u32 m_maxLineLength = 0;
};

#endif // TEXT_HPP_
16 changes: 1 addition & 15 deletions client/source/gui/TextButton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@
#include "TextButton.hpp"

TextButton::TextButton(Widget *parent) : Widget(200, 20, parent) {
// m_text.setFont("font-default");
// m_text.setCharacterSize(8);
//
// m_textShadow.setFont("font-default");
// m_textShadow.setCharacterSize(8);
// m_textShadow.setColor(gk::Color{70, 70, 70, 255});

m_background.setClipRect(0, 66, 200, 20);
m_hoverBackground.setClipRect(0, 86, 200, 20);
m_disabledBackground.setClipRect(0, 46, 200, 20);
Expand Down Expand Up @@ -62,15 +55,9 @@ void TextButton::onEvent(const SDL_Event &event) {

void TextButton::setText(const std::string &text) {
m_text.setText(text);
m_text.updateVertexBuffer();
m_text.setPosition(m_width / 2 - m_text.getSize().x / 2,
m_height / 2 - m_text.getSize().y / 2, 0);

// m_text.setString(text);
// m_text.setPosition(m_width / 2 - m_text.getLocalBounds().width / 2,
// m_height / 2 - m_text.getLocalBounds().height / 2 - 1, 0);

// m_textShadow.setString(text);
// m_textShadow.setPosition(m_text.getPosition() + gk::Vector3f{1.f, 1.f, 0.f});
}

void TextButton::draw(gk::RenderTarget &target, gk::RenderStates states) const {
Expand All @@ -83,7 +70,6 @@ void TextButton::draw(gk::RenderTarget &target, gk::RenderStates states) const {
else
target.draw(m_background, states);

// target.draw(m_textShadow, states);
target.draw(m_text, states);
}

3 changes: 0 additions & 3 deletions client/source/gui/TextButton.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <sol.hpp>

#include <gk/graphics/Image.hpp>
// #include <gk/graphics/Text.hpp>

#include "Text.hpp"
#include "Widget.hpp"
Expand Down Expand Up @@ -63,8 +62,6 @@ class TextButton : public Widget {
gk::Image m_disabledBackground{"texture-widgets"};

Text m_text;
// gk::Text m_text;
// gk::Text m_textShadow;

CppCallback m_cppCallback;
LuaCallback m_luaCallback;
Expand Down
2 changes: 2 additions & 0 deletions client/source/hud/BlockInfoWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#ifndef BLOCKINFOWIDGET_HPP_
#define BLOCKINFOWIDGET_HPP_

#include <gk/graphics/Sprite.hpp>

#include "ItemWidget.hpp"

class BlockInfoWidget : public Widget {
Expand Down
1 change: 1 addition & 0 deletions client/source/hud/ChatMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ ChatMessage::ChatMessage(u16 clientID, const std::string &message, u32 posY) {
m_text.setBackgroundSize(300, 10);
m_text.setMaxLineLength(300);
m_text.setPadding(1, 1);
m_text.updateVertexBuffer();

m_timer.reset();
m_timer.start();
Expand Down
2 changes: 2 additions & 0 deletions client/source/hud/ChatMessage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#ifndef CHATMESSAGE_HPP_
#define CHATMESSAGE_HPP_

#include <gk/core/Timer.hpp>

#include "Text.hpp"

class ChatMessage : public gk::Drawable, public gk::Transformable {
Expand Down

0 comments on commit be86e66

Please sign in to comment.