matInstance.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  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 LinearColorF& 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. needsHighlighting = false;
  216. MATMGR->_track(this);
  217. }
  218. //----------------------------------------------------------------------------
  219. // Destructor
  220. //----------------------------------------------------------------------------
  221. MatInstance::~MatInstance()
  222. {
  223. SAFE_DELETE(mProcessedMaterial);
  224. SAFE_DELETE(mDefaultParameters);
  225. for (U32 i = 0; i < mCurrentHandles.size(); i++)
  226. SAFE_DELETE(mCurrentHandles[i]);
  227. MATMGR->_untrack(this);
  228. }
  229. //----------------------------------------------------------------------------
  230. // Init
  231. //----------------------------------------------------------------------------
  232. bool MatInstance::init( const FeatureSet &features,
  233. const GFXVertexFormat *vertexFormat )
  234. {
  235. AssertFatal( vertexFormat, "MatInstance::init - Got null vertex format!" );
  236. mFeatureList = features;
  237. mVertexFormat = vertexFormat;
  238. SAFE_DELETE(mProcessedMaterial);
  239. mIsValid = processMaterial();
  240. return mIsValid;
  241. }
  242. //----------------------------------------------------------------------------
  243. // reInitialize
  244. //----------------------------------------------------------------------------
  245. bool MatInstance::reInit()
  246. {
  247. if (!mVertexFormat)
  248. {
  249. mIsValid = false;
  250. return mIsValid;
  251. }
  252. SAFE_DELETE(mProcessedMaterial);
  253. deleteAllHooks();
  254. mIsValid = processMaterial();
  255. if ( mIsValid )
  256. {
  257. for (U32 i = 0; i < mCurrentHandles.size(); i++)
  258. mCurrentHandles[i]->loadHandle(mProcessedMaterial);
  259. for (U32 i = 0; i < mCurrentParameters.size(); i++)
  260. mCurrentParameters[i]->loadParameters(mProcessedMaterial);
  261. }
  262. return mIsValid;
  263. }
  264. //----------------------------------------------------------------------------
  265. // Process stages
  266. //----------------------------------------------------------------------------
  267. bool MatInstance::processMaterial()
  268. {
  269. AssertFatal( mMaterial, "MatInstance::processMaterial - Got null material!" );
  270. //AssertFatal( mVertexFormat, "MatInstance::processMaterial - Got null vertex format!" );
  271. if ( !mMaterial || !mVertexFormat )
  272. return false;
  273. SAFE_DELETE(mDefaultParameters);
  274. CustomMaterial *custMat = NULL;
  275. if( dynamic_cast<CustomMaterial*>(mMaterial) )
  276. {
  277. F32 pixVersion = GFX->getPixelShaderVersion();
  278. custMat = static_cast<CustomMaterial*>(mMaterial);
  279. if ((custMat->mVersion > pixVersion) || (custMat->mVersion == 0.0))
  280. {
  281. if(custMat->mFallback)
  282. {
  283. mMaterial = custMat->mFallback;
  284. return processMaterial();
  285. }
  286. else
  287. {
  288. AssertWarn(custMat->mVersion == 0.0f, avar("Can't load CustomMaterial %s for %s, using generic FF fallback",
  289. String(mMaterial->getName()).isEmpty() ? "Unknown" : mMaterial->getName(), custMat->mMapTo.c_str()));
  290. mProcessedMaterial = new ProcessedFFMaterial(*mMaterial);
  291. }
  292. }
  293. else
  294. mProcessedMaterial = new ProcessedCustomMaterial(*mMaterial);
  295. }
  296. else if(GFX->getPixelShaderVersion() > 0.001)
  297. mProcessedMaterial = getShaderMaterial();
  298. else
  299. mProcessedMaterial = new ProcessedFFMaterial(*mMaterial);
  300. if (mProcessedMaterial)
  301. {
  302. mProcessedMaterial->addStateBlockDesc( mUserDefinedState );
  303. mProcessedMaterial->setShaderMacros( mUserMacros );
  304. mProcessedMaterial->setUserObject( mUserObject );
  305. FeatureSet features( mFeatureList );
  306. features.exclude( MATMGR->getExclusionFeatures() );
  307. if (mVertexFormat->hasBlendIndices() && TSShape::smUseHardwareSkinning)
  308. {
  309. features.addFeature( MFT_HardwareSkinning );
  310. }
  311. if( !mProcessedMaterial->init(features, mVertexFormat, mFeaturesDelegate) )
  312. {
  313. Con::errorf( "Failed to initialize material '%s'", getMaterial()->getName() );
  314. SAFE_DELETE( mProcessedMaterial );
  315. return false;
  316. }
  317. mDefaultParameters = new MatInstParameters(mProcessedMaterial->getDefaultMaterialParameters());
  318. mActiveParameters = mDefaultParameters;
  319. const FeatureSet &finalFeatures = mProcessedMaterial->getFeatures();
  320. mHasNormalMaps = finalFeatures.hasFeature( MFT_NormalMap );
  321. mUsesHardwareSkinning = finalFeatures.hasFeature( MFT_HardwareSkinning );
  322. mIsForwardLit = ( custMat && custMat->mForwardLit ) ||
  323. ( !finalFeatures.hasFeature( MFT_IsEmissive ) &&
  324. finalFeatures.hasFeature( MFT_ForwardShading ) );
  325. mIsHardwareSkinned = finalFeatures.hasFeature( MFT_HardwareSkinning );
  326. return true;
  327. }
  328. return false;
  329. }
  330. const MatStateHint& MatInstance::getStateHint() const
  331. {
  332. if ( mProcessedMaterial )
  333. return mProcessedMaterial->getStateHint();
  334. else
  335. return MatStateHint::Default;
  336. }
  337. ProcessedMaterial* MatInstance::getShaderMaterial()
  338. {
  339. return new ProcessedShaderMaterial(*mMaterial);
  340. }
  341. void MatInstance::addStateBlockDesc(const GFXStateBlockDesc& desc)
  342. {
  343. mUserDefinedState = desc;
  344. }
  345. void MatInstance::updateStateBlocks()
  346. {
  347. if ( mProcessedMaterial )
  348. mProcessedMaterial->updateStateBlocks();
  349. }
  350. void MatInstance::addShaderMacro( const String &name, const String &value )
  351. {
  352. // Check to see if we already have this macro.
  353. Vector<GFXShaderMacro>::iterator iter = mUserMacros.begin();
  354. for ( ; iter != mUserMacros.end(); iter++ )
  355. {
  356. if ( iter->name == name )
  357. {
  358. iter->value = value;
  359. return;
  360. }
  361. }
  362. // Add a new macro.
  363. mUserMacros.increment();
  364. mUserMacros.last().name = name;
  365. mUserMacros.last().value = value;
  366. }
  367. //----------------------------------------------------------------------------
  368. // Setup pass - needs scenegraph data because the lightmap will change across
  369. // several materials.
  370. //----------------------------------------------------------------------------
  371. bool MatInstance::setupPass(SceneRenderState * state, const SceneData &sgData )
  372. {
  373. PROFILE_SCOPE( MatInstance_SetupPass );
  374. if( !mProcessedMaterial )
  375. return false;
  376. ++mCurPass;
  377. if ( !mProcessedMaterial->setupPass( state, sgData, mCurPass ) )
  378. {
  379. mCurPass = -1;
  380. return false;
  381. }
  382. return true;
  383. }
  384. void MatInstance::setTransforms(const MatrixSet &matrixSet, SceneRenderState *state)
  385. {
  386. PROFILE_SCOPE(MatInstance_setTransforms);
  387. mProcessedMaterial->setTransforms(matrixSet, state, getCurPass());
  388. }
  389. void MatInstance::setNodeTransforms(const MatrixF *address, const U32 numTransforms)
  390. {
  391. PROFILE_SCOPE(MatInstance_setNodeTransforms);
  392. mProcessedMaterial->setNodeTransforms(address, numTransforms, getCurPass());
  393. }
  394. void MatInstance::setSceneInfo(SceneRenderState * state, const SceneData& sgData)
  395. {
  396. PROFILE_SCOPE(MatInstance_setSceneInfo);
  397. mProcessedMaterial->setSceneInfo(state, sgData, getCurPass());
  398. }
  399. void MatInstance::setBuffers(GFXVertexBufferHandleBase* vertBuffer, GFXPrimitiveBufferHandle* primBuffer)
  400. {
  401. mProcessedMaterial->setBuffers(vertBuffer, primBuffer);
  402. }
  403. void MatInstance::setTextureStages(SceneRenderState * state, const SceneData &sgData )
  404. {
  405. PROFILE_SCOPE(MatInstance_setTextureStages);
  406. mProcessedMaterial->setTextureStages(state, sgData, getCurPass());
  407. }
  408. bool MatInstance::isInstanced() const
  409. {
  410. return mProcessedMaterial->getFeatures().hasFeature( MFT_UseInstancing );
  411. }
  412. bool MatInstance::stepInstance()
  413. {
  414. AssertFatal( isInstanced(), "MatInstance::stepInstance - This material isn't instanced!" );
  415. AssertFatal( mCurPass >= 0, "MatInstance::stepInstance - Must be within material setup pass!" );
  416. return mProcessedMaterial->stepInstance();
  417. }
  418. U32 MatInstance::getCurStageNum()
  419. {
  420. return mProcessedMaterial->getStageFromPass(getCurPass());
  421. }
  422. RenderPassData* MatInstance::getPass(U32 pass)
  423. {
  424. return mProcessedMaterial->getPass(pass);
  425. }
  426. bool MatInstance::hasGlow()
  427. {
  428. if( mProcessedMaterial )
  429. return mProcessedMaterial->hasGlow();
  430. else
  431. return false;
  432. }
  433. bool MatInstance::hasAccumulation()
  434. {
  435. if( mProcessedMaterial )
  436. return mProcessedMaterial->hasAccumulation();
  437. else
  438. return false;
  439. }
  440. const FeatureSet& MatInstance::getFeatures() const
  441. {
  442. return mProcessedMaterial->getFeatures();
  443. }
  444. MaterialParameterHandle* MatInstance::getMaterialParameterHandle(const String& name)
  445. {
  446. AssertFatal(mProcessedMaterial, "Not init'ed!");
  447. for (U32 i = 0; i < mCurrentHandles.size(); i++)
  448. {
  449. if (mCurrentHandles[i]->getName().equal(name))
  450. {
  451. return mCurrentHandles[i];
  452. }
  453. }
  454. MatInstanceParameterHandle* mph = new MatInstanceParameterHandle(name);
  455. mph->loadHandle(mProcessedMaterial);
  456. mCurrentHandles.push_back(mph);
  457. return mph;
  458. }
  459. MaterialParameters* MatInstance::allocMaterialParameters()
  460. {
  461. AssertFatal(mProcessedMaterial, "Not init'ed!");
  462. MatInstParameters* mip = new MatInstParameters();
  463. mip->loadParameters(mProcessedMaterial);
  464. mCurrentParameters.push_back(mip);
  465. return mip;
  466. }
  467. void MatInstance::setMaterialParameters(MaterialParameters* param)
  468. {
  469. AssertFatal(mProcessedMaterial, "Not init'ed!");
  470. mProcessedMaterial->setMaterialParameters(param, mCurPass);
  471. AssertFatal(dynamic_cast<MatInstParameters*>(param), "Incorrect param type!");
  472. mActiveParameters = static_cast<MatInstParameters*>(param);
  473. }
  474. MaterialParameters* MatInstance::getMaterialParameters()
  475. {
  476. AssertFatal(mProcessedMaterial, "Not init'ed!");
  477. return mActiveParameters;
  478. }
  479. void MatInstance::dumpShaderInfo() const
  480. {
  481. if ( mMaterial == NULL )
  482. {
  483. Con::errorf( "Trying to get Material information on an invalid MatInstance" );
  484. return;
  485. }
  486. Con::printf( "Material Info for object %s - %s", mMaterial->getName(), mMaterial->mMapTo.c_str() );
  487. if ( mProcessedMaterial == NULL )
  488. {
  489. Con::printf( " [no processed material!]" );
  490. return;
  491. }
  492. mProcessedMaterial->dumpMaterialInfo();
  493. }