diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-01-27 21:47:04 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-01-27 21:47:04 +0000 |
commit | 264640420882ceeafd9b1149eba9472cf8835e7b (patch) | |
tree | dad2b2cbe2bc8bf5560f4859880549472f808671 /ui | |
parent | Add traits vertex attrib func override for arrays (diff) | |
download | ilt-264640420882ceeafd9b1149eba9472cf8835e7b.tar.bz2 ilt-264640420882ceeafd9b1149eba9472cf8835e7b.tar.xz ilt-264640420882ceeafd9b1149eba9472cf8835e7b.zip |
Render text in N draw calls
Creates a single buffer per required texture and draws the whole buffer in one go. It does
introduce the use of deprecated GL_QUADS primitive, but it's the easiest way to go without
needing indices, repeated vertices etc
Diffstat (limited to 'ui')
-rw-r--r-- | ui/text.cpp | 63 | ||||
-rw-r--r-- | ui/text.h | 17 |
2 files changed, 43 insertions, 37 deletions
diff --git a/ui/text.cpp b/ui/text.cpp index 5b9e591..5675061 100644 --- a/ui/text.cpp +++ b/ui/text.cpp @@ -1,37 +1,48 @@ #include "text.h" #include "font.h" #include "gfx/gl/uiShader.h" +#include "gfx/gl/vertexArrayObject.h" #include "uiComponent.h" #include <array> +#include <collections.h> #include <glArrays.h> #include <glm/gtc/type_ptr.hpp> +#include <maths.h> +#include <numeric> #include <utility> -Text::Text(std::string_view s, const Font & font, Position pos, glm::vec3 c) : UIComponent {pos}, colour {c} +Text::Text(std::string_view s, const Font & font, Position pos, glm::vec3 c) : + UIComponent {pos}, colour {c}, font {font} { - for (const auto & textureQuads : font.render(s)) { - auto & rendering - = models.emplace_back(textureQuads.first, static_cast<GLsizei>(6 * textureQuads.second.size())); - glBindVertexArray(rendering.vao); - - glBindBuffer(GL_ARRAY_BUFFER, rendering.vbo); - std::vector<glm::vec4> vertices; - vertices.reserve(6 * textureQuads.second.size()); - for (const auto & quad : textureQuads.second) { - for (auto offset = 0U; offset < 3; offset += 2) { - for (auto vertex = 0U; vertex < 3; vertex += 1) { - vertices.emplace_back(quad[(vertex + offset) % 4] + glm::vec4 {position.origin, 0, 0}); - } - } - }; - glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(sizeof(glm::vec4)) * rendering.count, - glm::value_ptr(vertices.front()), GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), nullptr); + VertexArrayObject {vao}.addAttribs<Font::Quad::value_type>(quads.bufferName(), 0); + operator=(s); +} - glBindVertexArray(0); +Text & +Text::operator=(const std::string_view s) +{ + auto tquads = font.render(s); + models.resize(tquads.size()); + const auto glyphCount = std::accumulate(tquads.begin(), tquads.end(), size_t {}, [](auto && init, const auto & q) { + return init += q.second.size(); + }); + quads.resize(glyphCount); + GLint current = 0; + auto model = models.begin(); + auto quad = quads.begin(); + for (const auto & [texture, fquads] : tquads) { + model->first = texture; + model->second = {fquads.size() * 4, current * 4}; + current += static_cast<GLint>(fquads.size()); + model++; + quad = std::transform(fquads.begin(), fquads.end(), quad, [this](const Font::Quad & q) { + return q * [this](const glm::vec4 & corner) { + return corner + glm::vec4 {this->position.origin, 0, 0}; + }; + }); } + quads.unmap(); + return *this; } void @@ -39,10 +50,10 @@ Text::render(const UIShader & shader, const Position &) const { shader.text.use(colour); glActiveTexture(GL_TEXTURE0); + glBindVertexArray(vao); for (const auto & m : models) { - glBindTexture(GL_TEXTURE_2D, m.texture); - glBindVertexArray(m.vao); - glDrawArrays(GL_TRIANGLES, 0, m.count); + glBindTexture(GL_TEXTURE_2D, m.first); + glDrawArrays(GL_QUADS, m.second.second, m.second.first); } glBindVertexArray(0); glBindTexture(GL_TEXTURE_2D, 0); @@ -53,5 +64,3 @@ Text::handleInput(const SDL_Event &, const Position &) { return false; } - -Text::Model::Model(GLuint t, GLsizei c) : texture {t}, count {c} { } @@ -1,12 +1,12 @@ #pragma once #include "font.h" +#include "glContainer.h" #include "uiComponent.h" #include <glArrays.h> #include <glad/gl.h> #include <glm/glm.hpp> #include <string_view> -#include <vector> class UIShader; union SDL_Event; @@ -18,15 +18,12 @@ public: void render(const UIShader &, const Position & parentPos) const override; bool handleInput(const SDL_Event &, const Position & parentPos) override; -private: - struct Model { - Model(GLuint, GLsizei); - GLuint texture; - GLsizei count; - glVertexArray vao; - glBuffer vbo; - }; + Text & operator=(const std::string_view s); - std::vector<Model> models; +private: + std::vector<std::pair<GLuint, std::pair<GLsizei, GLint>>> models; + glContainer<Font::Quad> quads; + glVertexArray vao; glm::vec3 colour; + const Font & font; }; |