Process some scene traversals only once when rendering in stereo

This commit is contained in:
kaetemi 2014-08-06 14:36:09 +02:00
parent 758e87e115
commit 7db83ce7da
15 changed files with 226 additions and 103 deletions

View file

@ -139,7 +139,7 @@ public:
* \param renderPart : The part of the scene that must be rendered * \param renderPart : The part of the scene that must be rendered
* \param newRender true If scene render is beginning. Otherwise other parts of the scene have already been rendered. * \param newRender true If scene render is beginning. Otherwise other parts of the scene have already been rendered.
*/ */
void traverse(UScene::TRenderPart renderPart, bool newRender); void traverse(UScene::TRenderPart renderPart, bool newRender, bool generateShadows);
//@} //@}
/// \name RenderList. /// \name RenderList.

View file

@ -157,7 +157,7 @@ public:
* \param doHrcPass set it to false to indicate that the CHrcTrav have not to be traversed. Useful to optimize if * \param doHrcPass set it to false to indicate that the CHrcTrav have not to be traversed. Useful to optimize if
* you know that NONE of your models have moved (a good example is a shoot of the scene from different cameras). * you know that NONE of your models have moved (a good example is a shoot of the scene from different cameras).
*/ */
void render(bool doHrcPass=true); void render(bool doHrcPass = true);
/** Begin Part Rendering /** Begin Part Rendering
* During beginPartRender()/endPartRender(), you can ask other scene to render their part, but you should * During beginPartRender()/endPartRender(), you can ask other scene to render their part, but you should
@ -171,10 +171,10 @@ public:
* WARNING: always must begin rendering with at least UScene::RenderOpaque, else shadows won't work * WARNING: always must begin rendering with at least UScene::RenderOpaque, else shadows won't work
* WARNING: assert-crash if a part in 'rp' has already been rendered since the last beginPartRender() * WARNING: assert-crash if a part in 'rp' has already been rendered since the last beginPartRender()
*/ */
void renderPart(UScene::TRenderPart rp, bool doHrcPass=true); void renderPart(UScene::TRenderPart rp, bool doHrcPass = true, bool doTrav = true, bool keepTrav = false);
/** End Part Rendering (commit model creation and deletion that were asked during rendering) /** End Part Rendering (commit model creation and deletion that were asked during rendering)
*/ */
void endPartRender(); void endPartRender(bool keepTrav = false);
//@} //@}

View file

@ -96,8 +96,8 @@ public:
// render methods // render methods
virtual void render(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true); virtual void render(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true);
virtual void beginPartRender(); virtual void beginPartRender();
virtual void renderPart(TRenderPart rp); virtual void renderPart(TRenderPart rp, bool doHrcPass = true, bool doTrav = true, bool keepTrav = false);
virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true); virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true, bool keepTrav = true);
// update async loading whithout a call to render // update async loading whithout a call to render
virtual void updateWaitingInstances(double ellapsedTime); virtual void updateWaitingInstances(double ellapsedTime);

View file

@ -96,11 +96,18 @@ public:
virtual bool wantClear(); virtual bool wantClear();
/// The 3D scene /// The 3D scene
virtual bool wantScene(); virtual bool wantScene();
/// Scene post processing effects
virtual bool wantSceneEffects();
/// Interface within the 3D scene /// Interface within the 3D scene
virtual bool wantInterface3D(); virtual bool wantInterface3D();
/// 2D Interface /// 2D Interface
virtual bool wantInterface2D(); virtual bool wantInterface2D();
/// Is this the first 3D scene of the frame
virtual bool isSceneFirst();
/// Is this the last 3D scene of the frame
virtual bool isSceneLast();
/// Returns true if a new render target was set, always fase if not using render targets /// Returns true if a new render target was set, always fase if not using render targets
virtual bool beginRenderTarget(); virtual bool beginRenderTarget();
/// Returns true if a render target was fully drawn, always false if not using render targets /// Returns true if a render target was fully drawn, always false if not using render targets

View file

