Torque3D Documentation / _generateds / processedFFMaterial.cpp

processedFFMaterial.cpp

Engine/source/materials/processedFFMaterial.cpp

More...

Classes:

Detailed Description

  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/processedFFMaterial.h"
 26
 27#include "gfx/sim/cubemapData.h"
 28#include "materials/sceneData.h"
 29#include "materials/customMaterialDefinition.h"
 30#include "materials/materialFeatureTypes.h"
 31#include "gfx/sim/gfxStateBlockData.h"
 32#include "gfx/gfxDevice.h"
 33#include "gfx/genericConstBuffer.h"
 34#include "materials/materialParameters.h"
 35#include "lighting/lightInfo.h"
 36#include "scene/sceneRenderState.h"
 37#include "core/util/safeDelete.h"
 38#include "math/util/matrixSet.h"
 39
 40class FFMaterialParameterHandle : public MaterialParameterHandle
 41{
 42public:
 43   virtual ~FFMaterialParameterHandle() {}
 44   virtual const String& getName() const { return mName; }
 45   virtual bool isValid() const { return false; }
 46   virtual S32 getSamplerRegister( U32 pass ) const { return -1; }
 47private:
 48   String mName;
 49};
 50
 51ProcessedFFMaterial::ProcessedFFMaterial()
 52{
 53   VECTOR_SET_ASSOCIATION( mParamDesc );
 54
 55   _construct();
 56}
 57
 58ProcessedFFMaterial::ProcessedFFMaterial(Material &mat, const bool isLightingMaterial)
 59{
 60   VECTOR_SET_ASSOCIATION( mParamDesc );
 61
 62   _construct();
 63   mMaterial = &mat;
 64   mIsLightingMaterial = isLightingMaterial;
 65}
 66
 67void ProcessedFFMaterial::_construct()
 68{   
 69   mHasSetStageData = false;
 70   mHasGlow = false;
 71   mHasAccumulation = false;
 72   mIsLightingMaterial = false;
 73   mDefaultHandle = new FFMaterialParameterHandle();
 74   mDefaultParameters = new MaterialParameters();
 75   mCurrentParams = mDefaultParameters;
 76}
 77
 78ProcessedFFMaterial::~ProcessedFFMaterial()
 79{
 80   SAFE_DELETE(mDefaultParameters);
 81   SAFE_DELETE( mDefaultHandle );
 82}
 83
 84void ProcessedFFMaterial::_createPasses( U32 stageNum, const FeatureSet &features )
 85{
 86   FixedFuncFeatureData featData;
 87   _determineFeatures(stageNum, featData, features);
 88   // Just create a simple pass!
 89   _addPass(0, featData);
 90
 91   mFeatures.clear();
 92   if ( featData.features[FixedFuncFeatureData::DiffuseMap] ) 
 93      mFeatures.addFeature( MFT_DiffuseMap );
 94   if ( featData.features[FixedFuncFeatureData::LightMap] ) 
 95      mFeatures.addFeature( MFT_LightMap );
 96   if ( featData.features[FixedFuncFeatureData::ToneMap] ) 
 97      mFeatures.addFeature( MFT_ToneMap );
 98
 99}
