From eb00566953ff81afb7998ad808a4592d90b88f83 Mon Sep 17 00:00:00 2001 From: Light Date: Mon, 13 Sep 2021 12:17:26 +0430 Subject: [PATCH] Implemented ShaderConductor into Shaders - glShader now uses ShaderConductor and compiles from .hlsl files - Added Shader::Stage enum - Removed .glsl files - Improvements to CMakeLists files - Maintenance --- CMakeLists.txt | 18 +- Engine/CMakeLists.txt | 45 ++-- Engine/res/Shaders/Quad/Quad_PS.glsl | 10 - Engine/res/Shaders/Quad/Quad_VS.glsl | 17 -- Engine/res/Shaders/Texture/Texture_PS.glsl | 12 - Engine/res/Shaders/Texture/Texture_VS.glsl | 18 -- .../TintedTexture/TintedTexture_PS.glsl | 13 -- .../TintedTexture/TintedTexture_VS.glsl | 21 -- .../RendererPrograms/QuadRendererProgram.cpp | 2 +- .../TextureRendererProgram.cpp | 2 +- .../TintedTextureRendererProgram.cpp | 2 +- Engine/src/Engine/Graphics/Shader.cpp | 6 +- Engine/src/Engine/Graphics/Shader.h | 11 +- Engine/src/Engine/Utility/ResourceManager.cpp | 91 +++----- Engine/src/Engine/Utility/ResourceManager.h | 5 - .../Platform/GraphicsAPI/DirectX/dxShader.cpp | 8 +- .../Platform/GraphicsAPI/DirectX/dxShader.h | 2 +- .../Platform/GraphicsAPI/OpenGL/glShader.cpp | 206 +++++++++++------- .../Platform/GraphicsAPI/OpenGL/glShader.h | 9 +- 19 files changed, 214 insertions(+), 284 deletions(-) delete mode 100644 Engine/res/Shaders/Quad/Quad_PS.glsl delete mode 100644 Engine/res/Shaders/Quad/Quad_VS.glsl delete mode 100644 Engine/res/Shaders/Texture/Texture_PS.glsl delete mode 100644 Engine/res/Shaders/Texture/Texture_VS.glsl delete mode 100644 Engine/res/Shaders/TintedTexture/TintedTexture_PS.glsl delete mode 100644 Engine/res/Shaders/TintedTexture/TintedTexture_VS.glsl diff --git a/CMakeLists.txt b/CMakeLists.txt index b11f3aa..2ef5b52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,24 +1,22 @@ cmake_minimum_required(VERSION 3.21.2) project(Light VERSION 1.0.0) -add_subdirectory(Dependencies/ShaderConductor) -set(CMAKE_CXX_STANDARD 17) - -# target_compile_features(Light PUBLIC cxx_std_17) -# set_property(TARGET Light CXX_STANDARD 17) +add_subdirectory(Dependencies/ShaderConductor) # <-- this project should not use "cxx_standard 17" +# directories set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + set(MIRROR_DIR ${CMAKE_BINARY_DIR}/../Mirror/) set(ENGINE_DIR ${CMAKE_BINARY_DIR}/../Engine/) set(DEPENDENCIES_DIR ${CMAKE_BINARY_DIR}/../Dependencies/) -# MIRROR +# projects +set(CMAKE_CXX_STANDARD 17) add_compile_definitions(LIGHT_PLATFORM_WINDOWS) -# projects add_subdirectory(${ENGINE_DIR}/) add_subdirectory(${MIRROR_DIR}/) @@ -40,4 +38,8 @@ target_link_libraries(Engine ShaderConductor) target_link_libraries(imgui glad) target_link_libraries(imgui glfw) -target_link_libraries(Mirror Engine) \ No newline at end of file +target_link_libraries(Mirror Engine) + +if(MSVC) + set_property(DIRECTORY ${CMAE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Mirror) +endif() \ No newline at end of file diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt index 5d8e1b9..79e0c5c 100644 --- a/Engine/CMakeLists.txt +++ b/Engine/CMakeLists.txt @@ -1,42 +1,40 @@ cmake_minimum_required(VERSION 3.21.2) -message("______________________________________________________________________") -message("Building Engine...") - if (CMAKE_COMPILER_IS_GNUCC) - add_compile_options(-w) + add_compile_options(-w) endif() + if(MSVC) - add_compile_options(/MP) - add_compile_options(/W0) + add_compile_options(/MP) + add_compile_options(/W0) endif() file(GLOB_RECURSE ENGINE_ALL_FILES true ABSOLUTE ${ENGINE_DIR}src/*) file(GLOB_RECURSE ENGINE_RES_FILES true ABSOLUTE ${ENGINE_DIR}res/*) list(LENGTH ENGINE_ALL_FILES ENGINE_ALL_FILES_COUNT) -message("Found " ${ENGINE_ALL_FILES_COUNT} " files in Engine") if(NOT WIN32) set (DX_DIR ${ENGINE_DIR}src/Platform/GraphicsAPI/DirectX/) set (WIN_DIR ${ENGINE_DIR}src/Platform/OS/Windows/) list(REMOVE_ITEM ENGINE_ALL_FILES - ${DX_DIR}dxBlender.cpp - ${DX_DIR}dxBuffers.cpp - ${DX_DIR}dxFramebuffer.cpp - ${DX_DIR}dxGraphicsContext.cpp - ${DX_DIR}dxRenderCommand.cpp - ${DX_DIR}dxShader.cpp - ${DX_DIR}dxSharedContext.cpp - ${DX_DIR}dxTexture.cpp - ${DX_DIR}dxUserInterface.cpp - ${DX_DIR}dxVertexLayout.cpp - ${WIN_DIR}wWindow.cpp) - + ${DX_DIR}dxBlender.cpp + ${DX_DIR}dxBuffers.cpp + ${DX_DIR}dxFramebuffer.cpp + ${DX_DIR}dxGraphicsContext.cpp + ${DX_DIR}dxRenderCommand.cpp + ${DX_DIR}dxShader.cpp + ${DX_DIR}dxSharedContext.cpp + ${DX_DIR}dxTexture.cpp + ${DX_DIR}dxUserInterface.cpp + ${DX_DIR}dxVertexLayout.cpp + ${WIN_DIR}wWindow.cpp) +else() + file(GLOB_RECURSE HLSL_FILES true ABSOLUTE ${ENGINE_DIR}res/*.hlsl) + set_source_files_properties(${HLSL_FILES} PROPERTIES VS_TOOL_OVERRIDE "None") endif() list(LENGTH ENGINE_ALL_FILES ENGINE_ALL_FILES_COUNT) -message(${ENGINE_ALL_FILES_COUNT} " files left in Engine after excludes") include_directories( ${ENGINE_DIR}src/Engine/ @@ -47,8 +45,9 @@ ${DEPENDENCIES_DIR}GLAD/include/ ${DEPENDENCIES_DIR}GLFW/include/ ${DEPENDENCIES_DIR}glm/ ${DEPENDENCIES_DIR}imgui/ -${DEPENDENCIES_DIR}spdlog/include +${DEPENDENCIES_DIR}spdlog/include/ ${DEPENDENCIES_DIR}stb_image/ +${DEPENDENCIES_DIR}ShaderConductor/Include/ ) source_group(TREE ${ENGINE_DIR} FILES ${ENGINE_ALL_FILES} ${ENGINE_RES_FILES}) @@ -58,6 +57,4 @@ if(WIN32) target_link_libraries(Engine d3d11) target_link_libraries(Engine dxguid) target_link_libraries(Engine D3DCompiler) -endif() - -message("______________________________________________________________________") \ No newline at end of file +endif() \ No newline at end of file diff --git a/Engine/res/Shaders/Quad/Quad_PS.glsl b/Engine/res/Shaders/Quad/Quad_PS.glsl deleted file mode 100644 index 4e278f2..0000000 --- a/Engine/res/Shaders/Quad/Quad_PS.glsl +++ /dev/null @@ -1,10 +0,0 @@ -#version 440 core - -in vec4 vso_FragmentColor; - -out vec4 fso_FragmentColor; - -void main() -{ - fso_FragmentColor = vso_FragmentColor; -} \ No newline at end of file diff --git a/Engine/res/Shaders/Quad/Quad_VS.glsl b/Engine/res/Shaders/Quad/Quad_VS.glsl deleted file mode 100644 index 1c5d0f9..0000000 --- a/Engine/res/Shaders/Quad/Quad_VS.glsl +++ /dev/null @@ -1,17 +0,0 @@ -#version 440 core - -layout(location = 0) in vec4 a_Position; -layout(location = 1) in vec4 a_Color; - -layout(std140, binding = 0) uniform ub_ViewProjection -{ - mat4 viewProjection; -}; - -out vec4 vso_FragmentColor; - -void main() -{ - gl_Position = viewProjection * a_Position; - vso_FragmentColor = a_Color; -} \ No newline at end of file diff --git a/Engine/res/Shaders/Texture/Texture_PS.glsl b/Engine/res/Shaders/Texture/Texture_PS.glsl deleted file mode 100644 index 19ba23e..0000000 --- a/Engine/res/Shaders/Texture/Texture_PS.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#version 440 core - -in vec2 vso_TexCoord; - -uniform sampler2D u_Texture; - -out vec4 fso_FragmentColor; - -void main() -{ - fso_FragmentColor = texture(u_Texture, vso_TexCoord); -} \ No newline at end of file diff --git a/Engine/res/Shaders/Texture/Texture_VS.glsl b/Engine/res/Shaders/Texture/Texture_VS.glsl deleted file mode 100644 index 42083ec..0000000 --- a/Engine/res/Shaders/Texture/Texture_VS.glsl +++ /dev/null @@ -1,18 +0,0 @@ -#version 440 core - -layout(location = 0) in vec4 a_Position; -layout(location = 1) in vec2 a_TexCoord; - -layout(std140, binding = 0) uniform ub_ViewProjection -{ - mat4 u_ViewProjection; -}; - -out vec2 vso_TexCoord; - -void main() -{ - gl_Position = u_ViewProjection * a_Position; - - vso_TexCoord = a_TexCoord; -} \ No newline at end of file diff --git a/Engine/res/Shaders/TintedTexture/TintedTexture_PS.glsl b/Engine/res/Shaders/TintedTexture/TintedTexture_PS.glsl deleted file mode 100644 index 0aa19e7..0000000 --- a/Engine/res/Shaders/TintedTexture/TintedTexture_PS.glsl +++ /dev/null @@ -1,13 +0,0 @@ -#version 440 core - -in vec4 vso_Tint; -in vec2 vso_TexCoord; - -uniform sampler2D u_Texture; - -out vec4 fso_FragmentColor; - -void main() -{ - fso_FragmentColor = texture(u_Texture, vso_TexCoord) * vso_Tint; -} \ No newline at end of file diff --git a/Engine/res/Shaders/TintedTexture/TintedTexture_VS.glsl b/Engine/res/Shaders/TintedTexture/TintedTexture_VS.glsl deleted file mode 100644 index ff835df..0000000 --- a/Engine/res/Shaders/TintedTexture/TintedTexture_VS.glsl +++ /dev/null @@ -1,21 +0,0 @@ -#version 440 core - -layout(location = 0) in vec4 a_Position; -layout(location = 1) in vec4 a_Tint; -layout(location = 2) in vec2 a_TexCoord; - -layout(std140, binding = 0) uniform ub_ViewProjection -{ - mat4 u_ViewProjection; -}; - -out vec4 vso_Tint; -out vec2 vso_TexCoord; - -void main() -{ - gl_Position = u_ViewProjection * a_Position; - - vso_Tint = a_Tint; - vso_TexCoord = a_TexCoord; -} \ No newline at end of file diff --git a/Engine/src/Engine/Graphics/RendererPrograms/QuadRendererProgram.cpp b/Engine/src/Engine/Graphics/RendererPrograms/QuadRendererProgram.cpp index 84814dd..c7563ea 100644 --- a/Engine/src/Engine/Graphics/RendererPrograms/QuadRendererProgram.cpp +++ b/Engine/src/Engine/Graphics/RendererPrograms/QuadRendererProgram.cpp @@ -21,7 +21,7 @@ namespace Light { m_MaxVertices(maxVertices) { // #todo: don't use relative path - ResourceManager::LoadShader("LT_ENGINE_RESOURCES_QUAD_SHADER", "../../Engine/res/Shaders/Quad/Quad_VS", "../../Engine//res/Shaders/Quad/Quad_PS"); + ResourceManager::LoadShader("LT_ENGINE_RESOURCES_QUAD_SHADER", "../../Engine/res/Shaders/Quad/Quad_VS.hlsl", "../../Engine//res/Shaders/Quad/Quad_PS.hlsl"); m_Shader = ResourceManager::GetShader("LT_ENGINE_RESOURCES_QUAD_SHADER"); m_VertexBuffer = Ref(VertexBuffer::Create(nullptr, sizeof(QuadVertexData), maxVertices, sharedContext)); diff --git a/Engine/src/Engine/Graphics/RendererPrograms/TextureRendererProgram.cpp b/Engine/src/Engine/Graphics/RendererPrograms/TextureRendererProgram.cpp index a195ab4..6a1cb7b 100644 --- a/Engine/src/Engine/Graphics/RendererPrograms/TextureRendererProgram.cpp +++ b/Engine/src/Engine/Graphics/RendererPrograms/TextureRendererProgram.cpp @@ -21,7 +21,7 @@ namespace Light { m_MaxVertices(maxVertices) { // #todo: don't use relative path - ResourceManager::LoadShader("LT_ENGINE_RESOURCES_TEXTURE_SHADER", "../../Engine/res/Shaders/Texture/Texture_VS", "../../Engine/res/Shaders/Texture/Texture_PS"); + ResourceManager::LoadShader("LT_ENGINE_RESOURCES_TEXTURE_SHADER", "../../Engine/res/Shaders/Texture/Texture_VS.hlsl", "../../Engine/res/Shaders/Texture/Texture_PS.hlsl"); m_Shader = ResourceManager::GetShader("LT_ENGINE_RESOURCES_TEXTURE_SHADER"); m_VertexBuffer = Ref(VertexBuffer::Create(nullptr, sizeof(TextureVertexData), maxVertices, sharedContext)); diff --git a/Engine/src/Engine/Graphics/RendererPrograms/TintedTextureRendererProgram.cpp b/Engine/src/Engine/Graphics/RendererPrograms/TintedTextureRendererProgram.cpp index 80a17cf..b28a614 100644 --- a/Engine/src/Engine/Graphics/RendererPrograms/TintedTextureRendererProgram.cpp +++ b/Engine/src/Engine/Graphics/RendererPrograms/TintedTextureRendererProgram.cpp @@ -21,7 +21,7 @@ namespace Light { m_MaxVertices(maxVertices) { // #todo: don't use relative path - ResourceManager::LoadShader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER", "../../Engine/res/Shaders/TintedTexture/TintedTexture_VS", "../../Engine/res/Shaders/TintedTexture/TintedTexture_PS"); + ResourceManager::LoadShader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER", "../../Engine/res/Shaders/TintedTexture/TintedTexture_VS.hlsl", "../../Engine/res/Shaders/TintedTexture/TintedTexture_PS.hlsl"); m_Shader = ResourceManager::GetShader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER"); m_VertexBuffer = Ref(VertexBuffer::Create(nullptr, sizeof(TintedTextureVertexData), maxVertices, sharedContext)); diff --git a/Engine/src/Engine/Graphics/Shader.cpp b/Engine/src/Engine/Graphics/Shader.cpp index cd25b64..0242171 100644 --- a/Engine/src/Engine/Graphics/Shader.cpp +++ b/Engine/src/Engine/Graphics/Shader.cpp @@ -11,16 +11,16 @@ namespace Light { - Ref Shader::Create(const std::string& vertexSource, const std::string& pixelSource, Ref sharedContext) + Ref Shader::Create(const std::vector& vertexBlob, const std::vector& pixelBlob, const std::string& vertexFileName, const std::string& pixelFileName, Ref sharedContext) { // load shader source switch (GraphicsContext::GetGraphicsAPI()) { case GraphicsAPI::OpenGL: - return CreateRef(vertexSource, pixelSource); + return CreateRef(vertexBlob, pixelBlob, vertexFileName, pixelFileName); case GraphicsAPI::DirectX: LT_WIN( - return CreateRef(vertexSource, pixelSource, std::static_pointer_cast(sharedContext));) + return CreateRef(vertexBlob, pixelBlob, std::static_pointer_cast(sharedContext));) default: LT_ENGINE_ASSERT(false, "Shader::Create: invalid/unsupported 'GraphicsAPI' {}", GraphicsContext::GetGraphicsAPI()); diff --git a/Engine/src/Engine/Graphics/Shader.h b/Engine/src/Engine/Graphics/Shader.h index cc37914..19b9a10 100644 --- a/Engine/src/Engine/Graphics/Shader.h +++ b/Engine/src/Engine/Graphics/Shader.h @@ -11,7 +11,16 @@ namespace Light { class Shader { public: - static Ref Create(const std::string& vertexPath, const std::string& pixelPath, Ref sharedContext); + enum Stage + { + NONE = 0, + VERTEX = 1, + PIXEL = 2, + GEOMETRY = 3 + }; + + public: + static Ref Create(const std::vector& vertexBlob, const std::vector& pixelBlob, const std::string& vertexFileName, const std::string& pixelFileName, Ref sharedContext); virtual ~Shader() = default; diff --git a/Engine/src/Engine/Utility/ResourceManager.cpp b/Engine/src/Engine/Utility/ResourceManager.cpp index c9c1327..03fef49 100644 --- a/Engine/src/Engine/Utility/ResourceManager.cpp +++ b/Engine/src/Engine/Utility/ResourceManager.cpp @@ -27,52 +27,41 @@ namespace Light { stbi_set_flip_vertically_on_load(true); } - 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" : ""; - - // check - LT_ENGINE_ASSERT(!vertexSource.empty(), "ResourceManager::CreateShaderImpl: 'vertexSource' is empty"); - LT_ENGINE_ASSERT(!vertexSource.empty(), "ResourceManager::CreateShaderImpl: 'pixelSource' is empty"); - LT_ENGINE_ASSERT(!delim.empty(), "ResourceManager::CreateShaderImpl: invalid/unsupported 'GraphicsAPI': {}", GraphicsContext::GetGraphicsAPI()); - - // save to string - std::string vsSource = vertexSource; - std::string psSource = pixelSource; - - // extract shader source - ResourceManager::ExtractShaderSource(vsSource, delim); - ResourceManager::ExtractShaderSource(psSource, delim); - - // create shader - m_Shaders[name] = Ref(Shader::Create(vsSource, psSource, m_SharedGraphicsContext)); - } - void ResourceManager::LoadShaderImpl(const std::string& name, const std::string& vertexPath, const std::string& pixelPath) { - // check - LT_ENGINE_ASSERT(!vertexPath.empty(), "ResourceManager::LoadShaderImpl: 'vertexPath' is empty"); - LT_ENGINE_ASSERT(!pixelPath.empty(), "ResourceManager::LoadShaderImpl: 'pixelPath' is empty"); + std::vector vertexFile, pixelFile; - std::string vPath = vertexPath + (GraphicsContext::GetGraphicsAPI() == GraphicsAPI::OpenGL ? ".glsl" : ".hlsl"); - std::string pPath = pixelPath + (GraphicsContext::GetGraphicsAPI() == GraphicsAPI::OpenGL ? ".glsl" : ".hlsl"); + std::ifstream file; + std::ios_base::openmode mode = std::ios_base::in; + + // read vertex shader file + file.open(vertexPath.c_str(), mode); + LT_ENGINE_ASSERT(file, "ResourceManager::LoadShaderImpl: failed to load vertex shader at path: {}", vertexPath); + if (file) + { + file.seekg(0, std::ios::end); + vertexFile.resize(static_cast(file.tellg())); + file.seekg(0, std::ios::beg); + file.read(reinterpret_cast(vertexFile.data()), vertexFile.size()); + vertexFile.resize(static_cast(file.gcount())); + file.close(); + } - // initialize - std::ifstream vsStream(vPath), psStream(pPath); - std::stringstream vsSS, psSS; // pss pss pss pss :D - std::string line; - - // read - while (std::getline(vsStream, line)) - vsSS << line << '\n'; - - while (std::getline(psStream, line)) - psSS << line << '\n'; + // read pixel shader file + file.open(pixelPath.c_str(), mode); + LT_ENGINE_ASSERT(file, "ResourceManager::LoadShaderImpl: failed to load vertex shader at path: {}", vertexPath); + if (file) + { + file.seekg(0, std::ios::end); + pixelFile.resize(static_cast(file.tellg())); + file.seekg(0, std::ios::beg); + file.read(reinterpret_cast(pixelFile.data()), pixelFile.size()); + pixelFile.resize(static_cast(file.gcount())); + file.close(); + } // create shader - m_Shaders[name] = Ref(Shader::Create(vsSS.str(), psSS.str(), m_SharedGraphicsContext)); + m_Shaders[name] = Ref(Shader::Create(vertexFile, pixelFile, vertexPath, pixelPath, m_SharedGraphicsContext)); } void ResourceManager::LoadTextureImpl(const std::string& name, const std::string& path, unsigned int desiredComponents /* = 4u */) @@ -104,26 +93,4 @@ namespace Light { m_Textures[name] = nullptr; } - 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 index 90d791c..207a1d1 100644 --- a/Engine/src/Engine/Utility/ResourceManager.h +++ b/Engine/src/Engine/Utility/ResourceManager.h @@ -24,7 +24,6 @@ namespace Light { static Scope Create(Ref 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 void LoadTexture(const std::string& name, const std::string& path, unsigned int desiredComponents = 4u) { s_Context->LoadTextureImpl(name, path, desiredComponents); } @@ -37,15 +36,11 @@ namespace Light { private: ResourceManager(Ref 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); void LoadTextureImpl(const std::string& name, const std::string& path, unsigned int desiredComponents = 4u); void ReleaseTextureImpl(const std::string& name); - - private: - void ExtractShaderSource(std::string& src, const std::string& delim); }; } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxShader.cpp b/Engine/src/Platform/GraphicsAPI/DirectX/dxShader.cpp index 08b847f..f7c44fc 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxShader.cpp +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxShader.cpp @@ -6,7 +6,7 @@ namespace Light { - dxShader::dxShader(const std::string& vertexSource, const std::string& pixelSource, Ref sharedContext) + dxShader::dxShader(const std::vector& vertexBlob, const std::vector pixelBlob, Ref sharedContext) : m_Context(sharedContext), m_VertexShader(nullptr), m_PixelShader(nullptr), @@ -14,9 +14,9 @@ namespace Light { { Microsoft::WRL::ComPtr ps = nullptr, vsErr = nullptr, psErr = nullptr; - // compile shaders (we don't use DXC here because if D3DCompile fails it throws a dxException without logging the vsErr/psErr) - D3DCompile(vertexSource.c_str(), vertexSource.length(), NULL, nullptr, nullptr, "main", "vs_4_0", NULL, NULL, &m_VertexBlob, &vsErr); - D3DCompile(pixelSource.c_str(), pixelSource.length(), NULL, nullptr, nullptr, "main", "ps_4_0", NULL, NULL, &ps, &psErr); + // compile shaders (we don't use DXC here because if D3DCompile fails it throws a dxException without logging the vsErr/psErr + D3DCompile(vertexBlob.data(), vertexBlob.size(), NULL, nullptr, nullptr, "main", "vs_4_0", NULL, NULL, &m_VertexBlob, &vsErr); + D3DCompile(pixelBlob.data(), pixelBlob.size(), NULL, nullptr, nullptr, "main", "ps_4_0", NULL, NULL, &ps, &psErr); // check LT_ENGINE_ASSERT(!vsErr.Get(), "dxShader::dxShader: vertex shader compile error: {}", (char*)vsErr->GetBufferPointer()); diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxShader.h b/Engine/src/Platform/GraphicsAPI/DirectX/dxShader.h index 13b1b3e..a4d3e91 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxShader.h +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxShader.h @@ -22,7 +22,7 @@ namespace Light { Microsoft::WRL::ComPtr m_VertexBlob; public: - dxShader(const std::string& vertexSource, const std::string& pixelSource, Ref sharedContext); + dxShader(const std::vector& vertexBlob, const std::vector pixelBlob, Ref sharedContext); ~dxShader(); void Bind() override; diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glShader.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glShader.cpp index 0f7db90..812b1dd 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glShader.cpp +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glShader.cpp @@ -7,104 +7,43 @@ #include #include + namespace Light { - glShader::glShader(const std::string& vertexSource, const std::string& fragmentSource) + glShader::glShader(const std::vector& vertexBlob, const std::vector& pixelBlob, const std::string& vertexFileName, const std::string& pixelFileName) : m_ShaderID(NULL) { + // create m_ShaderID = glCreateProgram(); - // create shaders - unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); - unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + // compile hlsl to glsl + ShaderConductor::Compiler::ResultDesc vertexResult = CompileHLSL(vertexBlob, vertexFileName, Shader::Stage::VERTEX); + ShaderConductor::Compiler::ResultDesc pixelResult = CompileHLSL(pixelBlob, pixelFileName, Shader::Stage::PIXEL); - // &(address of) needs an lvalue - const char* lVertexSource = vertexSource.c_str(); - const char* lFragmentSource = fragmentSource.c_str(); + LT_ENGINE_ASSERT(!vertexResult.hasError, "glShader::glShader: failed to compile hlsl vertex shader: {}", vertexFileName); + LT_ENGINE_ASSERT(!pixelResult.hasError, "glShader::glShader: failed to compile hlsl pixel shader: {}", pixelFileName); - // set shaders' source code - glShaderSource(vertexShader, 1, &lVertexSource, NULL); - glShaderSource(fragmentShader, 1, &lFragmentSource, NULL); + // extract glsl source + std::string vertexSource = std::string(reinterpret_cast(vertexResult.target.Data())); + vertexSource.resize(vertexResult.target.Size()); - // compile shaders - glCompileShader(vertexShader); - glCompileShader(fragmentShader); - - /* #TEMP_HANDLE_SHADER_COMPILE_FAILURE# */ - int isCompiled = 0; - glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled); - if (isCompiled == GL_FALSE) - { - int logLength = 0; - glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength); - - char* errorLog = (char*)alloca(logLength); - glGetShaderInfoLog(vertexShader, logLength, &logLength, &errorLog[0]); - - glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); - - LT_ENGINE_ASSERT(false, "glShader::glShader: failed to compile vertex shader:\n {}", errorLog); - - return; - } - - glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled); - if (isCompiled == GL_FALSE) - { - int logLength = 0; - glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength); - - char* errorLog = (char*)alloca(logLength); - glGetShaderInfoLog(fragmentShader, logLength, &logLength, &errorLog[0]); - - glDeleteShader(fragmentShader); - glDeleteShader(vertexShader); - - LT_ENGINE_ASSERT(false, "glShader::glShader: failed to compile fragment shader:\n {}", errorLog); - - return; - } - /* #TEMP_HANDLE_SHADER_COMPILE_FAILURE# */ - - -#ifdef LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG - { - int logLength = 0; - glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength); - if(logLength) - { - char* infoLog = (char*)alloca(logLength); - glGetShaderInfoLog(vertexShader, logLength, &logLength, &infoLog[0]); - - LT_ENGINE_TRACE(infoLog); - } - } - - { - int logLength = 0; - glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength) - { - char* infoLog = (char*)alloca(logLength); - glGetShaderInfoLog(fragmentShader, logLength, &logLength, &infoLog[0]); - - LT_ENGINE_TRACE(infoLog); - } - } -#endif + std::string pixelSource = std::string(reinterpret_cast(pixelResult.target.Data())); + pixelSource.resize(pixelResult.target.Size()); + // compile glsl + unsigned int vertexShader = CompileShader(vertexSource, Shader::Stage::VERTEX); + unsigned int pixelShader = CompileShader(pixelSource, Shader::Stage::PIXEL); // attach shaders glAttachShader(m_ShaderID, vertexShader); - glAttachShader(m_ShaderID, fragmentShader); - + glAttachShader(m_ShaderID, pixelShader); + // link shader program glLinkProgram(m_ShaderID); - + // delete shaders (free memory) glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); + glDeleteShader(pixelShader); } glShader::~glShader() @@ -122,4 +61,109 @@ namespace Light { glUseProgram(NULL); } + ShaderConductor::Compiler::ResultDesc glShader::CompileHLSL(std::vector blob, std::string fileName, Shader::Stage stage) + { + // check + LT_ENGINE_ASSERT(!blob.empty(), "glShader::CompileHLSL: 'blob' is empty"); + LT_ENGINE_ASSERT(!fileName.empty(), "glShader::CompileHLSL: 'fileName' is empty"); + LT_ENGINE_ASSERT(stage, "glShader::CompileHLSL: 'stage' is invalid: None"); + + // compiler options + ShaderConductor::Compiler::Options options = {}; + options.packMatricesInRowMajor = true; + options.enableDebugInfo = true; + options.disableOptimizations = true; + options.inheritCombinedSamplerBindings = true; + options.shaderModel = { 4, 5 }; + + // compiler target descriptor + ShaderConductor::Compiler::TargetDesc targetDesc = {}; + targetDesc.language = ShaderConductor::ShadingLanguage::Glsl; + targetDesc.version = "440 core"; + targetDesc.asModule = false; + + // compiler source descriptor + ShaderConductor::Compiler::SourceDesc sourceDesc = {}; + std::string source = std::string(reinterpret_cast(blob.data()), blob.size()); + sourceDesc.source = source.c_str(); + sourceDesc.fileName = fileName.c_str(); + sourceDesc.entryPoint = "main"; + sourceDesc.stage = stage == Shader::Stage::VERTEX ? ShaderConductor::ShaderStage::VertexShader : + stage == Shader::Stage::PIXEL ? ShaderConductor::ShaderStage::PixelShader : + ShaderConductor::ShaderStage::GeometryShader; + sourceDesc.defines = nullptr; + sourceDesc.numDefines = 0u; + sourceDesc.loadIncludeCallback = nullptr; + + // compilation result + ShaderConductor::Compiler::ResultDesc result = ShaderConductor::Compiler::Compile(sourceDesc, options, targetDesc); + + // log info + LT_ENGINE_INFO("_______________________________________"); + LT_ENGINE_INFO("Compiled with ShaderConductor:"); + LT_ENGINE_INFO(" hasError: {}", result.hasError); + LT_ENGINE_INFO(" isText: {}", result.isText); + + if (result.errorWarningMsg.Size() != 0u) + { + const char* errorStr = reinterpret_cast(result.errorWarningMsg.Data()); + LT_ENGINE_ERROR(" errorWarningMsg: \n{}", errorStr); + } + if (result.target.Size() != 0u) + { + const char* targetStr = reinterpret_cast(result.target.Data()); + LT_ENGINE_INFO(" target: \n{}", targetStr); + } + LT_ENGINE_INFO("_______________________________________"); + + return result; + } + + unsigned int glShader::CompileShader(const std::string& source, Shader::Stage stage) + { + // &(address of) needs an lvalue + const char* lvalue_source = reinterpret_cast(source.c_str()); + unsigned int shader = glCreateShader(stage == Shader::Stage::VERTEX ? GL_VERTEX_SHADER : + stage == Shader::Stage::PIXEL ? GL_FRAGMENT_SHADER : + stage == Shader::Stage::GEOMETRY ? GL_GEOMETRY_SHADER : + NULL); + + // compile + glShaderSource(shader, 1, &lvalue_source, NULL); + glCompileShader(shader); + + // check + int isCompiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) + { + int logLength = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); + + char* errorLog = (char*)alloca(logLength); + glGetShaderInfoLog(shader, logLength, &logLength, &errorLog[0]); + + LT_ENGINE_ASSERT(false, "glShader::glShader: failed to compile vertex shader:\n {}", errorLog); + + return NULL; + } + +#ifdef LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG + // info log + { + int logLength = 0; + glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength) + { + char* infoLog = (char*)alloca(logLength); + glGetShaderInfoLog(vertexShader, logLength, &logLength, &infoLog[0]); + + LT_ENGINE_TRACE(infoLog); + } + } +#endif + + return shader; + } + } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glShader.h b/Engine/src/Platform/GraphicsAPI/OpenGL/glShader.h index 54a7207..6b92f30 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glShader.h +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glShader.h @@ -4,6 +4,8 @@ #include "Base/Base.h" +#include + namespace Light { class glShader : public Shader @@ -12,11 +14,16 @@ namespace Light { unsigned int m_ShaderID; public: - glShader(const std::string& vetexSource, const std::string& fragmentSource); + glShader(const std::vector& vertexBlob, const std::vector& pixelBlob, const std::string& vertexFileName, const std::string& pixelFileName); ~glShader(); void Bind() override; void UnBind() override; + + private: + ShaderConductor::Compiler::ResultDesc CompileHLSL(std::vector blob, std::string fileName, Shader::Stage stage); + + unsigned int CompileShader(const std::string& source, Shader::Stage stage); }; } \ No newline at end of file