@ -119,11 +119,18 @@ public:
virtual bool wantClear() = 0; virtual bool wantClear() = 0;
/// The 3D scene /// The 3D scene
virtual bool wantScene() = 0; virtual bool wantScene() = 0;
/// Scene post processing effects
virtual bool wantSceneEffects() = 0;
/// Interface within the 3D scene /// Interface within the 3D scene
virtual bool wantInterface3D() = 0; virtual bool wantInterface3D() = 0;
/// 2D Interface /// 2D Interface
virtual bool wantInterface2D() = 0; virtual bool wantInterface2D() = 0;
/// Is this the first 3D scene of the frame
virtual bool isSceneFirst() = 0;
/// Is this the last 3D scene of the frame
virtual bool isSceneLast() = 0;
/// Returns true if a new render target was set, always fase if not using render targets /// Returns true if a new render target was set, always fase if not using render targets
virtual bool beginRenderTarget() = 0; virtual bool beginRenderTarget() = 0;
/// Returns true if a render target was fully drawn, always false if not using render targets /// Returns true if a render target was fully drawn, always false if not using render targets

View file

@ -113,11 +113,18 @@ public:
virtual bool wantClear(); virtual bool wantClear();
/// The 3D scene /// The 3D scene
virtual bool wantScene(); virtual bool wantScene();
/// Scene post processing effects
virtual bool wantSceneEffects();
/// Interface within the 3D scene /// Interface within the 3D scene
virtual bool wantInterface3D(); virtual bool wantInterface3D();
/// 2D Interface /// 2D Interface
virtual bool wantInterface2D(); virtual bool wantInterface2D();
/// Is this the first 3D scene of the frame
virtual bool isSceneFirst();
/// Is this the last 3D scene of the frame
virtual bool isSceneLast();
/// Returns true if a new render target was set, always fase if not using render targets /// Returns true if a new render target was set, always fase if not using render targets
virtual bool beginRenderTarget(); virtual bool beginRenderTarget();
/// Returns true if a render target was fully drawn, always false if not using render targets /// Returns true if a render target was fully drawn, always false if not using render targets

View file

@ -134,14 +134,17 @@ public:
/** Render a part (see render() for what it does) /** Render a part (see render() for what it does)
* beginPartRender() must have been called * beginPartRender() must have been called
* \param renderPart a combination of UScene::TRenderPart flags, allow to choose which part of the scene must be rendered * \param renderPart a combination of UScene::TRenderPart flags, allow to choose which part of the scene must be rendered
* \param doHrcPass set it to false to indicate that the CHrcTrav have not to be traversed. Useful to optimize if
* you know that NONE of your models have moved (a good example is a shoot of the scene from different cameras).
* \param doTrav set to false when processing a second frame for stereo rending to avoid unnecessary traversals.
* WARNING: always must begin rendering with at least UScene::RenderOpaque, else shadows won't work * WARNING: always must begin rendering with at least UScene::RenderOpaque, else shadows won't work
* WARNING: assert-crash if a part in 'rp' has already been rendered since the last beginPartRender() * WARNING: assert-crash if a part in 'rp' has already been rendered since the last beginPartRender()
*/ */
virtual void renderPart(UScene::TRenderPart rp) =0; virtual void renderPart(UScene::TRenderPart rp, bool doHrcPass = true, bool doTrav = true, bool keepTrav = false) =0;
/** End Part Rendering (commit model creation and deletion that were asked during rendering) /** End Part Rendering (commit model creation and deletion that were asked during rendering)
*/ */
virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true) =0; virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true, bool keepTrav = false) =0;
/** Update waiting instances and igs that are loaded asynchronously /** Update waiting instances and igs that are loaded asynchronously

View file

@ -92,7 +92,7 @@ CRenderTrav::CRenderTrav()
// *************************************************************************** // ***************************************************************************
void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender) void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender, bool generateShadows)
{ {
#ifdef NL_DEBUG_RENDER_TRAV #ifdef NL_DEBUG_RENDER_TRAV
nlwarning("Render trave begin"); nlwarning("Render trave begin");
@ -279,7 +279,8 @@ void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender)
*/ */
// Generate ShadowMaps // Generate ShadowMaps
_ShadowMapManager.renderGenerate(Scene); if (generateShadows)
_ShadowMapManager.renderGenerate(Scene);
// Render the Landscape // Render the Landscape
renderLandscapes(); renderLandscapes();

