#include "DirectRenderer.h" #include "GameEngine.h" #include Texture DirectRenderer::FONTS[FONTS_LENGTH]; DirectRenderer::DirectRenderer() { } DirectRenderer::DirectRenderer(const DirectRenderer& orig) { } DirectRenderer::~DirectRenderer() { glDeleteVertexArrays(1, &vba); glDeleteBuffers(1, &vbo); } void DirectRenderer::init() { if(!FONTS[0].isLoaded()) { FONTS[0].load("resources/font8x8.png"); } if(!FONTS[1].isLoaded()) { FONTS[1].load("resources/font16x16.png"); } if(!FONTS[2].isLoaded()) { FONTS[2].load("resources/font24x24.png"); } 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); } void DirectRenderer::prepare() { int scale = GameEngine::scale; view.set(0, 0, (2.0f * scale) / GameEngine::width); view.set(1, 1, (-2.0f * scale) / GameEngine::height); view.set(2, 2, (-1.0f * scale) / GameEngine::height); view.set(0, 3, -1.0f); view.set(1, 3, 1.0f); view.set(2, 3, 0.5f); view.set(3, 3, 1.0f); GameEngine::updateView(view); glUniformMatrix4fv(GameEngine::unifProjMatrix, 1, 0, proj.getValues()); } 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(GameEngine::scale - 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; } /* public Rectangle getSize(String s) { int length = 0; int counter = 0; for(int i = 0; i < s.length(); i++) { switch(s.charAt(i)) { case '\n': counter++; break; case COLOR_CHAR: i++; break; default: length++; } } return new Rectangle(FONT_SIZE * length, (FONT_SIZE + LINE_STEP) * counter); } public Rectangle getSize(int w, int h) { return new Rectangle(FONT_SIZE * w, (FONT_SIZE + LINE_STEP) * h); } public float getHeight() { return FONT_SIZE + LINE_STEP; } public float getWidth() { return FONT_SIZE; } */