Torque3D Documentation / _generateds / renderMeshMgr.cpp

renderMeshMgr.cpp

Engine/source/renderInstance/renderMeshMgr.cpp

More...

Public Functions

ConsoleDocClass(RenderMeshMgr , "@brief A <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> bin <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> mesh <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">rendering.\n\n</a>" "This is the primary <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> bin in Torque which does most of the " "work of rendering DTS shapes and arbitrary mesh geometry. It knows " "how <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> mesh instances using materials and supports hardware mesh " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">instancing.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">RenderBin\n</a>" )

Detailed Description

Public Functions

ConsoleDocClass(RenderMeshMgr , "@brief A <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> bin <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> mesh <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">rendering.\n\n</a>" "This is the primary <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> bin in Torque which does most of the " "work of rendering DTS shapes and arbitrary mesh geometry. It knows " "how <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> mesh instances using materials and supports hardware mesh " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">instancing.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">RenderBin\n</a>" )

IMPLEMENT_CONOBJECT(RenderMeshMgr )

  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 "renderInstance/renderMeshMgr.h"
 26
 27#include "console/consoleTypes.h"
 28#include "gfx/gfxTransformSaver.h"
 29#include "gfx/gfxPrimitiveBuffer.h"
 30#include "materials/sceneData.h"
 31#include "materials/processedMaterial.h"
 32#include "materials/materialManager.h"
 33#include "scene/sceneRenderState.h"
 34#include "gfx/gfxDebugEvent.h"
 35#include "math/util/matrixSet.h"
 36
 37
 38IMPLEMENT_CONOBJECT(RenderMeshMgr);
 39
 40ConsoleDocClass( RenderMeshMgr, 
 41   "@brief A render bin for mesh rendering.\n\n"
 42   "This is the primary render bin in Torque which does most of the "
 43   "work of rendering DTS shapes and arbitrary mesh geometry.  It knows "
 44   "how to render mesh instances using materials and supports hardware mesh "
 45   "instancing.\n\n"
 46   "@ingroup RenderBin\n" );
 47
 48
 49RenderMeshMgr::RenderMeshMgr()
 50: RenderBinManager(RenderPassManager::RIT_Mesh, 1.0f, 1.0f)
 51{
 52}
 53
 54RenderMeshMgr::RenderMeshMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder)
 55   : RenderBinManager(riType, renderOrder, processAddOrder)
 56{
 57}
 58
 59void RenderMeshMgr::init()
 60{
 61   GFXStateBlockDesc d;
 62
 63   d.cullDefined = true;
 64   d.cullMode = GFXCullCCW;
 65   d.samplersDefined = true;
 66   d.samplers[0] = GFXSamplerStateDesc::getWrapLinear();
 67
 68   mNormalSB = GFX->createStateBlock(d);
 69
 70   d.cullMode = GFXCullCW;
 71   mReflectSB = GFX->createStateBlock(d);
 72}
 73
 74void RenderMeshMgr::initPersistFields()
 75{
 76   Parent::initPersistFields();
 77}
 78
 79//-----------------------------------------------------------------------------
 80// add element
 81//-----------------------------------------------------------------------------
 82void RenderMeshMgr::addElement( RenderInst *inst )
 83{
 84   // If this instance is translucent handle it in RenderTranslucentMgr
 85   if (inst->translucentSort)
 86      return;
 87
 88   AssertFatal( inst->defaultKey != 0, "RenderMeshMgr::addElement() - Got null sort key... did you forget to set it?" );
 89
 90   internalAddElement(inst);
 91}
 92
 93//-----------------------------------------------------------------------------
 94// render
 95//-----------------------------------------------------------------------------
 96void RenderMeshMgr::render(SceneRenderState * state)
 97{
 98   PROFILE_SCOPE(RenderMeshMgr_render);
 99
100   // Early out if nothing to draw.
101   if(!mElementList.size())
102      return;
103
104
105   GFXDEBUGEVENT_SCOPE( RenderMeshMgr_Render, ColorI::GREEN );
106
107   // Automagically save & restore our viewport and transforms.
108   GFXTransformSaver saver;
109
110   // Restore transforms
111   MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
112   matrixSet.restoreSceneViewProjection();
113
114   // init loop data
115   GFXTextureObject *lastLM = NULL;
116   GFXCubemap *lastCubemap = NULL;
117   GFXTextureObject *lastReflectTex = NULL;
118   GFXTextureObject *lastMiscTex = NULL;
119   GFXTextureObject *lastAccuTex = NULL;
120
121   SceneData sgData;
122   sgData.init( state );
123
124   U32 binSize = mElementList.size();
125
126   for( U32 j=0; j<binSize; )
127   {
128      MeshRenderInst *ri = static_cast<MeshRenderInst*>(mElementList[j].inst);
129
130      setupSGData( ri, sgData );
131      BaseMatInstance *mat = ri->matInst;
132
133      // If we have an override delegate then give it a 
134      // chance to swap the material with another.
135      if ( mMatOverrideDelegate )
136      {
137         mat = mMatOverrideDelegate( mat );
138         if ( !mat )
139         {
140            j++;
141            continue;
142         }
143      }
144
145      if( !mat )
146         mat = MATMGR->getWarningMatInstance();
147
148      // Check if bin is disabled in advanced lighting.
149      // Allow forward rendering pass on custom materials.
150
151      if ( ( MATMGR->getDeferredEnabled() && mBasicOnly && !mat->isCustomMaterial() ) )
152      {
153         j++;
154         continue;
155      }
156
157      U32 matListEnd = j;
158      lastMiscTex = sgData.miscTex;
159      U32 a;
160
161      while( mat && mat->setupPass(state, sgData ) )
162      {
163         for( a=j; a<binSize; a++ )
164         {
165            MeshRenderInst *passRI = static_cast<MeshRenderInst*>(mElementList[a].inst);
166
167            // Check to see if we need to break this batch.
168            if (  newPassNeeded( ri, passRI ) ||
169                  lastMiscTex != passRI->miscTex )
170            {
171               lastLM = NULL;
172               break;
173            }
174
175            matrixSet.setWorld(*passRI->objectToWorld);
176            matrixSet.setView(*passRI->worldToCamera);
177            matrixSet.setProjection(*passRI->projection);
178            mat->setTransforms(matrixSet, state);
179
180            // Setup HW skinning transforms if applicable
181            if (mat->usesHardwareSkinning())
182            {
183               mat->setNodeTransforms(passRI->mNodeTransforms, passRI->mNodeTransformCount);
184            }
185
186         //push along any overriden fields that are instance-specific as well
187         if (passRI->mCustomShaderData.size() > 0)
188         {
189            mat->setCustomShaderData(passRI->mCustomShaderData);
190         }
191
192            setupSGData( passRI, sgData );
193            mat->setSceneInfo( state, sgData );
194
195            // If we're instanced then don't render yet.
196            if ( mat->isInstanced() )
197            {
198               // Let the material increment the instance buffer, but
199               // break the batch if it runs out of room for more.
200               if ( !mat->stepInstance() )
201               {
202                  a++;
203                  break;
204               }
205
206               continue;
207            }
208
209            // TODO: This could proably be done in a cleaner way.
210            //
211            // This section of code is dangerous, it overwrites the
212            // lightmap values in sgData.  This could be a problem when multiple
213            // render instances use the same multi-pass material.  When
214            // the first pass is done, setupPass() is called again on
215            // the material, but the lightmap data has been changed in
216            // sgData to the lightmaps in the last renderInstance rendered.
217
218            // This section sets the lightmap data for the current batch.
219            // For the first iteration, it sets the same lightmap data,
220            // however the redundancy will be caught by GFXDevice and not
221            // actually sent to the card.  This is done for simplicity given
222            // the possible condition mentioned above.  Better to set always
223            // than to get bogged down into special case detection.
224            //-------------------------------------
225            bool dirty = false;
226
227            // set the lightmaps if different
228            if( passRI->lightmap && passRI->lightmap != lastLM )
229            {
230               sgData.lightmap = passRI->lightmap;
231               lastLM = passRI->lightmap;
232               dirty = true;
233            }
234
235            // set the cubemap if different.
236            if ( passRI->cubemap != lastCubemap )
237            {
238               sgData.cubemap = passRI->cubemap;
239               lastCubemap = passRI->cubemap;
240               dirty = true;
241            }
242
243            if ( passRI->reflectTex != lastReflectTex )
244            {
245               sgData.reflectTex = passRI->reflectTex;
246               lastReflectTex = passRI->reflectTex;
247               dirty = true;
248            }
249
250            // Update accumulation texture if it changed.
251            // Note: accumulation texture can be NULL, and must be updated.
252            if ( passRI->accuTex != lastAccuTex )
253            {
254               sgData.accuTex = passRI->accuTex;
255               lastAccuTex = passRI->accuTex;
256               dirty = true;
257            }
258
259            if ( dirty )
260               mat->setTextureStages( state, sgData );
261
262            // Setup the vertex and index buffers.
263            mat->setBuffers( passRI->vertBuff, passRI->primBuff );
264
265            // Render this sucker.
266            if ( passRI->prim )
267               GFX->drawPrimitive( *passRI->prim );
268            else
269               GFX->drawPrimitive( passRI->primBuffIndex );
270         }
271
272         // Draw the instanced batch.
273         if ( mat->isInstanced() )
274         {
275            // Sets the buffers including the instancing stream.
276            mat->setBuffers( ri->vertBuff, ri->primBuff );
277
278            // Render the instanced stream.
279            if ( ri->prim )
280               GFX->drawPrimitive( *ri->prim );
281            else
282               GFX->drawPrimitive( ri->primBuffIndex );
283         }
284
285         matListEnd = a;
286      }
287
288      // force increment if none happened, otherwise go to end of batch
289      j = ( j == matListEnd ) ? j+1 : matListEnd;
290   }
291}
292
293