| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "Material/BsMaterial.h"
- #include "Material/BsShader.h"
- #include "Material/BsTechnique.h"
- #include "Material/BsPass.h"
- #include "RenderAPI/BsRenderAPI.h"
- #include "RTTI/BsMaterialRTTI.h"
- #include "Material/BsMaterialManager.h"
- #include "Resources/BsResources.h"
- #include "Allocators/BsFrameAlloc.h"
- #include "Math/BsMatrixNxM.h"
- #include "Math/BsVector3I.h"
- #include "Math/BsVector4I.h"
- #include "Serialization/BsMemorySerializer.h"
- #include "Material/BsMaterialParams.h"
- #include "Material/BsGpuParamsSet.h"
- namespace bs
- {
- enum MaterialLoadFlags
- {
- Load_None = 0,
- Load_Shader = 1,
- Load_All = 2
- };
-
- template<class T>
- bool isShaderValid(const T& shader) { return false; }
- template<>
- bool isShaderValid(const HShader& shader) { return shader.isLoaded(); }
- template<>
- bool isShaderValid(const SPtr<ct::Shader>& shader) { return shader != nullptr; }
- template<bool Core> struct TMatType { };
- template<> struct TMatType<false> { typedef Material Type; };
- template<> struct TMatType<true> { typedef ct::Material Type; };
- template<bool Core>
- SPtr<typename TMatType<Core>::Type> getMaterialPtr(const TMaterial<Core>* material)
- {
- return std::static_pointer_cast<typename TMatType<Core>::Type>(static_cast<const typename TMatType<Core>::Type*>(material)->getThisPtr());
- }
- template<bool Core>
- SPtr<typename TMaterial<Core>::GpuParamsSetType> TMaterial<Core>::createParamsSet(UINT32 techniqueIdx)
- {
- if (techniqueIdx >= (UINT32)mTechniques.size())
- return nullptr;
- SPtr<TechniqueType> technique = mTechniques[techniqueIdx];
- return bs_shared_ptr_new<GpuParamsSetType>(technique, mShader, mParams);
- }
- template<bool Core>
- void TMaterial<Core>::updateParamsSet(const SPtr<GpuParamsSetType>& paramsSet, bool updateAll)
- {
- paramsSet->update(mParams, updateAll);
- }
- template<bool Core>
- UINT32 TMaterial<Core>::findTechnique(const StringID& tag) const
- {
- for(UINT32 i = 0; i < (UINT32)mTechniques.size(); i++)
- {
- if (mTechniques[i]->hasTag(tag))
- return i;
- }
- return (UINT32)-1;
- }
- template<bool Core>
- UINT32 TMaterial<Core>::getDefaultTechnique() const
- {
- for (UINT32 i = 0; i < (UINT32)mTechniques.size(); i++)
- {
- if (!mTechniques[i]->hasTags())
- return i;
- }
- return 0;
- }
- template<bool Core>
- UINT32 TMaterial<Core>::getNumPasses(UINT32 techniqueIdx) const
- {
- if (mShader == nullptr)
- return 0;
- if (techniqueIdx >= (UINT32)mTechniques.size())
- return 0;
- return mTechniques[techniqueIdx]->getNumPasses();
- }
- template<bool Core>
- SPtr<typename TMaterial<Core>::PassType> TMaterial<Core>::getPass(UINT32 passIdx, UINT32 techniqueIdx) const
- {
- if (mShader == nullptr)
- return nullptr;
- if (techniqueIdx >= (UINT32)mTechniques.size())
- return nullptr;
- if (passIdx < 0 || passIdx >= mTechniques[techniqueIdx]->getNumPasses())
- return nullptr;
- return mTechniques[techniqueIdx]->getPass(passIdx);
- }
- template<bool Core>
- TMaterialParamStruct<Core> TMaterial<Core>::getParamStruct(const String& name) const
- {
- throwIfNotInitialized();
- return TMaterialParamStruct<Core>(name, getMaterialPtr(this));
- }
- template<bool Core>
- TMaterialParamTexture<Core> TMaterial<Core>::getParamTexture(const String& name) const
- {
- throwIfNotInitialized();
- return TMaterialParamTexture<Core>(name, getMaterialPtr(this));
- }
- template<bool Core>
- TMaterialParamLoadStoreTexture<Core> TMaterial<Core>::getParamLoadStoreTexture(const String& name) const
- {
- throwIfNotInitialized();
- return TMaterialParamLoadStoreTexture<Core>(name, getMaterialPtr(this));
- }
- template<bool Core>
- TMaterialParamBuffer<Core> TMaterial<Core>::getParamBuffer(const String& name) const
- {
- throwIfNotInitialized();
- return TMaterialParamBuffer<Core>(name, getMaterialPtr(this));
- }
- template<bool Core>
- TMaterialParamSampState<Core> TMaterial<Core>::getParamSamplerState(const String& name) const
- {
- throwIfNotInitialized();
- return TMaterialParamSampState<Core>(name, getMaterialPtr(this));
- }
- template<bool Core>
- void TMaterial<Core>::initializeTechniques()
- {
- mTechniques.clear();
- if (isShaderValid(mShader))
- {
- mParams = bs_shared_ptr_new<MaterialParamsType>(mShader);
- mTechniques = mShader->getCompatibleTechniques();
- if (mTechniques.size() == 0)
- return;
- initDefaultParameters();
- }
- else
- mParams = nullptr;
- _markDependenciesDirty();
- }
- template <bool Core>
- template <typename T>
- void TMaterial<Core>::setParamValue(const String& name, UINT8* buffer, UINT32 numElements)
- {
- TMaterialDataParam<T, Core> param;
- getParam(name, param);
- T* ptr = (T*)buffer;
- for (UINT32 i = 0; i < numElements; i++)
- param.set(ptr[i], i);
- }
- template <bool Core>
- void TMaterial<Core>::initDefaultParameters()
- {
- const Map<String, SHADER_DATA_PARAM_DESC>& dataParams = mShader->getDataParams();
- for (auto& paramData : dataParams)
- {
- if (paramData.second.defaultValueIdx == (UINT32)-1)
- continue;
- UINT8* buffer = (UINT8*)mShader->getDefaultValue(paramData.second.defaultValueIdx);
- if (buffer == nullptr)
- continue;
- switch (paramData.second.type)
- {
- case GPDT_FLOAT1:
- setParamValue<float>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_FLOAT2:
- setParamValue<Vector2>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_FLOAT3:
- setParamValue<Vector3>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_FLOAT4:
- setParamValue<Vector4>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_MATRIX_2X2:
- setParamValue<Matrix2>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_MATRIX_2X3:
- setParamValue<Matrix2x3>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_MATRIX_2X4:
- setParamValue<Matrix2x4>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_MATRIX_3X2:
- setParamValue<Matrix3x2>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_MATRIX_3X3:
- setParamValue<Matrix3>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_MATRIX_3X4:
- setParamValue<Matrix3x4>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_MATRIX_4X2:
- setParamValue<Matrix4x2>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_MATRIX_4X3:
- setParamValue<Matrix4x3>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_MATRIX_4X4:
- setParamValue<Matrix4>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_INT1:
- setParamValue<int>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_INT2:
- setParamValue<Vector2I>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_INT3:
- setParamValue<Vector3I>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_INT4:
- setParamValue<Vector4I>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_BOOL:
- setParamValue<int>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_COLOR:
- setParamValue<Color>(paramData.first, buffer, paramData.second.arraySize);
- break;
- case GPDT_STRUCT:
- {
- TMaterialParamStruct<Core> param = getParamStruct(paramData.first);
- UINT32 elementSizeBytes = paramData.second.elementSize * sizeof(UINT32);
- UINT8* ptr = buffer;
- for (UINT32 i = 0; i < paramData.second.arraySize; i++)
- {
- param.set(ptr, elementSizeBytes, i);
- ptr += elementSizeBytes;
- }
- }
- break;
- default:
- break;
- }
- }
- const Map<String, SHADER_OBJECT_PARAM_DESC>& textureParams = mShader->getTextureParams();
- for (auto& param : textureParams)
- {
- if (param.second.defaultValueIdx == (UINT32)-1)
- continue;
- TextureType defaultTex = mShader->getDefaultTexture(param.second.defaultValueIdx);
- getParamTexture(param.first).set(defaultTex);
- }
- const Map<String, SHADER_OBJECT_PARAM_DESC>& samplerParams = mShader->getSamplerParams();
- for (auto& param : samplerParams)
- {
- if (param.second.defaultValueIdx == (UINT32)-1)
- continue;
- SamplerStateType defaultSampler = mShader->getDefaultSampler(param.second.defaultValueIdx);
- getParamSamplerState(param.first).set(defaultSampler);
- }
- }
- template <bool Core>
- template <typename T>
- void TMaterial<Core>::getParam(const String& name, TMaterialDataParam<T, Core>& output) const
- {
- throwIfNotInitialized();
- output = TMaterialDataParam<T, Core>(name, getMaterialPtr(this));
- }
- template<bool Core>
- void TMaterial<Core>::throwIfNotInitialized() const
- {
- if (mShader == nullptr)
- {
- BS_EXCEPT(InternalErrorException, "Material does not have shader set.");
- }
- if (mTechniques.size() == 0)
- {
- BS_EXCEPT(InternalErrorException, "Shader does not contain a supported technique.");
- }
- }
- template class TMaterial < false > ;
- template class TMaterial < true > ;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<float, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<int, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Color, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector2, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector3, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector4, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector2I, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector3I, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector4I, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix2, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix2x3, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix2x4, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix3, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix3x2, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix3x4, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix4, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix4x2, false>&) const;
- template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix4x3, false>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<float, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<int, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Color, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector2, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector3, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector4, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector2I, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector3I, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector4I, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix2, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix2x3, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix2x4, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix3, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix3x2, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix3x4, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix4, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix4x2, true>&) const;
- template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix4x3, true>&) const;
- Material::Material()
- :mLoadFlags(Load_None)
- { }
- Material::Material(const HShader& shader)
- :mLoadFlags(Load_None)
- {
- mShader = shader;
- }
- void Material::initialize()
- {
- _markResourcesDirty();
- initializeIfLoaded();
- Resource::initialize();
- }
- void Material::setShader(const HShader& shader)
- {
- if (mShader == shader)
- return;
- mShader = shader;
- mTechniques.clear();
- mLoadFlags = Load_None;
- _markResourcesDirty();
- initializeIfLoaded();
- }
- void Material::_markCoreDirty(MaterialDirtyFlags flags)
- {
- markCoreDirty((UINT32)flags);
- }
- void Material::_markDependenciesDirty()
- {
- markDependenciesDirty();
- }
- void Material::_markResourcesDirty()
- {
- markListenerResourcesDirty();
- }
- SPtr<ct::Material> Material::getCore() const
- {
- return std::static_pointer_cast<ct::Material>(mCoreSpecific);
- }
- SPtr<ct::CoreObject> Material::createCore() const
- {
- ct::Material* material = nullptr;
- SPtr<ct::Shader> shader;
- if (mShader.isLoaded())
- {
- shader = mShader->getCore();
- Vector<SPtr<ct::Technique>> techniques(mTechniques.size());
- for (UINT32 i = 0; i < (UINT32)mTechniques.size(); i++)
- techniques[i] = mTechniques[i]->getCore();
-
- SPtr<ct::MaterialParams> materialParams = bs_shared_ptr_new<ct::MaterialParams>(shader, mParams);
- material = new (bs_alloc<ct::Material>()) ct::Material(shader, techniques, materialParams);
- }
-
- if (material == nullptr)
- material = new (bs_alloc<ct::Material>()) ct::Material(shader);
- SPtr<ct::Material> materialPtr = bs_shared_ptr<ct::Material>(material);
- materialPtr->_setThisPtr(materialPtr);
- return materialPtr;
- }
- CoreSyncData Material::syncToCore(FrameAlloc* allocator)
- {
- bool syncAllParams = getCoreDirtyFlags() == (UINT32)MaterialDirtyFlags::ResourceChanged;
- UINT32 paramsSize = 0;
- if (mParams != nullptr)
- mParams->getSyncData(nullptr, paramsSize, syncAllParams);
- UINT32 numTechniques = (UINT32)mTechniques.size();
- UINT32 size = sizeof(UINT32) * 2 + sizeof(SPtr<ct::Shader>) +
- sizeof(SPtr<ct::Technique>) * numTechniques + paramsSize;
- UINT8* buffer = allocator->alloc(size);
- char* dataPtr = (char*)buffer;
-
- SPtr<ct::Shader>* shader = new (dataPtr)SPtr<ct::Shader>();
- if (mShader.isLoaded(false))
- *shader = mShader->getCore();
- else
- *shader = nullptr;
- dataPtr += sizeof(SPtr<ct::Shader>);
- dataPtr = rttiWriteElem(numTechniques, dataPtr);
- for(UINT32 i = 0; i < numTechniques; i++)
- {
- SPtr<ct::Technique>* technique = new (dataPtr)SPtr<ct::Technique>();
- *technique = mTechniques[i]->getCore();
- dataPtr += sizeof(SPtr<ct::Technique>);
- }
- dataPtr = rttiWriteElem(paramsSize, dataPtr);
- if (mParams != nullptr)
- mParams->getSyncData((UINT8*)dataPtr, paramsSize, syncAllParams);
- dataPtr += paramsSize;
- return CoreSyncData(buffer, size);
- }
- void Material::getCoreDependencies(Vector<CoreObject*>& dependencies)
- {
- if (mShader.isLoaded())
- dependencies.push_back(mShader.get());
- if(mParams != nullptr)
- mParams->getCoreObjectDependencies(dependencies);
- }
- void Material::getListenerResources(Vector<HResource>& resources)
- {
- if (mShader != nullptr)
- resources.push_back(mShader);
- if (mParams != nullptr)
- mParams->getResourceDependencies(resources);
- }
- void Material::getResourceDependencies(FrameVector<HResource>& dependencies) const
- {
- if (mShader != nullptr)
- dependencies.push_back(mShader);
- }
- void Material::initializeIfLoaded()
- {
- if (areDependenciesLoaded())
- {
- if (mLoadFlags != Load_All)
- {
- mLoadFlags = Load_All;
- // Shader about to change, so save parameters, rebuild material and restore parameters
- SPtr<MaterialParams> oldParams = mParams;
- initializeTechniques();
- markCoreDirty();
- if (mTechniques.size() == 0) // Wasn't initialized
- return;
- if(oldParams)
- setParams(oldParams);
- }
- }
- else
- {
- if (mShader.isLoaded() && mLoadFlags == Load_None)
- {
- mLoadFlags = Load_Shader;
- markListenerResourcesDirty(); // Need to register resources dependent on shader now
- }
- }
- }
- void Material::notifyResourceLoaded(const HResource& resource)
- {
- // Ready to initialize as soon as shader loads
- if (resource->getRTTI()->getRTTIId() == TID_Shader)
- initializeIfLoaded();
- }
- void Material::notifyResourceChanged(const HResource& resource)
- {
- // Need full rebuild if shader changed
- if (resource->getRTTI()->getRTTIId() == TID_Shader)
- {
- mLoadFlags = Load_None;
- initializeIfLoaded();
- }
- else
- {
- // Otherwise just sync changes (most likely just a texture got reimported)
- _markCoreDirty(MaterialDirtyFlags::ResourceChanged);
- }
- }
- HMaterial Material::clone()
- {
- UINT32 bufferSize = 0;
- MemorySerializer serializer;
- UINT8* buffer = serializer.encode(this, bufferSize, (void*(*)(UINT32))&bs_alloc);
- SPtr<Material> cloneObj = std::static_pointer_cast<Material>(serializer.decode(buffer, bufferSize));
- bs_free(buffer);
- return static_resource_cast<Material>(gResources()._createResourceHandle(cloneObj));
- }
- template<class T>
- void copyParam(const SPtr<MaterialParams>& from, Material* to, const String& name,
- const MaterialParams::ParamData& paramRef, UINT32 arraySize)
- {
- TMaterialDataParam<T, false> param;
- to->getParam(name, param);
- T paramData;
- for (UINT32 i = 0; i < arraySize; i++)
- {
- from->getDataParam(paramRef, i, paramData);
- param.set(paramData, i);
- }
- }
- void Material::setParams(const SPtr<MaterialParams>& params)
- {
- if (params == nullptr)
- return;
- std::function<
- void(const SPtr<MaterialParams>&, Material*, const String&, const MaterialParams::ParamData&, UINT32)>
- copyParamLookup[GPDT_COUNT];
- copyParamLookup[GPDT_FLOAT1] = ©Param<float>;
- copyParamLookup[GPDT_FLOAT2] = ©Param<Vector2>;
- copyParamLookup[GPDT_FLOAT3] = ©Param<Vector3>;
- copyParamLookup[GPDT_FLOAT4] = ©Param<Vector4>;
- copyParamLookup[GPDT_INT1] = ©Param<int>;
- copyParamLookup[GPDT_INT2] = ©Param<Vector2I>;
- copyParamLookup[GPDT_INT3] = ©Param<Vector3I>;
- copyParamLookup[GPDT_INT4] = ©Param<Vector4I>;
- copyParamLookup[GPDT_MATRIX_2X2] = ©Param<Matrix2>;
- copyParamLookup[GPDT_MATRIX_2X3] = ©Param<Matrix2x3>;
- copyParamLookup[GPDT_MATRIX_2X4] = ©Param<Matrix2x4>;
- copyParamLookup[GPDT_MATRIX_3X3] = ©Param<Matrix3>;
- copyParamLookup[GPDT_MATRIX_3X2] = ©Param<Matrix3x2>;
- copyParamLookup[GPDT_MATRIX_3X4] = ©Param<Matrix3x4>;
- copyParamLookup[GPDT_MATRIX_4X4] = ©Param<Matrix4>;
- copyParamLookup[GPDT_MATRIX_4X2] = ©Param<Matrix4x2>;
- copyParamLookup[GPDT_MATRIX_4X3] = ©Param<Matrix4x3>;
- copyParamLookup[GPDT_BOOL] = ©Param<int>;
- copyParamLookup[GPDT_COLOR] = ©Param<Color>;
- auto& dataParams = mShader->getDataParams();
- for (auto& param : dataParams)
- {
- UINT32 arraySize = param.second.arraySize > 1 ? param.second.arraySize : 1;
- const MaterialParams::ParamData* paramData = nullptr;
- auto result = params->getParamData(param.first, MaterialParams::ParamType::Data, param.second.type, 0, ¶mData);
- if (result != MaterialParams::GetParamResult::Success)
- continue;
- UINT32 elemsToCopy = std::min(arraySize, paramData->arraySize);
- auto& copyFunction = copyParamLookup[param.second.type];
- if (copyFunction != nullptr)
- copyFunction(params, this, param.first, *paramData, elemsToCopy);
- else
- {
- if(param.second.type == GPDT_STRUCT)
- {
- TMaterialParamStruct<false> curParam = getParamStruct(param.first);
- UINT32 structSize = params->getStructSize(*paramData);
- if (param.second.elementSize != structSize)
- continue;
- UINT8* structData = (UINT8*)bs_stack_alloc(structSize);
- for (UINT32 i = 0; i < elemsToCopy; i++)
- {
- params->getStructData(*paramData, structData, structSize, i);
- curParam.set(structData, structSize, i);
- }
- bs_stack_free(structData);
- }
- }
- }
- auto& textureParams = mShader->getTextureParams();
- for (auto& param : textureParams)
- {
- const MaterialParams::ParamData* paramData = nullptr;
- auto result = params->getParamData(param.first, MaterialParams::ParamType::Texture, GPDT_UNKNOWN, 0, ¶mData);
- if (result != MaterialParams::GetParamResult::Success)
- continue;
- bool isLoadStore = params->getIsTextureLoadStore(*paramData);
- if(!isLoadStore)
- {
- TMaterialParamTexture<false> curParam = getParamTexture(param.first);
- HTexture texture;
- TextureSurface surface;
- params->getTexture(*paramData, texture, surface);
- curParam.set(texture);
- }
- else
- {
- TMaterialParamLoadStoreTexture<false> curParam = getParamLoadStoreTexture(param.first);
- HTexture texture;
- TextureSurface surface;
- params->getLoadStoreTexture(*paramData, texture, surface);
- curParam.set(texture, surface);
- }
- }
- auto& bufferParams = mShader->getBufferParams();
- for (auto& param : bufferParams)
- {
- const MaterialParams::ParamData* paramData = nullptr;
- auto result = params->getParamData(param.first, MaterialParams::ParamType::Buffer, GPDT_UNKNOWN, 0, ¶mData);
- if (result != MaterialParams::GetParamResult::Success)
- continue;
- TMaterialParamBuffer<false> curParam = getParamBuffer(param.first);
- SPtr<GpuBuffer> buffer;
- params->getBuffer(*paramData, buffer);
- curParam.set(buffer);
- }
- auto& samplerParams = mShader->getSamplerParams();
- for (auto& param : samplerParams)
- {
- const MaterialParams::ParamData* paramData = nullptr;
- auto result = params->getParamData(param.first, MaterialParams::ParamType::Sampler, GPDT_UNKNOWN, 0, ¶mData);
- if (result != MaterialParams::GetParamResult::Success)
- continue;
- TMaterialParamSampState<false> curParam = getParamSamplerState(param.first);
- SPtr<SamplerState> samplerState;
- params->getSamplerState(*paramData, samplerState);
- curParam.set(samplerState);
- }
- }
- HMaterial Material::create()
- {
- SPtr<Material> materialPtr = MaterialManager::instance().create();
- return static_resource_cast<Material>(gResources()._createResourceHandle(materialPtr));
- }
- HMaterial Material::create(const HShader& shader)
- {
- SPtr<Material> materialPtr = MaterialManager::instance().create(shader);
- return static_resource_cast<Material>(gResources()._createResourceHandle(materialPtr));
- }
- RTTITypeBase* Material::getRTTIStatic()
- {
- return MaterialRTTI::instance();
- }
- RTTITypeBase* Material::getRTTI() const
- {
- return Material::getRTTIStatic();
- }
- namespace ct
- {
- Material::Material(const SPtr<Shader>& shader)
- {
- setShader(shader);
- }
- Material::Material(const SPtr<Shader>& shader, const Vector<SPtr<Technique>>& techniques,
- const SPtr<MaterialParams>& materialParams)
- {
- mShader = shader;
- mParams = materialParams;
- mTechniques = techniques;
- }
- void Material::setShader(const SPtr<Shader>& shader)
- {
- mShader = shader;
- initializeTechniques();
- _markCoreDirty();
- }
- void Material::syncToCore(const CoreSyncData& data)
- {
- char* dataPtr = (char*)data.getBuffer();
- SPtr<Shader>* shader = (SPtr<Shader>*)dataPtr;
- mShader = *shader;
- shader->~SPtr<Shader>();
- dataPtr += sizeof(SPtr<Shader>);
- UINT32 numTechniques;
- dataPtr = rttiReadElem(numTechniques, dataPtr);
- mTechniques.resize(numTechniques);
- for(UINT32 i = 0; i < numTechniques; i++)
- {
- SPtr<Technique>* technique = (SPtr<Technique>*)dataPtr;
- mTechniques[i] = *technique;
- technique->~SPtr<Technique>();
- dataPtr += sizeof(SPtr<Technique>);
- }
- UINT32 paramsSize = 0;
- dataPtr = rttiReadElem(paramsSize, dataPtr);
- if (mParams == nullptr)
- mParams = bs_shared_ptr_new<MaterialParams>(mShader);
- mParams->setSyncData((UINT8*)dataPtr, paramsSize);
- dataPtr += paramsSize;
- }
- SPtr<Material> Material::create(const SPtr<Shader>& shader)
- {
- Material* material = new (bs_alloc<Material>()) Material(shader);
- SPtr<Material> materialPtr = bs_shared_ptr<Material>(material);
- materialPtr->_setThisPtr(materialPtr);
- materialPtr->initialize();
- return materialPtr;
- }
- }
- }
|