From e8fc757d998ffe9da2b7d09f60c8bb57ffaa3134 Mon Sep 17 00:00:00 2001 From: redstrate <54911369+redstrate@users.noreply.github.com> Date: Tue, 16 Feb 2021 17:10:37 -0500 Subject: [PATCH] Add basic shader editing system POC, only registered shader is the sky shader --- engine/core/include/debug.hpp | 7 ++ engine/core/src/debug.cpp | 69 ++++++++++++++ engine/gfx/metal/src/gfx_metal.mm | 20 ++-- engine/gfx/public/gfx.hpp | 2 - engine/platform/CMakeLists.txt | 3 + engine/renderer/include/renderer.hpp | 17 +++- engine/renderer/src/dofpass.cpp | 4 +- engine/renderer/src/gaussianhelper.cpp | 4 +- engine/renderer/src/imguipass.cpp | 4 +- engine/renderer/src/materialcompiler.cpp | 6 +- engine/renderer/src/renderer.cpp | 95 ++++++++++++++++--- engine/renderer/src/scenecapture.cpp | 12 +-- engine/renderer/src/shadowpass.cpp | 4 +- engine/renderer/src/smaapass.cpp | 8 +- engine/shadercompiler/CMakeLists.txt | 2 + .../shadercompiler/include/shadercompiler.hpp | 20 +++- engine/shadercompiler/src/shadercompiler.cpp | 7 +- tools/common/src/debugpass.cpp | 16 ++-- 18 files changed, 239 insertions(+), 61 deletions(-) create mode 100755 engine/platform/CMakeLists.txt diff --git a/engine/core/include/debug.hpp b/engine/core/include/debug.hpp index 6434b05..6595e9b 100644 --- a/engine/core/include/debug.hpp +++ b/engine/core/include/debug.hpp @@ -1,3 +1,10 @@ #pragma once +#include + void draw_debug_ui(); + +void load_debug_options(); +void save_debug_options(); + +std::string_view get_shader_source_directory(); diff --git a/engine/core/src/debug.cpp b/engine/core/src/debug.cpp index cc0b97b..f5e23d8 100644 --- a/engine/core/src/debug.cpp +++ b/engine/core/src/debug.cpp @@ -11,6 +11,13 @@ #include "imgui_utility.hpp" #include "scene.hpp" #include "renderer.hpp" +#include "file.hpp" + +struct Options { + std::string shader_source_path; +}; + +static inline Options options; void draw_general() { ImGui::Text("Platform: %s", platform::get_name()); @@ -145,6 +152,51 @@ void draw_renderer() { } } +static inline std::string selected_shader; +static inline std::string loaded_shader_string; + +void draw_shader_editor() { + if(options.shader_source_path.empty()) { + ImGui::Text("You haven't specified a shader source path yet. Please select one below:"); + if(ImGui::Button("Select Path")) { + platform::open_dialog(false, [](std::string path) { + // open_dialog() can't select folders yet, so use this as a workaround + options.shader_source_path = file::Path(path).parent_path().string(); + }); + } + } else { + if(ImGui::BeginCombo("Select", nullptr)) { + for(auto& shader : engine->get_renderer()->registered_shaders) { + if(ImGui::Selectable(shader.filename.data())) { + selected_shader = shader.filename; + loaded_shader_string.clear(); + } + } + + ImGui::EndCombo(); + } + + if(!selected_shader.empty()) { + if(loaded_shader_string.empty()) { + file::Path base_shader_path = options.shader_source_path; + + shader_compiler.set_include_path(base_shader_path.string()); + + file::Path shader_path = file::Path(selected_shader); + + auto file = file::open(base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl")); + + loaded_shader_string = file->read_as_string(); + } + + ImGui::InputTextMultiline("Source", &loaded_shader_string); + + if(ImGui::Button("Reload")) + engine->get_renderer()->reload_shader(selected_shader, loaded_shader_string); + } + } +} + void draw_debug_ui() { if(ImGui::Begin("General")) draw_general(); @@ -165,4 +217,21 @@ void draw_debug_ui() { draw_renderer(); ImGui::End(); + + if(ImGui::Begin("Shader Editor")) + draw_shader_editor(); + + ImGui::End(); +} + +void load_debug_options() { + // stub +} + +void save_debug_options() { + // stub +} + +std::string_view get_shader_source_directory() { + return options.shader_source_path; } diff --git a/engine/gfx/metal/src/gfx_metal.mm b/engine/gfx/metal/src/gfx_metal.mm index d17a0f9..f69a2b9 100755 --- a/engine/gfx/metal/src/gfx_metal.mm +++ b/engine/gfx/metal/src/gfx_metal.mm @@ -443,17 +443,17 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI MTLRenderPipelineDescriptor *pipelineDescriptor = [MTLRenderPipelineDescriptor new]; - const bool has_vertex_stage = !info.shaders.vertex_path.empty() || !info.shaders.vertex_src.empty(); - const bool has_fragment_stage = !info.shaders.fragment_path.empty() || !info.shaders.fragment_src.empty(); + const bool has_vertex_stage = !info.shaders.vertex_src.empty(); + const bool has_fragment_stage = !info.shaders.fragment_src.empty(); if(has_vertex_stage) { id vertexLibrary; { std::string vertex_src; - if(info.shaders.vertex_path.empty()) { + if(info.shaders.vertex_src.is_string()) { vertex_src = info.shaders.vertex_src.as_string(); } else { - const auto vertex_path = utility::format("{}.msl", info.shaders.vertex_path); + const auto vertex_path = utility::format("{}.msl", info.shaders.vertex_src.as_path().string()); auto file = file::open(file::internal_domain / vertex_path); if(file != std::nullopt) { @@ -471,8 +471,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI id vertexFunc = [vertexLibrary newFunctionWithName:@"main0" constantValues:vertex_constants error:nil]; - if(debug_enabled) - vertexFunc.label = [NSString stringWithFormat:@"%s", info.shaders.vertex_path.data()]; + if(debug_enabled && info.shaders.vertex_src.is_path()) + vertexFunc.label = [NSString stringWithFormat:@"%s", info.shaders.vertex_src.as_path().string().data()]; pipelineDescriptor.vertexFunction = vertexFunc; } @@ -482,10 +482,10 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI id fragmentLibrary; { std::string fragment_src; - if(info.shaders.fragment_path.empty()) { + if(info.shaders.fragment_src.is_string()) { fragment_src = info.shaders.fragment_src.as_string(); } else { - const auto fragment_path = utility::format("{}.msl", info.shaders.fragment_path); + const auto fragment_path = utility::format("{}.msl", info.shaders.fragment_src.as_path().string()); auto file = file::open(file::internal_domain / fragment_path); if(file != std::nullopt) { @@ -504,8 +504,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI id fragmentFunc = [fragmentLibrary newFunctionWithName:@"main0" constantValues:fragment_constants error:nil]; - if(debug_enabled) - fragmentFunc.label = [NSString stringWithFormat:@"%s", info.shaders.fragment_path.data()]; + if(debug_enabled && info.shaders.fragment_src.is_path()) + fragmentFunc.label = [NSString stringWithFormat:@"%s", info.shaders.fragment_src.as_path().string().data()]; pipelineDescriptor.fragmentFunction = fragmentFunc; } diff --git a/engine/gfx/public/gfx.hpp b/engine/gfx/public/gfx.hpp index e457f92..522b305 100755 --- a/engine/gfx/public/gfx.hpp +++ b/engine/gfx/public/gfx.hpp @@ -157,8 +157,6 @@ struct GFXGraphicsPipelineCreateInfo { std::string label; // only used for debug struct Shaders { - std::string_view vertex_path, fragment_path; - ShaderSource vertex_src, fragment_src; GFXShaderConstants vertex_constants, fragment_constants; diff --git a/engine/platform/CMakeLists.txt b/engine/platform/CMakeLists.txt new file mode 100755 index 0000000..5c70dc7 --- /dev/null +++ b/engine/platform/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(Platform INTERFACE) +target_include_directories(Platform INTERFACE include) +target_link_libraries(Platform INTERFACE Utility) diff --git a/engine/renderer/include/renderer.hpp b/engine/renderer/include/renderer.hpp index 8af0af8..71779d3 100755 --- a/engine/renderer/include/renderer.hpp +++ b/engine/renderer/include/renderer.hpp @@ -10,6 +10,7 @@ #include "common.hpp" #include "render_options.hpp" #include "path.hpp" +#include "shadercompiler.hpp" namespace ui { class Screen; @@ -128,7 +129,21 @@ public: GFXRenderPass* unormRenderPass = nullptr; GFXPipeline* renderToUnormTexturePipeline = nullptr; GFXRenderPass* viewportRenderPass = nullptr; - + + ShaderSource register_shader(const std::string_view shader_file); + void associate_shader_reload(const std::string_view shader_file, const std::function reload_function); + void reload_shader(const std::string_view shader_file, const std::string_view shader_source); + + struct RegisteredShader { + std::string filename; + std::string injected_shader_source; + std::function reload_function; + }; + + std::vector registered_shaders; + + bool reloading_shader = false; + private: void createDummyTexture(); void createOffscreenResources(); diff --git a/engine/renderer/src/dofpass.cpp b/engine/renderer/src/dofpass.cpp index 0343061..ce16718 100755 --- a/engine/renderer/src/dofpass.cpp +++ b/engine/renderer/src/dofpass.cpp @@ -27,9 +27,9 @@ DoFPass::DoFPass(GFX* gfx, Renderer* renderer) : renderer(renderer) { height_constant.value = extent.height; GFXGraphicsPipelineCreateInfo create_info = {}; - create_info.shaders.vertex_path = "dof.vert"; + create_info.shaders.vertex_src = file::Path("dof.vert"); create_info.shaders.vertex_constants = {width_constant, height_constant}; - create_info.shaders.fragment_path = "dof.frag"; + create_info.shaders.fragment_src = file::Path("dof.frag"); create_info.shader_input.bindings = { {0, GFXBindingType::StorageImage}, diff --git a/engine/renderer/src/gaussianhelper.cpp b/engine/renderer/src/gaussianhelper.cpp index f810f9e..c8ac1b4 100755 --- a/engine/renderer/src/gaussianhelper.cpp +++ b/engine/renderer/src/gaussianhelper.cpp @@ -14,8 +14,8 @@ GaussianHelper::GaussianHelper(GFX* gfx, const prism::Extent extent) : extent(ex // pipeline GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Gaussian"; - pipelineInfo.shaders.vertex_path = "gaussian.vert"; - pipelineInfo.shaders.fragment_path = "gaussian.frag"; + pipelineInfo.shaders.vertex_src = file::Path("gaussian.vert"); + pipelineInfo.shaders.fragment_src = file::Path("gaussian.frag"); pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; diff --git a/engine/renderer/src/imguipass.cpp b/engine/renderer/src/imguipass.cpp index 7d4af48..1335424 100755 --- a/engine/renderer/src/imguipass.cpp +++ b/engine/renderer/src/imguipass.cpp @@ -22,8 +22,8 @@ void ImGuiPass::initialize() { void ImGuiPass::resize(const prism::Extent extent) { GFXGraphicsPipelineCreateInfo createInfo; createInfo.label = "ImGui"; - createInfo.shaders.vertex_path = "imgui.vert"; - createInfo.shaders.fragment_path = "imgui.frag"; + createInfo.shaders.vertex_src = file::Path("imgui.vert"); + createInfo.shaders.fragment_src = file::Path("imgui.frag"); GFXVertexInput vertexInput = {}; vertexInput.stride = sizeof(ImDrawVert); diff --git a/engine/renderer/src/materialcompiler.cpp b/engine/renderer/src/materialcompiler.cpp index 4006cc8..e421b71 100755 --- a/engine/renderer/src/materialcompiler.cpp +++ b/engine/renderer/src/materialcompiler.cpp @@ -36,7 +36,7 @@ ShaderSource get_shader(std::string filename, bool skinned, bool cubemap) { GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only, bool cubemap) { // take vertex src - std::string vertex_path = createInfo.shaders.vertex_path.data(); + std::string vertex_path = createInfo.shaders.vertex_src.as_path().string(); vertex_path += ".glsl"; if (positions_only) @@ -46,7 +46,6 @@ GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateI createInfo.label += "cubemap ver"; createInfo.shaders.vertex_src = get_shader(vertex_path, false, cubemap); - createInfo.shaders.vertex_path = ""; if(positions_only) { createInfo.vertex_input.inputs = { @@ -81,11 +80,10 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate createInfo.label += " (Skinned)"; // take vertex src - std::string vertex_path = createInfo.shaders.vertex_path.data(); + std::string vertex_path = createInfo.shaders.vertex_src.as_path().string(); vertex_path += ".glsl"; createInfo.shaders.vertex_src = get_shader(vertex_path, true, false); - createInfo.shaders.vertex_path = ""; createInfo.shader_input.bindings.push_back({ 14, GFXBindingType::StorageBuffer }); diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index 165d8ea..697e02c 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -24,6 +24,7 @@ #include "frustum.hpp" #include "shadercompiler.hpp" #include "asset.hpp" +#include "debug.hpp" struct ElementInstance { Vector4 color; @@ -710,8 +711,8 @@ void Renderer::create_mesh_pipeline(Material& material) { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Mesh"; - pipelineInfo.shaders.vertex_path = "mesh.vert"; - pipelineInfo.shaders.fragment_path = "mesh.frag"; + pipelineInfo.shaders.vertex_src = file::Path("mesh.vert"); + pipelineInfo.shaders.fragment_src = file::Path("mesh.frag"); pipelineInfo.shaders.vertex_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant}; pipelineInfo.shaders.fragment_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant}; @@ -738,7 +739,6 @@ void Renderer::create_mesh_pipeline(Material& material) { pipelineInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha; pipelineInfo.shaders.fragment_src = material_compiler.compile_material_fragment(material); - pipelineInfo.shaders.fragment_path = ""; for (auto [index, texture] : material.bound_textures) { GFXShaderBinding binding; @@ -852,8 +852,8 @@ void Renderer::createPostPipeline() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Post"; - pipelineInfo.shaders.vertex_path = "post.vert"; - pipelineInfo.shaders.fragment_path = "post.frag"; + pipelineInfo.shaders.vertex_src = file::Path("post.vert"); + pipelineInfo.shaders.fragment_src = file::Path("post.frag"); pipelineInfo.shader_input.bindings = { {4, GFXBindingType::PushConstant}, @@ -904,8 +904,8 @@ void Renderer::createFontPipeline() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Text"; - pipelineInfo.shaders.vertex_path = "text.vert"; - pipelineInfo.shaders.fragment_path = "text.frag"; + pipelineInfo.shaders.vertex_src = file::Path("text.vert"); + pipelineInfo.shaders.fragment_src = file::Path("text.frag"); pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; @@ -950,8 +950,8 @@ void Renderer::createSkyPipeline() { pipelineInfo.label = "Sky"; pipelineInfo.render_pass = offscreenRenderPass; - pipelineInfo.shaders.vertex_path = "sky.vert"; - pipelineInfo.shaders.fragment_path = "sky.frag"; + pipelineInfo.shaders.vertex_src = register_shader("sky.vert"); + pipelineInfo.shaders.fragment_src = register_shader("sky.frag"); pipelineInfo.shader_input.bindings = { {1, GFXBindingType::PushConstant} @@ -964,14 +964,22 @@ void Renderer::createSkyPipeline() { pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual; skyPipeline = gfx->create_graphics_pipeline(pipelineInfo); + + associate_shader_reload("sky.vert", [this] { + createSkyPipeline(); + }); + + associate_shader_reload("sky.frag", [this] { + createSkyPipeline(); + }); } void Renderer::createUIPipeline() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "UI"; - pipelineInfo.shaders.vertex_path = "ui.vert"; - pipelineInfo.shaders.fragment_path = "ui.frag"; + pipelineInfo.shaders.vertex_src = file::Path("ui.vert"); + pipelineInfo.shaders.fragment_src = file::Path("ui.frag"); pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; @@ -1026,8 +1034,8 @@ void Renderer::createBRDF() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "BRDF"; - pipelineInfo.shaders.vertex_path = "brdf.vert"; - pipelineInfo.shaders.fragment_path = "brdf.frag"; + pipelineInfo.shaders.vertex_src = file::Path("brdf.vert"); + pipelineInfo.shaders.fragment_src = file::Path("brdf.frag"); pipelineInfo.render_pass = brdfRenderPass; @@ -1100,3 +1108,64 @@ void Renderer::create_histogram_resources() { average_luminance_texture = gfx->create_texture(texture_info); } + +ShaderSource Renderer::register_shader(const std::string_view shader_file) { + if(!reloading_shader) { + RegisteredShader shader; + shader.filename = shader_file; + + registered_shaders.push_back(shader); + } + + std::string found_shader_source; + for(auto& shader : registered_shaders) { + if(shader.filename == shader_file) { + found_shader_source = shader.injected_shader_source; + } + } + + file::Path base_shader_path = get_shader_source_directory(); + + // if shader editor system is not initialized, use prebuilt shaders + if(base_shader_path.empty()) + return file::Path(shader_file); + + shader_compiler.set_include_path(base_shader_path.string()); + + file::Path shader_path = file::Path(shader_file); + + ShaderStage stage; + if(shader_path.extension() == ".vert") + stage = ShaderStage::Vertex; + else if(shader_path.extension() == ".frag") + stage = ShaderStage::Fragment; + + if(found_shader_source.empty()) { + auto file = file::open(base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl")); + + return shader_compiler.compile(ShaderLanguage::GLSL, stage, file->read_as_string(), ShaderLanguage::MSL).value(); + } else { + return shader_compiler.compile(ShaderLanguage::GLSL, stage, found_shader_source, ShaderLanguage::MSL).value(); + } +} + +void Renderer::associate_shader_reload(const std::string_view shader_file, const std::function reload_function) { + if(reloading_shader) + return; + + for(auto& shader : registered_shaders) { + if(shader.filename == shader_file) + shader.reload_function = reload_function; + } +} + +void Renderer::reload_shader(const std::string_view shader_file, const std::string_view shader_source) { + for(auto& shader : registered_shaders) { + if(shader.filename == shader_file) { + shader.injected_shader_source = shader_source; + reloading_shader = true; + shader.reload_function(); + reloading_shader = false; + } + } +} diff --git a/engine/renderer/src/scenecapture.cpp b/engine/renderer/src/scenecapture.cpp index 8238d91..6f48334 100755 --- a/engine/renderer/src/scenecapture.cpp +++ b/engine/renderer/src/scenecapture.cpp @@ -399,8 +399,8 @@ void SceneCapture::createSkyResources() { pipelineInfo.label = "Sky Scene Capture"; pipelineInfo.render_pass = renderPass; - pipelineInfo.shaders.vertex_path = "sky.vert"; - pipelineInfo.shaders.fragment_path = "sky.frag"; + pipelineInfo.shaders.vertex_src = file::Path("sky.vert"); + pipelineInfo.shaders.fragment_src = file::Path("sky.frag"); pipelineInfo.shader_input.bindings = { {1, GFXBindingType::PushConstant} @@ -443,8 +443,8 @@ void SceneCapture::createIrradianceResources() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Irradiance Convolution"; - pipelineInfo.shaders.vertex_path = "irradiance.vert"; - pipelineInfo.shaders.fragment_path = "irradiance.frag"; + pipelineInfo.shaders.vertex_src = file::Path("irradiance.vert"); + pipelineInfo.shaders.fragment_src = file::Path("irradiance.frag"); GFXVertexInput input; input.stride = sizeof(Vector3); @@ -495,8 +495,8 @@ void SceneCapture::createPrefilterResources() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Prefilter"; - pipelineInfo.shaders.vertex_path = "filter.vert"; - pipelineInfo.shaders.fragment_path = "filter.frag"; + pipelineInfo.shaders.vertex_src = file::Path("filter.vert"); + pipelineInfo.shaders.fragment_src = file::Path("filter.frag"); pipelineInfo.shaders.fragment_constants = {size_constant}; diff --git a/engine/renderer/src/shadowpass.cpp b/engine/renderer/src/shadowpass.cpp index 5a3d024..d7f0103 100755 --- a/engine/renderer/src/shadowpass.cpp +++ b/engine/renderer/src/shadowpass.cpp @@ -315,7 +315,7 @@ void ShadowPass::create_pipelines() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.shaders.vertex_constants = {point_light_max_constant}; - pipelineInfo.shaders.vertex_path = "shadow.vert"; + pipelineInfo.shaders.vertex_src = file::Path("shadow.vert"); pipelineInfo.shaders.fragment_constants = { point_light_max_constant }; //pipelineInfo.shaders.fragment_path = "shadow.frag"; @@ -360,7 +360,7 @@ void ShadowPass::create_pipelines() { { pipelineInfo.label = "Point Shadow"; - pipelineInfo.shaders.fragment_path = "omnishadow.frag"; + pipelineInfo.shaders.fragment_src = file::Path("omnishadow.frag"); auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true); diff --git a/engine/renderer/src/smaapass.cpp b/engine/renderer/src/smaapass.cpp index cb8e836..c654714 100755 --- a/engine/renderer/src/smaapass.cpp +++ b/engine/renderer/src/smaapass.cpp @@ -112,8 +112,8 @@ void SMAAPass::create_pipelines() { GFXGraphicsPipelineCreateInfo createInfo = {}; createInfo.label = "SMAA Edge"; - createInfo.shaders.vertex_path = "edge.vert"; - createInfo.shaders.fragment_path = "edge.frag"; + createInfo.shaders.vertex_src = file::Path("edge.vert"); + createInfo.shaders.fragment_src = file::Path("edge.frag"); createInfo.render_pass = render_pass; @@ -130,8 +130,8 @@ void SMAAPass::create_pipelines() { edge_pipeline = gfx->create_graphics_pipeline(createInfo); createInfo.label = "SMAA Blend"; - createInfo.shaders.vertex_path = "blend.vert"; - createInfo.shaders.fragment_path = "blend.frag"; + createInfo.shaders.vertex_src = file::Path("blend.vert"); + createInfo.shaders.fragment_src = file::Path("blend.frag"); createInfo.shader_input.bindings.push_back({3, GFXBindingType::Texture}); blend_pipeline = gfx->create_graphics_pipeline(createInfo); diff --git a/engine/shadercompiler/CMakeLists.txt b/engine/shadercompiler/CMakeLists.txt index e079267..4f77f6e 100755 --- a/engine/shadercompiler/CMakeLists.txt +++ b/engine/shadercompiler/CMakeLists.txt @@ -7,6 +7,8 @@ set(SRC add_library(ShaderCompiler STATIC ${SRC}) target_link_libraries(ShaderCompiler + PUBLIC + Platform PRIVATE Utility Log diff --git a/engine/shadercompiler/include/shadercompiler.hpp b/engine/shadercompiler/include/shadercompiler.hpp index 06bcb5f..e2145fb 100755 --- a/engine/shadercompiler/include/shadercompiler.hpp +++ b/engine/shadercompiler/include/shadercompiler.hpp @@ -6,6 +6,8 @@ #include #include +#include "file.hpp" + /// The shader stage that the shader is written in. enum class ShaderStage { Vertex, @@ -41,8 +43,14 @@ public: ShaderSource(const ShaderSource& rhs) : source (rhs.source) {} ShaderSource(const std::string source_string) : source(source_string) {} ShaderSource(const std::vector source_bytecode) : source(source_bytecode) {} - - std::variant> source; + ShaderSource(const file::Path shader_path) : source(shader_path) {} + + std::variant> source; + + /// Returns a view of the shader source as a path. + file::Path as_path() const { + return std::get(source); + } /// Returns a view of the shader source as plaintext. std::string_view as_string() const { @@ -57,6 +65,14 @@ public: bool empty() const { return std::holds_alternative(source); } + + bool is_path() const { + return std::holds_alternative(source); + } + + bool is_string() const { + return std::holds_alternative(source); + } }; /// Compiles GLSL shaders to a specified shader language offline or at runtime. diff --git a/engine/shadercompiler/src/shadercompiler.cpp b/engine/shadercompiler/src/shadercompiler.cpp index 0922b25..b2a451d 100755 --- a/engine/shadercompiler/src/shadercompiler.cpp +++ b/engine/shadercompiler/src/shadercompiler.cpp @@ -9,14 +9,14 @@ #include "includer.hpp" #include "defaultresources.hpp" -static inline std::string include_path; +static inline std::vector include_path; ShaderCompiler::ShaderCompiler() { glslang::InitializeProcess(); } void ShaderCompiler::set_include_path(const std::string_view path) { - include_path = path; + include_path.push_back(path.data()); } const std::vector compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) { @@ -50,7 +50,8 @@ const std::vector compile_glsl_to_spv(const std::string_view source_st EShMessages messages = (EShMessages) (EShMsgDefault); DirStackFileIncluder includer; - includer.pushExternalLocalDirectory(include_path); + for(auto path : include_path) + includer.pushExternalLocalDirectory(path); if (!Shader.parse(&Resources, 100, false, messages, includer)) { console::error(System::Renderer, "{}", Shader.getInfoLog()); diff --git a/tools/common/src/debugpass.cpp b/tools/common/src/debugpass.cpp index fba83e6..9c4b388 100755 --- a/tools/common/src/debugpass.cpp +++ b/tools/common/src/debugpass.cpp @@ -21,8 +21,8 @@ void DebugPass::initialize() { { GFXGraphicsPipelineCreateInfo createInfo; - createInfo.shaders.vertex_path = "debug.vert"; - createInfo.shaders.fragment_path = "debug.frag"; + createInfo.shaders.vertex_src = file::Path("debug.vert"); + createInfo.shaders.fragment_src = file::Path("debug.frag"); GFXVertexInput vertexInput = {}; vertexInput.stride = sizeof(Vector3); @@ -69,8 +69,8 @@ void DebugPass::initialize() { // pipeline GFXGraphicsPipelineCreateInfo pipelineInfo = {}; - pipelineInfo.shaders.vertex_path = "color.vert"; - pipelineInfo.shaders.fragment_path = "color.frag"; + pipelineInfo.shaders.vertex_src = file::Path("color.vert"); + pipelineInfo.shaders.fragment_src = file::Path("color.frag"); GFXVertexInput input; input.stride = sizeof(Vector3); @@ -110,8 +110,8 @@ void DebugPass::initialize() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Sobel"; - pipelineInfo.shaders.vertex_path = "color.vert"; - pipelineInfo.shaders.fragment_path = "color.frag"; + pipelineInfo.shaders.vertex_src = file::Path("color.vert"); + pipelineInfo.shaders.fragment_src = file::Path("color.frag"); GFXVertexInput input; input.stride = sizeof(Vector3); @@ -142,8 +142,8 @@ void DebugPass::initialize() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Billboard"; - pipelineInfo.shaders.vertex_path = "billboard.vert"; - pipelineInfo.shaders.fragment_path = "billboard.frag"; + pipelineInfo.shaders.vertex_src = file::Path("billboard.vert"); + pipelineInfo.shaders.fragment_src = file::Path("billboard.frag"); pipelineInfo.shader_input.bindings = { {1, GFXBindingType::PushConstant},