From 6149c0da704d74dc1776070132c1ab06eece3cf1 Mon Sep 17 00:00:00 2001 From: Light Date: Mon, 28 Jun 2021 14:37:48 +0430 Subject: [PATCH] ResourceManager - Added ResourceManager - Removed FileManager - Shader's constructor now takes the shader source specific to the current GraphicsAPI --- Engine/premake5.lua | 24 ++-- Engine/res/Shaders/QuadShader.h | 53 +++++++++ .../src/Engine/Graphics/GraphicsContext.cpp | 3 + Engine/src/Engine/Graphics/GraphicsContext.h | 6 + Engine/src/Engine/Graphics/Renderer.cpp | 8 +- Engine/src/Engine/Graphics/Shader.cpp | 35 +----- Engine/src/Engine/Utility/FileManager.cpp | 24 ---- Engine/src/Engine/Utility/FileManager.h | 14 --- Engine/src/Engine/Utility/ResourceManager.cpp | 111 ++++++++++++++++++ Engine/src/Engine/Utility/ResourceManager.h | 40 +++++++ 10 files changed, 236 insertions(+), 82 deletions(-) create mode 100644 Engine/res/Shaders/QuadShader.h delete mode 100644 Engine/src/Engine/Utility/FileManager.cpp delete mode 100644 Engine/src/Engine/Utility/FileManager.h create mode 100644 Engine/src/Engine/Utility/ResourceManager.cpp create mode 100644 Engine/src/Engine/Utility/ResourceManager.h diff --git a/Engine/premake5.lua b/Engine/premake5.lua index b12e39e..cb01812 100644 --- a/Engine/premake5.lua +++ b/Engine/premake5.lua @@ -21,10 +21,16 @@ project "Engine" -- Project Files --- files { - "%{prj.location}/src/**.h" , - "%{prj.location}/src/**.cpp" , - "%{prj.location}/**.lua" , - "%{prj.location}/dxgidebug.dll" , + -- src + "%{prj.location}/src/**.h", + "%{prj.location}/src/**.cpp", + + -- premake + "%{prj.location}/preake5*.lua", + + "%{prj.location}/dxgidebug.dll", -- :#todo + + "%{prj.location}/res/**" } -- Dependencies -- @@ -38,11 +44,11 @@ project "Engine" -- 3rd party (dependenciesdir .. "spdlog/include/"), - (dependenciesdir .. "GLFW/include/" ), - (dependenciesdir .. "GLAD/include" ), - (dependenciesdir .. "imgui/backends" ), - (dependenciesdir .. "imgui/" ), - (dependenciesdir .. "glm/" ), + (dependenciesdir .. "GLFW/include/"), + (dependenciesdir .. "GLAD/include"), + (dependenciesdir .. "imgui/backends"), + (dependenciesdir .. "imgui/"), + (dependenciesdir .. "glm/"), } links diff --git a/Engine/res/Shaders/QuadShader.h b/Engine/res/Shaders/QuadShader.h new file mode 100644 index 0000000..7557a34 --- /dev/null +++ b/Engine/res/Shaders/QuadShader.h @@ -0,0 +1,53 @@ +#define LT_ENGINE_RESOURCES_QUAD_SHADER_VS \ +R"( ++GLSL +#version 440 core + +layout(location = 0) in vec3 a_Position; +layout(location = 1) in vec4 a_Color; + +out vec4 fragColor; + +void main() +{ + gl_Position = vec4(a_Position, 1.0); + fragColor = a_Color; +} +-GLSL ++HLSL +struct VertexOut +{ + float4 Color : COLOR; + float4 Position : SV_Position; +}; + +VertexOut main(float3 InPosition : POSITION, float4 InColor : COLOR) +{ + VertexOut vso; + vso.Position = float4(InPosition.x, InPosition.y, InPosition.z, 1.0); + vso.Color = InColor; + return vso; +} +-HLSL)" + +#define LT_ENGINE_RESOURCES_QUAD_SHADER_PS \ +R"( ++GLSL +#version 440 core + +in vec4 fragColor; + +out vec4 FragmentColor; + +void main() +{ + FragmentColor = fragColor; +} +-GLSL ++HLSL +float4 main(float4 Color : COLOR) : SV_Target +{ + return Color; +} +-HLSL +)" \ No newline at end of file diff --git a/Engine/src/Engine/Graphics/GraphicsContext.cpp b/Engine/src/Engine/Graphics/GraphicsContext.cpp index 304e9e8..1a9e6cb 100644 --- a/Engine/src/Engine/Graphics/GraphicsContext.cpp +++ b/Engine/src/Engine/Graphics/GraphicsContext.cpp @@ -12,6 +12,7 @@ #include "RenderCommand.h" #include "UserInterface/UserInterface.h" +#include "Utility/ResourceManager.h" #include "Utility/Stringifier.h" namespace Light { @@ -61,6 +62,8 @@ namespace Light { } // create gfx context dependent classes + s_Context->m_ResourceManager = std::unique_ptr(ResourceManager::Create(s_Context->m_SharedContext)); + s_Context->m_RenderCommand = std::unique_ptr(RenderCommand::Create(windowHandle, s_Context->m_SharedContext)); s_Context->m_UserInterface = std::unique_ptr(UserInterface::Create(windowHandle, s_Context->m_SharedContext)); s_Context->m_Renderer = std::unique_ptr(Renderer::Create(s_Context->m_RenderCommand, s_Context->m_SharedContext)); diff --git a/Engine/src/Engine/Graphics/GraphicsContext.h b/Engine/src/Engine/Graphics/GraphicsContext.h index 9db420b..cbc95be 100644 --- a/Engine/src/Engine/Graphics/GraphicsContext.h +++ b/Engine/src/Engine/Graphics/GraphicsContext.h @@ -6,8 +6,12 @@ struct GLFWwindow; +#include "Utility/ResourceManager.h" + + namespace Light { + class ResourceManager; class Renderer; class RenderCommand; class UserInterface; @@ -28,6 +32,8 @@ namespace Light { private: static GraphicsContext* s_Context; + std::unique_ptr m_ResourceManager; + std::unique_ptr m_Renderer; std::shared_ptr m_RenderCommand; std::unique_ptr m_UserInterface; diff --git a/Engine/src/Engine/Graphics/Renderer.cpp b/Engine/src/Engine/Graphics/Renderer.cpp index 44d0f9c..61e37be 100644 --- a/Engine/src/Engine/Graphics/Renderer.cpp +++ b/Engine/src/Engine/Graphics/Renderer.cpp @@ -3,6 +3,10 @@ #include "GraphicsContext.h" +#include "Utility/ResourceManager.h" + +#include "../res/Shaders/QuadShader.h" + #include "RenderCommand.h" namespace Light { @@ -14,8 +18,10 @@ namespace Light { { s_Context = this; + ResourceManager::CreateShader("QuadShader", LT_ENGINE_RESOURCES_QUAD_SHADER_VS, LT_ENGINE_RESOURCES_QUAD_SHADER_PS); + // QUADRENDERER // - m_QuadRenderer.shader = std::unique_ptr(Shader::Create("res/vertex.vertex", "res/fragment.fragment", m_SharedContext)); + m_QuadRenderer.shader = ResourceManager::GetShader("QuadShader"); m_QuadRenderer.vertexBuffer = std::unique_ptr(VertexBuffer::Create(nullptr, sizeof(QuadRendererProgram::QuadVertexData), LT_MAX_QUAD * 4, m_SharedContext)); m_QuadRenderer.indexBuffer = std::unique_ptr(IndexBuffer::Create(nullptr, LT_MAX_QUAD * 6, m_SharedContext)); m_QuadRenderer.vertexLayout = std::unique_ptr(VertexLayout::Create(m_QuadRenderer.vertexBuffer.get(), m_QuadRenderer.shader.get(), { { "POSITION", VertexElementType::Float3 },{ "COLOR", VertexElementType::Float4 } }, m_SharedContext)); diff --git a/Engine/src/Engine/Graphics/Shader.cpp b/Engine/src/Engine/Graphics/Shader.cpp index fe6e772..6365987 100644 --- a/Engine/src/Engine/Graphics/Shader.cpp +++ b/Engine/src/Engine/Graphics/Shader.cpp @@ -9,28 +9,17 @@ #include "GraphicsContext.h" -#include "Utility/FileManager.h" - namespace Light { - Shader* Shader::Create(const std::string& vertexPath, const std::string& pixelPath, std::shared_ptr sharedContext) + Shader* Shader::Create(const std::string& vertexSource, const std::string& pixelSource, std::shared_ptr sharedContext) { // load shader source - std::string vertexSource = FileManager::ReadTXTFile(vertexPath); - std::string pixelSource = FileManager::ReadTXTFile(pixelPath); - switch (GraphicsContext::GetGraphicsAPI()) { case GraphicsAPI::OpenGL: - ExtractShaderSource(vertexSource, "GLSL"); - ExtractShaderSource(pixelSource, "GLSL"); - return new glShader(vertexSource, pixelSource); case GraphicsAPI::DirectX: LT_WIN( - ExtractShaderSource(vertexSource, "HLSL"); - ExtractShaderSource(pixelSource, "HLSL"); - return new dxShader(vertexSource, pixelSource, std::static_pointer_cast(sharedContext));) default: @@ -39,26 +28,4 @@ namespace Light { } } - void Shader::ExtractShaderSource(std::string& src, const std::string& delim) - { - size_t begDelimPos, endDelimPos; - - // find begin and end delimiter (eg. +GLSL ... -GLSL ) - begDelimPos = src.find('+' + delim) + 5; - endDelimPos = src.find('-' + delim); - - // check - LT_ENGINE_ASSERT(begDelimPos != std::string::npos + 5, - "Shader::ExtractShaderSource: failed to find the start delimeter in shader source, delim: {}, shader:\n{}", - delim, src); - - - LT_ENGINE_ASSERT(endDelimPos != std::string::npos, - "Shader::ExtractShaderSource: failed to find the end delimeter in shader source, delim: {}, shader:\n{}", - delim, src); - - // extract the shader - src = src.substr(begDelimPos, endDelimPos - begDelimPos); - } - } \ No newline at end of file diff --git a/Engine/src/Engine/Utility/FileManager.cpp b/Engine/src/Engine/Utility/FileManager.cpp deleted file mode 100644 index 47287d1..0000000 --- a/Engine/src/Engine/Utility/FileManager.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "ltpch.h" -#include "FileManager.h" - -namespace Light { - - std::string FileManager::ReadTXTFile(const std::string& path) - { - // initialize - std::ifstream stream(path); - std::stringstream ss; - std::string line; - - // check - LT_ENGINE_ASSERT(!path.empty(), "FileManager::ReadTXTFile: path is empty"); - LT_ENGINE_ASSERT(stream.is_open(), "FileManager::ReadTXTFile: invalid path: {}", path); - - // read - while (std::getline(stream, line)) - ss << line << '\n'; - - return ss.str(); - } - -} \ No newline at end of file diff --git a/Engine/src/Engine/Utility/FileManager.h b/Engine/src/Engine/Utility/FileManager.h deleted file mode 100644 index c5019f1..0000000 --- a/Engine/src/Engine/Utility/FileManager.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "Base.h" - -namespace Light { - - // TODO: optimize!! - class FileManager - { - public: - static std::string ReadTXTFile(const std::string& path); - }; - -} \ No newline at end of file diff --git a/Engine/src/Engine/Utility/ResourceManager.cpp b/Engine/src/Engine/Utility/ResourceManager.cpp new file mode 100644 index 0000000..ef02559 --- /dev/null +++ b/Engine/src/Engine/Utility/ResourceManager.cpp @@ -0,0 +1,111 @@ +#include "ltpch.h" +#include "ResourceManager.h" + +#include "Graphics/GraphicsContext.h" +#include "Graphics/Shader.h" + +#define STB_IMAGE_IMPLEMENTATION +#include g + +namespace Light { + + ResourceManager* ResourceManager::s_Context = nullptr; + + ResourceManager* ResourceManager::Create(std::shared_ptr sharedContext) + { + return new ResourceManager(sharedContext); + } + + ResourceManager::ResourceManager(std::shared_ptr sharedContext) + : m_SharedContext(sharedContext) + { + LT_ENGINE_ASSERT(!s_Context, "ResourceManager::ResourceManager: an instance of 'resource manager' already exists, do not construct this class"); + s_Context = this; + } + + void ResourceManager::CreateShaderImpl(const std::string& name, const std::string& vertexSource, const std::string& pixelSource) + { + // delim + std::string delim = GraphicsContext::GetGraphicsAPI() == GraphicsAPI::OpenGL ? "GLSL" : + GraphicsContext::GetGraphicsAPI() == GraphicsAPI::DirectX ? "HLSL" : NULL; + + // check + LT_ENGINE_ASSERT(!vertexSource.empty(), "ResourceManager::CreateShader: vertex source is empty"); + LT_ENGINE_ASSERT(!vertexSource.empty(), "ResourceManager::CreateShader: pixel source is empty"); + LT_ENGINE_ASSERT(!delim.empty(), "ResourceManager::LoadShader: invalid/unsupported graphics api: {}", GraphicsContext::GetGraphicsAPI()); + + // save to string + std::string vsSource = vertexSource; + std::string psSource = pixelSource; + + // extract source + ResourceManager::ExtractShaderSource(vsSource, delim); + ResourceManager::ExtractShaderSource(psSource, delim); + + // create shader + m_Shaders[name] = std::shared_ptr(Shader::Create(vsSource, psSource, m_SharedContext)); + } + + void ResourceManager::LoadShaderImpl(const std::string& name, const std::string& vertexPath, const std::string& pixelPath) + { + // check + LT_ENGINE_ASSERT(!vertexPath.empty(), "ResourceManager::LoadShader: vertex path is empty"); + LT_ENGINE_ASSERT(!pixelPath.empty(), "ResourceManager::LoadShader: pixel path is empty"); + + // initialize + std::ifstream vsStream(vertexPath), psStream(pixelPath); + std::stringstream vsSS, psSS; // pss pss pss pss :D + std::string vertexSource, pixelSource; + std::string line; + + // delim + std::string delim = GraphicsContext::GetGraphicsAPI() == GraphicsAPI::OpenGL ? "GLSL" : + GraphicsContext::GetGraphicsAPI() == GraphicsAPI::DirectX ? "HLSL" : NULL; + + // check + LT_ENGINE_ASSERT(!delim.empty(), "ResourceManager::LoadShader: invalid/unsupported graphics api: {}", GraphicsContext::GetGraphicsAPI()); + LT_ENGINE_ASSERT(vsStream.is_open(), "ResourceManager::LoadShader: invalid vertex path: {}", vertexPath); + LT_ENGINE_ASSERT(psStream.is_open(), "ResourceManager::LoadShader: invalid pixel path: {}", pixelPath); + + // read + while (std::getline(vsStream, line)) + vsSS << line << '\n'; + + while (std::getline(psStream, line)) + psSS << line << '\n'; + + // save to string + vertexSource = vsSS.str(); + pixelSource = psSS.str(); + + // extract source + ResourceManager::ExtractShaderSource(vertexSource, delim); + ResourceManager::ExtractShaderSource(pixelSource, delim); + + // create shader + m_Shaders[name] = std::shared_ptr(Shader::Create(vertexSource, pixelSource, m_SharedContext)); + } + + void ResourceManager::ExtractShaderSource(std::string& src, const std::string& delim) + { + size_t begDelimPos, endDelimPos; + + // find begin and end delimiter (eg. +GLSL ... -GLSL ) + begDelimPos = src.find('+' + delim) + 5; + endDelimPos = src.find('-' + delim); + + // check + LT_ENGINE_ASSERT(begDelimPos != std::string::npos + 5, + "Shader::ExtractShaderSource: failed to find the start delimeter in shader source, delim: {}, shader:\n{}", + delim, src); + + + LT_ENGINE_ASSERT(endDelimPos != std::string::npos, + "Shader::ExtractShaderSource: failed to find the end delimeter in shader source, delim: {}, shader:\n{}", + delim, src); + + // extract the shader + src = src.substr(begDelimPos, endDelimPos - begDelimPos); + } + +} \ No newline at end of file diff --git a/Engine/src/Engine/Utility/ResourceManager.h b/Engine/src/Engine/Utility/ResourceManager.h new file mode 100644 index 0000000..9591eb0 --- /dev/null +++ b/Engine/src/Engine/Utility/ResourceManager.h @@ -0,0 +1,40 @@ +#pragma once + +#include "Base.h" + +#include + +namespace Light { + + class Shader; + class SharedContext; + + class ResourceManager + { + private: + std::unordered_map> m_Shaders; + + std::shared_ptr m_SharedContext; + + static ResourceManager* s_Context; + + public: + static ResourceManager* Create(std::shared_ptr sharedContext); + + // #todo: add geometry shader support + static inline void CreateShader(const std::string& name, const std::string& vertexSource, const std::string& pixelSource) { s_Context->CreateShaderImpl(name, vertexSource, pixelSource); } + static inline void LoadShader(const std::string& name, const std::string& vertexPath, const std::string& pixelPath) { s_Context->LoadShaderImpl(name, vertexPath, pixelPath); } + + static inline std::shared_ptr GetShader(const std::string& name) { return s_Context->m_Shaders[name]; } + + private: + ResourceManager(std::shared_ptr sharedContext); + + void CreateShaderImpl(const std::string& name, const std::string& vertexSource, const std::string& pixelSource); + void LoadShaderImpl(const std::string& name, const std::string& vertexPath, const std::string& pixelPath); + + private: + void ExtractShaderSource(std::string& src, const std::string& delim); + }; + +} \ No newline at end of file