#include "DefaultRendererOpenGL.hpp" #include "BehaviourScripts/Camera.hpp" #include "BehaviourScripts/Renderable.hpp" #define RENDERER_MAX_SPRITES 20000 #define RENDERER_MAX_INDECIES 60000 TSE::GLFW::DefaultRendererOpenGL::DefaultRendererOpenGL(Shader &shader) { iboData = new ushort[RENDERER_MAX_INDECIES]; InitShader(shader, true); } TSE::GLFW::DefaultRendererOpenGL::~DefaultRendererOpenGL() { if(vao != 0) glDeleteVertexArrays(1, &vao); delete[] iboData; delete ibo; } void TSE::GLFW::DefaultRendererOpenGL::InitShader(Shader &s, bool init) { if(!init) End(); if(vao != 0) { glDeleteVertexArrays(1, &vao); vao = 0; } s.Enable(); glGenVertexArrays(1, &vao); glBindVertexArray(vao); vbo.Bind(); int RENDERER_SPRITE_SIZE = s.packageSize() * 3; int RENDERER_BUFFER_SIZE = RENDERER_SPRITE_SIZE * RENDERER_MAX_SPRITES; vbo.SetData(RENDERER_BUFFER_SIZE, nullptr, GL_DYNAMIC_DRAW); s.Enable(true); vbo.Unbind(); glBindVertexArray(0); lastShader = &s; if(!init) Begin(); } void TSE::GLFW::DefaultRendererOpenGL::End() { glUnmapBuffer(GL_ARRAY_BUFFER); vbo.Unbind(); } void TSE::GLFW::DefaultRendererOpenGL::Flush() { lastShader->Flush(); glBindVertexArray(vao); bool ibobound = false; if(!CreateIbo()) { ibo->Bind(); ibobound = true; } for (int i = 0; i < camerasToRenderWith.size(); i++) { camerasToRenderWith[i]->PreDraw(lastShader); lastShader->DrawCall(indexCount); camerasToRenderWith[i]->PostDraw(); } if(ibobound) { ibo->Unbind(); } glBindVertexArray(0); indexCount = 0; iboOffset = 0; } void TSE::GLFW::DefaultRendererOpenGL::Begin() { vbo.Bind(); bufferPointer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); } void TSE::GLFW::DefaultRendererOpenGL::Submit(const Transformable &trans, TransformationStack &stack) { Submit(trans, (IShader*)lastShader, stack); } void TSE::GLFW::DefaultRendererOpenGL::Submit(const Transformable &trans, IShader *shader, TransformationStack &stack) { Shader* s = dynamic_cast(shader); if(lastShader == nullptr) InitShader(*s, true); if(!s->IsEnabled()) { if(indexCount != 0) { End(); Flush(); Begin(); } lastShader->Disable(); InitShader(*s); } auto* r = dynamic_cast(trans.GetBehaviourScript(RENDERABLE)); const std::vector indecies = r->GetIndices(); if(indexCount + indecies.size() > RENDERER_MAX_INDECIES) { End(); Flush(); Begin(); } int i = 0; for(ushort index : indecies) { iboData[indexCount + i++] = index + iboOffset; } iboOffset += r->GetVertexCount(); indexCount += indecies.size(); lastShader->Submit(trans, bufferPointer, stack, Redraw, *this); } void TSE::GLFW::DefaultRendererOpenGL::Redraw(IRenderer &rnd) { rnd.End(); rnd.Flush(); rnd.Begin(); } bool TSE::GLFW::DefaultRendererOpenGL::CreateIbo() { if(indexCount == 0) return true; if(ibo != nullptr) { ibo->WriteData(iboData, indexCount); } else { ibo = new IndexBuffer(iboData, indexCount); } return false; }