100
101void ProcessedFFMaterial::_determineFeatures(   U32 stageNum, 
102                                                FixedFuncFeatureData& featData, 
103                                                const FeatureSet &features )
104{
105   if ( mStages[stageNum].getTex( MFT_DiffuseMap ) )
106      featData.features[FixedFuncFeatureData::DiffuseMap] = true;
107
108   if ( features.hasFeature( MFT_LightMap ) )
109      featData.features[FixedFuncFeatureData::LightMap] = true;
110   if ( features.hasFeature( MFT_ToneMap )) 
111      featData.features[FixedFuncFeatureData::ToneMap] = true;
112}
113
114U32 ProcessedFFMaterial::getNumStages()
115{
116   // Loops through all stages to determine how many stages we actually use
117   U32 numStages = 0;
118
119   U32 i;
120   for( i=0; i<Material::MAX_STAGES; i++ )
121   {
122      // Assume stage is inactive
123      bool stageActive = false;
124
125      // Cubemaps only on first stage
126      if( i == 0 )
127      {
128         // If we have a cubemap the stage is active
129         if( mMaterial->mCubemapData || mMaterial->mDynamicCubemap )
130         {
131            numStages++;
132            continue;
133         }
134      }
135
136      // If we have a texture for the a feature the 
137      // stage is active.
138      if ( mStages[i].hasValidTex() )
139         stageActive = true;
140
141      // If this stage has specular lighting, it's active
142      if (  mMaterial->mPixelSpecular[i] )
143         stageActive = true;
144
145      // If we have a Material that is vertex lit
146      // then it may not have a texture
147      if( mMaterial->mVertLit[i] )
148      {
149         stageActive = true;
150      }
151
152      // Increment the number of active stages
153      numStages += stageActive;
154   }
155
156
157   return numStages;
158}
159
160bool ProcessedFFMaterial::setupPass( SceneRenderState *state, const SceneData &sgData, U32 pass )
161{
162   PROFILE_SCOPE( ProcessedFFMaterial_SetupPass );
163
164   // Make sure we have a pass
165   if(pass >= mPasses.size())
166      return false;
167
168   _setRenderState( state, sgData, pass );
169
170   // Bind our textures
171   setTextureStages( state, sgData, pass );
172   return true;
173}
174
175void ProcessedFFMaterial::setTextureStages(SceneRenderState * state, const SceneData& sgData, U32 pass)
176{
177   // We may need to do some trickery in here for fixed function, this is just copy/paste from MatInstance
178#ifdef TORQUE_DEBUG
179   AssertFatal( pass<mPasses.size(), "Pass out of bounds" );
180#endif
181   RenderPassData *rpd = mPasses[pass];
182   for( U32 i=0; i<rpd->mNumTex; i++ )
183   {      
184      U32 currTexFlag = rpd->mTexType[i];
185      if (!LIGHTMGR || !LIGHTMGR->setTextureStage(sgData, currTexFlag, i, NULL, NULL))
186      {
187         switch( currTexFlag )
188         {
189         case Material::NoTexture:
190            if (rpd->mTexSlot[i].texObject)
191               GFX->setTexture( i, rpd->mTexSlot[i].texObject );
192            break;
193
194         case Material::NormalizeCube:
195            GFX->setCubeTexture(i, Material::GetNormalizeCube());
196            break;
197
198         case Material::Lightmap:
199            GFX->setTexture( i, sgData.lightmap );
200            break;
201
202         case Material::Cube:
203            // TODO: Is this right?
204            GFX->setTexture( i, rpd->mTexSlot[0].texObject );
205            break;
206
207         case Material::SGCube:
208            // No cubemap support just yet
209            //GFX->setCubeTexture( i, sgData.cubemap );
210            GFX->setTexture( i, rpd->mTexSlot[0].texObject );
211            break;
212
213         case Material::BackBuff:
214            GFX->setTexture( i, sgData.backBuffTex );
215            break;
216         }
217      }
218   }
219}
220
221MaterialParameters* ProcessedFFMaterial::allocMaterialParameters()
222{   
223   return new MaterialParameters();
224}
225
226MaterialParameters* ProcessedFFMaterial::getDefaultMaterialParameters()
227{
228   return mDefaultParameters;
229}
230
231MaterialParameterHandle* ProcessedFFMaterial::getMaterialParameterHandle(const String& name)
232{
233   return mDefaultHandle;
234}
235
236void ProcessedFFMaterial::setTransforms(const MatrixSet &matrixSet, SceneRenderState *state, const U32 pass)
237{
238   GFX->setWorldMatrix(matrixSet.getObjectToWorld());
239   GFX->setViewMatrix(matrixSet.getWorldToCamera());
240   GFX->setProjectionMatrix(matrixSet.getCameraToScreen());
241}
242
243void ProcessedFFMaterial::setSceneInfo(SceneRenderState * state, const SceneData& sgData, U32 pass)
244{
245   _setPrimaryLightInfo(*sgData.objTrans, sgData.lights[0], pass);
246   _setSecondaryLightInfo(*sgData.objTrans, sgData.lights[1]);   
247}
248
249void ProcessedFFMaterial::_setPrimaryLightInfo(const MatrixF &_objTrans, LightInfo* light, U32 pass)
250{
251   // Just in case
252   GFX->setGlobalAmbientColor(ColorF(0.0f, 0.0f, 0.0f, 1.0f));
253   if ( light->getType() == LightInfo::Ambient )
254   {
255      // Ambient light
256      GFX->setGlobalAmbientColor( light->getAmbient() );
257      return;
258   }
259
260   GFX->setLight(0, NULL);
261   GFX->setLight(1, NULL);
262   // This is a quick hack that lets us use FF lights
263   GFXLightMaterial lightMat;
264   lightMat.ambient = ColorF(1.0f, 1.0f, 1.0f, 1.0f);
265   lightMat.diffuse = ColorF(1.0f, 1.0f, 1.0f, 1.0f);
266   lightMat.emissive = ColorF(0.0f, 0.0f, 0.0f, 0.0f);
267   lightMat.specular = ColorF(0.0f, 0.0f, 0.0f, 0.0f);
268   lightMat.shininess = 128.0f;
269   GFX->setLightMaterial(lightMat);   
270
271   // set object transform
272   MatrixF objTrans = _objTrans;
273   objTrans.inverse();
274
275   // fill in primary light
276   //-------------------------
277   GFXLightInfo xlatedLight;
278   light->setGFXLight(&xlatedLight);
279   Point3F lightPos = light->getPosition();
280   Point3F lightDir = light->getDirection();
281   objTrans.mulP(lightPos);
282   objTrans.mulV(lightDir);
283
284   xlatedLight.mPos = lightPos;
285   xlatedLight.mDirection = lightDir;
286
287   GFX->setLight(0, &xlatedLight);
288}
289
290void ProcessedFFMaterial::_setSecondaryLightInfo(const MatrixF &_objTrans, LightInfo* light)
291{
292   // set object transform
293   MatrixF objTrans = _objTrans;
294   objTrans.inverse();
295
296   // fill in secondary light
297   //-------------------------
298   GFXLightInfo xlatedLight;
299   light->setGFXLight(&xlatedLight);
300
301   Point3F lightPos = light->getPosition();
302   Point3F lightDir = light->getDirection();
303   objTrans.mulP(lightPos);
304   objTrans.mulV(lightDir);
305
306   xlatedLight.mPos = lightPos;
307   xlatedLight.mDirection = lightDir;
308
309   GFX->setLight(1, &xlatedLight);
310}
311
312bool ProcessedFFMaterial::init(  const FeatureSet &features, 
313                                 const GFXVertexFormat *vertexFormat,
314                                 const MatFeaturesDelegate &featuresDelegate )
315{
316   TORQUE_UNUSED( vertexFormat );
317   TORQUE_UNUSED( featuresDelegate );
318
319   _setStageData();
320
321   // Just create a simple pass
322   _createPasses(0, features);
323   _initRenderPassDataStateBlocks();
324   mStateHint.init( this );
325
326   return true;
327}
328
329void ProcessedFFMaterial::_addPass(U32 stageNum, FixedFuncFeatureData& featData)
330{
331   U32 numTex = 0;
332
333   // Just creates a simple pass, but it can still glow!
334   RenderPassData rpd;
335
336   // Base texture, texunit 0
337   if(featData.features[FixedFuncFeatureData::DiffuseMap])
338   {
339      rpd.mTexSlot[0].texObject = mStages[stageNum].getTex( MFT_DiffuseMap );
340      rpd.mTexType[0] = Material::NoTexture;
341      numTex++;
342   }
343
344   // lightmap, texunit 1
345   if(featData.features[FixedFuncFeatureData::LightMap])
346   {
347      rpd.mTexType[1] = Material::Lightmap;
348      numTex++;
349   }
350
351   rpd.mNumTex = numTex;
352   rpd.mStageNum = stageNum;
353   rpd.mGlow = false;
354
355   mPasses.push_back( new RenderPassData(rpd) );
356}
357
358void ProcessedFFMaterial::_setPassBlendOp()
359{
360
361}
362
363void ProcessedFFMaterial::_initPassStateBlock( RenderPassData *rpd, GFXStateBlockDesc &result )
364{
365   Parent::_initPassStateBlock( rpd, result );
366
367   if ( mIsLightingMaterial )
368   {
369      result.ffLighting = true;
370      result.blendDefined = true;
371      result.blendEnable = true;
372      result.blendSrc = GFXBlendOne;
373      result.blendDest = GFXBlendZero;
374   }
375
376   // This is here for generic FF shader fallbacks.
377   CustomMaterial* custmat = dynamic_cast<CustomMaterial*>(mMaterial);
378   if (custmat && custmat->getStateBlockData() )
379      result.addDesc(custmat->getStateBlockData()->getState());
380}
381