RenderPrePassMgr* LightManager::_findPrePassRenderBin()
{
   RenderPassManager* rpm = getSceneManager()->getDefaultRenderPass();
   for( U32 i = 0; i < rpm->getManagerCount(); i++ )
   {
      RenderBinManager *bin = rpm->getManager( i );
      if( bin->getRenderInstType() == RenderPrePassMgr::RIT_PrePass )
      {
         return ( RenderPrePassMgr* ) bin;
      }
   }

   return NULL;
}
void RenderTranslucentMgr::render( SceneRenderState *state )
{
    PROFILE_SCOPE(RenderTranslucentMgr_render);

    // Early out if nothing to draw.
    if(!mElementList.size())
        return;

    GFXDEBUGEVENT_SCOPE(RenderTranslucentMgr_Render, ColorI::BLUE);

    // Find the particle render manager (if we don't have it)
    if(mParticleRenderMgr == NULL)
    {
        RenderPassManager *rpm = state->getRenderPass();
        for( U32 i = 0; i < rpm->getManagerCount(); i++ )
        {
            RenderBinManager *bin = rpm->getManager(i);
            if( bin->getRenderInstType() == RenderParticleMgr::RIT_Particles )
            {
                mParticleRenderMgr = reinterpret_cast<RenderParticleMgr *>(bin);
                break;
            }
        }
    }

    GFXTransformSaver saver;

    SceneData sgData;
    sgData.init( state );

    GFXVertexBuffer * lastVB = NULL;
    GFXPrimitiveBuffer * lastPB = NULL;

    // Restore transforms
    MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
    matrixSet.restoreSceneViewProjection();

    U32 binSize = mElementList.size();
    for( U32 j=0; j<binSize; )
    {
        RenderInst *baseRI = mElementList[j].inst;

        U32 matListEnd = j;

        // render these separately...
        if ( baseRI->type == RenderPassManager::RIT_ObjectTranslucent )
        {
            ObjectRenderInst* objRI = static_cast<ObjectRenderInst*>(baseRI);
            objRI->renderDelegate( objRI, state, NULL );

            lastVB = NULL;
            lastPB = NULL;
            j++;
            continue;
        }
        //Volumetric Fog Add
        else if (baseRI->type == RenderPassManager::RIT_VolumetricFog)
        {
            ObjectRenderInst* objRI = static_cast<ObjectRenderInst*>(baseRI);
            objRI->renderDelegate(objRI,state,NULL);

            lastVB = NULL;
            lastPB = NULL;
            j++;
            continue;
        }
        //Volumetric Fog Add
        else if ( baseRI->type == RenderPassManager::RIT_Particle )
        {
            ParticleRenderInst *ri = static_cast<ParticleRenderInst*>(baseRI);

            // Tell Particle RM to draw the system. (This allows the particle render manager
            // to manage drawing offscreen particle systems, and allows the systems
            // to be composited back into the scene with proper translucent
            // sorting order)
            mParticleRenderMgr->renderInstance(ri, state);

            lastVB = NULL;    // no longer valid, null it
            lastPB = NULL;    // no longer valid, null it

            j++;
            continue;
        }
        else if ( baseRI->type == RenderPassManager::RIT_Translucent )
        {
            MeshRenderInst* ri = static_cast<MeshRenderInst*>(baseRI);
            BaseMatInstance *mat = ri->matInst;

            setupSGData( ri, sgData );

            while( mat->setupPass( state, sgData ) )
            {
                U32 a;
                for( a=j; a<binSize; a++ )
                {
                    RenderInst* nextRI = mElementList[a].inst;
                    if ( nextRI->type != RenderPassManager::RIT_Translucent )
                        break;

                    MeshRenderInst *passRI = static_cast<MeshRenderInst*>(nextRI);

                    // Check to see if we need to break this batch.
                    if ( newPassNeeded( ri, passRI ) )
                        break;

                    // Z sorting and stuff is still not working in this mgr...
                    setupSGData( passRI, sgData );
                    mat->setSceneInfo(state, sgData);
                    matrixSet.setWorld(*passRI->objectToWorld);
                    matrixSet.setView(*passRI->worldToCamera);
                    matrixSet.setProjection(*passRI->projection);
                    mat->setTransforms(matrixSet, state);

                    // If we're instanced then don't render yet.
                    if ( mat->isInstanced() )
                    {
                        // Let the material increment the instance buffer, but
                        // break the batch if it runs out of room for more.
                        if ( !mat->stepInstance() )
                        {
                            a++;
                            break;
                        }

                        continue;
                    }

                    // Setup the vertex and index buffers.
                    mat->setBuffers( passRI->vertBuff, passRI->primBuff );

                    // Render this sucker.
                    if ( passRI->prim )
                        GFX->drawPrimitive( *passRI->prim );
                    else
                        GFX->drawPrimitive( passRI->primBuffIndex );
                }

                // Draw the instanced batch.
                if ( mat->isInstanced() )
                {
                    // Sets the buffers including the instancing stream.
                    mat->setBuffers( ri->vertBuff, ri->primBuff );

                    // Render the instanced stream.
                    if ( ri->prim )
                        GFX->drawPrimitive( *ri->prim );
                    else
                        GFX->drawPrimitive( ri->primBuffIndex );
                }

                matListEnd = a;
            }

            // force increment if none happened, otherwise go to end of batch
            j = ( j == matListEnd ) ? j+1 : matListEnd;
        }
    }
}
示例#3
0
void RenderGlowMgr::render( SceneRenderState *state )
{
   PROFILE_SCOPE( RenderGlowMgr_Render );
   
   if ( !isGlowEnabled() )
      return;

   const U32 binSize = mElementList.size();

   // If this is a non-diffuse pass or we have no objects to
   // render then tell the effect to skip rendering.
   if ( !state->isDiffusePass() || binSize == 0 )
   {
      getGlowEffect()->setSkip( true );
      return;
   }

   GFXDEBUGEVENT_SCOPE( RenderGlowMgr_Render, ColorI::GREEN );

   GFXTransformSaver saver;

   // Respect the current viewport
   mNamedTarget.setViewport(GFX->getViewport());

   // Tell the superclass we're about to render, preserve contents
   const bool isRenderingToTarget = _onPreRender( state, true );

   // Clear all the buffers to black.
   GFX->clear( GFXClearTarget, ColorI::BLACK, 1.0f, 0);

   // Restore transforms
   MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
   matrixSet.restoreSceneViewProjection();

   // init loop data
   SceneData sgData;
   sgData.init( state, SceneData::GlowBin );

   for( U32 j=0; j<binSize; )
   {
      RenderInst *_ri = mElementList[j].inst;
      if(_ri->type == RenderPassManager::RIT_Particle)
      {
         // Find the particle render manager (if we don't have it)
         if(mParticleRenderMgr == NULL)
         {
            RenderPassManager *rpm = state->getRenderPass();
            for( U32 i = 0; i < rpm->getManagerCount(); i++ )
            {
               RenderBinManager *bin = rpm->getManager(i);
               if( bin->getRenderInstType() == RenderParticleMgr::RIT_Particles )
               {
                  mParticleRenderMgr = reinterpret_cast<RenderParticleMgr *>(bin);
                  break;
               }
            }
         }

         ParticleRenderInst *ri = static_cast<ParticleRenderInst*>(_ri);

         GFX->setStateBlock(mParticleRenderMgr->_getHighResStateBlock(ri));
         mParticleRenderMgr->_getShaderConsts().mShaderConsts->setSafe(mParticleRenderMgr->_getShaderConsts().mModelViewProjSC, *ri->modelViewProj);

         mParticleRenderMgr->renderParticle(ri, state);
         j++;
         continue;
      }

      MeshRenderInst *ri = static_cast<MeshRenderInst*>(_ri);

      setupSGData( ri, sgData );

      BaseMatInstance *mat = ri->matInst;
      GlowMaterialHook *hook = mat->getHook<GlowMaterialHook>();
      if ( !hook )
      {
         hook = new GlowMaterialHook( ri->matInst );
         ri->matInst->addHook( hook );
      }
      BaseMatInstance *glowMat = hook->getMatInstance();

      U32 matListEnd = j;

      while( glowMat && glowMat->setupPass( state, sgData ) )
      {
         U32 a;
         for( a=j; a<binSize; a++ )
         {
            if (mElementList[a].inst->type == RenderPassManager::RIT_Particle)
               break;

            MeshRenderInst *passRI = static_cast<MeshRenderInst*>(mElementList[a].inst);

            if ( newPassNeeded( ri, passRI ) )
               break;

            matrixSet.setWorld(*passRI->objectToWorld);
            matrixSet.setView(*passRI->worldToCamera);
            matrixSet.setProjection(*passRI->projection);
            glowMat->setTransforms(matrixSet, state);

            glowMat->setSceneInfo(state, sgData);
            glowMat->setBuffers(passRI->vertBuff, passRI->primBuff);

            if ( passRI->prim )
               GFX->drawPrimitive( *passRI->prim );
            else
               GFX->drawPrimitive( passRI->primBuffIndex );
         }
         matListEnd = a;
         setupSGData( ri, sgData );
      }

      // force increment if none happened, otherwise go to end of batch
      j = ( j == matListEnd ) ? j+1 : matListEnd;
   }

   // Finish up.
   if ( isRenderingToTarget )
      _onPostRender();

   // Make sure the effect is gonna render.
   getGlowEffect()->setSkip( false );
}