~sircmpwn/xrgears

ref: 7c503767ced2ca3450233e4447bbf057aaac6f79 xrgears/vitamin-k/scene/vikSkyBox.hpp -rw-r--r-- 4.3 KiB
7c503767 — Lubosz Sarnecki xrgears: Use struct initializers. 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * vitamin-k
 *
 * Copyright 2016 Sascha Willems - www.saschawillems.de
 * Copyright 2017-2018 Collabora Ltd.
 *
 * Authors: Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
 * SPDX-License-Identifier: MIT
 */

#pragma once

#include <vector>
#include <string>

#include "../render/vikTexture.hpp"
#include "../render/vikModel.hpp"

#include "../system/vikAssets.hpp"
#include "../render/vikShader.hpp"

namespace vik {
class SkyBox {
 private:
  TextureCubeMap cube_map;
  VkDescriptorSet descriptor_set;
  VkDevice device;
  VkDescriptorImageInfo texture_descriptor;
  Model model;
  VkPipeline pipeline;

 public:
  explicit SkyBox(VkDevice device) : device(device) {}

  ~SkyBox() {
    cube_map.destroy();
    model.destroy();
    vkDestroyPipeline(device, pipeline, nullptr);
  }

  void init_texture_descriptor() {
    // Image descriptor for the cube map texture
    texture_descriptor =
        initializers::descriptorImageInfo(
          cube_map.sampler,
          cube_map.view,
          cube_map.imageLayout);
  }

  VkWriteDescriptorSet
  get_cube_map_write_descriptor_set(unsigned binding, VkDescriptorSet ds) {
    return initializers::writeDescriptorSet(
          ds,
          VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
          binding,
          &texture_descriptor);
  }

  void load_assets(VertexLayout vertexLayout, Device *vik_device, VkQueue queue,
                   const std::string& file_name, VkFormat format) {
    model.loadFromFile(vik::Assets::get_asset_path() + "models/cube.obj",
                       vertexLayout, 10.0f, vik_device, queue);
    cube_map.loadFromFile(file_name, format, vik_device, queue);
    init_texture_descriptor();
  }

  void create_descriptor_set(const VkDescriptorSetAllocateInfo& allocInfo,
                             VkDescriptorBufferInfo* cameraDescriptor) {
    vik_log_check(vkAllocateDescriptorSets(device, &allocInfo, &descriptor_set));

    std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
      initializers::writeDescriptorSet(
      descriptor_set,
      VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
      2,
      cameraDescriptor)
    };

    writeDescriptorSets.push_back(get_cube_map_write_descriptor_set(3, descriptor_set));

    vkUpdateDescriptorSets(device,
                           static_cast<uint32_t>(writeDescriptorSets.size()),
                           writeDescriptorSets.data(),
                           0,
                           nullptr);
  }

  void draw(VkCommandBuffer cmdbuffer, VkPipelineLayout pipelineLayout) {
    VkDeviceSize offsets[1] = { 0 };

    vkCmdBindDescriptorSets(cmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
                            pipelineLayout, 0, 1, &descriptor_set, 0, nullptr);
    vkCmdBindVertexBuffers(cmdbuffer, 0, 1, &model.vertices.buffer, offsets);
    vkCmdBindIndexBuffer(cmdbuffer, model.indices.buffer, 0, VK_INDEX_TYPE_UINT32);

    vkCmdBindPipeline(cmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);

    vkCmdDrawIndexed(cmdbuffer, model.indexCount, 1, 0, 0, 0);
  }

  void init_pipeline(VkGraphicsPipelineCreateInfo* pipeline_info,
                     const VkPipelineCache& pipeline_cache) {
    VkPipelineRasterizationStateCreateInfo rasterization_state =
        initializers::pipelineRasterizationStateCreateInfo(
          VK_POLYGON_MODE_FILL,
          VK_CULL_MODE_BACK_BIT,
          VK_FRONT_FACE_COUNTER_CLOCKWISE,
          0);

    // Skybox pipeline (background cube)
    std::array<VkPipelineShaderStageCreateInfo, 3> shader_stages;

    shader_stages[0] = vik::Shader::load(device, "xrgears/sky.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
    shader_stages[1] = vik::Shader::load(device, "xrgears/sky.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
    shader_stages[2] = vik::Shader::load(device, "xrgears/sky.geom.spv", VK_SHADER_STAGE_GEOMETRY_BIT);

    pipeline_info->stageCount = shader_stages.size();
    pipeline_info->pStages = shader_stages.data();
    pipeline_info->pRasterizationState = &rasterization_state;

    vik_log_check(vkCreateGraphicsPipelines(device, pipeline_cache, 1,
                                            pipeline_info, nullptr, &pipeline));

    vkDestroyShaderModule(device, shader_stages[0].module, nullptr);
    vkDestroyShaderModule(device, shader_stages[1].module, nullptr);
    vkDestroyShaderModule(device, shader_stages[2].module, nullptr);
  }
};
}  // namespace vik