Skip to content

Commit 962e6a5

Browse files
committed
feat(asset): add material pool to bind multiple textures to different models independently
1 parent 964c1f0 commit 962e6a5

File tree

14 files changed

+216
-75
lines changed

14 files changed

+216
-75
lines changed

Examples/Sofa/Main.cpp

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,54 @@ class MainApp final : public fra::AbstractApplication
77
AbstractApplication(serviceProvider)
88
{
99

10-
mMeshPool = serviceProvider->GetService<fra::MeshPool>();
11-
mTexturePool = serviceProvider->GetService<fra::TexturePool>();
10+
mMeshPool = serviceProvider->GetService<fra::MeshPool>();
11+
mTexturePool = serviceProvider->GetService<fra::TexturePool>();
12+
mMaterialPool = serviceProvider->GetService<fra::MaterialPool>();
1213
}
1314

1415
void StartUp() override
1516
{
1617
mRenderer->ClearProjections();
1718

18-
mModelMatrix[0] = glm::translate(
19-
glm::scale(glm::mat4(1), glm::vec3(3)), glm::vec3(-1, 0, 0));
19+
mModelMatrix[0] = glm::scale(
20+
glm::translate(glm::mat4(1), glm::vec3(-3, 2, 0)), glm::vec3(0.3));
2021

21-
mModelMatrix[1] = glm::translate(
22-
glm::scale(glm::mat4(1), glm::vec3(3)), glm::vec3(1, 0, 0));
22+
mModelMatrix[1] = glm::scale(
23+
glm::translate(glm::mat4(1), glm::vec3(3, 2, 0)), glm::vec3(0.3));
2324

24-
mTextureA = mTexturePool->CreateTextureFromFile(
25+
mModelMatrix[2] = glm::scale(
26+
glm::translate(glm::mat4(1), glm::vec3(-3, -2, 0)), glm::vec3(2));
27+
28+
mModelMatrix[3] = glm::scale(
29+
glm::translate(glm::mat4(1), glm::vec3(3, -2, 0)), glm::vec3(2));
30+
31+
mSofaAlbedo = mTexturePool->CreateTextureFromFile(
2532
"./Resources/Textures/OfficeSofa_BaseColor.png");
26-
mTextureB = mTexturePool->CreateTextureFromFile(
33+
mSofaNormal = mTexturePool->CreateTextureFromFile(
2734
"./Resources/Textures/OfficeSofa_Normal.png");
28-
mTextureC = mTexturePool->CreateTextureFromFile(
35+
mSofaRoughness = mTexturePool->CreateTextureFromFile(
2936
"./Resources/Textures/OfficeSofa_Roughness.png");
30-
mModelA =
37+
38+
mSofaMaterial =
39+
mMaterialPool->Create({ mSofaAlbedo, mSofaNormal, mSofaRoughness });
40+
41+
mSofaModel =
3142
mMeshPool->CreateMeshFromFile("./Resources/Models/OfficeSofa.fbx");
43+
44+
mSpaceShipAlbedo = mTexturePool->CreateTextureFromFile(
45+
"./Resources/Textures/SpaceShip_Base_color.jpg");
46+
47+
mSpaceShipNormal = mTexturePool->CreateTextureFromFile(
48+
"./Resources/Textures/SpaceShip_Normal.jpg");
49+
50+
mSpaceShipRoughness = mTexturePool->CreateTextureFromFile(
51+
"./Resources/Textures/SpaceShip_Roughness.jpg");
52+
53+
mSpaceShipMaterial = mMaterialPool->Create(
54+
{ mSpaceShipAlbedo, mSpaceShipNormal, mSpaceShipRoughness });
55+
56+
mSpaceShipModel =
57+
mMeshPool->CreateMeshFromFile("./Resources/Models/SpaceShip.fbx");
3258
}
3359

3460
void Update() override
@@ -42,46 +68,64 @@ class MainApp final : public fra::AbstractApplication
4268
mModelMatrix[1], glm::radians(15.0f * mWindow->GetDeltaTime()),
4369
glm::normalize(glm::vec3(0.0, 1.0, 0.0)));
4470

71+
mModelMatrix[2] = glm::rotate(
72+
mModelMatrix[2], glm::radians(15.0f * mWindow->GetDeltaTime()),
73+
glm::normalize(glm::vec3(0.0, 1.0, 0.0)));
74+
75+
mModelMatrix[3] = glm::rotate(
76+
mModelMatrix[3], glm::radians(15.0f * mWindow->GetDeltaTime()),
77+
glm::normalize(glm::vec3(0.0, 1.0, 0.0)));
78+
4579
mRenderer->BeginFrame();
4680

4781
if (mInstanceMatrixBuffers == nullptr)
4882
mInstanceMatrixBuffers =
4983
mRenderer->GetBufferBuilder()
5084
.SetData(&mModelMatrix[0][0])
51-
.SetSize(sizeof(glm::mat4) * 2)
85+
.SetSize(sizeof(glm::mat4) * 4)
5286
.SetUsage(fra::BufferUsage::Instance)
5387
.Build();
5488
else
5589
mInstanceMatrixBuffers->Copy(
56-
&mModelMatrix[0][0], sizeof(glm::mat4) * 2);
90+
&mModelMatrix[0][0], sizeof(glm::mat4) * 4);
5791

5892
mRenderer->BindBuffer(mInstanceMatrixBuffers);
5993

60-
for (const auto& mesh : mModelA)
94+
mMaterialPool->Bind(mSpaceShipMaterial);
95+
96+
for (const auto& mesh : mSpaceShipModel)
6197
{
62-
mTexturePool->Bind(mTextureA, 0);
63-
mTexturePool->Bind(mTextureB, 1);
64-
mTexturePool->Bind(mTextureC, 2);
98+
mMeshPool->DrawInstanced(mesh, 2);
99+
}
65100

66-
mMeshPool->DrawInstanced(mesh, 1);
67-
mMeshPool->DrawInstanced(mesh, 1, 1);
101+
mMaterialPool->Bind(mSofaMaterial);
102+
103+
for (const auto& mesh : mSofaModel)
104+
{
105+
mMeshPool->DrawInstanced(mesh, 2, 2);
68106
}
69107

70108
mRenderer->EndFrame();
71109
}
72110

