Engine
Frameworkcreatedbymeusableforthecreationofsimplegames.CurrentlysupportsOpenGL(Verysimple)andVulkan.
VulkanDebugRenderer.cpp
Go to the documentation of this file.
2 #ifdef USING_VULKAN
3 
4 #include <ThirdParty/glm/glm/gtc/matrix_transform.hpp>
5 
7 
8 namespace Engine {
9 
10  VulkanDebugRenderer::VulkanDebugRenderer(VulkanRenderer * renderer, VulkanLogicalDevice * device, VulkanDescriptorPool * descriptorPool)
11  {
12  this->renderer = renderer;
13  this->device = device;
14  this->descriptorPool = descriptorPool;
15 
16  linePipeline = eastl::unique_ptr<VulkanPipeline>(new VulkanPipeline(device, renderer));
17 
18  linePipeline->LoadShader(VulkanPipeline::SHADER_TYPE::VERTEX_SHADER, "Line.vert.spv");
19  linePipeline->LoadShader(VulkanPipeline::SHADER_TYPE::FRAGMENT_SHADER, "Line.frag.spv");
20 
21  linePipeline->AddVertexInputBindingDescription(0, static_cast<uint32_t>(sizeof(VertexInfo_t)), VK_VERTEX_INPUT_RATE_VERTEX);
22  linePipeline->AddVertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0);
23 
24  linePipeline->CreateDescriptorSet();
25 
26  linePipeline->AddDescriptorSetBinding(0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr);
27 
28  linePipeline->AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, 0, static_cast<uint32_t>(sizeof(PushConstants_t)));
29 
30  linePipeline->SetRenderPassInfo(renderer->GetRenderPass(), static_cast<int>(VulkanRenderer::RenderSubPasses::RENDER_PASS));
31 
32  linePipeline->CreateColorBlendAttachment();
33 
34  linePipeline->SetInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_LINE_LIST, false);
35 
36  linePipeline->SetRasterizerSettings();
37 
38  linePipeline->Compile();
39 
40  vertexBuffer = eastl::unique_ptr<VulkanBuffer>(new VulkanBuffer(device, renderer->GetVmaAllocator(),
41  static_cast<uint32_t>(sizeof(VertexInfo_t) * 2),
42  VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, true, renderer->GetGraphicsCommandPool()));
43 
44  uniformBuffer = eastl::unique_ptr<VulkanBuffer>(new VulkanBuffer(device, renderer->GetVmaAllocator(),
45  static_cast<uint32_t>(sizeof(Ubo_t)),
46  VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, false, renderer->GetGraphicsCommandPool()));
47 
48  eastl::vector<VertexInfo_t> vertexData = {
49  {{0.f,0.f,0.f}},
50  {{0.f,1.f,0.f}}
51  };
52 
53  vertexBuffer->UpdateBuffer(vertexData.data(), 0, static_cast<uint32_t>(sizeof(VertexInfo_t)*vertexData.size()));
54 
55  ubo = { glm::mat4(), glm::mat4() };
56 
57  uniformBuffer->UpdateBuffer(&ubo, 0, static_cast<uint32_t>(sizeof(ubo)));
58 
59  VkDescriptorSetLayout layouts[] = { linePipeline->GetDescriptorSetLayout(0) };
60  descriptorPool->AllocateDescriptorSet(1, layouts, &uboDescriptorSet);
61 
62  descriptorPool->DescriptorSetBindToBuffer(uboDescriptorSet, uniformBuffer->GetBuffer(), 0, static_cast<VkDeviceSize>(sizeof(ubo)),
63  0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
64 
65 
66  }
67 
68  VulkanDebugRenderer::~VulkanDebugRenderer()
69  {
70  vertexBuffer.reset();
71  uniformBuffer.reset();
72 
73  linePipeline.reset();
74  }
75 
76  void VulkanDebugRenderer::StartRender(VkCommandBuffer commandBuffer, glm::mat4 view, glm::mat4 projection)
77  {
78  this->commandBuffer = commandBuffer;
79 
80  if (ubo.view != view || ubo.proj != projection) {
81  ubo.view = view;
82  ubo.proj = projection;
83 
84  uniformBuffer->UpdateBuffer(&ubo, 0, static_cast<uint32_t>(sizeof(ubo)));
85  }
86 
87  renderer->StartSecondaryCommandBufferRecording(commandBuffer,
88  VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
89  renderer->GetRenderPass(), static_cast<int>(VulkanRenderer::RenderSubPasses::RENDER_PASS), renderer->GetFrameBuffer());
90 
91  VkRect2D scissor = { 0,0,renderer->GetSwapChainExtent() };
92 
93  VkBuffer vertexBuffers[] = { (vertexBuffer->GetBuffer()) };
94  VkDeviceSize offsets[] = { 0 };
95 
96  vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
97 
98  vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, linePipeline->GetPipeline());
99 
100  vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, linePipeline->GetPipelineLayout(), 0, 1, &uboDescriptorSet, 0, nullptr);
101 
102  vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
103 
104  }
105 
106  void VulkanDebugRenderer::RenderLine(glm::vec3 start, glm::vec3 end, glm::vec4 color)
107  {
108  PushConstants_t constants = {};
109 
110  glm::vec3 translation = start;
111 
112  glm::vec3 rotationVector = glm::cross(glm::vec3(0.f, 1.f, 0.f), glm::normalize(end - start));
113  float rotationAngle = acosf(glm::dot(glm::vec3(0.f, 1.f, 0.f), (end - start)) / (glm::length(end - start)));
114 
115  if (rotationVector == glm::vec3(0.f, 0.f, 0.f)) {
116  rotationVector = glm::vec3(1.f, 1.f, 1.f);
117  rotationAngle = 0.f;
118  }
119 
120  float scale = glm::length(end - start);
121 
122  constants.model = glm::translate(glm::mat4(), translation)*
123  glm::rotate(glm::mat4(), rotationAngle, rotationVector)*
124  glm::scale(glm::mat4(), glm::vec3(1.f, scale, 1.f));
125  constants.color = color;
126 
127  lines.push_back(constants);
128 
129  }
130 
131  void VulkanDebugRenderer::FinishRender()
132  {
133  for (size_t i = 0, size = lines.size(); i < size; ++i) {
134  vkCmdPushConstants(commandBuffer, linePipeline->GetPipelineLayout(),
135  VK_SHADER_STAGE_VERTEX_BIT, 0, static_cast<uint32_t>(sizeof(lines[i])), &lines[i]);
136 
137  vkCmdDraw(commandBuffer, 2, 1, 0, 0);
138  }
139  renderer->EndSecondaryCommandBufferRecording(commandBuffer);
140 
141  lines.clear();
142  }
143 
144  void VulkanDebugRenderer::Clean()
145  {
146  linePipeline->Clean();
147  }
148 
149  void VulkanDebugRenderer::Recreate()
150  {
151  linePipeline->SetRenderPassInfo(renderer->GetRenderPass(), static_cast<int>(VulkanRenderer::RenderSubPasses::RENDER_PASS));
152  linePipeline->Recreate();
153  }
154 
155 } // namespace Engine
156 
157 #endif // USING_VULKAN