Lugdunum  0.1.0
SkyBox.cpp
Go to the documentation of this file.
2 
17 
18 namespace lug {
19 namespace Graphics {
20 namespace Vulkan {
21 namespace Builder {
22 namespace SkyBox {
23 
24 static bool initSkyBoxPipeline(Renderer& renderer, API::GraphicsPipeline& skyBoxPipeline) {
25  API::Builder::GraphicsPipeline graphicsPipelineBuilder(renderer.getDevice());
26 
27  // Set shaders
28  {
29  if (!graphicsPipelineBuilder.setShaderFromFile(VK_SHADER_STAGE_VERTEX_BIT, "main", renderer.getInfo().shadersRoot + "skybox.vert.spv")
30  || !graphicsPipelineBuilder.setShaderFromFile(VK_SHADER_STAGE_FRAGMENT_BIT, "main", renderer.getInfo().shadersRoot + "skybox.frag.spv")) {
31  LUG_LOG.error("initPipeline: Can't create skybox shader");
32  return false;
33  }
34 
35  // Set vertex input state
36  auto vertexBinding = graphicsPipelineBuilder.addInputBinding(sizeof(lug::Math::Vec3f), VK_VERTEX_INPUT_RATE_VERTEX);
37 
38  vertexBinding.addAttributes(VK_FORMAT_R32G32B32_SFLOAT, 0); // Position
39  }
40 
41  // Set input assembly state
42  graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false);
43 
44  // Set viewport state
45  const VkViewport viewport{
46  /* viewport.x */ 0.0f,
47  /* viewport.y */ 0.0f,
48  /* viewport.width */ 0.0f,
49  /* viewport.height */ 0.0f,
50  /* viewport.minDepth */ 0.0f,
51  /* viewport.maxDepth */ 1.0f,
52  };
53 
54  const VkRect2D scissor{
55  /* scissor.offset */ {0, 0},
56  /* scissor.extent */ {0, 0}
57  };
58 
59  auto viewportState = graphicsPipelineBuilder.getViewportState();
60  viewportState.addViewport(viewport);
61  viewportState.addScissor(scissor);
62 
63  // Inverse the front face because we are inside the cube
64  auto rasterizationState = graphicsPipelineBuilder.getRasterizationState();
65  rasterizationState.setFrontFace(VK_FRONT_FACE_CLOCKWISE);
66 
67  // Set color blend state
68  const VkPipelineColorBlendAttachmentState colorBlendAttachment{
69  /* colorBlendAttachment.blendEnable */ VK_TRUE,
70  /* colorBlendAttachment.srcColorBlendFactor */ VK_BLEND_FACTOR_ONE,
71  /* colorBlendAttachment.dstColorBlendFactor */ VK_BLEND_FACTOR_CONSTANT_COLOR,
72  /* colorBlendAttachment.colorBlendOp */ VK_BLEND_OP_ADD,
73  /* colorBlendAttachment.srcAlphaBlendFactor */ VK_BLEND_FACTOR_ZERO,
74  /* colorBlendAttachment.dstAlphaBlendFactor */ VK_BLEND_FACTOR_CONSTANT_COLOR,
75  /* colorBlendAttachment.alphaBlendOp */ VK_BLEND_OP_ADD,
76  /* colorBlendAttachment.colorWriteMask */ VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
77  };
78 
79  auto colorBlendState = graphicsPipelineBuilder.getColorBlendState();
80  colorBlendState.addAttachment(colorBlendAttachment);
81 
82  auto depthStencilState = graphicsPipelineBuilder.getDepthStencilState();
83  depthStencilState.enableDepthTest(VK_COMPARE_OP_LESS_OR_EQUAL);
84 
85  // Set dynamic states
86  graphicsPipelineBuilder.setDynamicStates({
87  VK_DYNAMIC_STATE_VIEWPORT,
88  VK_DYNAMIC_STATE_SCISSOR
89  });
90 
91  // Set descriptorSetLayouts
92  std::vector<Vulkan::API::DescriptorSetLayout> descriptorSetLayouts(2);
93  {
94  // Bindings set 0 : Camera uniform buffer (V)
95  {
96  API::Builder::DescriptorSetLayout descriptorSetLayoutBuilder(renderer.getDevice());
97 
98  // Camera uniform buffer
99  // We only need it in the vertex shader, but we still use VK_SHADER_STAGE_FRAGMENT_BIT
100  // because it needs to be compatible with the objects pipeline layout to use the same camera descriptor set
101  const VkDescriptorSetLayoutBinding binding{
102  /* binding.binding */ 0,
103  /* binding.descriptorType */ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
104  /* binding.descriptorCount */ 1,
105  /* binding.stageFlags */ VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
106  /* binding.pImmutableSamplers */ nullptr
107  };
108 
109  descriptorSetLayoutBuilder.setBindings({binding});
110  VkResult result{VK_SUCCESS};
111  if (!descriptorSetLayoutBuilder.build(descriptorSetLayouts[0], &result)) {
112  LUG_LOG.error("initPipeline: Can't create pipeline descriptor sets layout 0: {}", result);
113  return false;
114  }
115  }
116 
117  // Bindings set 1 : Skybox cube sampler (F)
118  {
119  API::Builder::DescriptorSetLayout descriptorSetLayoutBuilder(renderer.getDevice());
120 
121  // SkyBox cube sampler
122  const VkDescriptorSetLayoutBinding binding{
123  /* binding.binding */ 0,
124  /* binding.descriptorType */ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
125  /* binding.descriptorCount */ 1,
126  /* binding.stageFlags */ VK_SHADER_STAGE_FRAGMENT_BIT,
127  /* binding.pImmutableSamplers */ nullptr
128  };
129 
130  descriptorSetLayoutBuilder.setBindings({binding});
131  VkResult result{VK_SUCCESS};
132  if (!descriptorSetLayoutBuilder.build(descriptorSetLayouts[1], &result)) {
133  LUG_LOG.error("initPipeline: Can't create pipeline descriptor sets layout 1: {}", result);
134  return false;
135  }
136  }
137  }
138 
139  // Set pipeline layout
140  {
141  API::PipelineLayout pipelineLayout{};
142  API::Builder::PipelineLayout pipelineLayoutBuilder(renderer.getDevice());
143 
144  pipelineLayoutBuilder.setDescriptorSetLayouts(std::move(descriptorSetLayouts));
145 
146  VkResult result{VK_SUCCESS};
147  if (!pipelineLayoutBuilder.build(pipelineLayout, &result)) {
148  LUG_LOG.error("initPipeline: Can't create pipeline layout: {}", result);
149  return false;
150  }
151 
152  graphicsPipelineBuilder.setPipelineLayout(std::move(pipelineLayout));
153  }
154 
155  // Set render pass
156  {
157  API::Builder::RenderPass renderPassBuilder(renderer.getDevice());
158 
159  const VkAttachmentDescription colorAttachment{
160  /* colorAttachment.flags */ 0,
161  /* colorAttachment.format */ renderer.getRenderWindow()->getSwapchain().getFormat().format,
162  /* colorAttachment.samples */ VK_SAMPLE_COUNT_1_BIT,
163  /* colorAttachment.loadOp */ VK_ATTACHMENT_LOAD_OP_CLEAR,
164  /* colorAttachment.storeOp */ VK_ATTACHMENT_STORE_OP_STORE,
165  /* colorAttachment.stencilLoadOp */ VK_ATTACHMENT_LOAD_OP_DONT_CARE,
166  /* colorAttachment.stencilStoreOp */ VK_ATTACHMENT_STORE_OP_DONT_CARE,
167  /* colorAttachment.initialLayout */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
168  /* colorAttachment.finalLayout */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
169  };
170 
171  auto colorAttachmentIndex = renderPassBuilder.addAttachment(colorAttachment);
172 
173  const VkFormat depthFormat = API::Image::findSupportedFormat(
174  renderer.getDevice(),
175  {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT},
176  VK_IMAGE_TILING_OPTIMAL,
177  VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
178  );
179 
180  const VkAttachmentDescription depthAttachment{
181  /* depthAttachment.flags */ 0,
182  /* depthAttachment.format */ depthFormat,
183  /* depthAttachment.samples */ VK_SAMPLE_COUNT_1_BIT,
184  /* depthAttachment.loadOp */ VK_ATTACHMENT_LOAD_OP_CLEAR,
185  /* depthAttachment.storeOp */ VK_ATTACHMENT_STORE_OP_STORE,
186  /* depthAttachment.stencilLoadOp */ VK_ATTACHMENT_LOAD_OP_DONT_CARE,
187  /* depthAttachment.stencilStoreOp */ VK_ATTACHMENT_STORE_OP_DONT_CARE,
188  /* depthAttachment.initialLayout */ VK_IMAGE_LAYOUT_UNDEFINED,
189  /* depthAttachment.finalLayout */ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
190  };
191 
192  auto depthAttachmentIndex = renderPassBuilder.addAttachment(depthAttachment);
193 
194  const API::Builder::RenderPass::SubpassDescription subpassDescription{
195  /* subpassDescription.pipelineBindPoint */ VK_PIPELINE_BIND_POINT_GRAPHICS,
196  /* subpassDescription.inputAttachments */ {},
197  /* subpassDescription.colorAttachments */ {{colorAttachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}},
198  /* subpassDescription.resolveAttachments */ {},
199  /* subpassDescription.depthStencilAttachment */ {depthAttachmentIndex, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
200  /* subpassDescription.preserveAttachments */ {},
201  };
202 
203  renderPassBuilder.addSubpass(subpassDescription);
204 
205  VkResult result{VK_SUCCESS};
206  API::RenderPass renderPass;
207  if (!renderPassBuilder.build(renderPass, &result)) {
208  LUG_LOG.error("initPipeline: Can't create render pass: {}", result);
209  return false;
210  }
211 
212  graphicsPipelineBuilder.setRenderPass(std::move(renderPass), 0);
213  }
214 
215  VkResult result{VK_SUCCESS};
216  if (!graphicsPipelineBuilder.build(skyBoxPipeline, &result)) {
217  LUG_LOG.error("initPipeline: Can't create pipeline: {}", result);
218  return false;
219  }
220 
221  return true;
222 }
223 
224 static bool initIrradianceMapPipeline(Renderer& renderer, API::GraphicsPipeline& irradianceMapPipeline) {
225  API::Builder::GraphicsPipeline graphicsPipelineBuilder(renderer.getDevice());
226 
227  // Set shaders
228  {
229  if (!graphicsPipelineBuilder.setShaderFromFile(VK_SHADER_STAGE_VERTEX_BIT, "main", renderer.getInfo().shadersRoot + "filtercube.vert.spv")
230  || !graphicsPipelineBuilder.setShaderFromFile(VK_SHADER_STAGE_FRAGMENT_BIT, "main", renderer.getInfo().shadersRoot + "irradiance.frag.spv")) {
231  LUG_LOG.error("initPipeline: Can't create skybox shader");
232  return false;
233  }
234 
235  // Set vertex input state
236  auto vertexBinding = graphicsPipelineBuilder.addInputBinding(sizeof(lug::Math::Vec3f), VK_VERTEX_INPUT_RATE_VERTEX);
237 
238  vertexBinding.addAttributes(VK_FORMAT_R32G32B32_SFLOAT, 0); // Position
239  }
240 
241  // Set input assembly state
242  graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false);
243 
244  // Set viewport state
245  const VkViewport viewport{
246  /* viewport.x */ 0.0f,
247  /* viewport.y */ 0.0f,
248  /* viewport.width */ 0.0f,
249  /* viewport.height */ 0.0f,
250  /* viewport.minDepth */ 0.0f,
251  /* viewport.maxDepth */ 1.0f,
252  };
253 
254  const VkRect2D scissor{
255  /* scissor.offset */ {0, 0},
256  /* scissor.extent */ {0, 0}
257  };
258 
259  auto viewportState = graphicsPipelineBuilder.getViewportState();
260  viewportState.addViewport(viewport);
261  viewportState.addScissor(scissor);
262 
263  // Inverse the front face because we are inside the cube
264  auto rasterizationState = graphicsPipelineBuilder.getRasterizationState();
265  rasterizationState.setFrontFace(VK_FRONT_FACE_CLOCKWISE);
266 
267  // Set color blend state
268  const VkPipelineColorBlendAttachmentState colorBlendAttachment{
269  /* colorBlendAttachment.blendEnable */ VK_TRUE,
270  /* colorBlendAttachment.srcColorBlendFactor */ VK_BLEND_FACTOR_ONE,
271  /* colorBlendAttachment.dstColorBlendFactor */ VK_BLEND_FACTOR_CONSTANT_COLOR,
272  /* colorBlendAttachment.colorBlendOp */ VK_BLEND_OP_ADD,
273  /* colorBlendAttachment.srcAlphaBlendFactor */ VK_BLEND_FACTOR_ONE,
274  /* colorBlendAttachment.dstAlphaBlendFactor */ VK_BLEND_FACTOR_CONSTANT_COLOR,
275  /* colorBlendAttachment.alphaBlendOp */ VK_BLEND_OP_ADD,
276  /* colorBlendAttachment.colorWriteMask */ VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
277  };
278 
279  auto colorBlendState = graphicsPipelineBuilder.getColorBlendState();
280  colorBlendState.addAttachment(colorBlendAttachment);
281 
282  // Set dynamic states
283  graphicsPipelineBuilder.setDynamicStates({
284  VK_DYNAMIC_STATE_VIEWPORT,
285  VK_DYNAMIC_STATE_SCISSOR
286  });
287 
288  // Set descriptorSetLayouts
289  std::vector<Vulkan::API::DescriptorSetLayout> descriptorSetLayouts(1);
290  {
291  // Bindings set 0 : Skybox cube sampler (F)
292  {
293  API::Builder::DescriptorSetLayout descriptorSetLayoutBuilder(renderer.getDevice());
294 
295  // SkyBox cube sampler
296  const VkDescriptorSetLayoutBinding binding{
297  /* binding.binding */ 0,
298  /* binding.descriptorType */ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
299  /* binding.descriptorCount */ 1,
300  /* binding.stageFlags */ VK_SHADER_STAGE_FRAGMENT_BIT,
301  /* binding.pImmutableSamplers */ nullptr
302  };
303 
304  descriptorSetLayoutBuilder.setBindings({binding});
305  VkResult result{VK_SUCCESS};
306  if (!descriptorSetLayoutBuilder.build(descriptorSetLayouts[0], &result)) {
307  LUG_LOG.error("initPipeline: Can't create pipeline descriptor sets layout 1: {}", result);
308  return false;
309  }
310  }
311  }
312 
313  // Set pipeline layout
314  {
315  API::PipelineLayout pipelineLayout{};
316  API::Builder::PipelineLayout pipelineLayoutBuilder(renderer.getDevice());
317 
318  pipelineLayoutBuilder.setDescriptorSetLayouts(std::move(descriptorSetLayouts));
319 
320  // MVP matrix
321  const VkPushConstantRange pushConstant{
322  /* pushConstant.stageFlags */ VK_SHADER_STAGE_VERTEX_BIT,
323  /* pushConstant.offset */ 0,
324  /* pushConstant.size */ sizeof(Math::Mat4x4f)
325  };
326 
327  pipelineLayoutBuilder.setPushConstants({pushConstant});
328 
329  VkResult result{VK_SUCCESS};
330  if (!pipelineLayoutBuilder.build(pipelineLayout, &result)) {
331  LUG_LOG.error("initPipeline: Can't create pipeline layout: {}", result);
332  return false;
333  }
334 
335  graphicsPipelineBuilder.setPipelineLayout(std::move(pipelineLayout));
336  }
337 
338  // Set render pass
339  {
340  API::Builder::RenderPass renderPassBuilder(renderer.getDevice());
341 
342  const VkAttachmentDescription colorAttachment{
343  /* colorAttachment.flags */ 0,
344  /* colorAttachment.format */ VK_FORMAT_R32G32B32A32_SFLOAT, // TODO: Set the format otherwise
345  /* colorAttachment.samples */ VK_SAMPLE_COUNT_1_BIT,
346  /* colorAttachment.loadOp */ VK_ATTACHMENT_LOAD_OP_CLEAR,
347  /* colorAttachment.storeOp */ VK_ATTACHMENT_STORE_OP_STORE,
348  /* colorAttachment.stencilLoadOp */ VK_ATTACHMENT_LOAD_OP_DONT_CARE,
349  /* colorAttachment.stencilStoreOp */ VK_ATTACHMENT_STORE_OP_DONT_CARE,
350  /* colorAttachment.initialLayout */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
351  /* colorAttachment.finalLayout */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
352  };
353 
354  auto colorAttachmentIndex = renderPassBuilder.addAttachment(colorAttachment);
355 
356  const API::Builder::RenderPass::SubpassDescription subpassDescription{
357  /* subpassDescription.pipelineBindPoint */ VK_PIPELINE_BIND_POINT_GRAPHICS,
358  /* subpassDescription.inputAttachments */ {},
359  /* subpassDescription.colorAttachments */ {{colorAttachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}},
360  /* subpassDescription.resolveAttachments */ {},
361  /* subpassDescription.depthStencilAttachment */ {},
362  /* subpassDescription.preserveAttachments */ {},
363  };
364 
365  renderPassBuilder.addSubpass(subpassDescription);
366 
367  VkResult result{VK_SUCCESS};
368  API::RenderPass renderPass;
369  if (!renderPassBuilder.build(renderPass, &result)) {
370  LUG_LOG.error("initPipeline: Can't create render pass: {}", result);
371  return false;
372  }
373 
374  graphicsPipelineBuilder.setRenderPass(std::move(renderPass), 0);
375  }
376 
377  VkResult result{VK_SUCCESS};
378  if (!graphicsPipelineBuilder.build(irradianceMapPipeline, &result)) {
379  LUG_LOG.error("initPipeline: Can't create pipeline: {}", result);
380  return false;
381  }
382 
383  return true;
384 }
385 
386 static bool initPrefilteredMapPipeline(Renderer& renderer, API::GraphicsPipeline& irradianceMapPipeline) {
387  API::Builder::GraphicsPipeline graphicsPipelineBuilder(renderer.getDevice());
388 
389  // Set shaders
390  {
391  if (!graphicsPipelineBuilder.setShaderFromFile(VK_SHADER_STAGE_VERTEX_BIT, "main", renderer.getInfo().shadersRoot + "filtercube.vert.spv")
392  || !graphicsPipelineBuilder.setShaderFromFile(VK_SHADER_STAGE_FRAGMENT_BIT, "main", renderer.getInfo().shadersRoot + "prefiltered.frag.spv")) {
393  LUG_LOG.error("initPipeline: Can't create skybox shader");
394  return false;
395  }
396 
397  // Set vertex input state
398  auto vertexBinding = graphicsPipelineBuilder.addInputBinding(sizeof(lug::Math::Vec3f), VK_VERTEX_INPUT_RATE_VERTEX);
399 
400  vertexBinding.addAttributes(VK_FORMAT_R32G32B32_SFLOAT, 0); // Position
401  }
402 
403  // Set input assembly state
404  graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false);
405 
406  // Set viewport state
407  const VkViewport viewport{
408  /* viewport.x */ 0.0f,
409  /* viewport.y */ 0.0f,
410  /* viewport.width */ 0.0f,
411  /* viewport.height */ 0.0f,
412  /* viewport.minDepth */ 0.0f,
413  /* viewport.maxDepth */ 1.0f,
414  };
415 
416  const VkRect2D scissor{
417  /* scissor.offset */ {0, 0},
418  /* scissor.extent */ {0, 0}
419  };
420 
421  auto viewportState = graphicsPipelineBuilder.getViewportState();
422  viewportState.addViewport(viewport);
423  viewportState.addScissor(scissor);
424 
425  // Inverse the front face because we are inside the cube
426  auto rasterizationState = graphicsPipelineBuilder.getRasterizationState();
427  rasterizationState.setFrontFace(VK_FRONT_FACE_CLOCKWISE);
428 
429  // Set color blend state
430  const VkPipelineColorBlendAttachmentState colorBlendAttachment{
431  /* colorBlendAttachment.blendEnable */ VK_TRUE,
432  /* colorBlendAttachment.srcColorBlendFactor */ VK_BLEND_FACTOR_ONE,
433  /* colorBlendAttachment.dstColorBlendFactor */ VK_BLEND_FACTOR_CONSTANT_COLOR,
434  /* colorBlendAttachment.colorBlendOp */ VK_BLEND_OP_ADD,
435  /* colorBlendAttachment.srcAlphaBlendFactor */ VK_BLEND_FACTOR_ONE,
436  /* colorBlendAttachment.dstAlphaBlendFactor */ VK_BLEND_FACTOR_CONSTANT_COLOR,
437  /* colorBlendAttachment.alphaBlendOp */ VK_BLEND_OP_ADD,
438  /* colorBlendAttachment.colorWriteMask */ VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
439  };
440 
441  auto colorBlendState = graphicsPipelineBuilder.getColorBlendState();
442  colorBlendState.addAttachment(colorBlendAttachment);
443 
444  // Set dynamic states
445  graphicsPipelineBuilder.setDynamicStates({
446  VK_DYNAMIC_STATE_VIEWPORT,
447  VK_DYNAMIC_STATE_SCISSOR
448  });
449 
450  // Set descriptorSetLayouts
451  std::vector<Vulkan::API::DescriptorSetLayout> descriptorSetLayouts(1);
452  {
453  // Bindings set 0 : Skybox cube sampler (F)
454  {
455  API::Builder::DescriptorSetLayout descriptorSetLayoutBuilder(renderer.getDevice());
456 
457  // SkyBox cube sampler
458  const VkDescriptorSetLayoutBinding binding{
459  /* binding.binding */ 0,
460  /* binding.descriptorType */ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
461  /* binding.descriptorCount */ 1,
462  /* binding.stageFlags */ VK_SHADER_STAGE_FRAGMENT_BIT,
463  /* binding.pImmutableSamplers */ nullptr
464  };
465 
466  descriptorSetLayoutBuilder.setBindings({binding});
467  VkResult result{VK_SUCCESS};
468  if (!descriptorSetLayoutBuilder.build(descriptorSetLayouts[0], &result)) {
469  LUG_LOG.error("initPipeline: Can't create pipeline descriptor sets layout 1: {}", result);
470  return false;
471  }
472  }
473  }
474 
475  // Set pipeline layout
476  {
477  API::PipelineLayout pipelineLayout{};
478  API::Builder::PipelineLayout pipelineLayoutBuilder(renderer.getDevice());
479 
480  pipelineLayoutBuilder.setDescriptorSetLayouts(std::move(descriptorSetLayouts));
481 
482  // MVP matrix
483  const VkPushConstantRange pushConstantMVP{
484  /* pushConstant.stageFlags */ VK_SHADER_STAGE_VERTEX_BIT,
485  /* pushConstant.offset */ 0,
486  /* pushConstant.size */ sizeof(Math::Mat4x4f)
487  };
488 
489  // Roughness
490  const VkPushConstantRange pushConstantRoughness{
491  /* pushConstant.stageFlags */ VK_SHADER_STAGE_FRAGMENT_BIT,
492  /* pushConstant.offset */ sizeof(Math::Mat4x4f),
493  /* pushConstant.size */ sizeof(float)
494  };
495 
496  pipelineLayoutBuilder.setPushConstants({pushConstantMVP, pushConstantRoughness});
497 
498  VkResult result{VK_SUCCESS};
499  if (!pipelineLayoutBuilder.build(pipelineLayout, &result)) {
500  LUG_LOG.error("initPipeline: Can't create pipeline layout: {}", result);
501  return false;
502  }
503 
504  graphicsPipelineBuilder.setPipelineLayout(std::move(pipelineLayout));
505  }
506 
507  // Set render pass
508  {
509  API::Builder::RenderPass renderPassBuilder(renderer.getDevice());
510 
511  const VkAttachmentDescription colorAttachment{
512  /* colorAttachment.flags */ 0,
513  /* colorAttachment.format */ VK_FORMAT_R32G32B32A32_SFLOAT, // TODO: Set the format otherwise
514  /* colorAttachment.samples */ VK_SAMPLE_COUNT_1_BIT,
515  /* colorAttachment.loadOp */ VK_ATTACHMENT_LOAD_OP_CLEAR,
516  /* colorAttachment.storeOp */ VK_ATTACHMENT_STORE_OP_STORE,
517  /* colorAttachment.stencilLoadOp */ VK_ATTACHMENT_LOAD_OP_DONT_CARE,
518  /* colorAttachment.stencilStoreOp */ VK_ATTACHMENT_STORE_OP_DONT_CARE,
519  /* colorAttachment.initialLayout */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
520  /* colorAttachment.finalLayout */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
521  };
522 
523  auto colorAttachmentIndex = renderPassBuilder.addAttachment(colorAttachment);
524 
525  const API::Builder::RenderPass::SubpassDescription subpassDescription{
526  /* subpassDescription.pipelineBindPoint */ VK_PIPELINE_BIND_POINT_GRAPHICS,
527  /* subpassDescription.inputAttachments */ {},
528  /* subpassDescription.colorAttachments */ {{colorAttachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}},
529  /* subpassDescription.resolveAttachments */ {},
530  /* subpassDescription.depthStencilAttachment */ {},
531  /* subpassDescription.preserveAttachments */ {},
532  };
533 
534  renderPassBuilder.addSubpass(subpassDescription);
535 
536  VkResult result{VK_SUCCESS};
537  API::RenderPass renderPass;
538  if (!renderPassBuilder.build(renderPass, &result)) {
539  LUG_LOG.error("initPipeline: Can't create render pass: {}", result);
540  return false;
541  }
542 
543  graphicsPipelineBuilder.setRenderPass(std::move(renderPass), 0);
544  }
545 
546  VkResult result{VK_SUCCESS};
547  if (!graphicsPipelineBuilder.build(irradianceMapPipeline, &result)) {
548  LUG_LOG.error("initPipeline: Can't create pipeline: {}", result);
549  return false;
550  }
551 
552  return true;
553 }
554 
555 static bool initBrdfLutPipeline(Renderer& renderer, API::GraphicsPipeline& brdfLutPipeline) {
556  API::Builder::GraphicsPipeline graphicsPipelineBuilder(renderer.getDevice());
557 
558  // Set shaders
559  {
560  if (!graphicsPipelineBuilder.setShaderFromFile(VK_SHADER_STAGE_VERTEX_BIT, "main", renderer.getInfo().shadersRoot + "genbrdflut.vert.spv")
561  || !graphicsPipelineBuilder.setShaderFromFile(VK_SHADER_STAGE_FRAGMENT_BIT, "main", renderer.getInfo().shadersRoot + "genbrdflut.frag.spv")) {
562  LUG_LOG.error("initPipeline: Can't create skybox shader");
563  return false;
564  }
565  }
566 
567  // Set input assembly state
568  graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false);
569 
570  // Set viewport state
571  const VkViewport viewport{
572  /* viewport.x */ 0.0f,
573  /* viewport.y */ 0.0f,
574  /* viewport.width */ 0.0f,
575  /* viewport.height */ 0.0f,
576  /* viewport.minDepth */ 0.0f,
577  /* viewport.maxDepth */ 1.0f,
578  };
579 
580  const VkRect2D scissor{
581  /* scissor.offset */ {0, 0},
582  /* scissor.extent */ {0, 0}
583  };
584 
585  auto viewportState = graphicsPipelineBuilder.getViewportState();
586  viewportState.addViewport(viewport);
587  viewportState.addScissor(scissor);
588 
589  // Disable the culling
590  auto rasterizationState = graphicsPipelineBuilder.getRasterizationState();
591  rasterizationState.setCullMode(VK_CULL_MODE_NONE);
592 
593  // Set color blend state
594  const VkPipelineColorBlendAttachmentState colorBlendAttachment{
595  /* colorBlendAttachment.blendEnable */ VK_TRUE,
596  /* colorBlendAttachment.srcColorBlendFactor */ VK_BLEND_FACTOR_ONE,
597  /* colorBlendAttachment.dstColorBlendFactor */ VK_BLEND_FACTOR_CONSTANT_COLOR,
598  /* colorBlendAttachment.colorBlendOp */ VK_BLEND_OP_ADD,
599  /* colorBlendAttachment.srcAlphaBlendFactor */ VK_BLEND_FACTOR_ONE,
600  /* colorBlendAttachment.dstAlphaBlendFactor */ VK_BLEND_FACTOR_CONSTANT_COLOR,
601  /* colorBlendAttachment.alphaBlendOp */ VK_BLEND_OP_ADD,
602  /* colorBlendAttachment.colorWriteMask */ VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
603  };
604 
605  auto colorBlendState = graphicsPipelineBuilder.getColorBlendState();
606  colorBlendState.addAttachment(colorBlendAttachment);
607 
608  // Set dynamic states
609  graphicsPipelineBuilder.setDynamicStates({
610  VK_DYNAMIC_STATE_VIEWPORT,
611  VK_DYNAMIC_STATE_SCISSOR
612  });
613 
614  // Set pipeline layout
615  {
616  API::PipelineLayout pipelineLayout{};
617  API::Builder::PipelineLayout pipelineLayoutBuilder(renderer.getDevice());
618 
619  VkResult result{VK_SUCCESS};
620  if (!pipelineLayoutBuilder.build(pipelineLayout, &result)) {
621  LUG_LOG.error("initPipeline: Can't create pipeline layout: {}", result);
622  return false;
623  }
624 
625  graphicsPipelineBuilder.setPipelineLayout(std::move(pipelineLayout));
626  }
627 
628  // Set render pass
629  {
630  API::Builder::RenderPass renderPassBuilder(renderer.getDevice());
631 
632  const VkAttachmentDescription colorAttachment{
633  /* colorAttachment.flags */ 0,
634  /* colorAttachment.format */ VK_FORMAT_R16G16_SFLOAT, // TODO: Set the format otherwise
635  /* colorAttachment.samples */ VK_SAMPLE_COUNT_1_BIT,
636  /* colorAttachment.loadOp */ VK_ATTACHMENT_LOAD_OP_CLEAR,
637  /* colorAttachment.storeOp */ VK_ATTACHMENT_STORE_OP_STORE,
638  /* colorAttachment.stencilLoadOp */ VK_ATTACHMENT_LOAD_OP_DONT_CARE,
639  /* colorAttachment.stencilStoreOp */ VK_ATTACHMENT_STORE_OP_DONT_CARE,
640  /* colorAttachment.initialLayout */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
641  /* colorAttachment.finalLayout */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
642  };
643 
644  auto colorAttachmentIndex = renderPassBuilder.addAttachment(colorAttachment);
645 
646  const API::Builder::RenderPass::SubpassDescription subpassDescription{
647  /* subpassDescription.pipelineBindPoint */ VK_PIPELINE_BIND_POINT_GRAPHICS,
648  /* subpassDescription.inputAttachments */ {},
649  /* subpassDescription.colorAttachments */ {{colorAttachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}},
650  /* subpassDescription.resolveAttachments */ {},
651  /* subpassDescription.depthStencilAttachment */ {},
652  /* subpassDescription.preserveAttachments */ {},
653  };
654 
655  renderPassBuilder.addSubpass(subpassDescription);
656 
657  VkResult result{VK_SUCCESS};
658  API::RenderPass renderPass;
659  if (!renderPassBuilder.build(renderPass, &result)) {
660  LUG_LOG.error("initPipeline: Can't create render pass: {}", result);
661  return false;
662  }
663 
664  graphicsPipelineBuilder.setRenderPass(std::move(renderPass), 0);
665  }
666 
667  VkResult result{VK_SUCCESS};
668  if (!graphicsPipelineBuilder.build(brdfLutPipeline, &result)) {
669  LUG_LOG.error("initPipeline: Can't create pipeline: {}", result);
670  return false;
671  }
672 
673  return true;
674 }
675 
677  const std::vector<lug::Math::Vec3f> positions = {
678  // Back
679  {-1.0f, -1.0f, -1.0f},
680  {1.0f, -1.0f, -1.0f},
681  {-1.0f, 1.0f, -1.0f},
682  {1.0f, 1.0f, -1.0f},
683 
684  // Front
685  {-1.0f, -1.0f, 1.0f},
686  {1.0f, -1.0f, 1.0f},
687  {-1.0f, 1.0f, 1.0f},
688  {1.0f, 1.0f, 1.0f},
689 
690  // Left
691  {-1.0f, -1.0f, -1.0f},
692  {-1.0f, -1.0f, 1.0f},
693  {-1.0f, 1.0f, -1.0f},
694  {-1.0f, 1.0f, 1.0f},
695 
696  // Right
697  {1.0f, -1.0f, -1.0f},
698  {1.0f, -1.0f, 1.0f},
699  {1.0f, 1.0f, -1.0f},
700  {1.0f, 1.0f, 1.0f},
701 
702  // Bottom
703  {-1.0f, -1.0f, -1.0f},
704  {-1.0f, -1.0f, 1.0f},
705  {1.0f, -1.0f, -1.0f},
706  {1.0f, -1.0f, 1.0f},
707 
708  // Top
709  {-1.0f, 1.0f, -1.0f},
710  {-1.0f, 1.0f, 1.0f},
711  {1.0f, 1.0f, -1.0f},
712  {1.0f, 1.0f, 1.0}
713  };
714 
715  const std::vector<uint16_t> indices = {
716  // Back
717  0, 2, 1,
718  1, 2, 3,
719 
720  // Front
721  6, 4, 5,
722  7, 6, 5,
723 
724  // Left
725  10, 8, 9,
726  11, 10, 9,
727 
728  // Right
729  14, 13, 12,
730  15, 13, 14,
731 
732  // Bottom
733  17, 16, 19,
734  19, 16, 18,
735 
736  // Top
737  23, 20, 21,
738  22, 20, 23
739  };
740 
741  // Build the mesh
742  {
743  lug::Graphics::Builder::Mesh meshBuilder(renderer);
744  meshBuilder.setName("skybox");
745 
746  lug::Graphics::Builder::Mesh::PrimitiveSet* primitiveSet = meshBuilder.addPrimitiveSet();
747 
749 
750  primitiveSet->addAttributeBuffer(
751  indices.data(),
752  sizeof(uint16_t),
753  static_cast<uint32_t>(indices.size()),
755  );
756 
757  primitiveSet->addAttributeBuffer(
758  positions.data(),
759  sizeof(lug::Math::Vec3f),
760  static_cast<uint32_t>(positions.size()),
762  );
763 
764  skyBoxMesh = meshBuilder.build();
765 
766  if (!skyBoxMesh) {
767  LUG_LOG.error("initMesh: Can't create the skyBox mesh");
768  return false;
769  }
770  }
771 
772  return true;
773 }
774 
776  constexpr uint32_t brdfLutSize = 512;
777 
778  Vulkan::Renderer& vkRenderer = static_cast<Vulkan::Renderer&>(renderer);
779 
780  // Create the texture
781  // TODO: Set sampler borderColor to VK_BORDER_COOLOR_FLOAT_OPAQUE_WHITE
782  lug::Graphics::Builder::Texture textureBuilder(renderer);
783 
786 
787  if (!textureBuilder.addLayer(brdfLutSize, brdfLutSize, lug::Graphics::Render::Texture::Format::R16G16_SFLOAT)) {
788  LUG_LOG.error("Application: Can't create the brdf lut texture layer");
789  return false;
790  }
791 
792  brdfLut = textureBuilder.build();
793  if (!brdfLut) {
794  LUG_LOG.error("Application: Can't create the brdf lut texture");
795  return false;
796  }
797 
799 
800  // Create Framebuffer for brdf lut generation
801  API::CommandPool commandPool;
802  API::CommandBuffer cmdBuffer;
803  API::Framebuffer framebuffer;
804  API::Fence fence;
805  const API::Queue* graphicsQueue = nullptr;
806  VkResult result{VK_SUCCESS};
807  {
808  // Graphics queue
809  graphicsQueue = vkRenderer.getDevice().getQueue("queue_graphics");
810  if (!graphicsQueue) {
811  LUG_LOG.error("Skybox::initBrdfLut: Can't find queue with name queue_graphics");
812  return false;
813  }
814 
815  // Command pool
816  API::Builder::CommandPool commandPoolBuilder(vkRenderer.getDevice(), *graphicsQueue->getQueueFamily());
817  if (!commandPoolBuilder.build(commandPool, &result)) {
818  LUG_LOG.error("Skybox::initBrdfLut: Can't create the graphics command pool: {}", result);
819  return false;
820  }
821 
822  // Command buffer
823  API::Builder::CommandBuffer commandBufferBuilder(vkRenderer.getDevice(), commandPool);
824  commandBufferBuilder.setLevel(VK_COMMAND_BUFFER_LEVEL_PRIMARY);
825 
826  // Create the render command buffer
827  if (!commandBufferBuilder.build(cmdBuffer, &result)) {
828  LUG_LOG.error("Skybox::initBrdfLut: Can't create the command buffer: {}", result);
829  return false;
830  }
831 
832  // Fence
833  {
834  API::Builder::Fence fenceBuilder(vkRenderer.getDevice());
835 
836  if (!fenceBuilder.build(fence, &result)) {
837  LUG_LOG.error("Skybox::initBrdfLut: Can't create render fence: {}", result);
838  return false;
839  }
840  }
841 
842  // Create framebuffer
843  {
844  API::Builder::Framebuffer framebufferBuilder(vkRenderer.getDevice());
845 
846  const API::RenderPass* renderPass = brdfLutPipeline.getRenderPass();
847 
848  framebufferBuilder.setRenderPass(renderPass);
849  framebufferBuilder.addAttachment(&vKBrdfLut->getImageView());
850  framebufferBuilder.setWidth(brdfLutSize);
851  framebufferBuilder.setHeight(brdfLutSize);
852 
853  if (!framebufferBuilder.build(framebuffer, &result)) {
854  LUG_LOG.error("tFramebuffers: Can't create framebuffer: {}", result);
855  return false;
856  }
857  }
858  }
859 
860  // Generate the brdf lut
861  {
862  if (!cmdBuffer.begin()) {
863  return false;
864  }
865 
866  cmdBuffer.bindPipeline(brdfLutPipeline);
867 
868  // Change texture image layout to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL for render
869  {
870  API::CommandBuffer::CmdPipelineBarrier pipelineBarrier;
871  pipelineBarrier.imageMemoryBarriers.resize(1);
872  pipelineBarrier.imageMemoryBarriers[0].srcAccessMask = 0;
873  pipelineBarrier.imageMemoryBarriers[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
874  pipelineBarrier.imageMemoryBarriers[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
875  pipelineBarrier.imageMemoryBarriers[0].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
876  pipelineBarrier.imageMemoryBarriers[0].image = &vKBrdfLut->getImage();
877  pipelineBarrier.imageMemoryBarriers[0].subresourceRange.layerCount = 1;
878 
879  cmdBuffer.pipelineBarrier(pipelineBarrier);
880  }
881 
882  // Begin of the render pass
883  {
884  // All the pipelines have the same renderPass
885  const API::RenderPass* renderPass = brdfLutPipeline.getRenderPass();
886 
887  API::CommandBuffer::CmdBeginRenderPass beginRenderPass{
888  /* beginRenderPass.framebuffer */ framebuffer,
889  /* beginRenderPass.renderArea */ {},
890  /* beginRenderPass.clearValues */ {}
891  };
892 
893  beginRenderPass.renderArea.offset = {0, 0};
894  beginRenderPass.renderArea.extent = {brdfLutSize, brdfLutSize};
895 
896  beginRenderPass.clearValues.resize(2);
897  beginRenderPass.clearValues[0].color = {{0.0f, 0.0f, 0.0f, 1.0f}};
898  beginRenderPass.clearValues[1].depthStencil = {1.0f, 0};
899 
900  cmdBuffer.beginRenderPass(*renderPass, beginRenderPass);
901 
902  const VkViewport vkViewport{
903  /* vkViewport.x */ 0.0f,
904  /* vkViewport.y */ 0.0f,
905  /* vkViewport.width */ static_cast<float>(brdfLutSize),
906  /* vkViewport.height */ static_cast<float>(brdfLutSize),
907  /* vkViewport.minDepth */ 0.0f,
908  /* vkViewport.maxDepth */ 1.0f,
909  };
910 
911  const VkRect2D scissor{
912  /* scissor.offset */ {
913  0,
914  0
915  },
916  /* scissor.extent */ {
917  static_cast<uint32_t>(brdfLutSize),
918  static_cast<uint32_t>(brdfLutSize)
919  }
920  };
921 
922  cmdBuffer.setViewport({vkViewport});
923  cmdBuffer.setScissor({scissor});
924  }
925 
926  cmdBuffer.draw({
927  /* vertexCount */ 3,
928  /* instanceCount */ 1,
929  /* firstVertex */ 0,
930  /* firstInstance */ 0
931  });
932 
933  // End of the render pass
934  cmdBuffer.endRenderPass();
935 
936  // Change texture layout to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
937  {
938  API::CommandBuffer::CmdPipelineBarrier pipelineBarrier;
939  pipelineBarrier.imageMemoryBarriers.resize(1);
940  pipelineBarrier.imageMemoryBarriers[0].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
941  pipelineBarrier.imageMemoryBarriers[0].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
942  pipelineBarrier.imageMemoryBarriers[0].oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
943  pipelineBarrier.imageMemoryBarriers[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
944  pipelineBarrier.imageMemoryBarriers[0].image = &vKBrdfLut->getImage();
945  pipelineBarrier.imageMemoryBarriers[0].subresourceRange.layerCount = 1;
946 
947  cmdBuffer.pipelineBarrier(pipelineBarrier);
948  }
949 
950  if (!cmdBuffer.end()) {
951  return false;
952  }
953  }
954 
955  if (!graphicsQueue->submit(
956  cmdBuffer,
957  {},
958  {},
959  {},
960  static_cast<VkFence>(fence)
961  )) {
962  LUG_LOG.error("Skybox::initBrdfLut: Can't submit work to graphics queue: {}", result);
963  return false;
964  }
965 
966  if (!fence.wait() || !graphicsQueue->waitIdle()) {
967  LUG_LOG.error("Skybox::initBrdfLut:: Can't wait fence");
968  return false;
969  }
970 
971  cmdBuffer.destroy();
972  commandPool.destroy();
973  framebuffer.destroy();
974  fence.destroy();
975 
976  return true;
977 }
978 
979 Resource::SharedPtr<::lug::Graphics::Render::SkyBox> build(const ::lug::Graphics::Builder::SkyBox& builder) {
980  // Constructor of SkyBox is private, we can't use std::make_unique
981  std::unique_ptr<Resource> resource{new Vulkan::Render::SkyBox(builder._name)};
982  Vulkan::Render::SkyBox* skyBox = static_cast<Vulkan::Render::SkyBox*>(resource.get());
983 
984  Vulkan::Renderer& renderer = static_cast<Vulkan::Renderer&>(builder._renderer);
985 
986  // Load background image
987  if (builder._backgroundFilename.size())
988  {
989  lug::Graphics::Builder::Texture textureBuilder(builder._renderer);
990 
991  textureBuilder.setMagFilter(builder._magFilter);
992  textureBuilder.setMinFilter(builder._minFilter);
993  textureBuilder.setMipMapFilter(builder._mipMapFilter);
994  textureBuilder.setWrapS(builder._wrapS);
995  textureBuilder.setWrapT(builder._wrapT);
996 
997  if (!textureBuilder.addLayer(builder._backgroundFilename)) {
998  LUG_LOG.error("Resource::SharedPtr<::lug::Graphics::Render::SkyBox>::build Can't create skybox layers");
999  return nullptr;
1000  }
1001 
1002  skyBox->_backgroundTexture = textureBuilder.build();
1003  if (!skyBox->_backgroundTexture) {
1004  LUG_LOG.error("Resource::SharedPtr<::lug::Graphics::Render::SkyBox>::build Can't create skyBox texture");
1005  return nullptr;
1006  }
1007  }
1008 
1009  // Load environnement image
1010  if (builder._environnementFilename.size())
1011  {
1012  lug::Graphics::Builder::Texture textureBuilder(builder._renderer);
1013 
1014  textureBuilder.setMagFilter(builder._magFilter);
1015  textureBuilder.setMinFilter(builder._minFilter);
1016  textureBuilder.setMipMapFilter(builder._mipMapFilter);
1017  textureBuilder.setWrapS(builder._wrapS);
1018  textureBuilder.setWrapT(builder._wrapT);
1019 
1020  if (!textureBuilder.addLayer(builder._environnementFilename, true)) {
1021  LUG_LOG.error("Resource::SharedPtr<::lug::Graphics::Render::SkyBox>::build Can't create skybox layers");
1022  return nullptr;
1023  }
1024 
1025  skyBox->_environnementTexture = textureBuilder.build();
1026  if (!skyBox->_environnementTexture) {
1027  LUG_LOG.error("Resource::SharedPtr<::lug::Graphics::Render::SkyBox>::build Can't create skyBox texture");
1028  return nullptr;
1029  }
1030  }
1031 
1032  // Init the skyBox pipeline and mesh only one time
1034  if (Render::SkyBox::_skyBoxCount == 1) {
1040  !initMesh(renderer, Render::SkyBox::_mesh)) {
1041  LUG_LOG.error("Resource::SharedPtr<::lug::Graphics::Render::SkyBox>::build Can't init skybox pipeline/mesh resources");
1042  return nullptr;
1043  }
1044  }
1045 
1046  return builder._renderer.getResourceManager()->add<::lug::Graphics::Render::SkyBox>(std::move(resource));
1047 }
1048 
1049 } // SkyBox
1050 } // Builder
1051 } // Vulkan
1052 } // Graphics
1053 } // lug
Resource::SharedPtr< Render::Mesh > build()
Definition: Mesh.cpp:24
lug::Graphics::Resource::SharedPtr< lug::Graphics::Render::Texture > _environnementTexture
Definition: SkyBox.hpp:41
const API::Image & getImage() const
Definition: Texture.inl:5
PrimitiveSet * addPrimitiveSet()
Adds a primitive set to the builder and returns it.
Definition: Mesh.inl:21
lug::Graphics::Resource::SharedPtr< lug::Graphics::Render::Texture > _backgroundTexture
Definition: SkyBox.hpp:40
void setDescriptorSetLayouts(std::vector< API::DescriptorSetLayout > descriptorSetLayouts)
void setBindings(const std::vector< VkDescriptorSetLayoutBinding > &bindings)
static bool initMesh(Renderer &renderer, lug::Graphics::Resource::SharedPtr< lug::Graphics::Render::Mesh > &skyBoxMesh)
Definition: SkyBox.cpp:676
void setMinFilter(Render::Texture::Filter minFilter)
Definition: Texture.inl:17
void setName(const std::string &name)
Sets the name.
Definition: Mesh.inl:26
static lug::Graphics::Resource::SharedPtr< lug::Graphics::Render::Mesh > _mesh
Definition: SkyBox.hpp:58
void pipelineBarrier(const CmdPipelineBarrier &parameters, VkDependencyFlags dependencyFlags=VK_DEPENDENCY_BY_REGION_BIT, VkPipelineStageFlags srcStageMask=VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VkPipelineStageFlags dstStageMask=VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) const
const API::Queue * getQueue(const std::string &queueName) const
Definition: Device.cpp:70
bool submit(const CommandBuffer &commandBuffer, const std::vector< VkSemaphore > &signalSemaphores={}, const std::vector< VkSemaphore > &waitSemaphores={}, const std::vector< VkPipelineStageFlags > &waitDstStageMasks={}, VkFence fence=VK_NULL_HANDLE) const
Definition: Queue.cpp:32
void setWrapS(Render::Texture::WrappingMode wrapS)
Definition: Texture.inl:25
void addAttributeBuffer(const void *data, uint32_t elementSize, uint32_t elementsCount, Render::Mesh::PrimitiveSet::Attribute::Type type)
Definition: Mesh.cpp:11
void setLevel(VkCommandBufferLevel level)
static uint32_t _skyBoxCount
Store the number of skybox created to know when to create/destroy the pipeline and mesh...
Definition: SkyBox.hpp:66
static API::GraphicsPipeline _pipeline
Definition: SkyBox.hpp:54
AttachmentIndex addAttachment(const VkAttachmentDescription &attachmentDescription)
Definition: RenderPass.cpp:16
static bool initPrefilteredMapPipeline(Renderer &renderer, API::GraphicsPipeline &irradianceMapPipeline)
Definition: SkyBox.cpp:386
static bool initBrdfLutPipeline(Renderer &renderer, API::GraphicsPipeline &brdfLutPipeline)
Definition: SkyBox.cpp:555
static bool initIrradianceMapPipeline(Renderer &renderer, API::GraphicsPipeline &irradianceMapPipeline)
Definition: SkyBox.cpp:224
const API::Swapchain & getSwapchain() const
Definition: Window.inl:1
void setMagFilter(Render::Texture::Filter magFilter)
Definition: Texture.inl:13
const VkSurfaceFormatKHR & getFormat() const
Definition: Swapchain.inl:17
void beginRenderPass(const API::RenderPass &renderPass, const CmdBeginRenderPass &parameters, VkSubpassContents contents=VK_SUBPASS_CONTENTS_INLINE) const
bool addLayer(const std::string &filename, bool hdr=false)
Definition: Texture.cpp:98
static bool initBrdfLut(Renderer &renderer, API::GraphicsPipeline &brdfLutPipeline, lug::Graphics::Resource::SharedPtr< lug::Graphics::Render::Texture > &brdfLut)
Definition: SkyBox.cpp:775
const QueueFamily * getQueueFamily() const
Definition: Queue.cpp:86
void setWrapT(Render::Texture::WrappingMode wrapT)
Definition: Texture.inl:29
static API::GraphicsPipeline _prefilteredMapPipeline
Definition: SkyBox.hpp:56
static bool initSkyBoxPipeline(Renderer &renderer, API::GraphicsPipeline &skyBoxPipeline)
Definition: SkyBox.cpp:24
static VkFormat findSupportedFormat(const Device &device, const std::set< VkFormat > &formats, VkImageTiling tiling, VkFormatFeatureFlags features)
Definition: Image.cpp:82
Resource::SharedPtr< lug::Graphics::Render::SkyBox > build(const ::lug::Graphics::Builder::SkyBox &builder)
Definition: SkyBox.cpp:979
Render::Window * getRenderWindow() const
Definition: Renderer.inl:85
static SharedPtr< T > cast(const SharedPtr< RhsT > &rhs)
Dynamic casting of a SharedPtr to another one (RhsT to T)
const InitInfo & getInfo() const
Definition: Renderer.inl:1
void setMipMapFilter(Render::Texture::Filter mipMapFilter)
Definition: Texture.inl:21
#define LUG_LOG
Definition: Logger.hpp:73
void setMode(Render::Mesh::PrimitiveSet::Mode mode)
Definition: Mesh.inl:5
const API::ImageView & getImageView() const
Definition: Texture.inl:9
Resource::SharedPtr< Render::Texture > build()
Definition: Texture.cpp:37
static lug::Graphics::Resource::SharedPtr< lug::Graphics::Render::Texture > _brdfLut
Definition: SkyBox.hpp:59
bool begin(VkCommandBufferUsageFlags flags=VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) const
static API::GraphicsPipeline _irradianceMapPipeline
Definition: SkyBox.hpp:55
static API::GraphicsPipeline _brdfLutPipeline
Definition: SkyBox.hpp:57