Example #1
0
void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, SceneZoneSpace* baseObject, U32 baseZone )
{
   PROFILE_SCOPE( SceneGraph_renderScene );

   // Get the lights for rendering the scene.

   PROFILE_START( SceneGraph_registerLights );
      LIGHTMGR->registerGlobalLights( &renderState->getCullingFrustum(), false );
   PROFILE_END();

   // If its a diffuse pass, update the current ambient light level.
   // To do that find the starting zone and determine whether it has a custom
   // ambient light color.  If so, pass it on to the ambient light manager.
   // If not, use the ambient light color of the sunlight.
   //
   // Note that we retain the starting zone information here and pass it
   // on to renderSceneNoLights so that we don't need to look it up twice.

   if( renderState->isDiffusePass() )
   {
      if( !baseObject && getZoneManager() )
      {
         getZoneManager()->findZone( renderState->getCameraPosition(), baseObject, baseZone );
         AssertFatal( baseObject != NULL, "SceneManager::renderScene - findZone() did not return an object" );
      }

      ColorF zoneAmbient;
      if( baseObject && baseObject->getZoneAmbientLightColor( baseZone, zoneAmbient ) )
         mAmbientLightColor.setTargetValue( zoneAmbient );
      else
      {
         const LightInfo* sunlight = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
         if( sunlight )
            mAmbientLightColor.setTargetValue( sunlight->getAmbient() );
      }

      renderState->setAmbientLightColor( mAmbientLightColor.getCurrentValue() );
   }

   // Trigger the pre-render signal.

   PROFILE_START( SceneGraph_preRenderSignal);
      mCurrentRenderState = renderState;
      getPreRenderSignal().trigger( this, renderState );
      mCurrentRenderState = NULL;
   PROFILE_END();

   // Render the scene.

   if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
   {
      // Store previous values
      RectI originalVP = GFX->getViewport();
      MatrixF originalWorld = GFX->getWorldMatrix();
      Frustum originalFrustum = GFX->getFrustum();

      Point2F projOffset = GFX->getCurrentProjectionOffset();
      const FovPort *currentFovPort = GFX->getStereoFovPort();
      const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
      const MatrixF *worldEyeTransforms = GFX->getInverseStereoEyeTransforms();

      // Render left half of display
      GFX->activateStereoTarget(0);
      GFX->beginField();

      GFX->setWorldMatrix(worldEyeTransforms[0]);

      Frustum gfxFrustum = originalFrustum;
      MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[0], eyeTransforms[0]);
      GFX->setFrustum(gfxFrustum);

      SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
      SceneRenderState renderStateLeft( this, renderState->getScenePassType(), cameraStateLeft );
      renderStateLeft.setSceneRenderStyle(SRS_SideBySide);
      renderStateLeft.setSceneRenderField(0);

      renderSceneNoLights( &renderStateLeft, objectMask, baseObject, baseZone );

      // Indicate that we've just finished a field
      //GFX->clear(GFXClearTarget | GFXClearZBuffer | GFXClearStencil, ColorI(255,0,0), 1.0f, 0);
      GFX->endField();
      
      // Render right half of display
      GFX->activateStereoTarget(1);
      GFX->beginField();
      GFX->setWorldMatrix(worldEyeTransforms[1]);

      gfxFrustum = originalFrustum;
      MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[1], eyeTransforms[1]);
      GFX->setFrustum(gfxFrustum);

      SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
      SceneRenderState renderStateRight( this, renderState->getScenePassType(), cameraStateRight );
      renderStateRight.setSceneRenderStyle(SRS_SideBySide);
      renderStateRight.setSceneRenderField(1);

      renderSceneNoLights( &renderStateRight, objectMask, baseObject, baseZone );

      // Indicate that we've just finished a field
      //GFX->clear(GFXClearTarget | GFXClearZBuffer | GFXClearStencil, ColorI(0,255,0), 1.0f, 0);
      GFX->endField();

      // Restore previous values
      GFX->setWorldMatrix(originalWorld);
      GFX->setFrustum(originalFrustum);
      GFX->setViewport(originalVP);
   }
   else
   {
      renderSceneNoLights( renderState, objectMask, baseObject, baseZone );
   }

   // Trigger the post-render signal.

   PROFILE_START( SceneGraphRender_postRenderSignal );
      mCurrentRenderState = renderState;
      getPostRenderSignal().trigger( this, renderState );
      mCurrentRenderState = NULL;
   PROFILE_END();

   // Remove the previously registered lights.

   PROFILE_START( SceneGraph_unregisterLights);
      LIGHTMGR->unregisterAllLights();
   PROFILE_END();
}
void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, SceneZoneSpace* baseObject, U32 baseZone )
{
   PROFILE_SCOPE( SceneGraph_renderScene );

   // Get the lights for rendering the scene.

   PROFILE_START( SceneGraph_registerLights );
      LIGHTMGR->registerGlobalLights( &renderState->getFrustum(), false );
   PROFILE_END();

   // If its a diffuse pass, update the current ambient light level.
   // To do that find the starting zone and determine whether it has a custom
   // ambient light color.  If so, pass it on to the ambient light manager.
   // If not, use the ambient light color of the sunlight.
   //
   // Note that we retain the starting zone information here and pass it
   // on to renderSceneNoLights so that we don't need to look it up twice.

   if( renderState->isDiffusePass() )
   {
      if( !baseObject && getZoneManager() )
      {
         getZoneManager()->findZone( renderState->getCameraPosition(), baseObject, baseZone );
         AssertFatal( baseObject != NULL, "SceneManager::renderScene - findZone() did not return an object" );
      }

      ColorF zoneAmbient;
      if( baseObject && baseObject->getZoneAmbientLightColor( baseZone, zoneAmbient ) )
         mAmbientLightColor.setTargetValue( zoneAmbient );
      else
      {
         const LightInfo* sunlight = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
         if( sunlight )
            mAmbientLightColor.setTargetValue( sunlight->getAmbient() );
      }

      renderState->setAmbientLightColor( mAmbientLightColor.getCurrentValue() );
   }

   // Trigger the pre-render signal.

   PROFILE_START( SceneGraph_preRenderSignal);
      mCurrentRenderState = renderState;
      getPreRenderSignal().trigger( this, renderState );
      mCurrentRenderState = NULL;
   PROFILE_END();

   // Render the scene.

   if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
   {
      // Store previous values
      RectI originalVP = GFX->getViewport();
      MatrixF originalWorld = GFX->getWorldMatrix();

      Point2F projOffset = GFX->getCurrentProjectionOffset();
      Point3F eyeOffset = GFX->getStereoEyeOffset();

      // Render left half of display
      RectI leftVP = originalVP;
      leftVP.extent.x *= 0.5;
      GFX->setViewport(leftVP);

      MatrixF leftWorldTrans(true);
      leftWorldTrans.setPosition(Point3F(eyeOffset.x, eyeOffset.y, eyeOffset.z));
      MatrixF leftWorld(originalWorld);
      leftWorld.mulL(leftWorldTrans);
      GFX->setWorldMatrix(leftWorld);

      Frustum gfxFrustum = GFX->getFrustum();
      gfxFrustum.setProjectionOffset(Point2F(projOffset.x, projOffset.y));
      GFX->setFrustum(gfxFrustum);

      SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
      SceneRenderState renderStateLeft( this, renderState->getScenePassType(), cameraStateLeft );
      renderStateLeft.setSceneRenderStyle(SRS_SideBySide);
      renderStateLeft.setSceneRenderField(0);

      renderSceneNoLights( &renderStateLeft, objectMask, baseObject, baseZone );

      // Render right half of display
      RectI rightVP = originalVP;
      rightVP.extent.x *= 0.5;
      rightVP.point.x += rightVP.extent.x;
      GFX->setViewport(rightVP);

      MatrixF rightWorldTrans(true);
      rightWorldTrans.setPosition(Point3F(-eyeOffset.x, eyeOffset.y, eyeOffset.z));
      MatrixF rightWorld(originalWorld);
      rightWorld.mulL(rightWorldTrans);
      GFX->setWorldMatrix(rightWorld);

      gfxFrustum = GFX->getFrustum();
      gfxFrustum.setProjectionOffset(Point2F(-projOffset.x, projOffset.y));
      GFX->setFrustum(gfxFrustum);

      SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
      SceneRenderState renderStateRight( this, renderState->getScenePassType(), cameraStateRight );
      renderStateRight.setSceneRenderStyle(SRS_SideBySide);
      renderStateRight.setSceneRenderField(1);

      renderSceneNoLights( &renderStateRight, objectMask, baseObject, baseZone );

      // Restore previous values
      GFX->setWorldMatrix(originalWorld);
      gfxFrustum.clearProjectionOffset();
      GFX->setFrustum(gfxFrustum);
      GFX->setViewport(originalVP);
   }
   else
   {
      renderSceneNoLights( renderState, objectMask, baseObject, baseZone );
   }

   // Trigger the post-render signal.

   PROFILE_START( SceneGraphRender_postRenderSignal );
      mCurrentRenderState = renderState;
      getPostRenderSignal().trigger( this, renderState );
      mCurrentRenderState = NULL;
   PROFILE_END();

   // Remove the previously registered lights.

   PROFILE_START( SceneGraph_unregisterLights);
      LIGHTMGR->unregisterAllLights();
   PROFILE_END();
}