From eb6fc926be7f29d6d92f238146180d510d69c79e Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Thu, 11 Aug 2022 15:46:36 -0300 Subject: feat Create directional light --- src/vk/graphics_pipeline.cpp | 170 +++++++++++++++++++++++++++++-------------- src/vk/graphics_pipeline.hpp | 5 +- src/vk/uniform_buffer.hpp | 7 ++ 3 files changed, 126 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/vk/graphics_pipeline.cpp b/src/vk/graphics_pipeline.cpp index 1ba8a12..bd0406c 100644 --- a/src/vk/graphics_pipeline.cpp +++ b/src/vk/graphics_pipeline.cpp @@ -73,39 +73,45 @@ unload_descriptor_set_layout_model_instance(void *obj) } void -load_descriptor_set_layout_view_projection(void *obj) +load_descriptor_set_layout_world_view(void *obj) { auto self = static_cast(obj); - VkDescriptorSetLayoutBinding layout_binding{}; - layout_binding.binding = 0; - layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - layout_binding.descriptorCount = 1; - layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - layout_binding.pImmutableSamplers = nullptr; + std::array set_layouts{}; + set_layouts[0].binding = 0; + set_layouts[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + set_layouts[0].descriptorCount = 1; + set_layouts[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + set_layouts[0].pImmutableSamplers = nullptr; + + set_layouts[1].binding = 1; + set_layouts[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + set_layouts[1].descriptorCount = 1; + set_layouts[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + set_layouts[1].pImmutableSamplers = nullptr; VkDescriptorSetLayoutCreateInfo layout_info{}; layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; layout_info.pNext = nullptr; layout_info.flags = 0; - layout_info.bindingCount = 1; - layout_info.pBindings = &layout_binding; + layout_info.bindingCount = set_layouts.size(); + layout_info.pBindings = set_layouts.data(); if(vkCreateDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, - &self->descriptor_set_layout_view_projection) != VK_SUCCESS) + cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, + &self->descriptor_set_layout_world_view) != VK_SUCCESS) throw CommandError{ - "Failed to create Vulkan descriptor set layout for view projection."}; + "Failed to create Vulkan descriptor set layout for world view."}; } void -unload_descriptor_set_layout_view_projection(void *obj) +unload_descriptor_set_layout_world_view(void *obj) { auto self = static_cast(obj); vkDestroyDescriptorSetLayout( cg_core.vk_device_with_swapchain->device, - self->descriptor_set_layout_view_projection, nullptr); + self->descriptor_set_layout_world_view, nullptr); } void @@ -114,8 +120,8 @@ load_pipeline_layout(void *obj) auto self = static_cast(obj); std::array set_layouts{ - self->descriptor_set_layout_model_instance, - self->descriptor_set_layout_view_projection}; + self->descriptor_set_layout_world_view, + self->descriptor_set_layout_model_instance}; VkPipelineLayoutCreateInfo pipeline_layout_info{}; pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; @@ -127,8 +133,7 @@ load_pipeline_layout(void *obj) if(vkCreatePipelineLayout( cg_core.vk_device_with_swapchain->device, &pipeline_layout_info, nullptr, &self->pipeline_layout) != VK_SUCCESS) - throw CommandError{ - "Failed to create Vulkan descriptor set layout for view projection."}; + throw CommandError{"Failed to create Vulkan pipeline layout."}; } void @@ -141,7 +146,7 @@ unload_pipeline_layout(void *obj) } void -load_uniform_buffer(void *obj) +load_view_projection_uniform_buffer(void *obj) { auto self = static_cast(obj); @@ -159,13 +164,39 @@ load_uniform_buffer(void *obj) } void -unload_uniform_buffer(void *obj) +unload_view_projection_uniform_buffer(void *obj) { auto self = static_cast(obj); self->ub_view_projection.clear(); } +void +load_directional_light_uniform_buffer(void *obj) +{ + auto self = static_cast(obj); + + try + { + self->ub_view_projection.reserve(cg_core.vk_swapchain->images_count); + for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) + self->ub_directional_light.emplace_back( + cg_core.vk_device_with_swapchain, sizeof(VK::UBODirectionalLight)); + } + catch(const std::exception& e) + { + throw CommandError{e.what()}; + } +} + +void +unload_directional_light_uniform_buffer(void *obj) +{ + auto self = static_cast(obj); + + self->ub_directional_light.clear(); +} + void load_descriptor_pool(void *obj) { @@ -173,13 +204,15 @@ load_descriptor_pool(void *obj) VkDescriptorPoolSize descriptor_pool_size{}; descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_pool_size.descriptorCount = self->ub_view_projection.size(); + descriptor_pool_size.descriptorCount = + self->ub_view_projection.size() + self->ub_directional_light.size(); VkDescriptorPoolCreateInfo pool_info{}; pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info.pNext = nullptr; pool_info.flags = 0; - pool_info.maxSets = self->ub_view_projection.size(); + pool_info.maxSets = + self->ub_view_projection.size() + self->ub_directional_light.size(); pool_info.poolSizeCount = 1; pool_info.pPoolSizes = &descriptor_pool_size; @@ -199,13 +232,13 @@ unload_descriptor_pool(void *obj) } void -load_descriptor_sets(void *obj) +load_world_view_descriptor_sets(void *obj) { auto self = static_cast(obj); std::vector layouts( cg_core.vk_swapchain->images_count, - self->descriptor_set_layout_view_projection); + self->descriptor_set_layout_world_view); VkDescriptorSetAllocateInfo alloc_info{}; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; @@ -213,40 +246,55 @@ load_descriptor_sets(void *obj) alloc_info.descriptorSetCount = self->ub_view_projection.size(); alloc_info.pSetLayouts = layouts.data(); - self->view_projection_descriptor_sets.resize( + self->world_view_descriptor_sets.resize( cg_core.vk_swapchain->images_count); if(vkAllocateDescriptorSets( cg_core.vk_device_with_swapchain->device, &alloc_info, - self->view_projection_descriptor_sets.data()) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan descriptor set."}; + self->world_view_descriptor_sets.data()) != VK_SUCCESS) + throw CommandError{"Failed to create Vulkan world view descriptor set."}; } void -load_descriptor_sets_to_buffers(void *obj) +load_resources_to_descriptor_sets(void *obj) { auto self = static_cast(obj); for(auto i{0}; i < self->ub_view_projection.size(); i++) { - VkDescriptorBufferInfo buffer_info{}; - buffer_info.buffer = self->ub_view_projection[i].buffer; - buffer_info.offset = 0; - buffer_info.range = sizeof(VK::UBOViewProjection); - - VkWriteDescriptorSet write_descriptor{}; - write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor.dstSet = self->view_projection_descriptor_sets[i]; - write_descriptor.dstBinding = 0; - write_descriptor.dstArrayElement = 0; - write_descriptor.descriptorCount = 1; - write_descriptor.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptor.pBufferInfo = &buffer_info; - write_descriptor.pImageInfo = nullptr; - write_descriptor.pTexelBufferView = nullptr; + VkDescriptorBufferInfo view_projection_info{}; + view_projection_info.buffer = self->ub_view_projection[i].buffer; + view_projection_info.offset = 0; + view_projection_info.range = sizeof(VK::UBOViewProjection); + + VkDescriptorBufferInfo directional_light_info{}; + directional_light_info.buffer = self->ub_directional_light[i].buffer; + directional_light_info.offset = 0; + directional_light_info.range = sizeof(VK::UBODirectionalLight); + + std::array write_descriptors{}; + write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptors[0].dstSet = self->world_view_descriptor_sets[i]; + write_descriptors[0].dstBinding = 0; + write_descriptors[0].dstArrayElement = 0; + write_descriptors[0].descriptorCount = 1; + write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + write_descriptors[0].pBufferInfo = &view_projection_info; + write_descriptors[0].pImageInfo = nullptr; + write_descriptors[0].pTexelBufferView = nullptr; + + write_descriptors[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptors[1].dstSet = self->world_view_descriptor_sets[i]; + write_descriptors[1].dstBinding = 1; + write_descriptors[1].dstArrayElement = 0; + write_descriptors[1].descriptorCount = 1; + write_descriptors[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + write_descriptors[1].pBufferInfo = &directional_light_info; + write_descriptors[1].pImageInfo = nullptr; + write_descriptors[1].pTexelBufferView = nullptr; vkUpdateDescriptorSets( - cg_core.vk_device_with_swapchain->device, 1, &write_descriptor, 0, - nullptr); + cg_core.vk_device_with_swapchain->device, write_descriptors.size(), + write_descriptors.data(), 0, nullptr); } } @@ -773,14 +821,17 @@ load_draw_command_buffer(void *obj) const CommandChain loader{ {&load_descriptor_set_layout_model_instance, &unload_descriptor_set_layout_model_instance}, - {&load_descriptor_set_layout_view_projection, - &unload_descriptor_set_layout_view_projection}, + {&load_descriptor_set_layout_world_view, + &unload_descriptor_set_layout_world_view}, {&load_pipeline_layout, &unload_pipeline_layout}, - {&load_uniform_buffer, &unload_uniform_buffer}, + {&load_view_projection_uniform_buffer, + &unload_view_projection_uniform_buffer}, + {&load_directional_light_uniform_buffer, + &unload_directional_light_uniform_buffer}, {&load_descriptor_pool, &unload_descriptor_pool}, // By destroying the pool the sets are also destroyed. - {&load_descriptor_sets, nullptr}, - {&load_descriptor_sets_to_buffers, nullptr}, + {&load_world_view_descriptor_sets, nullptr}, + {&load_resources_to_descriptor_sets, nullptr}, {&load_depth_image, &unload_depth_image}, {&load_depth_image_view, &unload_depth_image_view}, {&load_render_pass, &unload_render_pass}, @@ -879,8 +930,8 @@ GraphicsPipeline::draw() // Commands { std::array vk_descriptor_sets{ - model->descriptor_sets[image_index], - this->view_projection_descriptor_sets[image_index]}; + this->world_view_descriptor_sets[image_index], + model->descriptor_sets[image_index]}; VkBuffer vertex_buffers[]{model->vertex_buffer->buffer}; VkDeviceSize offsets[]{0}; @@ -918,7 +969,7 @@ GraphicsPipeline::draw() instance_matrix = glm::translate( instance_matrix, instances[i].position); - ubo_model_instance.model[i] = instance_matrix; + ubo_model_instance.model[i] = instance_matrix; } model->ub_model_instance[image_index].copy_data(&ubo_model_instance); @@ -929,7 +980,7 @@ GraphicsPipeline::draw() throw std::runtime_error{"Failed to end draw command buffer."}; } - // Update uniform buffers + // Update view projection uniform buffers { VK::UBOViewProjection ubo_view_projection{}; @@ -955,9 +1006,20 @@ GraphicsPipeline::draw() 0.1f, 100.0f); ubo_view_projection.proj[1][1] *= -1; + ubo_view_projection.ambient_color = glm::vec4{0.25, 0.25, 0.25, 1.0}; + this->ub_view_projection[image_index].copy_data(&ubo_view_projection); } + // Update directional light uniform buffers + { + UBODirectionalLight ubo_directional_light{}; + ubo_directional_light.direction = glm::vec3{-0.57735, -0.57735, -0.57735}; + ubo_directional_light.color = glm::vec4{0.8, 0.8, 0.8, 1.0}; + + this->ub_directional_light[image_index].copy_data(&ubo_directional_light); + } + // Submit drawing command. { auto queue{this->queue_family->get_queue()}; diff --git a/src/vk/graphics_pipeline.hpp b/src/vk/graphics_pipeline.hpp index c7cc0a0..dffd6fb 100644 --- a/src/vk/graphics_pipeline.hpp +++ b/src/vk/graphics_pipeline.hpp @@ -34,7 +34,7 @@ namespace VK struct GraphicsPipeline { VkDescriptorSetLayout descriptor_set_layout_model_instance; - VkDescriptorSetLayout descriptor_set_layout_view_projection; + VkDescriptorSetLayout descriptor_set_layout_world_view; VkPipelineLayout pipeline_layout; // Depth image. @@ -44,9 +44,10 @@ struct GraphicsPipeline // FIXME: if this vector get resized, it will cause a segmentation fault! std::vector ub_view_projection; + std::vector ub_directional_light; VkDescriptorPool descriptor_pool; - std::vector view_projection_descriptor_sets; + std::vector world_view_descriptor_sets; VkRenderPass render_pass; std::vector swapchain_framebuffers; diff --git a/src/vk/uniform_buffer.hpp b/src/vk/uniform_buffer.hpp index c044699..14deead 100644 --- a/src/vk/uniform_buffer.hpp +++ b/src/vk/uniform_buffer.hpp @@ -35,6 +35,13 @@ struct UBOViewProjection { glm::mat4 view; glm::mat4 proj; + glm::vec4 ambient_color; +}; + +struct UBODirectionalLight +{ + glm::vec3 direction; + glm::vec4 color; }; // FIXME: this class need to delete or create custom copy constructors! -- cgit v1.2.3