summaryrefslogtreecommitdiff
path: root/ui/text.cpp
blob: 5675061e2740a4f09ea4a372e922494e5301299a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#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}, font {font}
{
	VertexArrayObject {vao}.addAttribs<Font::Quad::value_type>(quads.bufferName(), 0);
	operator=(s);
}

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
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.first);
		glDrawArrays(GL_QUADS, m.second.second, m.second.first);
	}
	glBindVertexArray(0);
	glBindTexture(GL_TEXTURE_2D, 0);
}

bool
Text::handleInput(const SDL_Event &, const Position &)
{
	return false;
}