From dd1befc2a08f01c0009b46e4a47ce731bd394149 Mon Sep 17 00:00:00 2001 From: Nathan Date: Tue, 10 Feb 2026 13:37:49 -0600 Subject: [PATCH] work on renderer --- include/pch.hpp | 1 + include/utils/Renderer/RenderTarget.h | 184 ++++++++++++++++++ include/utils/Renderer/Renderer.h | 100 ++-------- .../RendererOpenGL/RendererOpenGL.h | 104 ++++++++-- .../Window/WindowImpl/WindowGLFW/WindowGLFW.h | 2 + .../TestTriangle/TestTriangle.cpp | 99 ++-------- .../TestTriangle/TestTriangle.h | 11 +- modules/ImguiModule/ImguiModule.cpp | 28 ++- modules/ImguiModule/ImguiModule.h | 15 +- 9 files changed, 335 insertions(+), 209 deletions(-) create mode 100644 include/utils/Renderer/RenderTarget.h diff --git a/include/pch.hpp b/include/pch.hpp index 87d2d19..1825e6e 100644 --- a/include/pch.hpp +++ b/include/pch.hpp @@ -2,6 +2,7 @@ #define PCH_HPP #include +#include #include #include #include diff --git a/include/utils/Renderer/RenderTarget.h b/include/utils/Renderer/RenderTarget.h new file mode 100644 index 0000000..0ed4536 --- /dev/null +++ b/include/utils/Renderer/RenderTarget.h @@ -0,0 +1,184 @@ +#ifndef RENDERTARGET_H +#define RENDERTARGET_H + +#include "pch.hpp" + +#include "extratools.h" + +namespace Archimedes { + + class LayoutElement { + + public: + LayoutElement(unsigned int type, size_t count) : type(type), count(count) {} + + ~LayoutElement() {} + + unsigned int getType() const { return type; } + + size_t getSize() const { return size; } + + size_t getCount() const { return count; } + private: + + unsigned int type; + size_t size; + size_t count; + }; + + class VertexLayout { + + public: + VertexLayout() {} + ~VertexLayout() {} + + const std::vector& getElements() const { return elements; } + + private: + std::vector elements; + }; + + class VertexBuffer { + + public: + VertexBuffer(const void* data, size_t size) : data(data), size(size) { + } + + ~VertexBuffer() {} + + const void* getData() const { return data; } + size_t getSize() const { return size; } + + unsigned int id; + private: + const void* data; + size_t size; + }; + + class VertexArray { + + public: + VertexArray() { + } + + ~VertexArray() {} + + + unsigned int id; + private: + }; + + class IndexArray { + + public: + IndexArray(const unsigned int* indices, size_t count) : indices(indices), count(count) { + } + + ~IndexArray() {} + + const void* getIndicies() const { return indices; } + size_t getCount() const { return count; } + + unsigned int id; + private: + const unsigned int* indices; + size_t count; + }; + + class Shader { + + public: + enum class LoadType { + FromSource, + FromBin, + FromFileSource, + FromFileBin + }; + + Shader(const std::string& vs, const std::string& fs, LoadType loadType) : loadType(loadType) { + switch(loadType) { + case LoadType::FromSource: + this->vs = vs; + this->fs = fs; + break; + case LoadType::FromBin: + break; + case LoadType::FromFileSource: + this->vs = readSourceFile(vs); + this->fs = readSourceFile(fs); + break; + case LoadType::FromFileBin: + break; + default: + break; + } + } + + ~Shader() {} + + + std::string getVSource() const { return vs; } + std::string getFSource() const { return fs; } + + unsigned int id; + private: + LoadType loadType; + + std::string vs; + std::string fs; + + std::string readSourceFile(const std::string& path) { + + std::ifstream file(path); + + if(!file.is_open()) { + return ""; + } + + std::string s; + + while(!file.eof()) { + file >> s; + } + + return s; + + } + }; + + class RenderTarget { + + public: + RenderTarget(const void* data, size_t size, unsigned int* indices, size_t count, VertexLayout layout, const std::string& vs, const std::string& fs) + : vertexBuffer(data, size), + indexArray(indices, count), + layout(layout), + shader(vs, fs, Shader::LoadType::FromFileSource) { + + } + + RenderTarget(VertexBuffer vb, IndexArray ia, VertexLayout vl, Shader s) + : vertexBuffer(vb), + indexArray(ia), + layout(vl), + shader(s) { + + } + + ~RenderTarget() {} + + //private: + + VertexBuffer vertexBuffer; + + VertexArray vertexArray; + + VertexLayout layout; + + IndexArray indexArray; + + Shader shader; + }; +} + +#endif diff --git a/include/utils/Renderer/Renderer.h b/include/utils/Renderer/Renderer.h index 385c147..1cd405d 100644 --- a/include/utils/Renderer/Renderer.h +++ b/include/utils/Renderer/Renderer.h @@ -5,89 +5,10 @@ #include "extratools.h" +#include "RenderTarget.h" + namespace Archimedes { - - - class VertexArray { - - public: - VertexArray(const void* data, size_t size) : data(data), size(size) { - } - - ~VertexArray() {} - - const void* getData() const { return data; } - size_t getSize() const { return size; } - unsigned int getId() const { return id; } - - private: - const void* data; - size_t size; - unsigned int id; - }; - - class IndexArray { - - public: - IndexArray(const unsigned int* indices, size_t count) : indices(indices), count(count) { - } - - ~IndexArray() {} - - const void* getIndicies() const { return indices; } - size_t getCount() const { return count; } - - private: - const unsigned int* indices; - size_t count; - unsigned int id; - }; - - class Shader { - - public: - enum class LoadType { - FromSource, - FromFileSource, - FromFileBin - }; - - Shader(const std::string& source, LoadType loadType) { - switch(loadType) { - case LoadType::FromSource: - break; - case LoadType::FromFileSource: - break; - case LoadType::FromFileBin: - break; - default: - break; - } - } - - ~Shader() {} - - unsigned int getId() const { return id; } - - private: - unsigned int id; - }; - - class RenderTarget { - - public: - RenderTarget(const void* data, size_t size, size_t count, const std::string& shader) - : data(data), size(size), count(count), shader(shader) {} - - ~RenderTarget() {} - - private: - const void* data; - size_t size; - size_t count; - const std::string& shader; - }; - + class Renderer { public: @@ -103,7 +24,20 @@ namespace Archimedes { virtual void render() = 0; - virtual void draw(const VertexArray&, const IndexArray&, const Shader&) = 0; + virtual Shader createShader(const std::string& vs, const std::string& fs, const Shader::LoadType& lt) = 0; + + virtual RenderTarget* createRenderTarget( + const void* data, + size_t size, + unsigned int* indices, + size_t count, + VertexLayout layout, + const std::string& vs, + const std::string& fs, + const Shader::LoadType& lt + ) = 0; + + virtual void draw(const RenderTarget&) = 0; virtual Renderer* getRendererImpl() = 0; diff --git a/include/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.h b/include/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.h index 44cc944..358f22a 100644 --- a/include/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.h +++ b/include/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.h @@ -1,5 +1,4 @@ -#define RENDERER_OPENGL #ifdef RENDERER_OPENGL #undef RENDERER_OPENGL @@ -13,12 +12,6 @@ namespace Archimedes { - class VertexArrayOpenGL : public VertexArray {}; - - class IndexArrayOpenGL : public IndexArray {}; - - class ShaderOpenGL : public Shader {}; - class RendererOpenGL : public Renderer { public: @@ -39,13 +32,102 @@ namespace Archimedes { } - void draw(const VertexArray& va, const IndexArray& ia, const Shader& shader) override { + Shader createShader(const std::string& vs, const std::string& fs, const Shader::LoadType& lt) override { + + + Shader shader(vs, fs, lt); - glUseProgram(shader.id); + std::string vss = shader.getVSource(); + std::string fss = shader.getFSource(); - glBindVertexArray(va.id); + const char* vsc = vss.c_str(); + const char* fsc = fss.c_str(); - glDrawElements(GL_TRIANGLES, va.count, GL_UNSIGNED_INT, 0); + unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vsc, NULL); + glCompileShader(vertexShader); + // check for shader compile errors + int success; + char infoLog[512]; + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // fragment shader + unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fsc, NULL); + glCompileShader(fragmentShader); + // check for shader compile errors + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // link shaders + unsigned int shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + glLinkProgram(shaderProgram); + // check for linking errors + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; + } + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + shader.id = shaderProgram; + + return shader; + } + + RenderTarget* createRenderTarget(const void* data, size_t size, unsigned int* indices, size_t count, VertexLayout layout, const std::string& vs, const std::string& fs, const Shader::LoadType& lt) override { + + VertexBuffer vb(data, size); + + IndexArray ia(indices, count); + + Shader s = createShader(vs, fs, lt); + + auto rt = new RenderTarget(vb, ia, layout, s); + + glGenVertexArrays(1, &rt->vertexArray.id); + + glGenBuffers(1, &rt->vertexBuffer.id); + + glBindVertexArray(rt->vertexArray.id); + + glBindBuffer(GL_ARRAY_BUFFER, rt->vertexBuffer.id); + glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); + + + glGenBuffers(1, &rt->indexArray.id); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rt->indexArray.id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + + + glVertexAttribPointer(rt->vertexArray.id, count, GL_FLOAT, GL_FALSE, count * sizeof(float), (void*)0); + glEnableVertexAttribArray(rt->vertexArray.id); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + return rt; + }; + + void draw(const RenderTarget& rt) override { + + glUseProgram(rt.shader.id); + + glBindVertexArray(rt.vertexArray.id); + + glDrawElements(GL_TRIANGLES, rt.indexArray.getCount(), GL_UNSIGNED_INT, 0); glBindVertexArray(0); } diff --git a/include/utils/Window/WindowImpl/WindowGLFW/WindowGLFW.h b/include/utils/Window/WindowImpl/WindowGLFW/WindowGLFW.h index 5a67dcb..037e757 100644 --- a/include/utils/Window/WindowImpl/WindowGLFW/WindowGLFW.h +++ b/include/utils/Window/WindowImpl/WindowGLFW/WindowGLFW.h @@ -33,6 +33,8 @@ namespace Archimedes { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + //glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1); } window = glfwCreateWindow(640, 480, "Archimedes", NULL, NULL); diff --git a/modules/Archimedes-Modules/TestTriangle/TestTriangle.cpp b/modules/Archimedes-Modules/TestTriangle/TestTriangle.cpp index 7201d9b..f5c4cc3 100644 --- a/modules/Archimedes-Modules/TestTriangle/TestTriangle.cpp +++ b/modules/Archimedes-Modules/TestTriangle/TestTriangle.cpp @@ -18,7 +18,6 @@ TestTriangle::~TestTriangle() { if(app) { WindowModule* wm; { wm = (WindowModule*) moduleInstances[WindowModule()]; } - wm->getRenderer()->getCmdList().erase(rcmd_it); /* #if WINDOW == 2 wm->removeEventFn(ecmd_it); @@ -39,98 +38,22 @@ void TestTriangle::onLoad() { window = wm->aquireWindow(); - - wm->getRenderer()->getCmdList().push_back([this](){ - // draw our first triangle - glUseProgram(shaderProgram); - glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized - glDrawArrays(GL_TRIANGLES, 0, 3); - glBindVertexArray(0); // no need to unbind it every time - }); - - rcmd_it = --wm->getRenderer()->getCmdList().end()++; - - - //////////////////////glew - - /* - if(glewInit() != GLEW_OK) { - std::cout << "glew is not ok!" << std::endl; - std::abort(); - } - */ - ///////////////////////////////NUCLEAR - - - // build and compile our shader program - // ------------------------------------ - // vertex shader - unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); - glCompileShader(vertexShader); - // check for shader compile errors - int success; - char infoLog[512]; - glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); - if (!success) - { - glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); - std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; - } - // fragment shader - unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); - glCompileShader(fragmentShader); - // check for shader compile errors - glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); - if (!success) - { - glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); - std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; - } - // link shaders - shaderProgram = glCreateProgram(); - glAttachShader(shaderProgram, vertexShader); - glAttachShader(shaderProgram, fragmentShader); - glLinkProgram(shaderProgram); - // check for linking errors - glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); - if (!success) { - glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); - std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; - } - glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); - - // set up vertex data (and buffer(s)) and configure vertex attributes - // ------------------------------------------------------------------ - - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &VBO); - // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). - glBindVertexArray(VAO); - - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); - glEnableVertexAttribArray(0); - - // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind - glBindBuffer(GL_ARRAY_BUFFER, 0); - - // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other - // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. - glBindVertexArray(0); - - - // uncomment this call to draw in wireframe polygons. - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + rt = window->getRenderer()->createRenderTarget( + vertices, + 9 * sizeof(float), + indices, + 3, + Archimedes::VertexLayout(), + vertexShaderSource, + fragmentShaderSource, + Archimedes::Shader::LoadType::FromSource + ); } void TestTriangle::run() { + window->getRenderer()->draw(*rt); } diff --git a/modules/Archimedes-Modules/TestTriangle/TestTriangle.h b/modules/Archimedes-Modules/TestTriangle/TestTriangle.h index 2f40ef6..d40f526 100644 --- a/modules/Archimedes-Modules/TestTriangle/TestTriangle.h +++ b/modules/Archimedes-Modules/TestTriangle/TestTriangle.h @@ -29,8 +29,6 @@ class TestTriangle : public Archimedes::Module { Archimedes::Window* window; - std::list>::iterator rcmd_it; - const char *vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "void main()\n" @@ -44,14 +42,19 @@ class TestTriangle : public Archimedes::Module { " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" "}\n\0"; - unsigned int shaderProgram; - unsigned int VBO, VAO; + Archimedes::RenderTarget* rt; float vertices[9] = { -0.5f, -0.5f, 0.0f, // left 0.5f, -0.5f, 0.0f, // right 0.0f, 0.5f, 0.0f // top }; + + unsigned int indices[3] = { + 1, // left + 2, // right + 3 // top + }; }; #ifdef TESTTRIANGLE_DYNAMIC diff --git a/modules/ImguiModule/ImguiModule.cpp b/modules/ImguiModule/ImguiModule.cpp index ae7a200..ed6ca47 100644 --- a/modules/ImguiModule/ImguiModule.cpp +++ b/modules/ImguiModule/ImguiModule.cpp @@ -15,8 +15,6 @@ ImguiModule::~ImguiModule() { if(app) { WindowModule* wm; { wm = (WindowModule*) moduleInstances[WindowModule()]; } - wm->getRenderer()->getCmdList().erase(rcmd_it); - #if WINDOW == 2 wm->removeEventFn(ecmd_it); #endif @@ -80,21 +78,6 @@ void ImguiModule::onLoad() { std::cout << "rendererInit failed!\n" << std::endl; } - wm->getRenderer()->getCmdList().push_back([this](){ - ImGui::Render(); - - rendererRenderDrawData(); - - if(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { - ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); - - window->getWindowImpl().restoreContext(); - } - }); - - rcmd_it = --wm->getRenderer()->getCmdList().end()++; - #if WINDOW == 2 ecmd_it = wm->addEventFn([](Archimedes::Event* e){ if(e->userData.type() == typeid(SDL_Event*)) { @@ -113,6 +96,17 @@ void ImguiModule::run() { rendererNewFrame(); windowNewFrame(); ImGui::NewFrame(); + + ImGui::Render(); + + rendererRenderDrawData(); + + if(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + + window->getWindowImpl().restoreContext(); + } }; bool ImguiModule::onEvent(const Archimedes::Event &e) { diff --git a/modules/ImguiModule/ImguiModule.h b/modules/ImguiModule/ImguiModule.h index b951023..bb0758d 100644 --- a/modules/ImguiModule/ImguiModule.h +++ b/modules/ImguiModule/ImguiModule.h @@ -84,19 +84,22 @@ class ImguiModule : public Archimedes::Module { void rendererRenderDrawData() { ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), renderer); } #endif -#if WINDOW == 1 -#if RENDERER == 1 - auto windowInit() { return ImGui_ImplGlfw_InitForOpenGL(window->getWindowImpl().getWindow(), true); } +#ifdef WINDOW_GLFW +#ifdef RENDERER_OPENGL + auto windowInit() { return ImGui_ImplGlfw_InitForOpenGL(window->getWindowImpl()->getWindow(), true); } #endif void windowShutdown() { ImGui_ImplGlfw_Shutdown(); } void windowNewFrame() { ImGui_ImplGlfw_NewFrame(); } -#elif WINDOW == 2 -#if RENDERER == 1 +#endif + +#ifdef WINDOW_SDL3 +#ifdef RENDERER_OPENGL auto windowInit() { return ImGui_ImplSDL3_InitForOpenGL(window->getWindowImpl().getWindow(), window->getWindowImpl().getContext()); } -#elif RENDERER == 2 +#endif +#ifdef RENDERER_SDL3 auto windowInit() { return ImGui_ImplSDL3_InitForSDLRenderer(window->getWindowImpl().getWindow(), renderer); } #endif