73111
private:
74-
std::vector<unsigned> mModelA;
75-
std::uint32_t mTextureA {};
76-
77-
std::vector<unsigned> mModelB;
78-
std::uint32_t mTextureB {};
79-
std::uint32_t mTextureC {};
80-
81-
Ref<fra::TexturePool> mTexturePool;
82-
Ref<fra::MeshPool> mMeshPool;
83-
glm::mat4 mModelMatrix[2] {};
84-
float mCurrentTime {};
112+
std::vector<unsigned> mSofaModel;
113+
std::uint32_t mSofaAlbedo {};
114+
std::uint32_t mSofaNormal {};
115+
std::uint32_t mSofaRoughness {};
116+
std::uint32_t mSofaMaterial {};
117+
118+
std::vector<unsigned> mSpaceShipModel;
119+
std::uint32_t mSpaceShipAlbedo {};
120+
std::uint32_t mSpaceShipNormal {};
121+
std::uint32_t mSpaceShipRoughness {};
122+
std::uint32_t mSpaceShipMaterial {};
123+
124+
Ref<fra::MaterialPool> mMaterialPool;
125+
Ref<fra::TexturePool> mTexturePool;
126+
Ref<fra::MeshPool> mMeshPool;
127+
glm::mat4 mModelMatrix[4] {};
128+
float mCurrentTime {};
85129

86130
Ref<fra::Buffer> mInstanceMatrixBuffers;
87131
};
15.7 KB
Binary file not shown.
1.17 MB
Binary file not shown.
2.46 MB
Loading
2.89 MB
Loading
1.31 MB
Loading

src/Freya/Asset/Material.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
namespace FREYA_NAMESPACE
4+
{
5+
struct Material
6+
{
7+
operator std::uint32_t() const { return id; }
8+
9+
std::vector<vk::DescriptorSet> descriptorSets;
10+
std::uint32_t id;
11+
};
12+
13+
} // namespace FREYA_NAMESPACE

src/Freya/Asset/MaterialPool.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include "MaterialPool.hpp"
2+
3+
namespace FREYA_NAMESPACE
4+
{
5+
std::uint32_t MaterialPool::CreateFromTextureFiles(
6+
std::vector<std::string> texturesPath)
7+
{
8+
return 0;
9+
}
10+
11+
std::uint32_t MaterialPool::Create(std::vector<std::uint32_t> textures)
12+
{
13+
auto material = Material {
14+
.id = static_cast<std::uint32_t>(mMaterials.size()),
15+
};
16+
17+
const auto samplerDescriptorSetAllocInfo =
18+
vk::DescriptorSetAllocateInfo()
19+
.setSetLayouts(mRenderPass->GetSamplerLayout())
20+
.setDescriptorPool(mRenderPass->GetSamplerDescriptorPool());
21+
22+
material.descriptorSets =
23+
std::move(mDevice->Get().allocateDescriptorSets(
24+
samplerDescriptorSetAllocInfo));
25+
26+
for (size_t binding = 0; binding < textures.size(); binding++)
27+
{
28+
auto& texture = mTexturePool->GetTexture(textures[binding]);
29+
30+
auto descriptorImageInfo =
31+
vk::DescriptorImageInfo()
32+
.setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal)
33+
.setSampler(texture.sampler)
34+
.setImageView(texture.image->GetImageView());
35+
36+
auto samplerDescriptorWriter =
37+
vk::WriteDescriptorSet()
38+
.setDstSet(material.descriptorSets[0])
39+
.setDstBinding(binding)
40+
.setDstArrayElement(0)
41+
.setDescriptorType(
42+
vk::DescriptorType::eCombinedImageSampler)
43+
.setDescriptorCount(1)
44+
.setImageInfo(descriptorImageInfo);
45+
46+
mDevice->Get()
47+
.updateDescriptorSets(1, &samplerDescriptorWriter, 0, nullptr);
48+
}
49+
50+
mMaterials.insert(material);
51+
52+
return material.id;
53+
}
54+
55+
void MaterialPool::Bind(std::uint32_t materialId)
56+
{
57+
if (!mMaterials.contains(materialId))
58+
return;
59+
60+
const auto& material = mMaterials[materialId];
61+
62+
mCommandPool->GetCommandBuffer().bindDescriptorSets(
63+
vk::PipelineBindPoint::eGraphics,
64+
mRenderPass->GetPipelineLayout(),
65+
1,
66+
material.descriptorSets,
67+
nullptr);
68+
}
69+
} // namespace FREYA_NAMESPACE

