diff --git a/Application/Chunk.cpp b/Application/Chunk.cpp index 5fd33dc..ca348d7 100644 --- a/Application/Chunk.cpp +++ b/Application/Chunk.cpp @@ -2,6 +2,8 @@ #include #include +#include + #define POS_TO_INDEX(posx, posz) (posx * CHUNK_SIZE.x + posz) constexpr Scop::Vec2ui SPRITE_SIZE = { 16, 16 }; @@ -29,6 +31,11 @@ enum class Side : std::uint8_t Side }; +struct WaterData +{ + float time; +}; + Scop::Vec2f GetAtlasOffset(BlockType type, Side side) { Scop::Vec2ui pos = BLOCKS_TO_ATLAS[static_cast(type)][static_cast(side)]; @@ -80,7 +87,7 @@ void Chunk::GenerateMesh() std::vector& index_data = (is_water ? m_water_mesh_index_data : m_mesh_index_data); std::uint32_t& offset = (is_water ? water_offset : mesh_offset); - Scop::Vec4f base_color = is_water ? Scop::Vec4f{ 0.3f, 0.5f, 0.5f, 0.8f } : Scop::Vec4f{ 1.0f }; + Scop::Vec4f base_color = is_water ? Scop::Vec4f{ 0.3f, 0.1f, 0.05f, 0.98f } : Scop::Vec4f{ 1.0f }; std::uint32_t invalid_limit = is_water ? static_cast(BlockType::Air) : static_cast(BlockType::Water); if(GetBlock(Scop::Vec3i(x, y, z + 1)) <= invalid_limit) @@ -333,6 +340,19 @@ void Chunk::UploadMesh() actor.SetScale(Scop::Vec3f{ 2.0f }); actor.SetPosition(Scop::Vec3f(m_position.x, 0.0f, m_position.y)); actor.SetIsOpaque(false); + actor.SetCustomPipeline({ + .pipeline = m_world.GetWaterPipeline(), + .data{ sizeof(WaterData) } + }); + std::memset(actor.GetCustomPipeline()->data.GetData(), 0, actor.GetCustomPipeline()->data.GetSize()); + + auto object_update = [](Scop::NonOwningPtr scene, Scop::NonOwningPtr actor, Scop::Inputs& input, float delta) + { + WaterData* data = actor->GetCustomPipeline()->data.GetDataAs(); + data->time += delta; + }; + using actor_hook = std::function)>; + actor.AttachScript(std::make_shared(actor_hook{}, object_update, actor_hook{})); p_water_actor = &actor; } } diff --git a/Application/World.cpp b/Application/World.cpp index bd03569..babf747 100644 --- a/Application/World.cpp +++ b/Application/World.cpp @@ -6,8 +6,18 @@ #include #include -World::World(Scop::Scene& scene) : m_noisecollection(42), m_fps_counter(), m_scene(scene), m_previous_chunk_position(-1000, 10000) +World::World(Scop::Scene& scene) : m_noisecollection(42), p_water_pipeline(std::make_shared()), m_fps_counter(), m_scene(scene), m_previous_chunk_position(-1000, 10000) { + p_water_vertex_shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Shaders/Build/WaterVertex.spv", Scop::ShaderType::Vertex, Scop::DefaultForwardVertexShaderLayout); + p_water_fragment_shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Shaders/Build/WaterFragment.spv", Scop::ShaderType::Fragment, Scop::DefaultShaderLayout); + + Scop::GraphicPipelineDescriptor pipeline_descriptor; + pipeline_descriptor.vertex_shader = p_water_vertex_shader; + pipeline_descriptor.fragment_shader = p_water_fragment_shader; + pipeline_descriptor.clear_color_attachments = false; + pipeline_descriptor.name = "water_forward_pass_pipeline"; + p_water_pipeline->Init(pipeline_descriptor); + Scop::Vec2ui32 map_size; Scop::MaterialTextures material_params; material_params.albedo = std::make_shared(Scop::LoadBMPFile(GetResourcesPath() / "atlas.bmp", map_size), map_size.x, map_size.y); diff --git a/Application/World.h b/Application/World.h index be32d96..2761fa6 100644 --- a/Application/World.h +++ b/Application/World.h @@ -36,6 +36,8 @@ class World [[nodiscard]] inline Scop::Scene& GetScene() noexcept { return m_scene; } [[nodiscard]] inline std::shared_ptr GetBlockMaterial() const { return p_block_material; } + [[nodiscard]] inline std::shared_ptr GetWaterPipeline() const { return p_water_pipeline; } + [[nodiscard]] Scop::NonOwningPtr GetChunk(Scop::Vec2i position); [[nodiscard]] NoiseCollection& GetNoiseGenerator() noexcept { return m_noisecollection; } @@ -52,6 +54,9 @@ class World std::unordered_map m_chunks; ThreadSafeQueue> m_chunks_to_upload; std::shared_ptr p_block_material; + std::shared_ptr p_water_pipeline; + std::shared_ptr p_water_vertex_shader; + std::shared_ptr p_water_fragment_shader; Scop::Scene& m_scene; Scop::Vec2i m_previous_chunk_position; Scop::Vec2i m_current_chunk_position; diff --git a/Application/main.cpp b/Application/main.cpp index a4a5cf2..59d7c2d 100644 --- a/Application/main.cpp +++ b/Application/main.cpp @@ -9,8 +9,8 @@ int main(int ac, char** av) { Scop::ScopEngine engine(ac, av, "Vox", 0, 0, GetExecutablePath().parent_path().parent_path() / "ScopEngine/Assets"); Scop::Scene& splash_scene = SplashScreen(); - std::shared_ptr shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Fragment.spv", Scop::ShaderType::Fragment, Scop::DefaultShaderLayout); - std::shared_ptr post_process_shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/PostProcess.spv", Scop::ShaderType::Fragment, Scop::PostProcessShaderLayout); + std::shared_ptr shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Shaders/Build/Fragment.spv", Scop::ShaderType::Fragment, Scop::DefaultShaderLayout); + std::shared_ptr post_process_shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Shaders/Build/PostProcess.spv", Scop::ShaderType::Fragment, Scop::PostProcessShaderLayout); Scop::SceneDescriptor main_scene_desc; main_scene_desc.fragment_shader = shader; diff --git a/Makefile b/Makefile index b2f1216..e249974 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,16 @@ NAME = vox SRCS += $(wildcard $(addsuffix /*.cpp, ./Application)) +SHADER_SRCS = $(wildcard $(addsuffix /*.nzsl, ./Resources/Shaders)) + BIN_DIR = Bin OBJ_DIR = Objects RES_DIR = Resources +SHADER_DIR = Resources/Shaders/Build +SHADER_MODULE_DIR = ScopEngine/Assets/Shaders/Modules OBJS = $(addprefix $(OBJ_DIR)/, $(SRCS:.cpp=.o)) +SPVS = $(addprefix $(SHADER_DIR)/, $(SHADER_SRCS:.nzsl=.spv)) CXX = clang++ CXXFLAGS = -std=c++20 -I ScopEngine/Runtime/Includes -I Application -I ScopEngine/ThirdParty/KVF -I ScopEngine/ThirdParty -D KVF_IMPL_VK_NO_PROTOTYPES @@ -58,15 +63,25 @@ $(OBJ_DIR)/%.o: %.cpp all: $(NAME) -$(NAME): $(OBJ_DIR) $(BIN_DIR) engine $(OBJS) - @printf "$(COLOR)($(_BOLD)100%%$(_RESET)$(COLOR)) $(_RESET)Compiling $(_BOLD)Resources/Fragment.nzsl$(_RESET)\n" - @$(NZSLC) --compile=spv Resources/Fragment.nzsl -o Resources/ --optimize --module="ScopEngine/Assets/Shaders/Modules" - @printf "$(COLOR)($(_BOLD)100%%$(_RESET)$(COLOR)) $(_RESET)Compiling $(_BOLD)Resources/Screen.nzsl$(_RESET)\n" - @$(NZSLC) --compile=spv Resources/PostProcess.nzsl -o Resources/ --optimize --module="ScopEngine/Assets/Shaders/Modules" +$(NAME): $(OBJ_DIR) $(BIN_DIR) shaders engine $(OBJS) @printf "Linking $(_BOLD)$(NAME)$(_RESET)\n" @$(CXX) -o $(BIN_DIR)/$(NAME) $(OBJS) $(LDFLAGS) @printf "$(_BOLD)$(NAME)$(_RESET) compiled $(COLOR)$(_BOLD)successfully$(_RESET)\n" +SPVS_TOTAL = $(words $(SPVS)) +N_SPVS := $(shell find $(SHADERS_DIR) -type f -name '*.spv.h' 2>/dev/null | wc -l) +SPVS_TOTAL := $(shell echo $$(( $(SPVS_TOTAL) - $(N_SPVS) ))) +ifeq ($(SPVS_TOTAL), 0) # Same + SPVS_TOTAL := 1 +endif +CURR_SPV = 0 + +$(SHADER_DIR)/%.spv: %.nzsl + @$(eval CURR_SPV=$(shell echo $$(( $(CURR_SPV) + 1 )))) + @$(eval PERCENT=$(shell echo $$(( $(CURR_SPV) * 100 / $(SPVS_TOTAL) )))) + @printf "$(COLOR)($(_BOLD)%3s%%$(_RESET)$(COLOR)) $(_RESET)Compiling $(_BOLD)$<$(_RESET)\n" "$(PERCENT)" + @$(NZSLC) --compile=spv $< -o $(SHADER_DIR) --optimize --module=$(SHADER_MODULE_DIR) + engine: @make -j$(JOBS) -C ScopEngine DEBUG=$(DEBUG) --no-print-directory @@ -76,10 +91,18 @@ $(OBJ_DIR): $(BIN_DIR): @mkdir -p $(BIN_DIR) +$(SHADER_DIR): + @mkdir -p $(SHADER_DIR) + +shaders: $(SHADER_DIR) $(SPVS) + run: @$(BIN_DIR)/$(NAME) $(RES_DIR)/42.obj -re-shaders: +clean-shaders: + @$(RM) $(SHADER_DIR) + +re-shaders: clean-shaders shaders @make -C ScopEngine re-shaders clean: @@ -92,4 +115,4 @@ fclean: clean re: fclean all -.PHONY: all run clean fclean re re-shaders +.PHONY: all run clean fclean re clean-shaders re-shaders diff --git a/Resources/Fragment.nzsl b/Resources/Shaders/Fragment.nzsl similarity index 100% rename from Resources/Fragment.nzsl rename to Resources/Shaders/Fragment.nzsl diff --git a/Resources/PostProcess.nzsl b/Resources/Shaders/PostProcess.nzsl similarity index 100% rename from Resources/PostProcess.nzsl rename to Resources/Shaders/PostProcess.nzsl diff --git a/Resources/Shaders/WaterFragment.nzsl b/Resources/Shaders/WaterFragment.nzsl new file mode 100644 index 0000000..0b8470b --- /dev/null +++ b/Resources/Shaders/WaterFragment.nzsl @@ -0,0 +1,39 @@ +[nzsl_version("1.0")] +module; + +struct VertOut +{ + [location(0)] color: vec4[f32], + [location(1)] uv: vec2[f32], + [location(2)] time: f32, + [builtin(position)] pos: vec4[f32] +} + +struct FragmentData +{ + dissolve_texture_factor: f32, + dissolve_black_white_colors_factor: f32, + dissolve_normals_colors_factor: f32, +} + +struct FragOut +{ + [location(0)] color: vec4[f32] +} + +external +{ + [set(1), binding(0)] u_albedo: sampler2D[f32], + [set(1), binding(1)] u_fragment_data: uniform[FragmentData], +} + +[entry(frag)] +fn main(input: VertOut) -> FragOut +{ + if(input.color.a == 0.0) + discard; + let output: FragOut; + output.color = input.color * u_albedo.Sample(input.uv) * vec4[f32](sin(input.time), 1.0, cos(input.time), 1.0); + return output; +} + diff --git a/Resources/Shaders/WaterVertex.nzsl b/Resources/Shaders/WaterVertex.nzsl new file mode 100644 index 0000000..824f2d4 --- /dev/null +++ b/Resources/Shaders/WaterVertex.nzsl @@ -0,0 +1,49 @@ +[nzsl_version("1.0")] +module; + +import ViewerData from ScopEngine.ViewerData; + +struct VertIn +{ + [location(0)] pos: vec4[f32], + [location(1)] color: vec4[f32], + [location(2)] normal: vec4[f32], + [location(3)] uv: vec2[f32] +} + +struct VertOut +{ + [location(0)] color: vec4[f32], + [location(1)] uv: vec2[f32], + [location(2)] time: f32, + [builtin(position)] pos: vec4[f32] +} + +struct ModelData +{ + matrix: mat4[f32], + normal: mat4[f32], +} + +struct CustomData +{ + time: f32, +} + +external +{ + [set(0), binding(0)] viewer_data: uniform[ViewerData], + [set(0), binding(1)] data: uniform[CustomData], + model: push_constant[ModelData] +} + +[entry(vert)] +fn main(input: VertIn) -> VertOut +{ + let output: VertOut; + output.color = input.color; + output.uv = input.uv; + output.time = data.time; + output.pos = viewer_data.view_proj_matrix * model.matrix * input.pos; + return output; +} diff --git a/ScopEngine/Runtime/Includes/Graphics/Actor.h b/ScopEngine/Runtime/Includes/Graphics/Actor.h index edaeb5e..cc49982 100644 --- a/ScopEngine/Runtime/Includes/Graphics/Actor.h +++ b/ScopEngine/Runtime/Includes/Graphics/Actor.h @@ -1,12 +1,14 @@ #ifndef __SCOP_GRAPHICS_ACTOR__ #define __SCOP_GRAPHICS_ACTOR__ +#include + +#include #include #include -#include #include +#include #include -#include namespace Scop { @@ -17,7 +19,9 @@ namespace Scop public: struct CustomPipeline { - std::shared_ptr shader; + std::shared_ptr pipeline; + std::shared_ptr set; + std::shared_ptr data_uniform_buffer; CPUBuffer data; }; @@ -33,6 +37,7 @@ namespace Scop inline void SetOrientation(Quatf orientation) noexcept { m_orientation = orientation; } inline void SetVisibility(bool show) noexcept { m_is_visible = show; } inline void SetIsOpaque(bool opaque) noexcept { m_is_opaque = opaque; } + inline void SetCustomPipeline(const CustomPipeline& pipeline) { m_custom_pipeline = pipeline; } [[nodiscard]] inline const Vec3f& GetPosition() const noexcept { return m_position; } [[nodiscard]] inline const Vec3f& GetScale() const noexcept { return m_scale; } @@ -42,6 +47,7 @@ namespace Scop [[nodiscard]] inline std::uint64_t GetUUID() const noexcept { return m_uuid; } [[nodiscard]] inline bool IsVisible() const noexcept { return m_is_visible; } [[nodiscard]] inline bool IsOpaque() const noexcept { return m_is_opaque; } + [[nodiscard]] inline std::optional& GetCustomPipeline() { return m_custom_pipeline; } ~Actor(); @@ -55,6 +61,7 @@ namespace Scop Vec3f m_scale = Vec3f{ 1.0f, 1.0f, 1.0f }; std::shared_ptr p_script; std::uint64_t m_uuid; + std::optional m_custom_pipeline; bool m_is_visible = true; bool m_is_opaque = true; }; diff --git a/ScopEngine/Runtime/Includes/Renderer/Pipelines/Graphics.h b/ScopEngine/Runtime/Includes/Renderer/Pipelines/Graphics.h index 8b511ef..c3195d5 100644 --- a/ScopEngine/Runtime/Includes/Renderer/Pipelines/Graphics.h +++ b/ScopEngine/Runtime/Includes/Renderer/Pipelines/Graphics.h @@ -6,6 +6,7 @@ #include +#include #include #include #include @@ -21,11 +22,11 @@ namespace Scop NonOwningPtr depth = nullptr; NonOwningPtr renderer = nullptr; std::string name = {}; - VkCullModeFlagBits culling = VK_CULL_MODE_FRONT_BIT; - VkPolygonMode mode = VK_POLYGON_MODE_FILL; + CullMode culling = CullMode::Front; bool no_vertex_inputs = false; bool depth_test_equal = false; bool clear_color_attachments = true; + bool wireframe = false; }; class GraphicPipeline : public Pipeline @@ -33,7 +34,7 @@ namespace Scop public: GraphicPipeline() = default; - void Init(const GraphicPipelineDescriptor& descriptor); + void Init(GraphicPipelineDescriptor descriptor); bool BindPipeline(VkCommandBuffer command_buffer, std::size_t framebuffer_index, std::array clear) noexcept; void EndPipeline(VkCommandBuffer command_buffer) noexcept override; void Destroy() noexcept; @@ -41,6 +42,8 @@ namespace Scop [[nodiscard]] inline VkPipeline GetPipeline() const override { return m_pipeline; } [[nodiscard]] inline VkPipelineLayout GetPipelineLayout() const override { return m_pipeline_layout; } [[nodiscard]] inline VkPipelineBindPoint GetPipelineBindPoint() const override { return VK_PIPELINE_BIND_POINT_GRAPHICS; } + [[nodiscard]] inline bool IsPipelineBound() const noexcept { return s_bound_pipeline == this; } + [[nodiscard]] inline GraphicPipelineDescriptor& GetDescription() noexcept { return m_description; } inline ~GraphicPipeline() noexcept { Destroy(); } @@ -52,16 +55,14 @@ namespace Scop bool BindPipeline(VkCommandBuffer) noexcept override { return false; }; private: - std::vector> m_attachments; + static inline GraphicPipeline* s_bound_pipeline = nullptr; + + GraphicPipelineDescriptor m_description; std::vector m_framebuffers; std::vector m_clears; - std::shared_ptr p_vertex_shader; - std::shared_ptr p_fragment_shader; VkRenderPass m_renderpass = VK_NULL_HANDLE; VkPipeline m_pipeline = VK_NULL_HANDLE; VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE; - NonOwningPtr p_renderer; - NonOwningPtr p_depth; }; } diff --git a/ScopEngine/Runtime/Includes/Renderer/Pipelines/Shader.h b/ScopEngine/Runtime/Includes/Renderer/Pipelines/Shader.h index 1579bea..e386332 100644 --- a/ScopEngine/Runtime/Includes/Renderer/Pipelines/Shader.h +++ b/ScopEngine/Runtime/Includes/Renderer/Pipelines/Shader.h @@ -4,16 +4,20 @@ #include #include #include +#include #include +#include +#include + namespace Scop { struct ShaderSetLayout { - std::vector > binds; + std::unordered_map binds; - ShaderSetLayout(std::vector > b) : binds(std::move(b)) {} + ShaderSetLayout(std::unordered_map b) : binds(std::move(b)) {} inline bool operator==(const ShaderSetLayout& rhs) const { return binds == rhs.binds; } }; @@ -28,10 +32,10 @@ namespace Scop struct ShaderLayout { - std::vector > set_layouts; + std::unordered_map set_layouts; std::vector push_constants; - ShaderLayout(std::vector > s, std::vector pc) : set_layouts(std::move(s)), push_constants(std::move(pc)) {} + ShaderLayout(std::unordered_map s, std::vector pc) : set_layouts(std::move(s)), push_constants(std::move(pc)) {} }; enum class ShaderType @@ -57,6 +61,9 @@ namespace Scop [[nodiscard]] inline const ShaderPipelineLayoutPart& GetPipelineLayout() const noexcept { return m_pipeline_layout_part; } [[nodiscard]] inline VkShaderModule GetShaderModule() const noexcept { return m_module; } [[nodiscard]] inline VkShaderStageFlagBits GetShaderStage() const noexcept { return m_stage; } + [[nodiscard]] inline NonOwningPtr GetGraphicPipelineInUse() const noexcept { return p_pipeline_in_use; } + + inline void SetPipelineInUse(NonOwningPtr pipeline) noexcept { p_pipeline_in_use = pipeline; } void Destroy(); @@ -73,10 +80,22 @@ namespace Scop std::vector m_set_layouts; VkShaderStageFlagBits m_stage; VkShaderModule m_module = VK_NULL_HANDLE; + NonOwningPtr p_pipeline_in_use = nullptr; }; std::shared_ptr LoadShaderFromFile(const std::filesystem::path& filepath, ShaderType type, ShaderLayout layout); + static const ShaderLayout DefaultForwardVertexShaderLayout( + { + { 0, + ShaderSetLayout({ + { 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, + { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, + }) + } + }, { ShaderPushConstantLayout({ 0, sizeof(Mat4f) * 2 }) } + ); + static const Scop::ShaderLayout DefaultShaderLayout( { { 1, diff --git a/ScopEngine/Runtime/Sources/Graphics/Actor.cpp b/ScopEngine/Runtime/Sources/Graphics/Actor.cpp index cc1cf56..099f0d1 100644 --- a/ScopEngine/Runtime/Sources/Graphics/Actor.cpp +++ b/ScopEngine/Runtime/Sources/Graphics/Actor.cpp @@ -33,5 +33,7 @@ namespace Scop { if(p_script) p_script->OnQuit(this); + if(m_custom_pipeline.has_value() && m_custom_pipeline->data_uniform_buffer) + m_custom_pipeline->data_uniform_buffer->Destroy(); } } diff --git a/ScopEngine/Runtime/Sources/Graphics/Scene.cpp b/ScopEngine/Runtime/Sources/Graphics/Scene.cpp index babe688..bc85e37 100644 --- a/ScopEngine/Runtime/Sources/Graphics/Scene.cpp +++ b/ScopEngine/Runtime/Sources/Graphics/Scene.cpp @@ -165,7 +165,7 @@ namespace Scop if(m_descriptor.post_process_shader) { - m_post_process.set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(m_descriptor.post_process_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment); + m_post_process.set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(m_descriptor.post_process_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Fragment); m_post_process.data_buffer = std::make_shared(); m_post_process.data_buffer->Init(m_descriptor.post_process_data_size, m_name + "_post_process_data_buffer"); } @@ -178,13 +178,13 @@ namespace Scop m_forward.matrices_buffer = std::make_shared(); m_forward.matrices_buffer->Init(sizeof(ViewerData), m_name + "_matrice_buffer"); - m_forward.matrices_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(vertex_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Vertex); + m_forward.matrices_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(vertex_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Vertex); for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { m_forward.matrices_set->SetUniformBuffer(i, 0, m_forward.matrices_buffer->Get(i)); m_forward.matrices_set->Update(i); } - m_forward.albedo_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(m_descriptor.fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment); + m_forward.albedo_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(m_descriptor.fragment_shader->GetShaderLayout().set_layouts.at(1), ShaderType::Fragment); for(auto& child : m_scene_children) child.Init(renderer); diff --git a/ScopEngine/Runtime/Sources/Renderer/Descriptor.cpp b/ScopEngine/Runtime/Sources/Renderer/Descriptor.cpp index e0d4421..9555819 100644 --- a/ScopEngine/Runtime/Sources/Renderer/Descriptor.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/Descriptor.cpp @@ -84,13 +84,17 @@ namespace Scop } std::vector bindings(layout.binds.size()); - for(std::size_t i = 0; i < layout.binds.size(); i++) { - bindings[i].binding = layout.binds[i].first; - bindings[i].descriptorCount = 1; - bindings[i].descriptorType = layout.binds[i].second; - bindings[i].pImmutableSamplers = nullptr; - bindings[i].stageFlags = vulkan_shader_stage; + std::size_t i = 0; + for(auto& [bind, type] : layout.binds) + { + bindings[i].binding = bind; + bindings[i].descriptorCount = 1; + bindings[i].descriptorType = type; + bindings[i].pImmutableSamplers = nullptr; + bindings[i].stageFlags = vulkan_shader_stage; + i++; + } } VkDescriptorSetLayout vulkan_layout = kvfCreateDescriptorSetLayout(RenderCore::Get().GetDevice(), bindings.data(), bindings.size()); diff --git a/ScopEngine/Runtime/Sources/Renderer/Pipelines/Graphics.cpp b/ScopEngine/Runtime/Sources/Renderer/Pipelines/Graphics.cpp index 800b191..a394374 100644 --- a/ScopEngine/Runtime/Sources/Renderer/Pipelines/Graphics.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/Pipelines/Graphics.cpp @@ -2,47 +2,58 @@ #include #include #include +#include #include #include namespace Scop { - void GraphicPipeline::Init(const GraphicPipelineDescriptor& descriptor) + void GraphicPipeline::Init(GraphicPipelineDescriptor descriptor) { if(!descriptor.vertex_shader || !descriptor.fragment_shader) FatalError("Vulkan: invalid shaders"); - m_attachments = descriptor.color_attachments; - p_vertex_shader = descriptor.vertex_shader; - p_fragment_shader = descriptor.fragment_shader; - p_renderer = descriptor.renderer; - p_depth = descriptor.depth; + m_description = std::move(descriptor); + + m_description.vertex_shader->SetPipelineInUse(this); + m_description.fragment_shader->SetPipelineInUse(this); std::vector push_constants; std::vector set_layouts; - push_constants.insert(push_constants.end(), p_vertex_shader->GetPipelineLayout().push_constants.begin(), p_vertex_shader->GetPipelineLayout().push_constants.end()); - push_constants.insert(push_constants.end(), p_fragment_shader->GetPipelineLayout().push_constants.begin(), p_fragment_shader->GetPipelineLayout().push_constants.end()); - set_layouts.insert(set_layouts.end(), p_vertex_shader->GetPipelineLayout().set_layouts.begin(), p_vertex_shader->GetPipelineLayout().set_layouts.end()); - set_layouts.insert(set_layouts.end(), p_fragment_shader->GetPipelineLayout().set_layouts.begin(), p_fragment_shader->GetPipelineLayout().set_layouts.end()); + push_constants.insert(push_constants.end(), m_description.vertex_shader->GetPipelineLayout().push_constants.begin(), m_description.vertex_shader->GetPipelineLayout().push_constants.end()); + push_constants.insert(push_constants.end(), m_description.fragment_shader->GetPipelineLayout().push_constants.begin(), m_description.fragment_shader->GetPipelineLayout().push_constants.end()); + set_layouts.insert(set_layouts.end(), m_description.vertex_shader->GetPipelineLayout().set_layouts.begin(), m_description.vertex_shader->GetPipelineLayout().set_layouts.end()); + set_layouts.insert(set_layouts.end(), m_description.fragment_shader->GetPipelineLayout().set_layouts.begin(), m_description.fragment_shader->GetPipelineLayout().set_layouts.end()); m_pipeline_layout = kvfCreatePipelineLayout(RenderCore::Get().GetDevice(), set_layouts.data(), set_layouts.size(), push_constants.data(), push_constants.size()); - CreateFramebuffers(m_attachments, descriptor.clear_color_attachments); + CreateFramebuffers(m_description.color_attachments, m_description.clear_color_attachments); VkPhysicalDeviceFeatures features{}; RenderCore::Get().vkGetPhysicalDeviceFeatures(RenderCore::Get().GetPhysicalDevice(), &features); + VkCullModeFlags cullmode; + switch(m_description.culling) + { + case CullMode::None: cullmode = VK_CULL_MODE_NONE; break; + case CullMode::Back: cullmode = VK_CULL_MODE_BACK_BIT; break; + case CullMode::Front: cullmode = VK_CULL_MODE_FRONT_BIT; break; + case CullMode::FrontAndBack: cullmode = VK_CULL_MODE_FRONT_AND_BACK; break; + + default: break; + } + KvfGraphicsPipelineBuilder* builder = kvfCreateGPipelineBuilder(); - kvfGPipelineBuilderAddShaderStage(builder, p_vertex_shader->GetShaderStage(), p_vertex_shader->GetShaderModule(), "main"); - kvfGPipelineBuilderAddShaderStage(builder, p_fragment_shader->GetShaderStage(), p_fragment_shader->GetShaderModule(), "main"); + kvfGPipelineBuilderAddShaderStage(builder, m_description.vertex_shader->GetShaderStage(), m_description.vertex_shader->GetShaderModule(), "main"); + kvfGPipelineBuilderAddShaderStage(builder, m_description.fragment_shader->GetShaderStage(), m_description.fragment_shader->GetShaderModule(), "main"); kvfGPipelineBuilderSetInputTopology(builder, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); - kvfGPipelineBuilderSetCullMode(builder, descriptor.culling, VK_FRONT_FACE_CLOCKWISE); + kvfGPipelineBuilderSetCullMode(builder, cullmode, VK_FRONT_FACE_CLOCKWISE); kvfGPipelineBuilderEnableAlphaBlending(builder); - if(p_depth) - kvfGPipelineBuilderEnableDepthTest(builder, (descriptor.depth_test_equal ? VK_COMPARE_OP_EQUAL : VK_COMPARE_OP_LESS), true); + if(m_description.depth) + kvfGPipelineBuilderEnableDepthTest(builder, (m_description.depth_test_equal ? VK_COMPARE_OP_EQUAL : VK_COMPARE_OP_LESS), true); else kvfGPipelineBuilderDisableDepthTest(builder); - if(features.fillModeNonSolid) - kvfGPipelineBuilderSetPolygonMode(builder, descriptor.mode, 1.0f); + if(m_description.wireframe && features.fillModeNonSolid) + kvfGPipelineBuilderSetPolygonMode(builder, VK_POLYGON_MODE_LINE, 1.0f); else kvfGPipelineBuilderSetPolygonMode(builder, VK_POLYGON_MODE_FILL, 1.0f); if(features.sampleRateShading) @@ -50,7 +61,7 @@ namespace Scop else kvfGPipelineBuilderSetMultisampling(builder, VK_SAMPLE_COUNT_1_BIT); - if(!descriptor.no_vertex_inputs) + if(!m_description.no_vertex_inputs) { VkVertexInputBindingDescription binding_description = Vertex::GetBindingDescription(); auto attributes_description = Vertex::GetAttributeDescriptions(); @@ -65,7 +76,7 @@ namespace Scop name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; name_info.objectType = VK_OBJECT_TYPE_PIPELINE; name_info.objectHandle = reinterpret_cast(m_pipeline); - name_info.pObjectName = descriptor.name.data(); + name_info.pObjectName = m_description.name.data(); RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); name_info.objectType = VK_OBJECT_TYPE_RENDER_PASS; @@ -73,10 +84,10 @@ namespace Scop RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); name_info.objectType = VK_OBJECT_TYPE_SHADER_MODULE; - name_info.objectHandle = reinterpret_cast(p_vertex_shader->GetShaderModule()); + name_info.objectHandle = reinterpret_cast(m_description.vertex_shader->GetShaderModule()); RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); - name_info.objectHandle = reinterpret_cast(p_fragment_shader->GetShaderModule()); + name_info.objectHandle = reinterpret_cast(m_description.fragment_shader->GetShaderModule()); RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); name_info.objectType = VK_OBJECT_TYPE_FRAMEBUFFER; @@ -85,7 +96,7 @@ namespace Scop name_info.objectHandle = reinterpret_cast(fb); RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); } - Message("Vulkan: % graphics pipeline created", descriptor.name); + Message("Vulkan: % graphics pipeline created", m_description.name); #else Message("Vulkan: graphics pipeline created"); #endif @@ -93,6 +104,13 @@ namespace Scop bool GraphicPipeline::BindPipeline(VkCommandBuffer command_buffer, std::size_t framebuffer_index, std::array clear) noexcept { + if(s_bound_pipeline != nullptr) + { + Error("Vulkan: cannot bind a graphics pipeline because another one have not been unbound"); + return false; + } + + s_bound_pipeline = this; TransitionAttachments(command_buffer); VkFramebuffer fb = m_framebuffers[framebuffer_index]; @@ -120,7 +138,7 @@ namespace Scop m_clears[i].color.float32[3] = clear[3]; } - if(p_depth) + if(m_description.depth) m_clears.back().depthStencil = VkClearDepthStencilValue{ 1.0f, 0 }; kvfBeginRenderPass(m_renderpass, command_buffer, fb, fb_extent, m_clears.data(), m_clears.size()); @@ -130,7 +148,10 @@ namespace Scop void GraphicPipeline::EndPipeline(VkCommandBuffer command_buffer) noexcept { + if(s_bound_pipeline != this) + return; RenderCore::Get().vkCmdEndRenderPass(command_buffer); + s_bound_pipeline = nullptr; } void GraphicPipeline::Destroy() noexcept @@ -151,16 +172,14 @@ namespace Scop Message("Vulkan: renderpass destroyed"); kvfDestroyPipeline(RenderCore::Get().GetDevice(), m_pipeline); - p_vertex_shader.reset(); - p_fragment_shader.reset(); - m_attachments.clear(); + m_description.vertex_shader.reset(); + m_description.fragment_shader.reset(); + m_description.color_attachments.clear(); m_framebuffers.clear(); m_clears.clear(); m_renderpass = VK_NULL_HANDLE; m_pipeline = VK_NULL_HANDLE; m_pipeline_layout = VK_NULL_HANDLE; - p_renderer = nullptr; - p_depth = nullptr; Message("Vulkan: graphics pipeline destroyed"); } @@ -170,10 +189,10 @@ namespace Scop std::vector attachments; std::vector attachment_views; - if(p_renderer) + if(m_description.renderer) { - attachments.push_back(kvfBuildSwapchainAttachmentDescription(p_renderer->GetSwapchain().Get(), clear_attachments)); - attachment_views.push_back(p_renderer->GetSwapchain().GetSwapchainImages()[0].GetImageView()); + attachments.push_back(kvfBuildSwapchainAttachmentDescription(m_description.renderer->GetSwapchain().Get(), clear_attachments)); + attachment_views.push_back(m_description.renderer->GetSwapchain().GetSwapchainImages()[0].GetImageView()); } for(NonOwningPtr image : render_targets) @@ -182,10 +201,10 @@ namespace Scop attachment_views.push_back(image->GetImageView()); } - if(p_depth) + if(m_description.depth) { - attachments.push_back(kvfBuildAttachmentDescription(KVF_IMAGE_DEPTH, p_depth->GetFormat(), p_depth->GetLayout(), p_depth->GetLayout(), clear_attachments, VK_SAMPLE_COUNT_1_BIT)); - attachment_views.push_back(p_depth->GetImageView()); + attachments.push_back(kvfBuildAttachmentDescription(KVF_IMAGE_DEPTH, m_description.depth->GetFormat(), m_description.depth->GetLayout(), m_description.depth->GetLayout(), clear_attachments, VK_SAMPLE_COUNT_1_BIT)); + attachment_views.push_back(m_description.depth->GetImageView()); } m_renderpass = kvfCreateRenderPass(RenderCore::Get().GetDevice(), attachments.data(), attachments.size(), GetPipelineBindPoint()); @@ -193,9 +212,9 @@ namespace Scop m_clears.resize(attachments.size()); Message("Vulkan: renderpass created"); - if(p_renderer) + if(m_description.renderer) { - for(const Image& image : p_renderer->GetSwapchain().GetSwapchainImages()) + for(const Image& image : m_description.renderer->GetSwapchain().GetSwapchainImages()) { attachment_views[0] = image.GetImageView(); m_framebuffers.push_back(kvfCreateFramebuffer(RenderCore::Get().GetDevice(), m_renderpass, attachment_views.data(), attachment_views.size(), { .width = image.GetWidth(), .height = image.GetHeight() })); @@ -211,10 +230,10 @@ namespace Scop void GraphicPipeline::TransitionAttachments(VkCommandBuffer cmd) { - if(p_depth) - p_depth->TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, cmd); + if(m_description.depth) + m_description.depth->TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, cmd); - for(NonOwningPtr image : m_attachments) + for(NonOwningPtr image : m_description.color_attachments) image->TransitionLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, cmd); } } diff --git a/ScopEngine/Runtime/Sources/Renderer/Pipelines/Shader.cpp b/ScopEngine/Runtime/Sources/Renderer/Pipelines/Shader.cpp index f29c186..ff6154b 100644 --- a/ScopEngine/Runtime/Sources/Renderer/Pipelines/Shader.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/Pipelines/Shader.cpp @@ -31,16 +31,18 @@ namespace Scop void Shader::GeneratePipelineLayout(ShaderLayout layout) { - for(auto& [n, set] : layout.set_layouts) + for(auto& [_, set] : layout.set_layouts) { std::vector bindings(set.binds.size()); - for(std::size_t i = 0; i < set.binds.size(); i++) + std::size_t i = 0; + for(auto& [bind, type] : set.binds) { - bindings[i].binding = set.binds[i].first; + bindings[i].binding = bind; bindings[i].descriptorCount = 1; - bindings[i].descriptorType = set.binds[i].second; + bindings[i].descriptorType = type; bindings[i].pImmutableSamplers = nullptr; bindings[i].stageFlags = m_stage; + i++; } m_set_layouts.emplace_back(kvfCreateDescriptorSetLayout(RenderCore::Get().GetDevice(), bindings.data(), bindings.size())); Message("Vulkan: descriptor set layout created"); diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/2DPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/2DPass.cpp index 1e5c594..bcf7018 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/2DPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/2DPass.cpp @@ -49,8 +49,8 @@ namespace Scop }; EventBus::RegisterListener({ functor, "__ScopRender2DPass" }); - p_viewer_data_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_vertex_shader->GetShaderLayout().set_layouts[0].second,ShaderType::Vertex); - p_texture_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment); + p_viewer_data_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_vertex_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Vertex); + p_texture_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts.at(1), ShaderType::Fragment); p_viewer_data_buffer = std::make_shared(); p_viewer_data_buffer->Init(sizeof(ViewerData2D)); @@ -69,10 +69,10 @@ namespace Scop pipeline_descriptor.vertex_shader = p_vertex_shader; pipeline_descriptor.fragment_shader = p_fragment_shader; pipeline_descriptor.color_attachments = { &render_target }; - pipeline_descriptor.culling = VK_CULL_MODE_NONE; + pipeline_descriptor.culling = CullMode::None; pipeline_descriptor.clear_color_attachments = false; pipeline_descriptor.name = "2D_pass_pipeline"; - m_pipeline.Init(pipeline_descriptor); + m_pipeline.Init(std::move(pipeline_descriptor)); } std::uint32_t frame_index = renderer.GetCurrentFrameIndex(); diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/FinalPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/FinalPass.cpp index a11d942..01d84bb 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/FinalPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/FinalPass.cpp @@ -31,7 +31,7 @@ namespace Scop }; EventBus::RegisterListener({ functor, "__ScopFinalPass" }); - p_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment); + p_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Fragment); } void FinalPass::Pass(Scene& scene, Renderer& renderer, Texture& render_target) @@ -42,10 +42,10 @@ namespace Scop pipeline_descriptor.vertex_shader = p_vertex_shader; pipeline_descriptor.fragment_shader = p_fragment_shader; pipeline_descriptor.renderer = &renderer; - pipeline_descriptor.culling = VK_CULL_MODE_NONE; + pipeline_descriptor.culling = CullMode::None; pipeline_descriptor.no_vertex_inputs = true; pipeline_descriptor.name = "final_pass_pipeline"; - m_pipeline.Init(pipeline_descriptor); + m_pipeline.Init(std::move(pipeline_descriptor)); } VkCommandBuffer cmd = renderer.GetActiveCommandBuffer(); diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp index b36d378..764a915 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp @@ -17,33 +17,48 @@ namespace Scop void ForwardPass::Pass(Scene& scene, Renderer& renderer, class Texture& render_target) { - Scene::ForwardData& data = scene.GetForwardData(); - GraphicPipeline& pipeline = scene.GetPipeline(); - - if(pipeline.GetPipeline() == VK_NULL_HANDLE) + NonOwningPtr pipeline = &scene.GetPipeline(); + if(scene.GetPipeline().GetPipeline() == VK_NULL_HANDLE) { GraphicPipelineDescriptor pipeline_descriptor; pipeline_descriptor.vertex_shader = RenderCore::Get().GetDefaultVertexShader(); pipeline_descriptor.fragment_shader = scene.GetFragmentShader(); pipeline_descriptor.color_attachments = { &render_target }; pipeline_descriptor.depth = &scene.GetDepth(); - if(scene.GetForwardData().wireframe) - pipeline_descriptor.mode = VK_POLYGON_MODE_LINE; pipeline_descriptor.clear_color_attachments = false; pipeline_descriptor.name = "forward_pass_pipeline"; - switch(scene.GetDescription().culling) - { - case CullMode::None: pipeline_descriptor.culling = VK_CULL_MODE_NONE; break; - case CullMode::Back: pipeline_descriptor.culling = VK_CULL_MODE_BACK_BIT; break; - case CullMode::Front: pipeline_descriptor.culling = VK_CULL_MODE_FRONT_BIT; break; - case CullMode::FrontAndBack: pipeline_descriptor.culling = VK_CULL_MODE_FRONT_AND_BACK; break; - - default: break; - } - pipeline.Init(pipeline_descriptor); + scene.GetPipeline().Init(std::move(pipeline_descriptor)); } - auto setup_model = [](const Actor& actor) -> ModelData { + auto render_actor = [&render_target, &renderer, &scene, &pipeline](Actor& actor) + { + Scene::ForwardData& data = scene.GetForwardData(); + VkCommandBuffer cmd = renderer.GetActiveCommandBuffer(); + std::shared_ptr custom_pipeline = (actor.GetCustomPipeline().has_value() ? actor.GetCustomPipeline()->pipeline : nullptr); + + if(custom_pipeline && !custom_pipeline->IsPipelineBound()) + { + pipeline->EndPipeline(cmd); + pipeline = actor.GetCustomPipeline()->pipeline.get(); + if(pipeline->GetDescription().depth != NonOwningPtr{ &scene.GetDepth() }) + { + GraphicPipelineDescriptor descriptor = pipeline->GetDescription(); + pipeline->Destroy(); + descriptor.color_attachments = { &render_target }; + descriptor.depth = &scene.GetDepth(); + descriptor.renderer = nullptr; + descriptor.clear_color_attachments = false; + pipeline->Init(std::move(descriptor)); + } + pipeline->BindPipeline(cmd, 0, {}); + } + else if(!custom_pipeline && !scene.GetPipeline().IsPipelineBound()) + { + pipeline->EndPipeline(cmd); + pipeline = &scene.GetPipeline(); + pipeline->BindPipeline(cmd, 0, {}); + } + ModelData model_data; model_data.model_mat = Mat4f::Identity(); model_data.model_mat.SetTranslation(actor.GetPosition() - actor.GetModel().GetCenter()); @@ -51,36 +66,54 @@ namespace Scop model_data.model_mat = Mat4f::Translate(-actor.GetModel().GetCenter()) * Mat4f::Rotate(actor.GetOrientation()) * model_data.model_mat; model_data.normal_mat = model_data.model_mat; model_data.normal_mat.Inverse().Transpose(); - return model_data; + + RenderCore::Get().vkCmdPushConstants(cmd, pipeline->GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data); + + if(custom_pipeline) + { + if(!actor.GetCustomPipeline()->data_uniform_buffer) + { + actor.GetCustomPipeline()->data_uniform_buffer = std::make_shared(); + actor.GetCustomPipeline()->data_uniform_buffer->Init(actor.GetCustomPipeline()->data.GetSize(), "custom_data_buffer"); + } + else + actor.GetCustomPipeline()->data_uniform_buffer->SetData(actor.GetCustomPipeline()->data, renderer.GetCurrentFrameIndex()); + if(!actor.GetCustomPipeline()->set) + { + actor.GetCustomPipeline()->set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(custom_pipeline->GetDescription().vertex_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Vertex); + for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + { + actor.GetCustomPipeline()->set->SetUniformBuffer(i, 0, data.matrices_buffer->Get(i)); + actor.GetCustomPipeline()->set->SetUniformBuffer(i, 1, actor.GetCustomPipeline()->data_uniform_buffer->Get(i)); + actor.GetCustomPipeline()->set->Update(i); + } + } + actor.GetModel().Draw(cmd, actor.GetCustomPipeline()->set, *pipeline, data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex()); + } + else + actor.GetModel().Draw(cmd, data.matrices_set, *pipeline, data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex()); }; std::multimap sorted_actors; - VkCommandBuffer cmd = renderer.GetActiveCommandBuffer(); - pipeline.BindPipeline(cmd, 0, {}); for(auto& [_, actor] : scene.GetActors()) { if(!actor.IsVisible()) continue; - if(actor.IsOpaque()) - { - auto model_data = setup_model(actor); - RenderCore::Get().vkCmdPushConstants(cmd, pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data); - actor.GetModel().Draw(cmd, data.matrices_set, pipeline, data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex()); - } - else + if(!actor.IsOpaque()) { float distance = Vec3f::Distance(actor.GetPosition(), scene.GetCamera()->GetPosition()); sorted_actors.emplace(distance, const_cast(actor)); } + else + render_actor(const_cast(actor)); } for(auto it = sorted_actors.rbegin(); it != sorted_actors.rend(); ++it) { if(!it->second.IsVisible()) continue; - auto model_data = setup_model(it->second); - RenderCore::Get().vkCmdPushConstants(cmd, pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data); - it->second.GetModel().Draw(cmd, data.matrices_set, pipeline, data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex()); + render_actor(it->second); } - pipeline.EndPipeline(cmd); + if(pipeline) + pipeline->EndPipeline(renderer.GetActiveCommandBuffer()); } } diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/PostProcessPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/PostProcessPass.cpp index 23e3db5..478ab3c 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/PostProcessPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/PostProcessPass.cpp @@ -41,11 +41,11 @@ namespace Scop pipeline_descriptor.vertex_shader = p_vertex_shader; pipeline_descriptor.fragment_shader = scene.GetDescription().post_process_shader; pipeline_descriptor.color_attachments = { &m_render_texture }; - pipeline_descriptor.culling = VK_CULL_MODE_NONE; + pipeline_descriptor.culling = CullMode::None; pipeline_descriptor.clear_color_attachments = false; pipeline_descriptor.no_vertex_inputs = true; pipeline_descriptor.name = "post_process_pass_pipeline"; - m_pipeline.Init(pipeline_descriptor); + m_pipeline.Init(std::move(pipeline_descriptor)); } VkCommandBuffer cmd = renderer.GetActiveCommandBuffer(); diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/SkyboxPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/SkyboxPass.cpp index c80d2a9..fb89688 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/SkyboxPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/SkyboxPass.cpp @@ -40,7 +40,7 @@ namespace Scop EventBus::RegisterListener({ functor, "__ScopSkyboxPass" }); m_cube = CreateCube(); - p_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment); + p_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts.at(1), ShaderType::Fragment); } void SkyboxPass::Pass(Scene& scene, Renderer& renderer, class Texture& render_target) @@ -55,11 +55,11 @@ namespace Scop pipeline_descriptor.fragment_shader = p_fragment_shader; pipeline_descriptor.color_attachments = { &render_target }; pipeline_descriptor.depth = &scene.GetDepth(); - pipeline_descriptor.culling = VK_CULL_MODE_NONE; + pipeline_descriptor.culling = CullMode::None; pipeline_descriptor.depth_test_equal = true; pipeline_descriptor.clear_color_attachments = false; pipeline_descriptor.name = "skybox_pass_pipeline"; - m_pipeline.Init(pipeline_descriptor); + m_pipeline.Init(std::move(pipeline_descriptor)); } VkCommandBuffer cmd = renderer.GetActiveCommandBuffer();