#include #include "client/engine/DirectRenderer.h" DirectRenderer::DirectRenderer() { glGenVertexArrays(1, &vba); glGenBuffers(1, &vbo); glBindVertexArray(vba); glBindBuffer(GL_ARRAY_BUFFER, vbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, false, 24, (GLvoid*) 0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, 24, (GLvoid*) 12); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, false, 24, (GLvoid*) 16); } DirectRenderer::DirectRenderer(const DirectRenderer& orig) { } DirectRenderer::~DirectRenderer() { glDeleteVertexArrays(1, &vba); glDeleteBuffers(1, &vbo); } void DirectRenderer::drawRectangle(float minX, float minY, float maxX, float maxY, float tMinX, float tMinY, float tMaxX, float tMaxY, IntColor c) { glBindBuffer(GL_ARRAY_BUFFER, vbo); if(offset + OBJECT_LENGTH >= BUFFER_LENGTH) { offset = 0; glBufferData(GL_ARRAY_BUFFER, BUFFER_LENGTH, NULL, GL_STREAM_DRAW); } float* buffer = (float*) glMapBufferRange(GL_ARRAY_BUFFER, offset, OBJECT_LENGTH, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); if(buffer == NULL) { return; } buffer[0] = minX; buffer[1] = maxY; buffer[2] = 0.0f; buffer[3] = *((float*) (&c)); buffer[4] = tMinX; buffer[5] = tMaxY; buffer[6] = maxX; buffer[7] = maxY; buffer[8] = 0.0f; buffer[9] = *((float*) (&c)); buffer[10] = tMaxX; buffer[11] = tMaxY; buffer[12] = minX; buffer[13] = minY; buffer[14] = 0.0f; buffer[15] = *((float*) (&c)); buffer[16] = tMinX; buffer[17] = tMinY; buffer[18] = maxX; buffer[19] = minY; buffer[20] = 0.0f; buffer[21] = *((float*) (&c)); buffer[22] = tMaxX; buffer[23] = tMinY; glUnmapBuffer(GL_ARRAY_BUFFER); glBindVertexArray(vba); glDrawArrays(GL_TRIANGLE_STRIP, offset / (OBJECT_LENGTH / 4), 4); offset += OBJECT_LENGTH; } void DirectRenderer::drawRectangle(float minX, float minY, float maxX, float maxY, IntColor c) { drawRectangle(minX, minY, maxX, maxY, 0.0f, 0.0f, 0.0f, 0.0f, c); } void DirectRenderer::drawRectangle(float minX, float minY, float maxX, float maxY, float tMinX, float tMinY, float tMaxX, float tMaxY) { drawRectangle(minX, minY, maxX, maxY, tMinX, tMinY, tMaxX, tMaxY, 0); } float DirectRenderer::drawString(float x, float y, bool shadow, string& s) { int size = s.length() * OBJECT_LENGTH * (shadow + 1); glBindBuffer(GL_ARRAY_BUFFER, vbo); if(offset + size >= BUFFER_LENGTH) { offset = 0; glBufferData(GL_ARRAY_BUFFER, BUFFER_LENGTH, NULL, GL_STREAM_DRAW); } float* buffer = (float*) glMapBufferRange(GL_ARRAY_BUFFER, offset, size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); if(buffer == NULL) { return y; } int index = 0; if(shadow) { addString(x + SHADOW_STEP, y + SHADOW_STEP, index, buffer, Color::DARK_COLORS, s); } y = addString(x, y, index, buffer, Color::COLORS, s); glUnmapBuffer(GL_ARRAY_BUFFER); glBindVertexArray(vba); FONTS[min(Engine::getScale() - 1, FONTS_LENGTH - 1)].bind(); glDrawArrays(GL_TRIANGLE_STRIP, offset / (OBJECT_LENGTH / 4), (index + 1) / 6); offset += size; return y; } float DirectRenderer::addString(float x, float y, int& index, float* data, const IntColor* color, string& s) { int l = min((int) s.length(), static_cast(MAX_STRING_LENGTH)); //x = roundf(x / GameEngine::scale) * GameEngine::scale; //y = roundf(y / GameEngine::scale) * GameEngine::scale; float oldX = x; float currentColor = *((float*) (&(color[Color::COLOR_AMOUNT - 1]))); for(int pos = 0; pos < l; pos++) { char c = s[pos]; if(c == COLOR_CHAR) { pos++; if(pos < l) { int index = s[pos] - 'a'; if(index >= 0 && index < Color::COLOR_AMOUNT) { currentColor = *((float*) (&(color[index]))); } } continue; } else if(c == '\n') { y += FONT_SIZE + LINE_STEP; x = oldX; continue; } float tMinX = (c & 0xF) * 0.0625f; float tMinY = (c >> 4) * 0.0625f; float tMaxX = tMinX + 0.0625f; float tMaxY = tMinY + 0.0625f; float maxX = x + FONT_SIZE; float maxY = y + FONT_SIZE; data[index++] = x; data[index++] = maxY; data[index++] = 0.0f; data[index++] = currentColor; data[index++] = tMinX; data[index++] = tMaxY; data[index++] = maxX; data[index++] = maxY; data[index++] = 0.0f; data[index++] = currentColor; data[index++] = tMaxX; data[index++] = tMaxY; data[index++] = x; data[index++] = y; data[index++] = 0.0f; data[index++] = currentColor; data[index++] = tMinX; data[index++] = tMinY; data[index++] = maxX; data[index++] = y; data[index++] = 0.0f; data[index++] = currentColor; data[index++] = tMaxX; data[index++] = tMinY; x += FONT_SIZE; } return y + FONT_SIZE + LINE_STEP; } void DirectRenderer::getStringSize(float& width, float& height, string& s) { int l = min((int) s.length(), static_cast(MAX_STRING_LENGTH)); width = 0.0f; height = FONT_SIZE + LINE_STEP; float currentWidth = 0.0f; for(int pos = 0; pos < l; pos++) { char c = s[pos]; if(c == COLOR_CHAR) { pos++; continue; } else if(c == '\n') { if(currentWidth > width) { width = currentWidth; } height += FONT_SIZE + LINE_STEP; currentWidth = 0.0f; continue; } currentWidth += FONT_SIZE; } if(currentWidth > width) { width = currentWidth; } }