Torque3D Documentation / _generateds / matInstance.cpp

matInstance.cpp

Engine/source/materials/matInstance.cpp

More...

Classes:

Public Defines

define
MATINSTPARAMSET(handle, f)     (!mParameters) \
      return; \
   (dynamic_cast<*>(handle), "Invalid handle type!"); \
   MatInstanceParameterHandle* mph = static_cast<*>(handle); \
   mParameters->set(mph->mProcessedHandle, f); \

Detailed Description

Public Defines

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