Browse Source

Update ReflectionManager on Scene Field Change

During side-by-side rendering the refraction texture needs to be updated
for both the left and right fields.  These changes add a new GFXDevice
event type to track when a field is about to be rendered.  The
ReflectionManager listens to this new event and ensures that the
refraction texture will be updated if it is referenced by a material.
DavidWyand-GG 12 years ago
parent
commit
39ab93636c

+ 18 - 2
Engine/source/gfx/gfxDevice.cpp

@@ -794,6 +794,8 @@ void GFXDevice::setCubeTexture( U32 stage, GFXCubemap *texture )
    mCurrentTexture[stage] = NULL;
 }
 
+//------------------------------------------------------------------------------
+
 inline bool GFXDevice::beginScene()
 {
    AssertFatal( mCanCurrentlyRender == false, "GFXDevice::beginScene() - The scene has already begun!" );
@@ -806,8 +808,6 @@ inline bool GFXDevice::beginScene()
    return beginSceneInternal();
 }
 
-//------------------------------------------------------------------------------
-
 inline void GFXDevice::endScene()
 {
    AssertFatal( mCanCurrentlyRender == true, "GFXDevice::endScene() - The scene has already ended!" );
@@ -819,6 +819,22 @@ inline void GFXDevice::endScene()
    mDeviceStatistics.exportToConsole();
 }
 
+inline void GFXDevice::beginField()
+{
+   AssertFatal( mCanCurrentlyRender == true, "GFXDevice::beginField() - The scene has not yet begun!" );
+
+   // Send the start of field signal.
+   getDeviceEventSignal().trigger( GFXDevice::deStartOfField );
+}
+
+inline void GFXDevice::endField()
+{
+   AssertFatal( mCanCurrentlyRender == true, "GFXDevice::endField() - The scene has not yet begun!" );
+
+   // Send the end of field signal.
+   getDeviceEventSignal().trigger( GFXDevice::deEndOfField );
+}
+
 void GFXDevice::setViewport( const RectI &inRect ) 
 {
    // Clip the rect against the renderable size.

+ 8 - 0
Engine/source/gfx/gfxDevice.h

@@ -209,6 +209,12 @@ public:
       
       /// The device is about to finish rendering a frame
       deEndOfFrame,
+
+      /// The device has started rendering a frame's field (such as for side-by-side rendering)
+      deStartOfField,
+
+      /// The device is about to finish rendering a frame's field
+      deEndOfField,
    };
 
    typedef Signal <bool (GFXDeviceEventType)> DeviceEventSignal;
@@ -735,6 +741,8 @@ public:
    virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil ) = 0;
    virtual bool beginScene();
    virtual void endScene();
+   virtual void beginField();
+   virtual void endField();
 
    virtual GFXTexHandle & getFrontBuffer(){ return mFrontBuffer[mCurrentFrontBufferIdx]; }
 

+ 1 - 0
Engine/source/scene/reflectionManager.cpp

@@ -290,6 +290,7 @@ bool ReflectionManager::_handleDeviceEvent( GFXDevice::GFXDeviceEventType evt )
    switch( evt )
    {
    case GFXDevice::deStartOfFrame:
+   case GFXDevice::deStartOfField:
 
       mUpdateRefract = true;
       break;

+ 12 - 0
Engine/source/scene/sceneManager.cpp

@@ -242,6 +242,9 @@ void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, S
       Point2F projOffset = GFX->getCurrentProjectionOffset();
       Point3F eyeOffset = GFX->getStereoEyeOffset();
 
+      // Indicate that we're about to start a field
+      GFX->beginField();
+
       // Render left half of display
       RectI leftVP = originalVP;
       leftVP.extent.x *= 0.5;
@@ -264,6 +267,12 @@ void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, S
 
       renderSceneNoLights( &renderStateLeft, objectMask, baseObject, baseZone );
 
+      // Indicate that we've just finished a field
+      GFX->endField();
+
+      // Indicate that we're about to start a field
+      GFX->beginField();
+
       // Render right half of display
       RectI rightVP = originalVP;
       rightVP.extent.x *= 0.5;
@@ -287,6 +296,9 @@ void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, S
 
       renderSceneNoLights( &renderStateRight, objectMask, baseObject, baseZone );
 
+      // Indicate that we've just finished a field
+      GFX->endField();
+
       // Restore previous values
       GFX->setWorldMatrix(originalWorld);
       gfxFrustum.clearProjectionOffset();