View file

@ -353,28 +353,31 @@ void CScene::beginPartRender()
// *************************************************************************** // ***************************************************************************
void CScene::endPartRender() void CScene::endPartRender(bool keepTrav)
{ {
nlassert(_IsRendering); nlassert(_IsRendering);
// Delete model deleted during the rendering
_IsRendering = false; _IsRendering = false;
uint i;
for (i=0; i<_ToDelete.size(); i++)
deleteModel (_ToDelete[i]);
_ToDelete.clear ();
// Special for SkeletonSpawnScript animation. create models spawned now if (!keepTrav)
flushSSSModelRequests(); {
// Delete model deleted during the rendering
uint i;
for (i=0; i<_ToDelete.size(); i++)
deleteModel (_ToDelete[i]);
_ToDelete.clear ();
// Particle system handling (remove the resources of those which are too far, as their clusters may not have been parsed). // Special for SkeletonSpawnScript animation. create models spawned now
// Note that only a few of them are tested at each call flushSSSModelRequests();
_ParticleSystemManager.refreshModels(ClipTrav.WorldFrustumPyramid, ClipTrav.CamPos);
// Waiting Instance handling // Particle system handling (remove the resources of those which are too far, as their clusters may not have been parsed).
double deltaT = _DeltaSystemTimeBetweenRender; // Note that only a few of them are tested at each call
clamp (deltaT, 0.01, 0.1); _ParticleSystemManager.refreshModels(ClipTrav.WorldFrustumPyramid, ClipTrav.CamPos);
updateWaitingInstances(deltaT);
// Waiting Instance handling
double deltaT = _DeltaSystemTimeBetweenRender;
clamp (deltaT, 0.01, 0.1);
updateWaitingInstances(deltaT);
}
// Reset profiling // Reset profiling
_NextRenderProfile= false; _NextRenderProfile= false;
@ -555,7 +558,7 @@ void CScene::endPartRender()
// *************************************************************************** // ***************************************************************************
void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass) void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass, bool doTrav, bool keepTrav)
{ {
nlassert(_IsRendering); nlassert(_IsRendering);
@ -569,25 +572,31 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass)
// if first part to be rendered, do the start stuff // if first part to be rendered, do the start stuff
if (_RenderedPart == UScene::RenderNothing) if (_RenderedPart == UScene::RenderNothing)
{ {
// update water envmap
//updateWaterEnvmap();
RenderTrav.clearWaterModelList(); RenderTrav.clearWaterModelList();
_FirstFlare = NULL;
double fNewGlobalSystemTime = NLMISC::CTime::ticksToSecond(NLMISC::CTime::getPerformanceTime()); if (doTrav)
if(_GlobalSystemTime==0) {
_DeltaSystemTimeBetweenRender= 0.020; // update water envmap
else //updateWaterEnvmap();
_DeltaSystemTimeBetweenRender= fNewGlobalSystemTime - _GlobalSystemTime; _FirstFlare = NULL;
_GlobalSystemTime = fNewGlobalSystemTime;
double fNewGlobalSystemTime = NLMISC::CTime::ticksToSecond(NLMISC::CTime::getPerformanceTime());
if(_GlobalSystemTime==0)
_DeltaSystemTimeBetweenRender= 0.020;
else
_DeltaSystemTimeBetweenRender= fNewGlobalSystemTime - _GlobalSystemTime;
_GlobalSystemTime = fNewGlobalSystemTime;
}
// //
++ _NumRender; ++ _NumRender;
// //
nlassert(CurrentCamera); nlassert(CurrentCamera);
// update models. // update models.
updateModels(); updateModels();
// Use the camera to setup Clip / Render pass. // Use the camera to setup Clip / Render pass.
float left, right, bottom, top, znear, zfar; float left, right, bottom, top, znear, zfar;
CurrentCamera->getFrustum(left, right, bottom, top, znear, zfar); CurrentCamera->getFrustum(left, right, bottom, top, znear, zfar);
@ -609,49 +618,70 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass)
// **** For all render traversals, traverse them (except the Hrc one), in ascending order. // **** For all render traversals, traverse them (except the Hrc one), in ascending order.
if( doHrcPass ) if( doHrcPass )
HrcTrav.traverse(); HrcTrav.traverse();
else
HrcTrav._MovingObjects.clear();
// Set Cam World Matrix for all trav that need it // Set Cam World Matrix for all trav that need it
ClipTrav.setCamMatrix(CurrentCamera->getWorldMatrix()); ClipTrav.setCamMatrix(CurrentCamera->getWorldMatrix());
RenderTrav.setCamMatrix (CurrentCamera->getWorldMatrix()); RenderTrav.setCamMatrix (CurrentCamera->getWorldMatrix());
LoadBalancingTrav.setCamMatrix (CurrentCamera->getWorldMatrix()); LoadBalancingTrav.setCamMatrix (CurrentCamera->getWorldMatrix());
// clip // clip
ClipTrav.traverse(); ClipTrav.traverse();
// animDetail
AnimDetailTrav.traverse(); if (doTrav)
{
// animDetail
AnimDetailTrav.traverse();
}
// loadBalance // loadBalance
LoadBalancingTrav.traverse(); LoadBalancingTrav.traverse();
//
if (_RequestParticlesAnimate) if (doTrav)
{ {
_ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems //
_RequestParticlesAnimate = false; if (_RequestParticlesAnimate)
{
_ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems
_RequestParticlesAnimate = false;
}
} }
// Light // Light
LightTrav.traverse(); LightTrav.traverse();
} }
// render // render
RenderTrav.traverse(rp, _RenderedPart == UScene::RenderNothing); RenderTrav.traverse(rp, (_RenderedPart == UScene::RenderNothing), doTrav);
// Always must clear shadow caster (if render did not work because of IDriver::isLost()) if (!keepTrav)
RenderTrav.getShadowMapManager().clearAllShadowCasters(); {
// Always must clear shadow caster (if render did not work because of IDriver::isLost())
RenderTrav.getShadowMapManager().clearAllShadowCasters();
}
// render flare // render flare
if (rp & UScene::RenderFlare) if (rp & UScene::RenderFlare)
{ {
if (_FirstFlare) if (doTrav)
{ {
IDriver *drv = getDriver(); if (_FirstFlare)
CFlareModel::updateOcclusionQueryBegin(drv);
CFlareModel *currFlare = _FirstFlare;
do
{ {
currFlare->updateOcclusionQuery(drv); IDriver *drv = getDriver();
currFlare = currFlare->Next; CFlareModel::updateOcclusionQueryBegin(drv);
CFlareModel *currFlare = _FirstFlare;
do
{
currFlare->updateOcclusionQuery(drv);
currFlare = currFlare->Next;
}
while(currFlare);
CFlareModel::updateOcclusionQueryEnd(drv);
} }
while(currFlare); }
CFlareModel::updateOcclusionQueryEnd(drv); else
{
_FirstFlare = NULL;
} }
} }
_RenderedPart = (UScene::TRenderPart) (_RenderedPart | rp); _RenderedPart = (UScene::TRenderPart) (_RenderedPart | rp);

