You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
4.8 KiB
121 lines
4.8 KiB
#include "TextComponent.h" |
|
|
|
TextComponent::TextComponent(const std::string &text, const int x, const int y, const int fontSize, const bool bold, const int windowWidth, const int windowHeight) { |
|
this->text = text; |
|
this->x = x; |
|
this->y = y; |
|
this->fontSize = fontSize; |
|
this->bold = bold; |
|
|
|
rasterize(text, x, y, fontSize, bold, windowWidth, windowHeight); |
|
|
|
for (int i = 0; i < glyphVertices.size(); i++) { |
|
const Glyph &glyph = glyphs[i]; |
|
const std::unique_ptr<float[]> &glyphVertice = glyphVertices[i]; |
|
vertexArrayObjects.push_back(0); |
|
vertexBufferObjects.push_back(0); |
|
elementBufferObjects.push_back(0); |
|
glGenVertexArrays(1, &vertexArrayObjects.back()); |
|
glGenBuffers(1, &vertexBufferObjects.back()); |
|
glGenBuffers(1, &elementBufferObjects.back()); |
|
|
|
glBindVertexArray(vertexArrayObjects.back()); |
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjects.back()); |
|
glBufferData(GL_ARRAY_BUFFER, ((3 + 2) * 4) * sizeof(float), glyphVertice.get(), GL_STATIC_DRAW); |
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObjects.back()); |
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); |
|
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*) (0 * sizeof(float))); |
|
glEnableVertexAttribArray(0); |
|
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*) (3 * sizeof(float))); |
|
glEnableVertexAttribArray(1); |
|
|
|
textures.push_back(0); |
|
glGenTextures(1, &textures.back()); |
|
glBindTexture(GL_TEXTURE_2D, textures.back()); |
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glyph.textureWidth, glyph.textureHeight, 0, GL_RED, GL_UNSIGNED_BYTE, glyph.textureData.get()); |
|
glGenerateMipmap(GL_TEXTURE_2D); |
|
} |
|
} |
|
|
|
TextComponent::~TextComponent() { |
|
for (int i = 0; i < vertexArrayObjects.size(); i++) { |
|
glDeleteVertexArrays(1, &vertexArrayObjects[i]); |
|
glDeleteBuffers(1, &vertexBufferObjects[i]); |
|
glDeleteBuffers(1, &elementBufferObjects[i]); |
|
glDeleteTextures(1, &textures[i]); |
|
} |
|
} |
|
#include <iostream> |
|
void TextComponent::rasterize(const std::string &text, const int x, const int y, const int fontSize, const bool bold, const int windowWidth, const int windowHeight) { |
|
const std::unique_ptr<TextRasterizer> textRasterizer = std::make_unique<TextRasterizer>("DejaVuSerif.ttf", fontSize, 72, bold); |
|
unsigned int glyphCount; |
|
glyphs = textRasterizer->rasterize(text, x, y, windowWidth, windowHeight, height, glyphCount); |
|
if (glyphs == nullptr) { |
|
return; |
|
} |
|
|
|
glyphVertices.clear(); |
|
for (int i = 0; i < glyphCount; i++) { |
|
const Glyph &glyph = glyphs[i]; |
|
|
|
float vx0 = glyph.x0; |
|
float vy0 = glyph.y0; |
|
float vx1 = glyph.x1; |
|
float vy1 = glyph.y1; |
|
pointToViewport(vx0, vy0, windowWidth, windowHeight); |
|
pointToViewport(vx1, vy1, windowWidth, windowHeight); |
|
|
|
std::unique_ptr<float[]> vertices = std::make_unique<float[]>(20); |
|
vertices[(0 * 5) + 0] = vx0; |
|
vertices[(0 * 5) + 1] = vy0; |
|
vertices[(0 * 5) + 2] = 0.0f; |
|
vertices[(0 * 5) + 3] = glyph.s0; |
|
vertices[(0 * 5) + 4] = glyph.t0; |
|
vertices[(1 * 5) + 0] = vx0; |
|
vertices[(1 * 5) + 1] = vy1; |
|
vertices[(1 * 5) + 2] = 0.0f; |
|
vertices[(1 * 5) + 3] = glyph.s0; |
|
vertices[(1 * 5) + 4] = glyph.t1; |
|
vertices[(2 * 5) + 0] = vx1; |
|
vertices[(2 * 5) + 1] = vy1; |
|
vertices[(2 * 5) + 2] = 0.0f; |
|
vertices[(2 * 5) + 3] = glyph.s1; |
|
vertices[(2 * 5) + 4] = glyph.t1; |
|
vertices[(3 * 5) + 0] = vx1; |
|
vertices[(3 * 5) + 1] = vy0; |
|
vertices[(3 * 5) + 2] = 0.0f; |
|
vertices[(3 * 5) + 3] = glyph.s1; |
|
vertices[(3 * 5) + 4] = glyph.t0; |
|
glyphVertices.push_back(std::move(vertices)); |
|
} |
|
} |
|
|
|
void TextComponent::render() { |
|
if (verticesDirty) { |
|
for (int i = 0; i < vertexArrayObjects.size(); i++) { |
|
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjects[i]); |
|
glBufferData(GL_ARRAY_BUFFER, ((3 + 2) * 4) * sizeof(float), glyphVertices[i].get(), GL_STATIC_DRAW); |
|
} |
|
verticesDirty = false; |
|
} |
|
for (int i = vertexArrayObjects.size() - 1; i >= 0; i--) { |
|
glBindVertexArray(vertexArrayObjects[i]); |
|
glBindTexture(GL_TEXTURE_2D, textures[i]); |
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); |
|
} |
|
} |
|
|
|
void TextComponent::resize(const int x, const int y, const int windowWidth, const int windowHeight) { |
|
rasterize(text, x, y, fontSize, bold, windowWidth, windowHeight); |
|
verticesDirty = true; |
|
} |
|
|
|
void TextComponent::pointToViewport(float &x, float &y, const int windowWidth, const int windowHeight) const { |
|
x = ((x / windowWidth) * 2) - 1; |
|
y = ((y / windowHeight) * 2) - 1; |
|
}
|
|
|