-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMaterialFactory.cpp
153 lines (134 loc) · 4.51 KB
/
MaterialFactory.cpp
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "D3D12FrameWork/MaterialFactory.h"
#include "D3D12FrameWork/RPBufferController.h"
#include "D3D12FrameWork/RPBufferView.h"
#include <algorithm>
#include <stdexcept>
#include "D3D12FrameWork/CommandList.h"
#include "D3D12FrameWork/D3DDevice.h"
namespace D3D12FrameWork{
MaterialFactory* MaterialFactory::m_instance = nullptr;
bool
MaterialFactory::CreateMaterial(
std::string_view _matName,//作るマテリアルの名前
class IPipelineStateObject* _pso,//対象となるpso
UINT _rpIdx,//そのpsoの何番目のrpのマテリアルを作るのか
bool isDefault,//マテリアルセット作成時に値が指定されていない場合はこのマテリアルをデフォルトとするのか
uint32_t _bufferCount
) {
auto const& rprDesc = _pso->GetRPRegisterDesc(_rpIdx);
auto const& rsRpDesc = _pso->GetRootSignature()->GetRootParamDescs();
auto tmpRPB = std::make_unique<RootParameterBuffer>();
if (!tmpRPB->Init(rprDesc, rsRpDesc[_rpIdx], m_pRefDev, _bufferCount)) {
assert(false);
return false;
}
auto pso_name = _pso->GetName();
auto mat_name = std::string(_matName.data());
auto& rpBMap = m_psoRpBuffMap[pso_name.data()].RPBuffs;
if (rpBMap.count(mat_name)) {//重複を防ぐ
assert(false);
return false;
}
rpBMap[mat_name].reset(tmpRPB.release());
if (isDefault) {
_pso->SetDefaultMaterial(_matName, _rpIdx);
}
return true;
}
unqPtr<MaterialSet>
MaterialFactory::CreateMaterialSet(
MaterialSetDescriptor const& _matSetDesc,
IPipelineStateObject const* _pso,
uint32_t _lambdaBufferCount
) {
auto ret = std::make_unique<MaterialSet>();
ret->m_indicesNum = _matSetDesc.NumIndices;
auto rpNum = _pso->GetRootSignature()->GetRootParamDescs().size();
ret->m_materialControllers.clear();
ret->m_materialControllers.reserve(rpNum);
for (uint32_t i = 0; i < rpNum; i++) {
//rp番号のdescriptorを探す.
auto matDesc = std::find_if(_matSetDesc.MaterialDescs.begin(),
_matSetDesc.MaterialDescs.end(),
[i](MaterialDescriptor const& mdesc) {
return mdesc.RPIdx == i;
});
std::string_view matName = {};
if (matDesc == _matSetDesc.MaterialDescs.end()) {//マテリアルが指定されていないのでデフォルト値
matName = _pso->GetDefaultMaterialName(i);
}
else {//指定された名前
matName = matDesc->MaterialName;
}
RootParameterBuffer* matBuffer = nullptr;
if (matName.empty()) {
//無名バッファを作る。
ret->m_plambdaBuff.emplace_back(std::move(
std::make_unique<RootParameterBuffer>()
));
auto const& rprDesc = _pso->GetRPRegisterDesc(i);
auto const& rsRpDesc = _pso->GetRootSignature()->GetRootParamDescs();
matBuffer = ret->m_plambdaBuff.back().get();
if (!matBuffer->Init(rprDesc, rsRpDesc[i], m_pRefDev, _lambdaBufferCount)) {
assert(false);
return nullptr;
}
}
else {
auto psoName = _pso->GetName();
if (!m_psoRpBuffMap.count(psoName.data())) {
throw std::runtime_error("指定されたpsoで使用されるマテリアルは一つも登録されていません.");
//そのpsoのマテリアルは一つもない.
}
auto& rpBMap = m_psoRpBuffMap[psoName.data()].RPBuffs;
if (!rpBMap.count(matName.data())) {
//未作成のマテリアル
throw std::runtime_error("未作成のマテリアル");
}
matBuffer = rpBMap[matName.data()].get();
}
ret->m_materialControllers.emplace_back(
RPBufferController(
*matBuffer, m_pRefDev)
);
ret->m_materialViews.emplace_back(
RPBufferView(
*matBuffer
)
);
}
return ret;
}
RPBufferController
MaterialFactory::GetController(std::string_view _psoName, std::string_view _matName) {
if (!m_psoRpBuffMap.count(_psoName.data())) {
throw std::runtime_error("指定されたpsoで使用されるマテリアルは一つも登録されていません.");
//そのpsoのマテリアルは一つもない.
}
auto& rpBMap = m_psoRpBuffMap[_psoName.data()].RPBuffs;
if (!rpBMap.count(_matName.data())) {
//未作成のマテリアル
throw std::runtime_error("未作成のマテリアル");
}
auto matBuffer = rpBMap[_matName.data()].get();
return RPBufferController(
*matBuffer, m_pRefDev
);
}
RPBufferView
MaterialFactory::GetView(std::string_view _psoName, std::string_view _matName) {
if (!m_psoRpBuffMap.count(_psoName.data())) {
throw std::runtime_error("指定されたpsoで使用されるマテリアルは一つも登録されていません.");
//そのpsoのマテリアルは一つもない.
}
auto& rpBMap = m_psoRpBuffMap[_psoName.data()].RPBuffs;
if (!rpBMap.count(_matName.data())) {
//未作成のマテリアル
throw std::runtime_error("未作成のマテリアル");
}
auto matBuffer = rpBMap[_matName.data()].get();
return RPBufferView(
*matBuffer
);
}
}