matInstance.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "materials/matInstance.h"
  24. #include "materials/materialManager.h"
  25. #include "materials/customMaterialDefinition.h"
  26. #include "materials/processedMaterial.h"
  27. #include "materials/processedFFMaterial.h"
  28. #include "materials/processedShaderMaterial.h"
  29. #include "materials/processedCustomMaterial.h"
  30. #include "materials/materialFeatureTypes.h"
  31. #include "shaderGen/featureMgr.h"
  32. #include "gfx/gfxDevice.h"
  33. #include "gfx/sim/cubemapData.h"
  34. #include "gfx/gfxCubemap.h"
  35. #include "core/util/safeDelete.h"
  36. #include "ts/tsShape.h"
  37. class MatInstParameters;
  38. class MatInstanceParameterHandle : public MaterialParameterHandle
  39. {
  40. public:
  41. virtual ~MatInstanceParameterHandle() {}
  42. MatInstanceParameterHandle(const String& name);
  43. void loadHandle(ProcessedMaterial* pmat);
  44. // MaterialParameterHandle interface
  45. const String& getName() const { return mName; }
  46. virtual bool isValid() const;
  47. virtual S32 getSamplerRegister( U32 pass ) const;
  48. private:
  49. friend class MatInstParameters;
  50. String mName;
  51. MaterialParameterHandle* mProcessedHandle;
  52. };
  53. MatInstanceParameterHandle::MatInstanceParameterHandle(const String& name)
  54. {
  55. mName = name;
  56. mProcessedHandle = NULL;
  57. }
  58. bool MatInstanceParameterHandle::isValid() const
  59. {
  60. return mProcessedHandle && mProcessedHandle->isValid();
  61. }
  62. S32 MatInstanceParameterHandle::getSamplerRegister( U32 pass ) const
  63. {
  64. if ( !mProcessedHandle )
  65. return -1;
  66. return mProcessedHandle->getSamplerRegister( pass );
  67. }
  68. void MatInstanceParameterHandle::loadHandle(ProcessedMaterial* pmat)
  69. {
  70. mProcessedHandle = pmat->getMaterialParameterHandle(mName);
  71. }
  72. MatInstParameters::MatInstParameters()
  73. {
  74. mOwnParameters = false;
  75. mParameters = NULL;
  76. }
  77. MatInstParameters::MatInstParameters(MaterialParameters* matParams)
  78. {
  79. mOwnParameters = false;
  80. mParameters = matParams;
  81. }
  82. void MatInstParameters::loadParameters(ProcessedMaterial* pmat)
  83. {
  84. mOwnParameters = true;
  85. mParameters = pmat->allocMaterialParameters();
  86. }
  87. MatInstParameters::~MatInstParameters()
  88. {
  89. if (mOwnParameters)
  90. SAFE_DELETE(mParameters);
  91. }
  92. const Vector<GFXShaderConstDesc>& MatInstParameters::getShaderConstDesc() const
  93. {
  94. return mParameters->getShaderConstDesc();
  95. }
  96. U32 MatInstParameters::getAlignmentValue(const GFXShaderConstType constType)
  97. {
  98. return mParameters->getAlignmentValue(constType);
  99. }
  100. #define MATINSTPARAMSET(handle, f) \
  101. if (!mParameters) \
  102. return; \
  103. AssertFatal(dynamic_cast<MatInstanceParameterHandle*>(handle), "Invalid handle type!"); \
  104. MatInstanceParameterHandle* mph = static_cast<MatInstanceParameterHandle*>(handle); \
  105. mParameters->set(mph->mProcessedHandle, f); \
  106. void MatInstParameters::set(MaterialParameterHandle* handle, const F32 f)
  107. {
  108. MATINSTPARAMSET(handle, f);
  109. }
  110. void MatInstParameters::set(MaterialParameterHandle* handle, const Point2F& fv)
  111. {
  112. MATINSTPARAMSET(handle, fv);
  113. }
  114. void MatInstParameters::set(MaterialParameterHandle* handle, const Point3F& fv)
  115. {
  116. MATINSTPARAMSET(handle, fv);
  117. }
  118. void MatInstParameters::set(MaterialParameterHandle* handle, const Point4F& fv)
  119. {
  120. MATINSTPARAMSET(handle, fv);
  121. }
  122. void MatInstParameters::set(MaterialParameterHandle* handle, const ColorF& fv)
  123. {
  124. MATINSTPARAMSET(handle, fv);
  125. }
  126. void MatInstParameters::set(MaterialParameterHandle* handle, const S32 f)
  127. {
  128. MATINSTPARAMSET(handle, f);
  129. }
  130. void MatInstParameters::set(MaterialParameterHandle* handle, const Point2I& fv)
  131. {
  132. MATINSTPARAMSET(handle, fv);
  133. }
  134. void MatInstParameters::set(MaterialParameterHandle* handle, const Point3I& fv)
  135. {
  136. MATINSTPARAMSET(handle, fv);
  137. }
  138. void MatInstParameters::set(MaterialParameterHandle* handle, const Point4I& fv)
  139. {
  140. MATINSTPARAMSET(handle, fv);
  141. }
  142. void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<F32>& fv)
  143. {
  144. MATINSTPARAMSET(handle, fv);
  145. }
  146. void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point2F>& fv)
  147. {
  148. MATINSTPARAMSET(handle, fv);
  149. }
  150. void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point3F>& fv)
  151. {
  152. MATINSTPARAMSET(handle, fv);
  153. }
  154. void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point4F>& fv)
  155. {
  156. MATINSTPARAMSET(handle, fv);
  157. }
  158. void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<S32>& fv)
  159. {
  160. MATINSTPARAMSET(handle, fv);
  161. }
  162. void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point2I>& fv)
  163. {
  164. MATINSTPARAMSET(handle, fv);
  165. }
  166. void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point3I>& fv)
  167. {
  168. MATINSTPARAMSET(handle, fv);
  169. }
  170. void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point4I>& fv)
  171. {
  172. MATINSTPARAMSET(handle, fv);
  173. }
  174. void MatInstParameters::set(MaterialParameterHandle* handle, const MatrixF& mat, const GFXShaderConstType matrixType)
  175. {
  176. AssertFatal(dynamic_cast<MatInstanceParameterHandle*>(handle), "Invalid handle type!");
  177. MatInstanceParameterHandle* mph = static_cast<MatInstanceParameterHandle*>(handle);
  178. mParameters->set(mph->mProcessedHandle, mat, matrixType);
  179. }
  180. void MatInstParameters::set(MaterialParameterHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType)
  181. {
  182. AssertFatal(dynamic_cast<MatInstanceParameterHandle*>(handle), "Invalid handle type!");
  183. MatInstanceParameterHandle* mph = static_cast<MatInstanceParameterHandle*>(handle);
  184. mParameters->set(mph->mProcessedHandle, mat, arraySize, matrixType);
  185. }
  186. #undef MATINSTPARAMSET
  187. //****************************************************************************
  188. // Material Instance
  189. //****************************************************************************
  190. MatInstance::MatInstance( Material &mat )
  191. {
  192. VECTOR_SET_ASSOCIATION( mCurrentHandles );
  193. VECTOR_SET_ASSOCIATION( mCurrentParameters );
  194. mMaterial = &mat;
  195. mCreatedFromCustomMaterial = (dynamic_cast<CustomMaterial *>(&mat) != NULL);
  196. construct();
  197. }
  198. //----------------------------------------------------------------------------
  199. // Construct
  200. //----------------------------------------------------------------------------
  201. void MatInstance::construct()
  202. {
  203. mUserObject = NULL;
  204. mCurPass = -1;
  205. mProcessedMaterial = NULL;
  206. mVertexFormat = NULL;
  207. mMaxStages = 1;
  208. mActiveParameters = NULL;
  209. mDefaultParameters = NULL;
  210. mHasNormalMaps = false;
  211. mUsesHardwareSkinning = false;
  212. mIsForwardLit = false;
  213. mIsValid = false;
  214. mIsHardwareSkinned = false;
  215. MATMGR->_track(this);
  216. }
  217. //----------------------------------------------------------------------------
  218. // Destructor
  219. //----------------------------------------------------------------------------
  220. MatInstance::~MatInstance()
  221. {
  222. SAFE_DELETE(mProcessedMaterial);
  223. SAFE_DELETE(mDefaultParameters);
  224. for (U32 i = 0; i < mCurrentHandles.size(); i++)
  225. SAFE_DELETE(mCurrentHandles[i]);
  226. MATMGR->_untrack(this);
  227. }
  228. //----------------------------------------------------------------------------
  229. // Init
  230. //----------------------------------------------------------------------------
  231. bool MatInstance::init( const FeatureSet &features,
  232. const GFXVertexFormat *vertexFormat )
  233. {
  234. AssertFatal( vertexFormat, "MatInstance::init - Got null vertex format!" );
  235. mFeatureList = features;
  236. mVertexFormat = vertexFormat;
  237. SAFE_DELETE(mProcessedMaterial);
  238. mIsValid = processMaterial();
  239. return mIsValid;
  240. }
  241. //----------------------------------------------------------------------------
  242. // reInitialize
  243. //----------------------------------------------------------------------------
  244. bool MatInstance::reInit()
  245. {
  246. if (!mVertexFormat)
  247. {
  248. mIsValid = false;
  249. return mIsValid;
  250. }
  251. SAFE_DELETE(mProcessedMaterial);
  252. deleteAllHooks();
  253. mIsValid = processMaterial();
  254. if ( mIsValid )
  255. {
  256. for (U32 i = 0; i < mCurrentHandles.size(); i++)
  257. mCurrentHandles[i]->loadHandle(mProcessedMaterial);
  258. for (U32 i = 0; i < mCurrentParameters.size(); i++)
  259. mCurrentParameters[i]->loadParameters(mProcessedMaterial);
  260. }
  261. return mIsValid;
  262. }
  263. //----------------------------------------------------------------------------
  264. // Process stages
  265. //----------------------------------------------------------------------------
  266. bool MatInstance::processMaterial()
  267. {
  268. AssertFatal( mMaterial, "MatInstance::processMaterial - Got null material!" );
  269. //AssertFatal( mVertexFormat, "MatInstance::processMaterial - Got null vertex format!" );
  270. if ( !mMaterial || !mVertexFormat )
  271. return false;
  272. SAFE_DELETE(mDefaultParameters);
  273. CustomMaterial *custMat = NULL;
  274. if( dynamic_cast<CustomMaterial*>(mMaterial) )
  275. {
  276. F32 pixVersion = GFX->getPixelShaderVersion();
  277. custMat = static_cast<CustomMaterial*>(mMaterial);
  278. if ((custMat->mVersion > pixVersion) || (custMat->mVersion == 0.0))
  279. {
  280. if(custMat->mFallback)
  281. {
  282. mMaterial = custMat->mFallback;
  283. return processMaterial();
  284. }
  285. else
  286. {
  287. AssertWarn(custMat->mVersion == 0.0f, avar("Can't load CustomMaterial %s for %s, using generic FF fallback",
  288. String(mMaterial->getName()).isEmpty() ? "Unknown" : mMaterial->getName(), custMat->mMapTo.c_str()));
  289. mProcessedMaterial = new ProcessedFFMaterial(*mMaterial);
  290. }
  291. }
  292. else
  293. mProcessedMaterial = new ProcessedCustomMaterial(*mMaterial);
  294. }
  295. else if(GFX->getPixelShaderVersion() > 0.001)
  296. mProcessedMaterial = getShaderMaterial();
  297. else
  298. mProcessedMaterial = new ProcessedFFMaterial(*mMaterial);
  299. if (mProcessedMaterial)
  300. {
  301. mProcessedMaterial->addStateBlockDesc( mUserDefinedState );
  302. mProcessedMaterial->setShaderMacros( mUserMacros );
  303. mProcessedMaterial->setUserObject( mUserObject );
  304. FeatureSet features( mFeatureList );
  305. features.exclude( MATMGR->getExclusionFeatures() );
  306. if (mVertexFormat->hasBlendIndices() && TSShape::smUseHardwareSkinning)
  307. {
  308. features.addFeature( MFT_HardwareSkinning );
  309. }
  310. if( !mProcessedMaterial->init(features, mVertexFormat, mFeaturesDelegate) )
  311. {
  312. Con::errorf( "Failed to initialize material '%s'", getMaterial()->getName() );
  313. SAFE_DELETE( mProcessedMaterial );
  314. return false;
  315. }
  316. mDefaultParameters = new MatInstParameters(mProcessedMaterial->getDefaultMaterialParameters());
  317. mActiveParameters = mDefaultParameters;
  318. const FeatureSet &finalFeatures = mProcessedMaterial->getFeatures();
  319. mHasNormalMaps = finalFeatures.hasFeature( MFT_NormalMap );
  320. mUsesHardwareSkinning = finalFeatures.hasFeature( MFT_HardwareSkinning );
  321. mIsForwardLit = ( custMat && custMat->mForwardLit ) ||
  322. ( !finalFeatures.hasFeature( MFT_IsEmissive ) &&
  323. finalFeatures.hasFeature( MFT_ForwardShading ) );
  324. mIsHardwareSkinned = finalFeatures.hasFeature( MFT_HardwareSkinning );
  325. return true;
  326. }
  327. return false;
  328. }
  329. const MatStateHint& MatInstance::getStateHint() const
  330. {
  331. if ( mProcessedMaterial )
  332. return mProcessedMaterial->getStateHint();
  333. else
  334. return MatStateHint::Default;
  335. }
  336. ProcessedMaterial* MatInstance::getShaderMaterial()
  337. {
  338. return new ProcessedShaderMaterial(*mMaterial);
  339. }
  340. void MatInstance::addStateBlockDesc(const GFXStateBlockDesc& desc)
  341. {
  342. mUserDefinedState = desc;
  343. }
  344. void MatInstance::updateStateBlocks()
  345. {
  346. if ( mProcessedMaterial )
  347. mProcessedMaterial->updateStateBlocks();
  348. }
  349. void MatInstance::addShaderMacro( const String &name, const String &value )
  350. {
  351. // Check to see if we already have this macro.
  352. Vector<GFXShaderMacro>::iterator iter = mUserMacros.begin();
  353. for ( ; iter != mUserMacros.end(); iter++ )
  354. {
  355. if ( iter->name == name )
  356. {
  357. iter->value = value;
  358. return;
  359. }
  360. }
  361. // Add a new macro.
  362. mUserMacros.increment();
  363. mUserMacros.last().name = name;
  364. mUserMacros.last().value = value;
  365. }
  366. //----------------------------------------------------------------------------
  367. // Setup pass - needs scenegraph data because the lightmap will change across
  368. // several materials.
  369. //----------------------------------------------------------------------------
  370. bool MatInstance::setupPass(SceneRenderState * state, const SceneData &sgData )
  371. {
  372. PROFILE_SCOPE( MatInstance_SetupPass );
  373. if( !mProcessedMaterial )
  374. return false;
  375. ++mCurPass;
  376. if ( !mProcessedMaterial->setupPass( state, sgData, mCurPass ) )
  377. {
  378. mCurPass = -1;
  379. return false;
  380. }
  381. return true;
  382. }
  383. void MatInstance::setTransforms(const MatrixSet &matrixSet, SceneRenderState *state)
  384. {
  385. PROFILE_SCOPE(MatInstance_setTransforms);
  386. mProcessedMaterial->setTransforms(matrixSet, state, getCurPass());
  387. }
  388. void MatInstance::setNodeTransforms(const MatrixF *address, const U32 numTransforms)
  389. {
  390. PROFILE_SCOPE(MatInstance_setNodeTransforms);
  391. mProcessedMaterial->setNodeTransforms(address, numTransforms, getCurPass());
  392. }
  393. void MatInstance::setSceneInfo(SceneRenderState * state, const SceneData& sgData)
  394. {
  395. PROFILE_SCOPE(MatInstance_setSceneInfo);
  396. mProcessedMaterial->setSceneInfo(state, sgData, getCurPass());
  397. }
  398. void MatInstance::setBuffers(GFXVertexBufferHandleBase* vertBuffer, GFXPrimitiveBufferHandle* primBuffer)
  399. {
  400. mProcessedMaterial->setBuffers(vertBuffer, primBuffer);
  401. }
  402. void MatInstance::setTextureStages(SceneRenderState * state, const SceneData &sgData )
  403. {
  404. PROFILE_SCOPE(MatInstance_setTextureStages);
  405. mProcessedMaterial->setTextureStages(state, sgData, getCurPass());
  406. }
  407. bool MatInstance::isInstanced() const
  408. {
  409. return mProcessedMaterial->getFeatures().hasFeature( MFT_UseInstancing );
  410. }
  411. bool MatInstance::stepInstance()
  412. {
  413. AssertFatal( isInstanced(), "MatInstance::stepInstance - This material isn't instanced!" );
  414. AssertFatal( mCurPass >= 0, "MatInstance::stepInstance - Must be within material setup pass!" );
  415. return mProcessedMaterial->stepInstance();
  416. }
  417. U32 MatInstance::getCurStageNum()
  418. {
  419. return mProcessedMaterial->getStageFromPass(getCurPass());
  420. }
  421. RenderPassData* MatInstance::getPass(U32 pass)
  422. {
  423. return mProcessedMaterial->getPass(pass);
  424. }
  425. bool MatInstance::hasGlow()
  426. {
  427. if( mProcessedMaterial )
  428. return mProcessedMaterial->hasGlow();
  429. else
  430. return false;
  431. }
  432. bool MatInstance::hasAccumulation()
  433. {
  434. if( mProcessedMaterial )
  435. return mProcessedMaterial->hasAccumulation();
  436. else
  437. return false;
  438. }
  439. const FeatureSet& MatInstance::getFeatures() const
  440. {
  441. return mProcessedMaterial->getFeatures();
  442. }
  443. MaterialParameterHandle* MatInstance::getMaterialParameterHandle(const String& name)
  444. {
  445. AssertFatal(mProcessedMaterial, "Not init'ed!");
  446. for (U32 i = 0; i < mCurrentHandles.size(); i++)
  447. {
  448. if (mCurrentHandles[i]->getName().equal(name))
  449. {
  450. return mCurrentHandles[i];
  451. }
  452. }
  453. MatInstanceParameterHandle* mph = new MatInstanceParameterHandle(name);
  454. mph->loadHandle(mProcessedMaterial);
  455. mCurrentHandles.push_back(mph);
  456. return mph;
  457. }
  458. MaterialParameters* MatInstance::allocMaterialParameters()
  459. {
  460. AssertFatal(mProcessedMaterial, "Not init'ed!");
  461. MatInstParameters* mip = new MatInstParameters();
  462. mip->loadParameters(mProcessedMaterial);
  463. mCurrentParameters.push_back(mip);
  464. return mip;
  465. }
  466. void MatInstance::setMaterialParameters(MaterialParameters* param)
  467. {
  468. AssertFatal(mProcessedMaterial, "Not init'ed!");
  469. mProcessedMaterial->setMaterialParameters(param, mCurPass);
  470. AssertFatal(dynamic_cast<MatInstParameters*>(param), "Incorrect param type!");
  471. mActiveParameters = static_cast<MatInstParameters*>(param);
  472. }
  473. MaterialParameters* MatInstance::getMaterialParameters()
  474. {
  475. AssertFatal(mProcessedMaterial, "Not init'ed!");
  476. return mActiveParameters;
  477. }
  478. void MatInstance::dumpShaderInfo() const
  479. {
  480. if ( mMaterial == NULL )
  481. {
  482. Con::errorf( "Trying to get Material information on an invalid MatInstance" );
  483. return;
  484. }
  485. Con::printf( "Material Info for object %s - %s", mMaterial->getName(), mMaterial->mMapTo.c_str() );
  486. if ( mProcessedMaterial == NULL )
  487. {
  488. Con::printf( " [no processed material!]" );
  489. return;
  490. }
  491. mProcessedMaterial->dumpMaterialInfo();
  492. }