1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "Material/BsMaterialParam.h"
4#include "Math/BsVector2I.h"
5#include "Material/BsMaterialParams.h"
6#include "Material/BsMaterial.h"
7#include "Image/BsColorGradient.h"
8
9namespace bs
10{
11 template<int DATA_TYPE, bool Core>
12 TMaterialDataCommon<DATA_TYPE, Core>::TMaterialDataCommon(const String& name, const MaterialPtrType& material)
13 :mParamIndex(0), mArraySize(0), mMaterial(nullptr)
14 {
15 if(material != nullptr)
16 {
17 SPtr<MaterialParamsType> params = material->_getInternalParams();
18
19 UINT32 paramIndex;
20 auto result = params->getParamIndex(name, MaterialParams::ParamType::Data, (GpuParamDataType)DATA_TYPE, 0,
21 paramIndex);
22
23 if (result == MaterialParams::GetParamResult::Success)
24 {
25 const MaterialParams::ParamData* data = params->getParamData(paramIndex);
26
27 mMaterial = material;
28 mParamIndex = paramIndex;
29 mArraySize = data->arraySize;
30 }
31 else
32 params->reportGetParamError(result, name, 0);
33 }
34 }
35
36 template<class T, bool Core>
37 void TMaterialDataParam<T, Core>::set(const T& value, UINT32 arrayIdx) const
38 {
39 if (this->mMaterial == nullptr)
40 return;
41
42 if(arrayIdx >= this->mArraySize)
43 {
44 LOGWRN("Array index out of range. Provided index was " + toString(arrayIdx) +
45 " but array length is " + toString(this->mArraySize));
46 return;
47 }
48
49 SPtr<typename Base::MaterialParamsType> params = this->mMaterial->_getInternalParams();
50 const MaterialParams::ParamData* data = params->getParamData(this->mParamIndex);
51
52 params->setDataParam(*data, arrayIdx, value);
53 this->mMaterial->_markCoreDirty();
54 }
55
56 template<class T, bool Core>
57 T TMaterialDataParam<T, Core>::get(UINT32 arrayIdx) const
58 {
59 T output{};
60 if (this->mMaterial == nullptr || arrayIdx >= this->mArraySize)
61 return output;
62
63 SPtr<typename Base::MaterialParamsType> params = this->mMaterial->_getInternalParams();
64 const MaterialParams::ParamData* data = params->getParamData(this->mParamIndex);
65
66 params->getDataParam(*data, arrayIdx, output);
67 return output;
68 }
69
70 template<class T, bool Core>
71 void TMaterialCurveParam<T, Core>::set(TAnimationCurve<T> value, UINT32 arrayIdx) const
72 {
73 if (this->mMaterial == nullptr)
74 return;
75
76 if(arrayIdx >= this->mArraySize)
77 {
78 LOGWRN("Array index out of range. Provided index was " + toString(arrayIdx) +
79 " but array length is " + toString(this->mArraySize));
80 return;
81 }
82
83 SPtr<typename Base::MaterialParamsType> params = this->mMaterial->_getInternalParams();
84 const MaterialParams::ParamData* data = params->getParamData(this->mParamIndex);
85
86 params->setCurveParam(*data, arrayIdx, std::move(value));
87 this->mMaterial->_markCoreDirty();
88 }
89
90 template<class T, bool Core>
91 const TAnimationCurve<T>& TMaterialCurveParam<T, Core>::get(UINT32 arrayIdx) const
92 {
93 static TAnimationCurve<T> EMPTY_CURVE;
94
95 if (this->mMaterial == nullptr || arrayIdx >= this->mArraySize)
96 return EMPTY_CURVE;
97
98 SPtr<typename Base::MaterialParamsType> params = this->mMaterial->_getInternalParams();
99 const MaterialParams::ParamData* data = params->getParamData(this->mParamIndex);
100
101 return params->template getCurveParam<T>(*data, arrayIdx);
102 }
103
104 template<bool Core>
105 void TMaterialColorGradientParam<Core>::set(const ColorGradient& value, UINT32 arrayIdx) const
106 {
107 if (this->mMaterial == nullptr)
108 return;
109
110 if(arrayIdx >= this->mArraySize)
111 {
112 LOGWRN("Array index out of range. Provided index was " + toString(arrayIdx) +
113 " but array length is " + toString(this->mArraySize));
114 return;
115 }
116
117 SPtr<typename Base::MaterialParamsType> params = this->mMaterial->_getInternalParams();
118 const MaterialParams::ParamData* data = params->getParamData(this->mParamIndex);
119
120 params->setColorGradientParam(*data, arrayIdx, value);
121 this->mMaterial->_markCoreDirty();
122 }
123
124 template<bool Core>
125 const ColorGradient& TMaterialColorGradientParam<Core>::get(UINT32 arrayIdx) const
126 {
127 static ColorGradient EMPTY_GRADIENT;
128
129 if (this->mMaterial == nullptr || arrayIdx >= this->mArraySize)
130 return EMPTY_GRADIENT;
131
132 SPtr<typename Base::MaterialParamsType> params = this->mMaterial->_getInternalParams();
133 const MaterialParams::ParamData* data = params->getParamData(this->mParamIndex);
134
135 return params->getColorGradientParam(*data, arrayIdx);
136 }
137
138 template<bool Core>
139 void TMaterialParamStruct<Core>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
140 {
141 if (this->mMaterial == nullptr)
142 return;
143
144 if (arrayIdx >= this->mArraySize)
145 {
146 LOGWRN("Array index out of range. Provided index was " + toString(arrayIdx) +
147 " but array length is " + toString(this->mArraySize));
148 return;
149 }
150
151 SPtr<typename Base::MaterialParamsType> params = this->mMaterial->_getInternalParams();
152 const MaterialParams::ParamData* data = params->getParamData(this->mParamIndex);
153
154 params->setStructData(*data, value, sizeBytes, arrayIdx);
155 this->mMaterial->_markCoreDirty();
156 }
157
158 template<bool Core>
159 void TMaterialParamStruct<Core>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
160 {
161 if (this->mMaterial == nullptr || arrayIdx >= this->mArraySize)
162 return;
163
164 SPtr<typename Base::MaterialParamsType> params = this->mMaterial->_getInternalParams();
165 const MaterialParams::ParamData* data = params->getParamData(this->mParamIndex);
166
167 params->getStructData(*data, value, sizeBytes, arrayIdx);
168 }
169
170 template<bool Core>
171 UINT32 TMaterialParamStruct<Core>::getElementSize() const
172 {
173 if (this->mMaterial == nullptr)
174 return 0;
175
176 SPtr<typename Base::MaterialParamsType> params = this->mMaterial->_getInternalParams();
177 const MaterialParams::ParamData* data = params->getParamData(this->mParamIndex);
178
179 return params->getStructSize(*data);
180 }
181
182 template<bool Core>
183 TMaterialParamTexture<Core>::TMaterialParamTexture(const String& name, const MaterialPtrType& material)
184 :mParamIndex(0), mMaterial(nullptr)
185 {
186 if (material != nullptr)
187 {
188 SPtr<MaterialParamsType> params = material->_getInternalParams();
189
190 UINT32 paramIndex;
191 auto result = params->getParamIndex(name, MaterialParams::ParamType::Texture, GPDT_UNKNOWN, 0, paramIndex);
192
193 if (result == MaterialParams::GetParamResult::Success)
194 {
195 mMaterial = material;
196 mParamIndex = paramIndex;
197 }
198 else
199 params->reportGetParamError(result, name, 0);
200 }
201 }
202
203 template<bool Core>
204 void TMaterialParamTexture<Core>::set(const TextureType& texture, const TextureSurface& surface) const
205 {
206 if (mMaterial == nullptr)
207 return;
208
209 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
210 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
211
212 // If there is a default value, assign that instead of null
213 TextureType newValue = texture;
214 if (newValue == nullptr)
215 params->getDefaultTexture(*data, newValue);
216
217 params->setTexture(*data, newValue, surface);
218 mMaterial->_markCoreDirty();
219 mMaterial->_markDependenciesDirty();
220 mMaterial->_markResourcesDirty();
221 }
222
223 template<bool Core>
224 typename TMaterialParamTexture<Core>::TextureType TMaterialParamTexture<Core>::get() const
225 {
226 TextureType texture;
227 if (mMaterial == nullptr)
228 return texture;
229
230 TextureSurface surface;
231
232 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
233 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
234
235 params->getTexture(*data, texture, surface);
236 return texture;
237 }
238
239 template<bool Core>
240 TMaterialParamSpriteTexture<Core>::TMaterialParamSpriteTexture(const String& name, const MaterialPtrType& material)
241 :mParamIndex(0), mMaterial(nullptr)
242 {
243 if (material != nullptr)
244 {
245 SPtr<MaterialParamsType> params = material->_getInternalParams();
246
247 UINT32 paramIndex;
248 auto result = params->getParamIndex(name, MaterialParams::ParamType::Texture, GPDT_UNKNOWN, 0, paramIndex);
249
250 if (result == MaterialParams::GetParamResult::Success)
251 {
252 mMaterial = material;
253 mParamIndex = paramIndex;
254 }
255 else
256 params->reportGetParamError(result, name, 0);
257 }
258 }
259
260 template<bool Core>
261 void TMaterialParamSpriteTexture<Core>::set(const SpriteTextureType& texture) const
262 {
263 if (mMaterial == nullptr)
264 return;
265
266 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
267 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
268
269 if(texture == nullptr)
270 {
271 // If there is a default value, assign that instead of null
272 TextureType newValue;
273 params->getDefaultTexture(*data, newValue);
274 params->setTexture(*data, newValue, TextureSurface::COMPLETE);
275 }
276 else
277 params->setSpriteTexture(*data, texture);
278
279 mMaterial->_markCoreDirty();
280 mMaterial->_markDependenciesDirty();
281 mMaterial->_markResourcesDirty();
282 }
283
284 template<bool Core>
285 typename TMaterialParamSpriteTexture<Core>::SpriteTextureType TMaterialParamSpriteTexture<Core>::get() const
286 {
287 SpriteTextureType texture;
288 if (mMaterial == nullptr)
289 return texture;
290
291 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
292 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
293
294 params->getSpriteTexture(*data, texture);
295 return texture;
296 }
297
298 template<bool Core>
299 TMaterialParamLoadStoreTexture<Core>::TMaterialParamLoadStoreTexture(const String& name,
300 const MaterialPtrType& material)
301 :mParamIndex(0), mMaterial(nullptr)
302 {
303 if (material != nullptr)
304 {
305 SPtr<MaterialParamsType> params = material->_getInternalParams();
306
307 UINT32 paramIndex;
308 auto result = params->getParamIndex(name, MaterialParams::ParamType::Texture, GPDT_UNKNOWN, 0, paramIndex);
309
310 if (result == MaterialParams::GetParamResult::Success)
311 {
312 mMaterial = material;
313 mParamIndex = paramIndex;
314 }
315 else
316 params->reportGetParamError(result, name, 0);
317 }
318 }
319
320 template<bool Core>
321 void TMaterialParamLoadStoreTexture<Core>::set(const TextureType& texture, const TextureSurface& surface) const
322 {
323 if (mMaterial == nullptr)
324 return;
325
326 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
327 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
328
329 params->setLoadStoreTexture(*data, texture, surface);
330 mMaterial->_markCoreDirty();
331 mMaterial->_markDependenciesDirty();
332 mMaterial->_markResourcesDirty();
333 }
334
335 template<bool Core>
336 typename TMaterialParamLoadStoreTexture<Core>::TextureType TMaterialParamLoadStoreTexture<Core>::get() const
337 {
338 TextureType texture;
339 if (mMaterial == nullptr)
340 return texture;
341
342 TextureSurface surface;
343
344 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
345 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
346
347 params->getLoadStoreTexture(*data, texture, surface);
348
349 return texture;
350 }
351
352 template<bool Core>
353 TMaterialParamBuffer<Core>::TMaterialParamBuffer(const String& name, const MaterialPtrType& material)
354 :mParamIndex(0), mMaterial(nullptr)
355 {
356 if (material != nullptr)
357 {
358 SPtr<MaterialParamsType> params = material->_getInternalParams();
359
360 UINT32 paramIndex;
361 auto result = params->getParamIndex(name, MaterialParams::ParamType::Buffer, GPDT_UNKNOWN, 0, paramIndex);
362
363 if (result == MaterialParams::GetParamResult::Success)
364 {
365 mMaterial = material;
366 mParamIndex = paramIndex;
367 }
368 else
369 params->reportGetParamError(result, name, 0);
370 }
371 }
372
373 template<bool Core>
374 void TMaterialParamBuffer<Core>::set(const BufferType& buffer) const
375 {
376 if (mMaterial == nullptr)
377 return;
378
379 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
380 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
381
382 params->setBuffer(*data, buffer);
383 mMaterial->_markCoreDirty();
384 mMaterial->_markDependenciesDirty();
385 }
386
387 template<bool Core>
388 typename TMaterialParamBuffer<Core>::BufferType TMaterialParamBuffer<Core>::get() const
389 {
390 BufferType buffer;
391 if (mMaterial == nullptr)
392 return buffer;
393
394 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
395 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
396 params->getBuffer(*data, buffer);
397
398 return buffer;
399 }
400
401 template<bool Core>
402 TMaterialParamSampState<Core>::TMaterialParamSampState(const String& name, const MaterialPtrType& material)
403 :mParamIndex(0), mMaterial(nullptr)
404 {
405 if (material != nullptr)
406 {
407 SPtr<MaterialParamsType> params = material->_getInternalParams();
408
409 UINT32 paramIndex;
410 auto result = params->getParamIndex(name, MaterialParams::ParamType::Sampler, GPDT_UNKNOWN, 0, paramIndex);
411
412 if (result == MaterialParams::GetParamResult::Success)
413 {
414 mMaterial = material;
415 mParamIndex = paramIndex;
416 }
417 else
418 params->reportGetParamError(result, name, 0);
419 }
420 }
421
422 template<bool Core>
423 void TMaterialParamSampState<Core>::set(const SamplerStateType& sampState) const
424 {
425 if (mMaterial == nullptr)
426 return;
427
428 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
429 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
430
431 // If there is a default value, assign that instead of null
432 SamplerStateType newValue = sampState;
433 if (newValue == nullptr)
434 params->getDefaultSamplerState(*data, newValue);
435
436 params->setSamplerState(*data, newValue);
437 mMaterial->_markCoreDirty();
438 mMaterial->_markDependenciesDirty();
439 }
440
441 template<bool Core>
442 typename TMaterialParamSampState<Core>::SamplerStateType TMaterialParamSampState<Core>::get() const
443 {
444 SamplerStateType samplerState;
445 if (mMaterial == nullptr)
446 return samplerState;
447
448 SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
449 const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
450
451 params->getSamplerState(*data, samplerState);
452 return samplerState;
453 }
454
455#define MATERIAL_DATA_PARAM_INSTATIATE(type) \
456 template class TMaterialDataCommon<TGpuDataParamInfo<type>::TypeId, false>; \
457 template class TMaterialDataCommon<TGpuDataParamInfo<type>::TypeId, true>; \
458 template class TMaterialDataParam<type, false>; \
459 template class TMaterialDataParam<type, true>;
460
461 MATERIAL_DATA_PARAM_INSTATIATE(float)
462 MATERIAL_DATA_PARAM_INSTATIATE(int)
463 MATERIAL_DATA_PARAM_INSTATIATE(Color)
464 MATERIAL_DATA_PARAM_INSTATIATE(Vector2)
465 MATERIAL_DATA_PARAM_INSTATIATE(Vector3)
466 MATERIAL_DATA_PARAM_INSTATIATE(Vector4)
467 MATERIAL_DATA_PARAM_INSTATIATE(Vector2I)
468 MATERIAL_DATA_PARAM_INSTATIATE(Vector3I)
469 MATERIAL_DATA_PARAM_INSTATIATE(Vector4I)
470 MATERIAL_DATA_PARAM_INSTATIATE(Matrix2)
471 MATERIAL_DATA_PARAM_INSTATIATE(Matrix2x3)
472 MATERIAL_DATA_PARAM_INSTATIATE(Matrix2x4)
473 MATERIAL_DATA_PARAM_INSTATIATE(Matrix3)
474 MATERIAL_DATA_PARAM_INSTATIATE(Matrix3x2)
475 MATERIAL_DATA_PARAM_INSTATIATE(Matrix3x4)
476 MATERIAL_DATA_PARAM_INSTATIATE(Matrix4)
477 MATERIAL_DATA_PARAM_INSTATIATE(Matrix4x2)
478 MATERIAL_DATA_PARAM_INSTATIATE(Matrix4x3)
479
480#undef MATERIAL_DATA_PARAM_INSTATIATE
481
482 template class TMaterialDataCommon<GPDT_STRUCT, false>;
483 template class TMaterialDataCommon<GPDT_STRUCT, true>;
484 template class TMaterialParamStruct<false>;
485 template class TMaterialParamStruct<true>;
486
487 template class TMaterialCurveParam<float, false>;
488 template class TMaterialCurveParam<float, true>;
489
490 template class TMaterialColorGradientParam<false>;
491 template class TMaterialColorGradientParam<true>;
492
493 template class TMaterialParamTexture<false>;
494 template class TMaterialParamTexture<true>;
495
496 template class TMaterialParamSpriteTexture<false>;
497 template class TMaterialParamSpriteTexture<true>;
498
499 template class TMaterialParamLoadStoreTexture<false>;
500 template class TMaterialParamLoadStoreTexture<true>;
501
502 template class TMaterialParamBuffer<false>;
503 template class TMaterialParamBuffer<true>;
504
505 template class TMaterialParamSampState<false>;
506 template class TMaterialParamSampState<true>;
507}