SceneRenderState::SceneRenderState( SceneManager* sceneManager,
                                    ScenePassType passType,
                                    const SceneCameraState& view,
                                    RenderPassManager* renderPass /* = NULL */,
                                    bool usePostEffects /* = true */ )
   :  mSceneManager( sceneManager ),
      mCullingState( sceneManager, view ),
      mRenderPass( renderPass ? renderPass : sceneManager->getDefaultRenderPass() ),
      mScenePassType( passType ),
      mRenderNonLightmappedMeshes( true ),
      mRenderLightmappedMeshes( true ),
      mUsePostEffects( usePostEffects ),
      mDisableAdvancedLightingBins( false ),
      mRenderArea( view.getFrustum().getBounds() ),
      mAmbientLightColor( sceneManager->getAmbientLightColor() ),
      mSceneRenderStyle( SRS_Standard ),
      mRenderField( 0 )
{
   // Setup the default parameters for the screen metrics methods.
   mDiffuseCameraTransform = view.getViewWorldMatrix();

   // The vector eye is the camera vector with its 
   // length normalized to 1 / zFar.
   getCameraTransform().getColumn( 1, &mVectorEye );
   mVectorEye.normalize( 1.0f / getFarPlane() );

   // TODO: What about ortho modes?  Is near plane ok
   // or do i need to remove it... maybe ortho has a near
   // plane of 1 and it just works out?

   const Frustum& frustum = view.getFrustum();
   const RectI& viewport = view.getViewport();

   mWorldToScreenScale.set(   ( frustum.getNearDist() * viewport.extent.x ) / ( frustum.getNearRight() - frustum.getNearLeft() ),
                              ( frustum.getNearDist() * viewport.extent.y ) / ( frustum.getNearTop() - frustum.getNearBottom() ) );

   // Assign shared matrix data to the render pass.

   mRenderPass->assignSharedXform( RenderPassManager::View, view.getWorldViewMatrix() );
   mRenderPass->assignSharedXform( RenderPassManager::Projection, view.getProjectionMatrix() );
}
void OcclusionVolume::buildSilhouette( const SceneCameraState& cameraState, Vector< Point3F >& outPoints )
{
   // Extract the silhouette of the polyhedron.  This works differently
   // depending on whether we project orthogonally or in perspective.

   TempAlloc< U32 > indices( mPolyhedron.getNumPoints() );
   U32 numPoints;

   if( cameraState.getFrustum().isOrtho() )
   {
      // Transform the view direction into object space.

      Point3F osViewDir;
      getWorldTransform().mulV( cameraState.getViewDirection(), &osViewDir );

      // And extract the silhouette.

      SilhouetteExtractorOrtho< PolyhedronType > extractor( mPolyhedron );
      numPoints = extractor.extractSilhouette( osViewDir, indices, indices.size );
   }
   else
   {
      // Create a transform to go from view space to object space.

      MatrixF camView( true );
      camView.scale( Point3F( 1.0f / getScale().x, 1.0f / getScale().y, 1.0f / getScale().z ) );
      camView.mul( getRenderWorldTransform() );
      camView.mul( cameraState.getViewWorldMatrix() );

      // Do a perspective-correct silhouette extraction.

      numPoints = mSilhouetteExtractor.extractSilhouette(
         camView,
         indices, indices.size );
   }

   // If we haven't yet, transform the polyhedron's points
   // to world space.

   if( mTransformDirty )
   {
      const U32 numPoints = mPolyhedron.getNumPoints();
      const PolyhedronType::PointType* points = getPolyhedron().getPoints();

      mWSPoints.setSize( numPoints );
      for( U32 i = 0; i < numPoints; ++ i )
      {
         Point3F p = points[ i ];
         p.convolve( getScale() );
         getTransform().mulP( p, &mWSPoints[ i ] );
      }

      mTransformDirty = false;
   }

   // Now store the points.

   outPoints.setSize( numPoints );
   for( U32 i = 0; i < numPoints; ++ i )
      outPoints[ i ] = mWSPoints[ indices[ i ] ];
}
Exemple #3
0
void PlaneReflector::updateReflection( const ReflectParams &params )
{
   PROFILE_SCOPE(PlaneReflector_updateReflection);   
   GFXDEBUGEVENT_SCOPE( PlaneReflector_updateReflection, ColorI::WHITE );

   mIsRendering = true;

   S32 texDim = mDesc->texSize;
   texDim = getMax( texDim, 32 );

   // Protect against the reflection texture being bigger
   // than the current game back buffer.
   texDim = getMin( texDim, params.viewportExtent.x );
   texDim = getMin( texDim, params.viewportExtent.y );

   bool texResize = ( texDim != mLastTexSize );  
   mLastTexSize = texDim;

   const Point2I texSize( texDim, texDim );

   if (  texResize || 
         reflectTex.isNull() ||
         reflectTex->getFormat() != REFLECTMGR->getReflectFormat() )
      reflectTex = REFLECTMGR->allocRenderTarget( texSize );

   GFXTexHandle depthBuff = LightShadowMap::_getDepthTarget( texSize.x, texSize.y );

   // store current matrices
   GFXTransformSaver saver;
   
   Point2I viewport(params.viewportExtent);
   if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
   {
      viewport.x *= 0.5f;
   }
   F32 aspectRatio = F32( viewport.x ) / F32( viewport.y );

   Frustum frustum;
   frustum.set(false, params.query->fov, aspectRatio, params.query->nearPlane, params.query->farPlane);

   // Manipulate the frustum for tiled screenshots
   const bool screenShotMode = gScreenShot && gScreenShot->isPending();
   if ( screenShotMode )
      gScreenShot->tileFrustum( frustum );

   GFX->setFrustum( frustum );
      
   // Store the last view info for scoring.
   mLastDir = params.query->cameraMatrix.getForwardVector();
   mLastPos = params.query->cameraMatrix.getPosition();

   setGFXMatrices( params.query->cameraMatrix );

   // Adjust the detail amount
   F32 detailAdjustBackup = TSShapeInstance::smDetailAdjust;
   TSShapeInstance::smDetailAdjust *= mDesc->detailAdjust;


   if(reflectTarget.isNull())
      reflectTarget = GFX->allocRenderToTextureTarget();
   reflectTarget->attachTexture( GFXTextureTarget::Color0, reflectTex );
   reflectTarget->attachTexture( GFXTextureTarget::DepthStencil, depthBuff );
   GFX->pushActiveRenderTarget();
   GFX->setActiveRenderTarget( reflectTarget );   

   U32 objTypeFlag = -1;
   SceneCameraState reflectCameraState = SceneCameraState::fromGFX();
   LIGHTMGR->registerGlobalLights( &reflectCameraState.getFrustum(), false );

   // Since we can sometime be rendering a reflection for 1 or 2 frames before
   // it gets updated do to the lag associated with getting the results from
   // a HOQ we can sometimes see into parts of the reflection texture that
   // have nothing but clear color ( eg. under the water ).
   // To make this look less crappy use the ambient color of the sun.
   //
   // In the future we may want to fix this instead by having the scatterSky
   // render a skirt or something in its lower half.
   //
   ColorF clearColor = gClientSceneGraph->getAmbientLightColor();
   GFX->clear( GFXClearZBuffer | GFXClearStencil | GFXClearTarget, clearColor, 1.0f, 0 );

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

      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(params.query->cameraMatrix);
      leftWorld.mulL(leftWorldTrans);

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

      setGFXMatrices( leftWorld );

      SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
      SceneRenderState renderStateLeft( gClientSceneGraph, SPT_Reflect, cameraStateLeft );
      renderStateLeft.setSceneRenderStyle(SRS_SideBySide);
      renderStateLeft.setSceneRenderField(0);
      renderStateLeft.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
      renderStateLeft.setDiffuseCameraTransform( params.query->cameraMatrix );
      renderStateLeft.disableAdvancedLightingBins(true);

      gClientSceneGraph->renderSceneNoLights( &renderStateLeft, objTypeFlag );

      // 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(params.query->cameraMatrix);
      rightWorld.mulL(rightWorldTrans);

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

      setGFXMatrices( rightWorld );

      SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
      SceneRenderState renderStateRight( gClientSceneGraph, SPT_Reflect, cameraStateRight );
      renderStateRight.setSceneRenderStyle(SRS_SideBySide);
      renderStateRight.setSceneRenderField(1);
      renderStateRight.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
      renderStateRight.setDiffuseCameraTransform( params.query->cameraMatrix );
      renderStateRight.disableAdvancedLightingBins(true);

      gClientSceneGraph->renderSceneNoLights( &renderStateRight, objTypeFlag );

      // Restore previous values
      gfxFrustum.clearProjectionOffset();
      GFX->setFrustum(gfxFrustum);
      GFX->setViewport(originalVP);
   }
   else
   {
      SceneRenderState reflectRenderState
      (
         gClientSceneGraph,
         SPT_Reflect,
         SceneCameraState::fromGFX()
      );

      reflectRenderState.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
      reflectRenderState.setDiffuseCameraTransform( params.query->cameraMatrix );
      reflectRenderState.disableAdvancedLightingBins(true);

      gClientSceneGraph->renderSceneNoLights( &reflectRenderState, objTypeFlag );
   }

   LIGHTMGR->unregisterAllLights();

   // Clean up.
   reflectTarget->resolve();
   GFX->popActiveRenderTarget();

   // Restore detail adjust amount.
   TSShapeInstance::smDetailAdjust = detailAdjustBackup;

   mIsRendering = false;
}