Engine
Frameworkcreatedbymeusableforthecreationofsimplegames.CurrentlysupportsOpenGL(Verysimple)andVulkan.
VulkanMaterial.cpp
Go to the documentation of this file.
2 #ifdef USING_VULKAN
4 
5 namespace Engine {
6 
7  VkDescriptorSetLayout VulkanMaterial::CreateMaterialDescriptorSetLayout(VulkanLogicalDevice * device)
8  {
9  std::array<VkDescriptorSetLayoutBinding, 4> descriptorSetBindings;
10 
11  descriptorSetBindings[0] = {};
12  descriptorSetBindings[0].binding = 0;
13  descriptorSetBindings[0].descriptorCount = 1;
14  descriptorSetBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
15  descriptorSetBindings[0].pImmutableSamplers = nullptr;
16  descriptorSetBindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
17 
18  descriptorSetBindings[1] = {};
19  descriptorSetBindings[1].binding = 1;
20  descriptorSetBindings[1].descriptorCount = 1;
21  descriptorSetBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
22  descriptorSetBindings[1].pImmutableSamplers = nullptr;
23  descriptorSetBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
24 
25  descriptorSetBindings[2] = {};
26  descriptorSetBindings[2].binding = 2;
27  descriptorSetBindings[2].descriptorCount = 1;
28  descriptorSetBindings[2].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
29  descriptorSetBindings[2].pImmutableSamplers = nullptr;
30  descriptorSetBindings[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
31 
32  descriptorSetBindings[3] = {};
33  descriptorSetBindings[3].binding = 3;
34  descriptorSetBindings[3].descriptorCount = 1;
35  descriptorSetBindings[3].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
36  descriptorSetBindings[3].pImmutableSamplers = nullptr;
37  descriptorSetBindings[3].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
38 
39  VkDescriptorSetLayoutCreateInfo info = {};
40  info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
41  info.bindingCount = static_cast<uint32_t>(descriptorSetBindings.size());
42  info.pBindings = descriptorSetBindings.data();
43  info.flags = 0;
44 
45  VkDescriptorSetLayout layout;
46  vkCreateDescriptorSetLayout(device->GetDevice(), &info, nullptr, &layout);
47 
48  return layout;
49  }
50 
51  VulkanMaterial::VulkanMaterial(const aiScene* scene, uint32_t materialIndex, eastl::string modelName) :
52  Material(scene, materialIndex, modelName)
53  {
54  materialDataBuffer_ = eastl::unique_ptr<VulkanBuffer>(new VulkanBuffer(device_, allocator_,
55  static_cast<uint32_t>(sizeof(MaterialData_t)), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, true, commandPool_));
56 
58  }
59 
60  VulkanMaterial::~VulkanMaterial()
61  {
62  materialDataBuffer_.reset();
63  }
64 
65  VkDescriptorSet VulkanMaterial::CreateMaterialDescriptorSet(size_t threadID, size_t pipelineID, size_t set, VkDescriptorSetLayout layout)
66  {
67  if (materialDescriptorSets_.size() <= pipelineID) {
68  materialDescriptorSets_.resize(pipelineID + 1);
69  }
70  if (materialDescriptorSets_[pipelineID].size() <= set) {
71  materialDescriptorSets_[pipelineID].resize(set + 1);
72  }
73  if (materialDescriptorSets_[pipelineID][set].size() <= threadID) {
74  materialDescriptorSets_[pipelineID][set].resize(threadID + 1, VK_NULL_HANDLE);
75  }
76 
77 
78  VkDescriptorSetLayout layouts[] = { layout };
79  renderer_->GetDescriptorPool(threadID)->AllocateDescriptorSet(1, layouts, &materialDescriptorSets_[pipelineID][set][threadID]);
80  eastl::weak_ptr<VulkanTexture> missing = eastl::static_pointer_cast<VulkanTexture, Texture>(missingTexture.lock());
81  if (diffuseTexture.expired() == false) {
82  eastl::shared_ptr<VulkanTexture> diffuse = eastl::static_pointer_cast<VulkanTexture, Texture>(diffuseTexture.lock());
83  renderer_->GetDescriptorPool(threadID)->DescriptorSetBindToImage(materialDescriptorSets_[pipelineID][set][threadID], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
84  diffuse->GetImageView(),
85  diffuse->GetSampler(),
86  0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
87  }
88  else
89  renderer_->GetDescriptorPool(threadID)->DescriptorSetBindToImage(materialDescriptorSets_[pipelineID][set][threadID], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
90  missing.lock()->GetImageView(),
91  missing.lock()->GetSampler(),
92  0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
93 
94  if (specularTexture.expired() == false) {
95  eastl::shared_ptr<VulkanTexture> specular = eastl::static_pointer_cast<VulkanTexture, Texture>(specularTexture.lock());
96  renderer_->GetDescriptorPool(threadID)->DescriptorSetBindToImage(materialDescriptorSets_[pipelineID][set][threadID], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
97  specular->GetImageView(),
98  specular->GetSampler(),
99  1, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
100  }
101  else
102  renderer_->GetDescriptorPool(threadID)->DescriptorSetBindToImage(materialDescriptorSets_[pipelineID][set][threadID], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
103  missing.lock()->GetImageView(),
104  missing.lock()->GetSampler(),
105  1, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
106 
107  if (bumpMapTexture.expired() == false) {
108  eastl::shared_ptr<VulkanTexture> bumpMap = eastl::static_pointer_cast<VulkanTexture, Texture>(bumpMapTexture.lock());
109  renderer_->GetDescriptorPool(threadID)->DescriptorSetBindToImage(materialDescriptorSets_[pipelineID][set][threadID], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
110  bumpMap->GetImageView(),
111  bumpMap->GetSampler(),
112  2, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
113  }
114  else
115  renderer_->GetDescriptorPool(threadID)->DescriptorSetBindToImage(materialDescriptorSets_[pipelineID][set][threadID], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
116  missing.lock()->GetImageView(),
117  missing.lock()->GetSampler(),
118  2, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
119 
120  renderer_->GetDescriptorPool(threadID)->DescriptorSetBindToBuffer(materialDescriptorSets_[pipelineID][set][threadID], materialDataBuffer_->GetBuffer(),
121  0, static_cast<VkDeviceSize>(sizeof(MaterialData_t)), 3, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
122 
123  return materialDescriptorSets_[pipelineID][set][threadID];
124  }
125 
126  VkDescriptorSet VulkanMaterial::GetMaterialDescriptorSet(size_t threadID, size_t pipelineID, size_t set)
127  {
128  if (pipelineID >= materialDescriptorSets_.size())
129  return VK_NULL_HANDLE;
130  if (set >= materialDescriptorSets_[pipelineID].size())
131  return VK_NULL_HANDLE;
132  if (threadID >= materialDescriptorSets_[pipelineID][set].size())
133  return VK_NULL_HANDLE;
134  return materialDescriptorSets_[pipelineID][set][threadID];
135  }
136 
137  void VulkanMaterial::SetDiffuseTexture(eastl::shared_ptr<Texture> diffuseTexture)
138  {
139  Material::SetDiffuseTexture(diffuseTexture);
140 
141  for (size_t i = 0, size = materialDescriptorSets_.size(); i < size; ++i) {
142  for (size_t j = 0, size2 = materialDescriptorSets_[i].size(); j < size2; ++j) {
143  for (size_t k = 0, size3 = materialDescriptorSets_[i][j].size(); k < size3; ++k) {
144  if (materialDescriptorSets_[i][j][k] != VK_NULL_HANDLE) {
145  if (diffuseTexture != nullptr) {
146  eastl::shared_ptr<VulkanTexture> diffuse = eastl::static_pointer_cast<VulkanTexture, Texture>(diffuseTexture);
147  descriptorPool_->DescriptorSetBindToImage(materialDescriptorSets_[i][j][k], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
148  diffuse->GetImageView(),
149  diffuse->GetSampler(),
150  0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
151  }
152  else {
153  eastl::shared_ptr<VulkanTexture> missing = eastl::static_pointer_cast<VulkanTexture, Texture>(missingTexture.lock());
154  descriptorPool_->DescriptorSetBindToImage(materialDescriptorSets_[i][j][k], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
155  missing->GetImageView(),
156  missing->GetSampler(),
157  0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
158  }
159  }
160  }
161  }
162  }
163  }
164 
165  void VulkanMaterial::SetBumpMapTexture(eastl::shared_ptr<Texture> bumpMapTexture)
166  {
167  Material::SetBumpMapTexture(bumpMapTexture);
168 
169  for (size_t i = 0, size = materialDescriptorSets_.size(); i < size; ++i) {
170  for (size_t j = 0, size2 = materialDescriptorSets_[i].size(); j < size2; ++j) {
171  for (size_t k = 0, size3 = materialDescriptorSets_[i][j].size(); k < size3; ++k) {
172  if (materialDescriptorSets_[i][j][k] != VK_NULL_HANDLE) {
173  if (bumpMapTexture != nullptr) {
174  eastl::shared_ptr<VulkanTexture> bumpMap = eastl::static_pointer_cast<VulkanTexture, Texture>(bumpMapTexture);
175  descriptorPool_->DescriptorSetBindToImage(materialDescriptorSets_[i][j][k], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
176  bumpMap->GetImageView(),
177  bumpMap->GetSampler(),
178  2, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
179  }
180  else {
181  eastl::shared_ptr<VulkanTexture> missing = eastl::static_pointer_cast<VulkanTexture, Texture>(missingTexture.lock());
182  descriptorPool_->DescriptorSetBindToImage(materialDescriptorSets_[i][j][k], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
183  missing->GetImageView(),
184  missing->GetSampler(),
185  2, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
186  }
187  }
188  }
189  }
190  }
191  }
192 
193  void VulkanMaterial::SetSpecularTexture(eastl::shared_ptr<Texture> specularTexture)
194  {
195  Material::SetSpecularTexture(specularTexture);
196 
197  for (size_t i = 0, size = materialDescriptorSets_.size(); i < size; ++i) {
198  for (size_t j = 0, size2 = materialDescriptorSets_[i].size(); j < size2; ++j) {
199  for (size_t k = 0, size3 = materialDescriptorSets_[i][j].size(); k < size3; ++k) {
200  if (materialDescriptorSets_[i][j][k] != VK_NULL_HANDLE) {
201  if (diffuseTexture.expired() == false) {
202  eastl::shared_ptr<VulkanTexture> specular = eastl::static_pointer_cast<VulkanTexture, Texture>(specularTexture);
203  descriptorPool_->DescriptorSetBindToImage(materialDescriptorSets_[i][j][k], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
204  specular->GetImageView(),
205  specular->GetSampler(),
206  1, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
207  }
208  else {
209  eastl::shared_ptr<VulkanTexture> missing = eastl::static_pointer_cast<VulkanTexture, Texture>(missingTexture.lock());
210  descriptorPool_->DescriptorSetBindToImage(materialDescriptorSets_[i][j][k], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
211  missing->GetImageView(),
212  missing->GetSampler(),
213  1, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
214  }
215  }
216  }
217  }
218  }
219  }
220 
221  void VulkanMaterial::UpdateMaterialData()
222  {
223  if (materialDataBuffer_ != nullptr)
224  materialDataBuffer_->UpdateBuffer(&materialData_, 0, static_cast<uint32_t>(sizeof(MaterialData_t)));
225  }
226 
227  VulkanRenderer* VulkanMaterial::renderer_ = nullptr;
228  VulkanLogicalDevice* VulkanMaterial::device_ = nullptr;
229  VulkanDescriptorPool* VulkanMaterial::descriptorPool_ = nullptr;
230  VkCommandPool VulkanMaterial::commandPool_ = VK_NULL_HANDLE;
231  VmaAllocator VulkanMaterial::allocator_ = VK_NULL_HANDLE;
232 
233  void VulkanMaterial::InitMaterialData(VulkanRenderer * renderer, VulkanLogicalDevice * device, VulkanDescriptorPool * descriptorPool, VmaAllocator allocator)
234  {
235  VulkanMaterial::renderer_ = renderer;
236  VulkanMaterial::device_ = device;
237  VulkanMaterial::descriptorPool_ = descriptorPool;
238  VulkanMaterial::commandPool_ = renderer->GetGraphicsCommandPool();
239  VulkanMaterial::allocator_ = allocator;
240  }
241 
242 } // namespace Engine
243 #endif // USING_VULKAN
MaterialData_t materialData_
Definition: Material.hpp:223
virtual void SetDiffuseTexture(eastl::string diffuseTextureName)
Changes the diffuse texture of the material. NOTE: Texture will be loaded in, if it doesn&#39;t excist ye...
Definition: Material.cpp:83
eastl::weak_ptr< Texture > missingTexture
Definition: Material.hpp:235
virtual void SetSpecularTexture(eastl::shared_ptr< Texture > specularTexture)
Changes the specular texture of the material. Pass a nullptr to clear the current texture...
Definition: Material.cpp:185
struct Engine::Material::MaterialData MaterialData_t
eastl::weak_ptr< Texture > diffuseTexture
Definition: Material.hpp:228
eastl::weak_ptr< Texture > bumpMapTexture
Definition: Material.hpp:230
virtual void UpdateMaterialData()
Definition: Material.cpp:293
virtual void SetBumpMapTexture(eastl::string bumpMapTextureName)
Changes the bump map texture of the material. NOTE: Texture will be loaded in, if it doesn&#39;t excist y...
Definition: Material.cpp:134
eastl::weak_ptr< Texture > specularTexture
Definition: Material.hpp:232