From b03b82272f379100a16ceace67a4cb86560daec5 Mon Sep 17 00:00:00 2001 From: nigelbarink Date: Sat, 8 Oct 2022 15:34:02 +0200 Subject: [PATCH] Moving to a single renderer instance system --- .../Include/AssetManager/ModelImporter.h | 3 +- BarinkEngine/Include/BarinkEngine.h | 1 + BarinkEngine/Include/EventSystem/Event.h | 2 +- BarinkEngine/Include/Graphics/GPUBucket.h | 30 ++++++++++ BarinkEngine/Include/Graphics/Material.h | 2 +- BarinkEngine/Include/Graphics/Mesh.h | 22 ++----- BarinkEngine/Include/Graphics/Renderable.h | 13 +--- BarinkEngine/Include/Graphics/Renderer.h | 14 ++++- BarinkEngine/Include/Graphics/Shader.h | 2 +- BarinkEngine/Include/Graphics/Vertex.h | 9 +++ BarinkEngine/src/Graphics/GPUBucket.cpp | 37 ++++++++++++ BarinkEngine/src/Graphics/Material.cpp | 3 +- BarinkEngine/src/Graphics/ModelImporter.cpp | 11 +++- BarinkEngine/src/Graphics/Renderable.cpp | 53 ----------------- BarinkEngine/src/Graphics/Renderer.cpp | 58 +++++++++++++++++- BarinkEngine/src/Graphics/Shader.cpp | 4 +- BarinkEngine/src/Graphics/window.cpp | 9 +++ SandboxApplication/src/Sandbox.cpp | 59 +++++++------------ TODO.md | 7 ++- 19 files changed, 201 insertions(+), 138 deletions(-) create mode 100644 BarinkEngine/Include/Graphics/GPUBucket.h create mode 100644 BarinkEngine/Include/Graphics/Vertex.h create mode 100644 BarinkEngine/src/Graphics/GPUBucket.cpp delete mode 100644 BarinkEngine/src/Graphics/Renderable.cpp diff --git a/BarinkEngine/Include/AssetManager/ModelImporter.h b/BarinkEngine/Include/AssetManager/ModelImporter.h index 8576f84..abbff66 100644 --- a/BarinkEngine/Include/AssetManager/ModelImporter.h +++ b/BarinkEngine/Include/AssetManager/ModelImporter.h @@ -12,6 +12,7 @@ #include #include "Scene/SceneNodeTypes.h" + void ProcessVertices(aiMesh* mesh, std::vector& out_vertices); void ProcessIndices(aiMesh* mesh, std::vector& out_indices); @@ -20,7 +21,7 @@ namespace BarinkEngine { public: - SceneObject* Import(const std::string path); + BarinkEngine::SceneObject* Import(const std::string path); private: diff --git a/BarinkEngine/Include/BarinkEngine.h b/BarinkEngine/Include/BarinkEngine.h index d5e15c7..4f520c6 100644 --- a/BarinkEngine/Include/BarinkEngine.h +++ b/BarinkEngine/Include/BarinkEngine.h @@ -5,6 +5,7 @@ #include "graphics/Texture.h" #include "graphics/Camera.h" #include "graphics/Renderable.h" +#include "Graphics/Renderer.h" #include "Graphics/Material.h" #include "spdlog/spdlog.h" diff --git a/BarinkEngine/Include/EventSystem/Event.h b/BarinkEngine/Include/EventSystem/Event.h index 9489364..a11eaeb 100644 --- a/BarinkEngine/Include/EventSystem/Event.h +++ b/BarinkEngine/Include/EventSystem/Event.h @@ -1,5 +1,5 @@ #pragma once -#include +#include struct Event { diff --git a/BarinkEngine/Include/Graphics/GPUBucket.h b/BarinkEngine/Include/Graphics/GPUBucket.h new file mode 100644 index 0000000..74f6840 --- /dev/null +++ b/BarinkEngine/Include/Graphics/GPUBucket.h @@ -0,0 +1,30 @@ +#pragma once +#include "VertexArray.h" +#include "Buffer.h" +#include "Mesh.h" +#include "Material.h" + +namespace BarinkEngine { + + class GPU_Bucket { + public: + + GPU_Bucket(); + ~GPU_Bucket(); + + void Upload(const Mesh& renderable); + + GpuBuffer vertexBuffer; + GpuBuffer elementBuffer; + VertexArray vertexarray; + + const Mesh* mesh; + const Material* material; + + private : + unsigned int uv_id; + + }; + +}; + diff --git a/BarinkEngine/Include/Graphics/Material.h b/BarinkEngine/Include/Graphics/Material.h index 58e92ce..f780928 100644 --- a/BarinkEngine/Include/Graphics/Material.h +++ b/BarinkEngine/Include/Graphics/Material.h @@ -7,7 +7,7 @@ class Material { public: Material(const Shader& shader); - void Apply(); + void Apply()const; glm::vec3 Color; diff --git a/BarinkEngine/Include/Graphics/Mesh.h b/BarinkEngine/Include/Graphics/Mesh.h index 98d0b02..449a51f 100644 --- a/BarinkEngine/Include/Graphics/Mesh.h +++ b/BarinkEngine/Include/Graphics/Mesh.h @@ -1,26 +1,12 @@ #pragma once #include #include -#include "VertexArray.h" -#include "Buffer.h" +#include "Vertex.h" -namespace BarinkEngine{ - - struct Vertex { - glm::vec3 vertices; - glm::vec2 uv; - }; - - class Mesh { - public: +namespace BarinkEngine { + struct Mesh { std::vector vertices; std::vector elements; - - private: - GpuBuffer vertexBuffer; - GpuBuffer elementBuffer; - VertexArray VAO; - unsigned int UV_id; }; -} \ No newline at end of file +} diff --git a/BarinkEngine/Include/Graphics/Renderable.h b/BarinkEngine/Include/Graphics/Renderable.h index 3addd2c..370ab5a 100644 --- a/BarinkEngine/Include/Graphics/Renderable.h +++ b/BarinkEngine/Include/Graphics/Renderable.h @@ -1,23 +1,14 @@ #pragma once -#include #include "Mesh.h" - #include "Material.h" #include "Texture.h" - #include "Scene.h" namespace BarinkEngine { - class Renderable { - public: - Mesh mesh; + struct Renderable { + BarinkEngine::Mesh* mesh; Material* material; Texture* texture; - - Shader* shader; - - Renderable(); - ~Renderable(); }; } \ No newline at end of file diff --git a/BarinkEngine/Include/Graphics/Renderer.h b/BarinkEngine/Include/Graphics/Renderer.h index dad948a..aa2f60e 100644 --- a/BarinkEngine/Include/Graphics/Renderer.h +++ b/BarinkEngine/Include/Graphics/Renderer.h @@ -1,8 +1,16 @@ #pragma once -#include "Graphics/Renderable.h" - #include +#include +#include "glad/glad.h" +#include "GLFW/glfw3.h" + +#include "PerfCounter.h" + +#include "Graphics/Camera.h" +#include "Graphics/Renderable.h" +#include "Graphics/GPUBucket.h" + namespace BarinkEngine { class Renderer { @@ -15,7 +23,7 @@ namespace BarinkEngine { void Submit(Renderable* model); private: - std::vector models; + std::vector models; }; } diff --git a/BarinkEngine/Include/Graphics/Shader.h b/BarinkEngine/Include/Graphics/Shader.h index 6101847..1f0733d 100644 --- a/BarinkEngine/Include/Graphics/Shader.h +++ b/BarinkEngine/Include/Graphics/Shader.h @@ -14,7 +14,7 @@ class Shader { char* readFile (const char* filePath); public: Shader(const std::string vertexShaderPath, const std::string fragmentShaderPath); - void Use(); + void Use() const; void setUniformMat4(std::string uniformName, glm::mat4 matrix4)const; void setUniformVec4(std::string uniformName, glm::vec4 vector4)const; void setUniformVec3(std::string uniformName, glm::vec3 vector3)const; diff --git a/BarinkEngine/Include/Graphics/Vertex.h b/BarinkEngine/Include/Graphics/Vertex.h new file mode 100644 index 0000000..d7b04a6 --- /dev/null +++ b/BarinkEngine/Include/Graphics/Vertex.h @@ -0,0 +1,9 @@ +#pragma once +#include + +namespace BarinkEngine { + struct Vertex { + glm::vec3 vertices; + glm::vec2 uv; + }; +} \ No newline at end of file diff --git a/BarinkEngine/src/Graphics/GPUBucket.cpp b/BarinkEngine/src/Graphics/GPUBucket.cpp new file mode 100644 index 0000000..3f0a725 --- /dev/null +++ b/BarinkEngine/src/Graphics/GPUBucket.cpp @@ -0,0 +1,37 @@ +#include "Graphics/GPUBucket.h" +BarinkEngine::GPU_Bucket::GPU_Bucket() { +} +BarinkEngine::GPU_Bucket::~GPU_Bucket() { + +} + +void BarinkEngine::GPU_Bucket::Upload(const Mesh& renderable) { + + // keep a ref to the origin in main memory + mesh = &renderable; + + // Upload gpu + + vertexarray.Create(); + vertexarray.Bind(); + + vertexBuffer.createBuffer(); + vertexBuffer.Bind(false); + vertexBuffer.setBufferData((void*)&renderable.vertices[0], renderable.vertices.size() * sizeof(BarinkEngine::Vertex), false); + + if (renderable.elements.empty() == false) { + elementBuffer.createBuffer(); + elementBuffer.Bind(true); + elementBuffer.setBufferData((void*)&renderable.elements[0], renderable.elements.size() * sizeof(unsigned int), true); + } + + vertexarray.AttachAttribute(0, 3, sizeof(Vertex)); + + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(BarinkEngine::Vertex), (void*)offsetof(BarinkEngine::Vertex, vertices)); + glEnableVertexAttribArray(1); + + vertexBuffer.Unbind(false); + vertexarray.Unbind(); + + +} diff --git a/BarinkEngine/src/Graphics/Material.cpp b/BarinkEngine/src/Graphics/Material.cpp index 06d53cc..7b601bf 100644 --- a/BarinkEngine/src/Graphics/Material.cpp +++ b/BarinkEngine/src/Graphics/Material.cpp @@ -4,7 +4,8 @@ Material::Material(const Shader& shader) : shader(shader) { } +void Material::Apply() const { -void Material::Apply() { + shader.Use(); shader.setUniformVec3("Color", Color); } \ No newline at end of file diff --git a/BarinkEngine/src/Graphics/ModelImporter.cpp b/BarinkEngine/src/Graphics/ModelImporter.cpp index 5206439..e693933 100644 --- a/BarinkEngine/src/Graphics/ModelImporter.cpp +++ b/BarinkEngine/src/Graphics/ModelImporter.cpp @@ -1,9 +1,8 @@ #include "AssetManager/ModelImporter.h" - +#include "spdlog/spdlog.h" BarinkEngine::SceneObject* BarinkEngine::ModelImporter::Import(const std::string path) { - SceneObject* root = new SceneObject(std::string(path), nullptr); Assimp::Importer importer; @@ -12,9 +11,15 @@ BarinkEngine::SceneObject* BarinkEngine::ModelImporter::Import(const std::string aiNode* currentNode = scene->mRootNode; std::vector meshes = processNode(currentNode, scene); + + std::cout << "[DEBUG]: Loaded "<< meshes.size() << " meshes!" << std::endl; + + // create a renderable (per mesh ?? ) + root->renderable = new Renderable(); + root->renderable->mesh = &(meshes[0]); - return root; + return root; } diff --git a/BarinkEngine/src/Graphics/Renderable.cpp b/BarinkEngine/src/Graphics/Renderable.cpp deleted file mode 100644 index 7394915..0000000 --- a/BarinkEngine/src/Graphics/Renderable.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "Graphics/Renderable.h" -#include "AssetManager/ModelImporter.h" -#include "PerfCounter.h" - - -BarinkEngine::Renderable::Renderable() -{ - /* - - VAO.Create(); - VAO.Bind(); - - - vertexBuffer.createBuffer(); - vertexBuffer.Bind(false); - vertexBuffer.setBufferData(&meshes[0].vertices[0], meshes[0].vertices.size() * sizeof(BarinkEngine::Vertex), false); - - elementBuffer.createBuffer(); - elementBuffer.Bind(true); - elementBuffer.setBufferData(&meshes[0].elements[0], meshes[0].elements.size() * sizeof(unsigned int), true); - - VAO.AttachAttribute(0, 3, sizeof(BarinkEngine::Vertex)); - - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(BarinkEngine::Vertex),(void* )offsetof(BarinkEngine::Vertex, vertices)); - glEnableVertexAttribArray(1); - - //vertexBuffer.Unbind(false); - - VAO.Unbind(); - */ - -} - -BarinkEngine::Renderable::~Renderable() -{ - // glDeleteBuffers(1, &UV_id); -} - -// Draw call Example !! -/* - VAO.Bind(); - elementBuffer.Bind(true); - - glActiveTexture(GL_TEXTURE0); - glUniform1i(glGetUniformLocation(shader->id, "Texture"), GL_TEXTURE0); - texture->Bind(); - - ES->verts = meshes[0].vertices.size(); - ES->DC++; - glDrawElements(GL_TRIANGLES, static_cast(meshes[0].elements.size()), GL_UNSIGNED_INT, NULL); - VAO.Unbind(); - */ - diff --git a/BarinkEngine/src/Graphics/Renderer.cpp b/BarinkEngine/src/Graphics/Renderer.cpp index ac6f8a9..8498f1b 100644 --- a/BarinkEngine/src/Graphics/Renderer.cpp +++ b/BarinkEngine/src/Graphics/Renderer.cpp @@ -1,25 +1,77 @@ #include "Graphics/Renderer.h" + BarinkEngine::Renderer::Renderer() { - models = std::vector(); + models = std::vector(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } BarinkEngine::Renderer::~Renderer() { // CleanUp! + + // For each model submitted + for ( auto packet : models ) + { + delete packet; + } + + // glDeleteBuffers(1, &UV_id); } void BarinkEngine::Renderer::Render() { + // This creation of the projection and camera is somewhat wastefull + Camera cam = Camera(glm::vec3(0.0f, 1.5f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), 90.0f); + glm::mat4 projection = glm::perspective(glm::radians(cam.Zoom), (800.0f / 600.0f), 0.001f, 100.0f); + for (auto model : models) { - //model->Draw(); + // Push matrices etc .... + model->vertexarray.Bind(); + + model->elementBuffer.Bind(true); + + + if (model->material == nullptr) { + std::cout << "No material attached!" << std::endl; + } + else { + model->material->Apply(); + } + + // Update perf counters + ES->verts = model->mesh->vertices.size(); + ES->DC++; + + glDrawElements( GL_TRIANGLES, + static_cast(model->mesh->elements.size()), + GL_UNSIGNED_INT, + NULL + ); + model->vertexarray.Unbind(); + } + + } + +// Upload data to cpu and add object to render list void BarinkEngine::Renderer::Submit(Renderable* model) { - models.push_back(model); + // Upload mesh data to gpu for render + + GPU_Bucket* bucket = new GPU_Bucket(); + + bucket->material = model->material; + + bucket->Upload(*model->mesh); + + models.push_back(bucket); // Maybe push a GPU packet or something instead + } diff --git a/BarinkEngine/src/Graphics/Shader.cpp b/BarinkEngine/src/Graphics/Shader.cpp index bb817d0..c0cd94a 100644 --- a/BarinkEngine/src/Graphics/Shader.cpp +++ b/BarinkEngine/src/Graphics/Shader.cpp @@ -1,5 +1,6 @@ #include "Graphics/Shader.h" #include "spdlog/spdlog.h" + Shader::Shader(const std::string vertexShaderPath, const std::string fragmentShaderPath) { char infoLog[512]; @@ -57,6 +58,7 @@ Shader::Shader(const std::string vertexShaderPath, const std::string fragmentSha } + char* Shader::readFile (const char* filePath){ spdlog::info("Opening {} ", filePath); @@ -93,7 +95,7 @@ char* Shader::readFile (const char* filePath){ return FileBuffer; } -void Shader::Use() +void Shader::Use() const { glUseProgram(id); } diff --git a/BarinkEngine/src/Graphics/window.cpp b/BarinkEngine/src/Graphics/window.cpp index 8460601..8eefc09 100644 --- a/BarinkEngine/src/Graphics/window.cpp +++ b/BarinkEngine/src/Graphics/window.cpp @@ -16,6 +16,15 @@ Width(width), Height(height), FullScreen(false){ exit(-1); } + glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE); + glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_TRUE); + // No window decorations such as a border, a close widget + //glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); + //glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE); + // Disable resizing the window + glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); + + window = glfwCreateWindow(Width, Height, "BarinkEngine", NULL, NULL); if( !window) diff --git a/SandboxApplication/src/Sandbox.cpp b/SandboxApplication/src/Sandbox.cpp index 7ae2cf5..accf8ef 100644 --- a/SandboxApplication/src/Sandbox.cpp +++ b/SandboxApplication/src/Sandbox.cpp @@ -10,7 +10,6 @@ /* * Define globals */ -Camera* cam; Shader* shader; char* code = new char[254]; @@ -21,7 +20,8 @@ const std::string fragmentShaderSource = "../build/SandboxApplication/Debug/test BarinkEngine::ModelImporter* MI = new BarinkEngine::ModelImporter(); Scene* Level1; -// BarinkEngine::SceneObject* cube; +BarinkEngine::Renderer* renderer; +BarinkEngine::SceneObject* cube; /* * Runs once at startup * - USe to initialize the game/sandbox/demo @@ -34,30 +34,29 @@ void Start() { std::string levelName("Test Level"); Level1 = SceneManager::CreateScene(levelName); SceneManager::LoadScene(*Level1); + + shader = new Shader(vertexShaderSource, fragmentShaderSource); // Create a cube node - // Load a model - auto cube = MI->Import("../build/SandboxApplication/Debug/Models/Cube.obj"); + cube = MI->Import("../build/SandboxApplication/Debug/Models/Cube.obj"); + cube->renderable->material = new Material(*shader); + + // What is in cube now ?? + std::cout << "mesh vertices: " << cube->renderable->mesh->vertices.size() << std::endl; + std::cout << "mesh elements: " << cube->renderable->mesh->elements.size() << std::endl; + Level1->GetRoot().addChild(*cube); - - std::string groupName("Nested-Group"); - auto testGroup = new Group(groupName); - Level1->GetRoot().addChild( *testGroup); - - std::string group2Name("Nested-Group2"); - auto testGroup2 = new Group(group2Name); - Level1->GetRoot().addChild(*testGroup2); - - // Walk scene graph - PrintSceneTree(Level1->GetRoot(),0); - - shader = new Shader(vertexShaderSource, fragmentShaderSource); - cam = new Camera(glm::vec3(0.0f, 1.5f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), 90.0f); memset(code, '\0', 254); -} + // TODO: Move to runtime/ Engine + renderer = new BarinkEngine::Renderer(); + // NOTE: Submits should later be done through walking the sceneTree + renderer->Submit(cube->renderable); + + +} /* * Runs every frame @@ -74,7 +73,7 @@ void ImmediateGraphicsDraw() { ShowStats(); // Show different tooling for this specific sandbox - CameraTool(cam); + // CameraTool(cam); ScriptingTool(code); SceneExplorer(*Level1, "Scene Explorer"); @@ -87,26 +86,9 @@ void ImmediateGraphicsDraw() { */ void Update() { - /* - * NOTE: this needs to move to the renderer - * Render code should not appear in the sandbox file - */ - //glm::mat4 projection = glm::perspective(glm::radians(cam->Zoom), (800.0f / 600.0f), 0.001f, 100.0f); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - shader->Use(); - //shader->setUniformMat4("P", projection); - //shader->setUniformMat4("M", CalculateModelMat(cube->transform)); - - shader->setUniformMat4("V", cam->GetViewMatrix()); - //cube->renderable->material->Apply(); + renderer->Render(); - - //Cube->Draw(); - - } /* @@ -115,5 +97,6 @@ void Update() */ void Stop() { delete MI; + delete renderer; delete shader; } \ No newline at end of file diff --git a/TODO.md b/TODO.md index 90ee5ee..892bac6 100644 --- a/TODO.md +++ b/TODO.md @@ -11,7 +11,7 @@ Basic Textures \ Link GLEW or GLAD \ Work on basic logging \ - Input handling \ + Input handling \ More shader work \ Load FBX model files \ Basic Physics \ @@ -21,5 +21,6 @@ ## Resources -https://renderdoc.org/ -https://api.projectchrono.org/tutorial_table_of_content_chrono.html +https://renderdoc.org/ \ +https://api.projectchrono.org/tutorial_table_of_content_chrono.html \ +https://github.com/epezent/implot -- Useful when displaying graphs of any kind \ \ No newline at end of file