src/Freya/Asset/MaterialPool.hpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
#include "Freya/Asset/Material.hpp"
4+
#include "Freya/Asset/TexturePool.hpp"
5+
#include "Freya/Containers/SparseSet.hpp"
6+
#include "Freya/Core/CommandPool.hpp"
7+
#include "Freya/Core/Device.hpp"
8+
#include "Freya/Core/ForwardPass.hpp"
9+
10+
namespace FREYA_NAMESPACE
11+
{
12+
class MaterialPool
13+
{
14+
using MaterialSet = SparseSet<Material>;
15+
16+
public:
17+
MaterialPool(const Ref<Device>& device,
18+
const Ref<CommandPool>& commandPool,
19+
const Ref<ForwardPass>& renderPass,
20+
const Ref<TexturePool>& texturePool,
21+
const Ref<skr::Logger<MaterialPool>>& logger) :
22+
mDevice(device), mCommandPool(commandPool), mRenderPass(renderPass),
23+
mTexturePool(texturePool), mLogger(logger), mMaterials(4096) {};
24+
25+
~MaterialPool() = default;
26+
27+
std::uint32_t CreateFromTextureFiles(
28+
std::vector<std::string> texturesPath);
29+
30+
std::uint32_t Create(std::vector<std::uint32_t> textures);
31+
32+
void Bind(std::uint32_t materialId);
33+
34+
private:
35+
Ref<Device> mDevice;
36+
Ref<CommandPool> mCommandPool;
37+
Ref<ForwardPass> mRenderPass;
38+
Ref<TexturePool> mTexturePool;
39+
Ref<skr::Logger<MaterialPool>> mLogger;
40+
41+
MaterialSet mMaterials;
42+
};
43+
44+
} // namespace FREYA_NAMESPACE

src/Freya/Asset/TexturePool.cpp

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -103,41 +103,6 @@ namespace FREYA_NAMESPACE
103103
return texture.id;
104104
}
105105

106-
void TexturePool::Bind(const std::uint32_t uint32, int binding)
107-
{
108-
if (!mTextures.contains(uint32))
109-
return;
110-
111-
const auto& texture = mTextures[uint32];
112-
113-
auto descriptorImageInfo =
114-
vk::DescriptorImageInfo()
115-
.setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal)
116-
.setSampler(texture.sampler)
117-
.setImageView(texture.image->GetImageView());
118-
119-
auto samplerDescriptorWriter =
120-
vk::WriteDescriptorSet()
121-
.setDstSet(mTextureDescriptorSet)
122-
.setDstBinding(binding)
123-
.setDstArrayElement(0)
124-
.setDescriptorType(vk::DescriptorType::eCombinedImageSampler)
125-
.setDescriptorCount(1)
126-
.setImageInfo(descriptorImageInfo);
127-
128-
mDevice->Get()
129-
.updateDescriptorSets(1, &samplerDescriptorWriter, 0, nullptr);
130-
131-
const auto descriptorSets = std::array { mTextureDescriptorSet };
132-
133-
mCommandPool->GetCommandBuffer().bindDescriptorSets(
134-
vk::PipelineBindPoint::eGraphics,
135-
mRenderPass->GetPipelineLayout(),
136-
1,
137-
descriptorSets,
138-
nullptr);
139-
}
140-
141106
Ref<Buffer> TexturePool::queryStagingBuffer(std::uint32_t size)
142107
{
143108
for (auto stagingBuffer : mStagingBuffers)

0 commit comments

Comments
 (0)