point_light_system.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "point_light_system.h"
  2. #include "vk_initializers.h"
  3. #include "imgui.h"
  4. using namespace coral_3d;
  5. struct PointLightPushConstant
  6. {
  7. glm::vec4 position{}; // w is radius
  8. glm::vec4 color{}; // w is intensity
  9. };
  10. point_light_system::point_light_system(coral_device& device, VkRenderPass render_pass, std::vector<VkDescriptorSetLayout>& desc_set_layouts)
  11. : device_{device}
  12. {
  13. create_pipeline_layout(device_, desc_set_layouts);
  14. create_pipeline(render_pass);
  15. }
  16. point_light_system::~point_light_system()
  17. {
  18. vkDestroyPipelineLayout(device_.device(), pipeline_layout_, nullptr);
  19. }
  20. void point_light_system::update(FrameInfo &frame_info, GlobalUBO &ubo)
  21. {
  22. int light_index{0};
  23. for(auto& kv: frame_info.gameobjects)
  24. {
  25. auto& obj = kv.second;
  26. if(obj->point_light_ == nullptr) continue;
  27. // Copy light to UBO
  28. ubo.point_lights[light_index].position = glm::vec4(obj->transform_.translation, obj->transform_.scale.x);
  29. ubo.point_lights[light_index].color = obj->point_light_->color;
  30. light_index++;
  31. }
  32. ubo.num_lights = light_index;
  33. }
  34. void point_light_system::render(FrameInfo& frame_info)
  35. {
  36. pipeline_->bind(frame_info.command_buffer);
  37. vkCmdBindDescriptorSets(
  38. frame_info.command_buffer,
  39. VK_PIPELINE_BIND_POINT_GRAPHICS,
  40. pipeline_layout_,
  41. 0, 1,
  42. &frame_info.global_descriptor_set,
  43. 0, nullptr
  44. );
  45. for(auto& kv: frame_info.gameobjects)
  46. {
  47. auto &obj = kv.second;
  48. if (obj->point_light_ == nullptr) continue;
  49. PointLightPushConstant push_constant{};
  50. push_constant.position = glm::vec4(obj->transform_.translation, obj->transform_.scale.x);
  51. push_constant.color = obj->point_light_->color;
  52. vkCmdPushConstants(
  53. frame_info.command_buffer,
  54. pipeline_layout_,
  55. VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
  56. 0, sizeof (PointLightPushConstant),
  57. &push_constant
  58. );
  59. vkCmdDraw(frame_info.command_buffer, 6, 1, 0, 0);
  60. }
  61. }
  62. void point_light_system::create_pipeline_layout(coral_device &device, std::vector<VkDescriptorSetLayout>& desc_set_layouts)
  63. {
  64. VkPushConstantRange push_constant_range{};
  65. push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
  66. push_constant_range.offset = 0;
  67. push_constant_range.size = sizeof(PointLightPushConstant);
  68. VkPipelineLayoutCreateInfo layout_info{ vkinit::pipeline_layout_ci() };
  69. layout_info.pushConstantRangeCount = 1;
  70. layout_info.pPushConstantRanges = &push_constant_range;
  71. layout_info.setLayoutCount = static_cast<uint32_t>(desc_set_layouts.size());
  72. layout_info.pSetLayouts = desc_set_layouts.data();
  73. if (vkCreatePipelineLayout(device.device(), &layout_info, nullptr, &pipeline_layout_) != VK_SUCCESS)
  74. throw std::runtime_error("ERROR! point_light_system::create_pipeline_layout() >> Failed to create pipeline layout!");
  75. }
  76. void point_light_system::create_pipeline(VkRenderPass render_pass)
  77. {
  78. PipelineConfigInfo config_info{};
  79. coral_pipeline::default_pipeline_config_info(config_info);
  80. config_info.binding_descriptions.clear();
  81. config_info.attribute_descriptions.clear();
  82. config_info.render_pass = render_pass;
  83. config_info.pipeline_layout = pipeline_layout_;
  84. pipeline_ = std::make_unique<coral_pipeline>(
  85. device_,
  86. "assets/shaders/point_light.vert.spv",
  87. "assets/shaders/point_light.frag.spv",
  88. config_info
  89. );
  90. }