#include "client/rendering/FontRenderer.h" const size_t FontRenderer::BUFFER_LENGTH = 8 * 1024 * 1024; FontRenderer::FontRenderer() : tex("resources/font8x8.png"), offset(BUFFER_LENGTH), vba(0), vbo(0) { glGenVertexArrays(1, &vba); glBindVertexArray(vba); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof (float) * 7, static_cast (0)); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof (float) * 7, static_cast (0) + 2); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof (float) * 7, static_cast (0) + 4); glEnableVertexAttribArray(2); } FontRenderer::~FontRenderer() { glDeleteVertexArrays(1, &vba); glDeleteBuffers(1, &vbo); } void FontRenderer::drawString(float x, float y, const char* text) { glBindBuffer(GL_ARRAY_BUFFER, vbo); const size_t maxIndex = 256; const size_t maxLength = maxIndex * 4 * sizeof (float) * 7; if(offset + maxLength >= BUFFER_LENGTH) { offset = 0; glBufferData(GL_ARRAY_BUFFER, BUFFER_LENGTH, nullptr, GL_STREAM_DRAW); } float* buffer = static_cast (glMapBufferRange(GL_ARRAY_BUFFER, offset, maxLength, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT)); if(buffer == nullptr) { return; } size_t index = 0; size_t i = 0; float r = 1.0f; float g = 1.0f; float b = 1.0f; while(text[index] != '\0' && index < maxIndex) { char c = text[index]; if(c == '&') { if(text[index + 1] == '\0' || text[index + 2] == '\0' || text[index + 3] == '\0') { break; } r = (text[index + 1] - '0') * (1.0f / 9.0f); g = (text[index + 2] - '0') * (1.0f / 9.0f); b = (text[index + 3] - '0') * (1.0f / 9.0f); index += 4; continue; } float minX = (c & 0xF) * (1.0f / 16.0f); float minY = (c >> 4) * (1.0f / 16.0f); float maxX = minX + (1.0f / 16.0f); float maxY = minY + (1.0f / 16.0f); buffer[i++] = x; buffer[i++] = y; buffer[i++] = minX; buffer[i++] = minY; buffer[i++] = r; buffer[i++] = g; buffer[i++] = b; buffer[i++] = x; buffer[i++] = y + 8; buffer[i++] = minX; buffer[i++] = maxY; buffer[i++] = r; buffer[i++] = g; buffer[i++] = b; buffer[i++] = x + 8; buffer[i++] = y; buffer[i++] = maxX; buffer[i++] = minY; buffer[i++] = r; buffer[i++] = g; buffer[i++] = b; buffer[i++] = x + 8; buffer[i++] = y + 8; buffer[i++] = maxX; buffer[i++] = maxY; buffer[i++] = r; buffer[i++] = g; buffer[i++] = b; x += 8; index++; } glUnmapBuffer(GL_ARRAY_BUFFER); glBindVertexArray(vba); tex.bind(0); glDrawArrays(GL_TRIANGLE_STRIP, offset / (sizeof (float) * 7), i / 7); offset += maxLength; }