View file

@ -517,7 +517,7 @@ void CSceneUser::beginPartRender()
} }
// *************************************************************************** // ***************************************************************************
void CSceneUser::renderPart(TRenderPart rp) void CSceneUser::renderPart(TRenderPart rp, bool doHrcPass, bool doTrav, bool keepTrav)
{ {
// render the scene. // render the scene.
@ -526,18 +526,18 @@ void CSceneUser::renderPart(TRenderPart rp)
if(_Scene.getCam() == NULL) if(_Scene.getCam() == NULL)
nlerror("render(): try to render with no camera linked (may have been deleted)"); nlerror("render(): try to render with no camera linked (may have been deleted)");
_Scene.renderPart(rp, true); _Scene.renderPart(rp, doHrcPass, doTrav, keepTrav);
} }
} }
// *************************************************************************** // ***************************************************************************
void CSceneUser::endPartRender(bool updateWaitingInstancesFlag, bool restoreMatrixContextAfterRender) void CSceneUser::endPartRender(bool updateWaitingInstancesFlag, bool restoreMatrixContextAfterRender, bool keepTrav)
{ {
// render the scene. // render the scene.
{ {
NL3D_HAUTO_RENDER_SCENE_END NL3D_HAUTO_RENDER_SCENE_END
_Scene.endPartRender(); _Scene.endPartRender(keepTrav);
} }
if (updateWaitingInstancesFlag) updateWaitingInstances(); if (updateWaitingInstancesFlag) updateWaitingInstances();

View file

@ -415,6 +415,12 @@ bool CStereoDebugger::wantScene()
return m_Stage != 3; return m_Stage != 3;
} }
/// The 3D scene end (after multiple wantScene)
bool CStereoDebugger::wantSceneEffects()
{
return m_Stage != 3;
}
/// Interface within the 3D scene /// Interface within the 3D scene
bool CStereoDebugger::wantInterface3D() bool CStereoDebugger::wantInterface3D()
{ {
@ -429,6 +435,16 @@ bool CStereoDebugger::wantInterface2D()
return m_Stage == 3; return m_Stage == 3;
} }
bool CStereoDebugger::isSceneFirst()
{
return m_Stage == 1;
}
bool CStereoDebugger::isSceneLast()
{
return m_Stage == 2;
}
/// Returns true if a new render target was set, always fase if not using render targets /// Returns true if a new render target was set, always fase if not using render targets
bool CStereoDebugger::beginRenderTarget() bool CStereoDebugger::beginRenderTarget()
{ {

View file

@ -640,6 +640,16 @@ bool CStereoOVR::wantScene()
return m_Driver->getPolygonMode() != UDriver::Filled; return m_Driver->getPolygonMode() != UDriver::Filled;
} }
bool CStereoOVR::wantSceneEffects()
{
switch (m_Stage)
{
case 4:
return true;
}
return m_Driver->getPolygonMode() != UDriver::Filled;
}
bool CStereoOVR::wantInterface3D() bool CStereoOVR::wantInterface3D()
{ {
switch (m_Stage) switch (m_Stage)
@ -663,6 +673,26 @@ bool CStereoOVR::wantInterface2D()
return m_Driver->getPolygonMode() != UDriver::Filled; return m_Driver->getPolygonMode() != UDriver::Filled;
} }
bool CStereoOVR::isSceneFirst()
{
switch (m_Stage)
{
case 3:
return true;
}
return m_Driver->getPolygonMode() != UDriver::Filled;
}
bool CStereoOVR::isSceneLast()
{
switch (m_Stage)
{
case 4:
return true;
}
return m_Driver->getPolygonMode() != UDriver::Filled;
}
/// Returns non-NULL if a new render target was set /// Returns non-NULL if a new render target was set
bool CStereoOVR::beginRenderTarget() bool CStereoOVR::beginRenderTarget()
{ {

View file

@ -97,7 +97,9 @@ private:
// renderScene is called in main loop. It can called beginRenderLandscapePolyPart and renderLandscapePolyPart // renderScene is called in main loop. It can called beginRenderLandscapePolyPart and renderLandscapePolyPart
// methods. // methods.
friend void renderScene(); friend void beginRenderScene();
friend void drawRenderScene(bool wantTraversals, bool keepTraversals);
friend void endRenderScene(bool keepTraversals);
// Enable stencil test and initialize function and operation of stencil at the beginning of renderScene method, // Enable stencil test and initialize function and operation of stencil at the beginning of renderScene method,
// before opaque render of canopy and main scene parts. // before opaque render of canopy and main scene parts.

View file

@ -423,9 +423,9 @@ void beginRenderMainScenePart()
{ {
Scene->beginPartRender(); Scene->beginPartRender();
} }
void endRenderMainScenePart() void endRenderMainScenePart(bool keepTraversals)
{ {
Scene->endPartRender(true); Scene->endPartRender(!keepTraversals, true, keepTraversals);
} }
void beginRenderSkyPart() void beginRenderSkyPart()
@ -462,7 +462,7 @@ static void renderCanopyPart(UScene::TRenderPart renderPart)
// *************************************************************************************************************************** // ***************************************************************************************************************************
// Render a part of the main scene // Render a part of the main scene
static void renderMainScenePart(UScene::TRenderPart renderPart) static void renderMainScenePart(UScene::TRenderPart renderPart, bool wantTraversals, bool keepTraversals)
{ {
H_AUTO_USE ( RZ_Client_Main_Loop_Render_Main ) H_AUTO_USE ( RZ_Client_Main_Loop_Render_Main )
Driver->setDepthRange(0.f, CANOPY_DEPTH_RANGE_START); Driver->setDepthRange(0.f, CANOPY_DEPTH_RANGE_START);
@ -474,7 +474,7 @@ static void renderMainScenePart(UScene::TRenderPart renderPart)
{ {
MainFogState.setupInDriver (*Driver); MainFogState.setupInDriver (*Driver);
} }
Scene->renderPart(renderPart); Scene->renderPart(renderPart, true, wantTraversals, keepTraversals);
} }
@ -580,7 +580,7 @@ void renderScene(bool forceFullDetail, bool bloom)
s_ForceFullDetail.set(); s_ForceFullDetail.set();
} }
clearBuffers(); clearBuffers();
renderScene(); doRenderScene(true, false);
if (forceFullDetail) if (forceFullDetail)
{ {
s_ForceFullDetail.restore(); s_ForceFullDetail.restore();
@ -719,9 +719,7 @@ void updateWeather()
} }
} }
// *************************************************************************************************************************** void beginRenderScene()
// Render all scenes
void renderScene()
{ {
// Update Filter Flags // Update Filter Flags
Scene->enableElementRender(UScene::FilterAllMeshNoVP, Filter3D[FilterMeshNoVP]); Scene->enableElementRender(UScene::FilterAllMeshNoVP, Filter3D[FilterMeshNoVP]);
@ -743,28 +741,45 @@ void renderScene()
beginRenderCanopyPart(); beginRenderCanopyPart();
beginRenderMainScenePart(); beginRenderMainScenePart();
beginRenderSkyPart(); beginRenderSkyPart();
}
void drawRenderScene(bool wantTraversals, bool keepTraversals)
{
// Render part // Render part
// WARNING: always must begin rendering with at least UScene::RenderOpaque, // WARNING: always must begin rendering with at least UScene::RenderOpaque,
// else dynamic shadows won't work // else dynamic shadows won't work
renderCanopyPart(UScene::RenderOpaque); renderCanopyPart(UScene::RenderOpaque);
renderMainScenePart(UScene::RenderOpaque); renderMainScenePart(UScene::RenderOpaque, wantTraversals, keepTraversals);
// render of polygons on landscape // render of polygons on landscape
CLandscapePolyDrawer::getInstance().renderLandscapePolyPart(); CLandscapePolyDrawer::getInstance().renderLandscapePolyPart();
if (s_SkyMode != NoSky) renderSkyPart((UScene::TRenderPart) (UScene::RenderOpaque | UScene::RenderTransparent)); if (s_SkyMode != NoSky) renderSkyPart((UScene::TRenderPart) (UScene::RenderOpaque | UScene::RenderTransparent));
renderCanopyPart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare)); renderCanopyPart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare));
renderMainScenePart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare)); renderMainScenePart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare), wantTraversals, keepTraversals);
if (s_SkyMode == NewSky) renderSkyPart(UScene::RenderFlare); if (s_SkyMode == NewSky) renderSkyPart(UScene::RenderFlare);
}
void endRenderScene(bool keepTraversals)
{
// End Part Rendering // End Part Rendering
endRenderSkyPart(); endRenderSkyPart();
endRenderMainScenePart(); endRenderMainScenePart(keepTraversals);
endRenderCanopyPart(); endRenderCanopyPart();
// reset depth range // reset depth range
Driver->setDepthRange(0.f, CANOPY_DEPTH_RANGE_START); Driver->setDepthRange(0.f, CANOPY_DEPTH_RANGE_START);
} }
// ***************************************************************************************************************************
// Render all scenes
void doRenderScene(bool wantTraversals, bool keepTraversals)
{
beginRenderScene();
drawRenderScene(wantTraversals, keepTraversals);
endRenderScene(keepTraversals);
}
// *************************************************************************** // ***************************************************************************
class CMusicFader class CMusicFader
@ -1628,7 +1643,6 @@ bool mainLoop()
} }
uint i = 0; uint i = 0;
bool effectRender = false;
CTextureUser *effectRenderTarget = NULL; CTextureUser *effectRenderTarget = NULL;
bool haveEffects = Render && Driver->getPolygonMode() == UDriver::Filled bool haveEffects = Render && Driver->getPolygonMode() == UDriver::Filled
&& (ClientCfg.Bloom || FXAA); && (ClientCfg.Bloom || FXAA);
@ -1646,6 +1660,7 @@ bool mainLoop()
CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom);
} }
} }
bool fullDetail = false;
while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass()))
{ {
++i; ++i;
@ -1686,42 +1701,59 @@ bool mainLoop()
if (!StereoDisplay || StereoDisplay->wantClear()) if (!StereoDisplay || StereoDisplay->wantClear())
{ {
if (Render)
{
effectRender = haveEffects;
}
// Clear buffers // Clear buffers
clearBuffers(); clearBuffers();
} }
if (!StereoDisplay || StereoDisplay->wantScene()) if (!StereoDisplay || StereoDisplay->wantScene())
{ {
if (!ClientCfg.Light) if (!ClientCfg.Light && Render)
{ {
// Render if (!StereoDisplay || StereoDisplay->isSceneFirst())
if(Render)
{ {
// nb : force full detail if a screenshot is asked // nb : force full detail if a screenshot is asked
// todo : move outside render code // todo : move outside render code
bool fullDetail = ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail; if (!fullDetail)
if (fullDetail)
{ {
s_ForceFullDetail.backup(); fullDetail = ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail;
s_ForceFullDetail.set(); if (fullDetail)
{
s_ForceFullDetail.backup();
s_ForceFullDetail.set();
}
} }
}
// Render scene // Render scene
renderScene(); bool wantTraversals = !StereoDisplay || StereoDisplay->isSceneFirst();
bool keepTraversals = StereoDisplay && !StereoDisplay->isSceneLast();
doRenderScene(wantTraversals, keepTraversals);
if (!StereoDisplay || StereoDisplay->isSceneLast())
{
if (fullDetail) if (fullDetail)
{ {
s_ForceFullDetail.restore(); s_ForceFullDetail.restore();
fullDetail = false;
} }
} }
} }
} }
if (!StereoDisplay || StereoDisplay->wantSceneEffects())
{
if (!ClientCfg.Light && Render && haveEffects)
{
if (StereoDisplay) Driver->setViewport(NL3D::CViewport());
UCamera pCam = Scene->getCam();
Driver->setMatrixMode2D11();
if (FXAA) FXAA->applyEffect();
if (ClientCfg.Bloom) CBloomEffect::instance().applyBloom();
Driver->setMatrixMode3D(pCam);
if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport());
}
}
if (!StereoDisplay || StereoDisplay->wantInterface3D()) if (!StereoDisplay || StereoDisplay->wantInterface3D())
{ {
if (!ClientCfg.Light) if (!ClientCfg.Light)
@ -1729,18 +1761,6 @@ bool mainLoop()
// Render // Render
if (Render) if (Render)
{ {
if (effectRender)
{
if (StereoDisplay) Driver->setViewport(NL3D::CViewport());
UCamera pCam = Scene->getCam();
Driver->setMatrixMode2D11();
if (FXAA) FXAA->applyEffect();
if (ClientCfg.Bloom) CBloomEffect::instance().applyBloom();
Driver->setMatrixMode3D(pCam);
if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport());
effectRender = false;
}
// for that frame and // for that frame and
// tmp : display height grid // tmp : display height grid
//static volatile bool displayHeightGrid = true; //static volatile bool displayHeightGrid = true;

View file

@ -29,7 +29,7 @@ const uint NUM_MISSION_OPTIONS = 8;
bool mainLoop(); bool mainLoop();
// render all // render all
void renderScene(); void doRenderScene(bool wantTraversals, bool keepTraversals);
void renderScene(bool forceFullDetail, bool bloom); void renderScene(bool forceFullDetail, bool bloom);
void setDefaultChatWindow(CChatWindow *defaultChatWindow); void setDefaultChatWindow(CChatWindow *defaultChatWindow);