#include "client/rendering/Renderer.h" #include "rendering/Attributes.h" #include "utils/Buffer.h" Renderer::Renderer() : buffer(16), font("resources/font8x8.png"), text(nullptr), index(0), maxIndex(0), x(0.0f), y(0.0f), vertices(0) { vertexBuffer.setAttributes( Attributes().addFloat(2).addFloat(2).addColor4()); vertexBuffer.setStreamData(1024 * 1024); } void Renderer::setupStringRead(const char* s, int limit) { text = s; index = 0; maxIndex = limit; } void Renderer::setupString(const Vector2& pos, const char* s, int limit) { buffer.clear(); setupStringRead(s, limit); x = pos[0]; y = pos[1]; vertices = 0; color = {0xFF, 0xFF, 0xFF, 0x00}; } bool Renderer::hasStringData() const { return (index < maxIndex || maxIndex < 0) && text[index] != '\0'; } char32_t Renderer::readUnicode() { char32_t c = text[index]; index++; if(c > 128 && hasStringData()) { c = (text[index] & 0x3F) | ((c & 0x1F) << 6); index++; } return c; } bool Renderer::readColor(char32_t c) { if(c != '&') { return false; } for(int i = 0; i < 3; i++) { if(!hasStringData()) { return true; } color[i] = ((text[index] - '0') * 255) / 9; index++; } return true; } void Renderer::addChar(char32_t c) { float minX = (c & 0xF) * (1.0f / 16.0f) + (1.0f / 128.0f); float minY = (c >> 4) * (1.0f / 16.0f); float maxX = minX + (1.0f / 16.0f) - (2.0f / 128.0f); float maxY = minY + (1.0f / 16.0f); buffer.add(x).add(y).add(minX).add(minY).add(color); buffer.add(x).add(y + 8.0f).add(minX).add(maxY).add(color); buffer.add(x + 6.0f).add(y).add(maxX).add(minY).add(color); buffer.add(x + 6.0f).add(y + 8.0f).add(maxX).add(maxY).add(color); x += 6; vertices += 4; } void Renderer::renderString(const Vector2& pos, const char* text, int limit) { setupString(pos, text, limit); while(hasStringData()) { char32_t c = readUnicode(); if(readColor(c)) { continue; } addChar(c); } font.bindTo(0); update(); vertexBuffer.drawStrip(vertices); } Vector2 Renderer::getStringSize(const char* text, int limit) { setupStringRead(text, limit); Vector2 size(0.0f, 8.0f); while(hasStringData()) { char32_t c = readUnicode(); if(readColor(c)) { continue; } size[0] += 6.0f; } return size; } void Renderer::renderRectangle(const Vector2& pos, const Vector2& size, Color4 c) { buffer.clear(); buffer.add(pos[0]).add(pos[1]).add(0.0f).add(0.0f).add(c); buffer.add(pos[0]).add(pos[1] + size[1]).add(0.0f).add(0.0f).add(c); buffer.add(pos[0] + size[0]).add(pos[1]).add(0.0f).add(0.0f).add(c); buffer.add(pos[0] + size[0]) .add(pos[1] + size[1]) .add(0.0f) .add(0.0f) .add(c); update(); vertexBuffer.drawStrip(4); } void Renderer::update() { vertexBuffer.updateData( 0, std::min(buffer.getLength(), vertexBuffer.getSize()), buffer); } int Renderer::charsInSpace(float width) { return std::abs(width / 6.0f); }