diff --git a/TSE_GlfwOpenGlImpl/src/DefaultRendererOpenGL.cpp b/TSE_GlfwOpenGlImpl/src/DefaultRendererOpenGL.cpp new file mode 100644 index 0000000..7bfef24 --- /dev/null +++ b/TSE_GlfwOpenGlImpl/src/DefaultRendererOpenGL.cpp @@ -0,0 +1,156 @@ +#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; +} diff --git a/TSE_GlfwOpenGlImpl/src/DefaultRendererOpenGL.hpp b/TSE_GlfwOpenGlImpl/src/DefaultRendererOpenGL.hpp new file mode 100644 index 0000000..52cd326 --- /dev/null +++ b/TSE_GlfwOpenGlImpl/src/DefaultRendererOpenGL.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "shader/Shader.hpp" +#include "buffer/VertexBuffer.hpp" +#include "buffer/IndexBuffer.hpp" +#include "interfaces/IRenderer.hpp" +#include + +namespace TSE::GLFW +{ + class DefaultRendererOpenGL : public IRenderer + { + private: + uint vao = 0; + VertexBuffer vbo; + Shader* lastShader; + IndexBuffer* ibo = nullptr; //idk why this needs to be a pointer but not the vbo, just don't question it. it works MAK 28.05.25 + ushort* iboData; + int indexCount = 0; + ushort iboOffset = 0; + float* bufferPointer; + ushort* indexBufferPointer; + public: + DefaultRendererOpenGL(Shader& shader); + ~DefaultRendererOpenGL(); + + void InitShader(Shader& s, bool init = false); + void End() override; + void Flush() override; + void Begin() override; + void Submit(const Transformable& trans, TransformationStack& stack) override; + void Submit(const Transformable& trans, IShader* shader, TransformationStack& stack) override; + + private: + static void Redraw(IRenderer& rnd); + bool CreateIbo(); + }; +} // namespace TSE::GLFW