Make oversize screenshots be perfectly seamless

This commit is contained in:
kaetemi 2013-07-04 23:11:15 +02:00
parent 86870d66fb
commit 78276ab782
3 changed files with 69 additions and 53 deletions

View file

@ -542,9 +542,11 @@ void renderSceneScreenShot (uint left, uint right, uint top, uint bottom, uint s
CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight); CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight);
CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight); CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight);
// sky setup are copied from main scene before rendering so no setup done here // sky setup are copied from main scene before rendering so no setup done here
commitCameraSky();
renderScene(ClientCfg.ScreenShotFullDetail, ClientCfg.Bloom); renderScene(ClientCfg.ScreenShotFullDetail, ClientCfg.Bloom);
restoreCamera(*Scene, cbScene); restoreCamera(*Scene, cbScene);
restoreCamera(*SceneRoot, cbCanopy); restoreCamera(*SceneRoot, cbCanopy);
commitCameraSky();
} }
// *************************************************************************** // ***************************************************************************

View file

@ -352,6 +352,12 @@ void displaySceneProfiles();
// validate current dialogs (end them if the player is too far from its interlocutor) // validate current dialogs (end them if the player is too far from its interlocutor)
void validateDialogs(const CGameContextMenu &gcm); void validateDialogs(const CGameContextMenu &gcm);
// ***************************************************************************
enum TSkyMode { NoSky, OldSky, NewSky };
static TSkyMode s_SkyMode = NoSky;
void preRenderNewSky () void preRenderNewSky ()
{ {
CSky &sky = ContinentMngr.cur()->CurrentSky; CSky &sky = ContinentMngr.cur()->CurrentSky;
@ -362,29 +368,31 @@ void preRenderNewSky ()
cd.Hour = 12.f; cd.Hour = 12.f;
} }
sky.setup(cd, SmoothedClientDate, WeatherManager.getWeatherValue(), MainFogState.FogColor, Scene->getSunDirection(), false); sky.setup(cd, SmoothedClientDate, WeatherManager.getWeatherValue(), MainFogState.FogColor, Scene->getSunDirection(), false);
// setup camera
CFrustum frust = MainCam.getFrustum();
UCamera camSky = sky.getScene()->getCam();
sky.getScene()->setViewport(Scene->getViewport());
camSky.setTransformMode(UTransform::DirectMatrix);
// must have our own Far!!!
frust.Far= SkyCameraZFar;
camSky.setFrustum(frust);
CMatrix skyCameraMatrix;
skyCameraMatrix.identity();
skyCameraMatrix= MainCam.getMatrix();
skyCameraMatrix.setPos(CVector::Null);
camSky.setMatrix(skyCameraMatrix);
} }
//uint32 MainLoopCounter = 0; void commitCameraSky()
{
if (s_SkyMode == NewSky)
{
CSky &sky = ContinentMngr.cur()->CurrentSky;
// setup camera
CFrustum frust = MainCam.getFrustum();
UCamera camSky = sky.getScene()->getCam();
sky.getScene()->setViewport(Scene->getViewport());
camSky.setTransformMode(UTransform::DirectMatrix);
// must have our own Far!!!
frust.Far= SkyCameraZFar;
camSky.setFrustum(frust);
CMatrix skyCameraMatrix;
skyCameraMatrix.identity();
skyCameraMatrix= MainCam.getMatrix();
skyCameraMatrix.setPos(CVector::Null);
camSky.setMatrix(skyCameraMatrix);
}
}
// *************************************************************************** // ***************************************************************************
enum TSkyMode { NoSky, OldSky, NewSky };
// ***************************************************************************
void beginRenderCanopyPart() void beginRenderCanopyPart()
{ {
SceneRoot->beginPartRender(); SceneRoot->beginPartRender();
@ -403,17 +411,17 @@ void endRenderMainScenePart()
Scene->endPartRender(true); Scene->endPartRender(true);
} }
void beginRenderSkyPart(TSkyMode skyMode) void beginRenderSkyPart()
{ {
if(skyMode == NewSky) if (s_SkyMode == NewSky)
{ {
CSky &sky = ContinentMngr.cur()->CurrentSky; CSky &sky = ContinentMngr.cur()->CurrentSky;
sky.getScene()->beginPartRender(); sky.getScene()->beginPartRender();
} }
} }
void endRenderSkyPart(TSkyMode skyMode) void endRenderSkyPart()
{ {
if(skyMode == NewSky) if (s_SkyMode == NewSky)
{ {
CSky &sky = ContinentMngr.cur()->CurrentSky; CSky &sky = ContinentMngr.cur()->CurrentSky;
sky.getScene()->endPartRender(false); sky.getScene()->endPartRender(false);
@ -463,12 +471,12 @@ static void renderMainScenePart(UScene::TRenderPart renderPart)
// *************************************************************************************************************************** // ***************************************************************************************************************************
// Render a part of the sky // Render a part of the sky
static void renderSkyPart(UScene::TRenderPart renderPart, TSkyMode skyMode) static void renderSkyPart(UScene::TRenderPart renderPart)
{ {
nlassert(skyMode != NoSky); nlassert(s_SkyMode != NoSky);
Driver->setDepthRange(SKY_DEPTH_RANGE_START, 1.f); Driver->setDepthRange(SKY_DEPTH_RANGE_START, 1.f);
Driver->enableFog(false); Driver->enableFog(false);
if (skyMode == NewSky) if (s_SkyMode == NewSky)
{ {
CSky &sky = ContinentMngr.cur()->CurrentSky; CSky &sky = ContinentMngr.cur()->CurrentSky;
sky.getScene()->renderPart(renderPart); sky.getScene()->renderPart(renderPart);
@ -605,6 +613,29 @@ void updateWeather()
Driver->setPolygonMode(oldMode); Driver->setPolygonMode(oldMode);
} }
#endif #endif
// Update new sky
if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor)
{
if(Driver->getPolygonMode() == UDriver::Filled)
{
if (Filter3D[FilterSky])
{
CSky &sky = ContinentMngr.cur()->CurrentSky;
if (sky.getScene())
{
s_SkyMode = NewSky;
sky.getScene()->animate(TimeInSec-FirstTimeInSec);
// Setup the sky camera
preRenderNewSky();
}
else
{
s_SkyMode = OldSky;
}
}
}
}
} }
// *************************************************************************************************************************** // ***************************************************************************************************************************
@ -638,36 +669,13 @@ void renderScene()
if(Scene_Profile) if(Scene_Profile)
Scene->profileNextRender(); Scene->profileNextRender();
TSkyMode skyMode = NoSky;
if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor)
{
if(Driver->getPolygonMode() == UDriver::Filled)
{
if (Filter3D[FilterSky])
{
CSky &sky = ContinentMngr.cur()->CurrentSky;
if (sky.getScene())
{
skyMode = NewSky;
sky.getScene()->animate(TimeInSec-FirstTimeInSec);
// Setup the sky camera
preRenderNewSky();
}
else
{
skyMode = OldSky;
}
}
}
}
// initialisation of polygons renderer // initialisation of polygons renderer
CLandscapePolyDrawer::getInstance().beginRenderLandscapePolyPart(); CLandscapePolyDrawer::getInstance().beginRenderLandscapePolyPart();
// Start Part Rendering // Start Part Rendering
beginRenderCanopyPart(); beginRenderCanopyPart();
beginRenderMainScenePart(); beginRenderMainScenePart();
beginRenderSkyPart(skyMode); beginRenderSkyPart();
// 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
@ -677,12 +685,12 @@ void renderScene()
// render of polygons on landscape // render of polygons on landscape
CLandscapePolyDrawer::getInstance().renderLandscapePolyPart(); CLandscapePolyDrawer::getInstance().renderLandscapePolyPart();
if (skyMode != NoSky) renderSkyPart((UScene::TRenderPart) (UScene::RenderOpaque | UScene::RenderTransparent), skyMode); 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));
if (skyMode == NewSky) renderSkyPart(UScene::RenderFlare, skyMode); if (s_SkyMode == NewSky) renderSkyPart(UScene::RenderFlare);
// End Part Rendering // End Part Rendering
endRenderSkyPart(skyMode); endRenderSkyPart();
endRenderMainScenePart(); endRenderMainScenePart();
endRenderCanopyPart(); endRenderCanopyPart();
@ -1550,7 +1558,7 @@ bool mainLoop()
} }
#endif #endif
// TODO: Verify that moving this out of renderScene does not negatively impact oversize screenshots. // Update weather
updateWeather(); updateWeather();
if (ClientCfg.Bloom) if (ClientCfg.Bloom)
@ -1570,6 +1578,9 @@ bool mainLoop()
s_ForceFullDetail.set(); s_ForceFullDetail.set();
} }
// Commit camera changes to the sky camera
commitCameraSky();
// Render scene // Render scene
renderScene(); renderScene();

View file

@ -33,6 +33,9 @@ void renderScene();
void renderScene(bool forceFullDetail, bool bloom); void renderScene(bool forceFullDetail, bool bloom);
void setDefaultChatWindow(CChatWindow *defaultChatWindow); void setDefaultChatWindow(CChatWindow *defaultChatWindow);
// Commit sky scene camera for rendering
void commitCameraSky();
void updateDayNightCycleHour(); void updateDayNightCycleHour();