From aa4a1b675fcc138c5b15f7d031846f2253b62f89 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 19 Apr 2012 01:08:26 +0200 Subject: [PATCH] fixed the sky reflection issue --- apps/openmw/mwrender/renderconst.hpp | 2 ++ apps/openmw/mwrender/renderingmanager.cpp | 2 ++ apps/openmw/mwrender/water.cpp | 44 ++++++++++++++++++----- apps/openmw/mwrender/water.hpp | 9 ++++- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index 2c7f9e9acb..c4aa093c0d 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -52,6 +52,8 @@ enum VisibilityFlags // Sun glare (not visible in reflection) RV_Glare = 128, + RV_OcclusionQuery = 256, + RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water, /// \todo markers (normally hidden) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 3082cf0d73..5819738111 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -225,6 +225,8 @@ void RenderingManager::update (float duration){ mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); checkUnderwater(); + + mWater->update(); } void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ if(store->cell->data.flags & store->cell->HasWater){ diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 71cf56dfda..445677808b 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -11,7 +11,8 @@ namespace MWRender Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()), mIsUnderwater(false), mVisibilityFlags(0), - mReflectionTarget(0), mActive(1), mToggled(1) + mReflectionTarget(0), mActive(1), mToggled(1), + mReflectionRenderActive(false) { mSky = sky; @@ -81,6 +82,8 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mUnderwaterEffect = Settings::Manager::getBool("underwater effect", "Water"); + mSceneManager->addRenderQueueListener(this); + // ---------------------------------------------------------------------------------------------- // ---------------------------------- reflection debug overlay ---------------------------------- @@ -161,6 +164,7 @@ void Water::changeCell(const ESM::Cell* cell) void Water::setHeight(const float height) { mTop = height; + mWaterPlane = Plane(Vector3::UNIT_Y, height); mWaterNode->setPosition(0, height, 0); } @@ -220,17 +224,15 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) mReflectionCamera->setFarClipDistance(mCamera->getFarClipDistance()); mReflectionCamera->setAspectRatio(mCamera->getAspectRatio()); mReflectionCamera->setFOVy(mCamera->getFOVy()); + mReflectionRenderActive = true; - // Some messy code to get the skybox to show up at all - // The problem here is that it gets clipped by the water plane - // Therefore scale it up a bit + /// \todo For some reason this camera is delayed for 1 frame, which causes ugly sky reflection behaviour.. + /// to circumvent this we just scale the sky up, so it's not that noticable Vector3 pos = mCamera->getRealPosition(); pos.y = mTop*2 - pos.y; mSky->setSkyPosition(pos); - mSky->scaleSky(mCamera->getFarClipDistance() / 1000.f); - - mReflectionCamera->enableCustomNearClipPlane(Plane(Vector3::UNIT_Y, mTop)); - mReflectionCamera->enableReflection(Plane(Vector3::UNIT_Y, mTop)); + mSky->scaleSky(mCamera->getFarClipDistance() / 5000.f); + mReflectionCamera->enableReflection(mWaterPlane); } } @@ -240,8 +242,9 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) { mSky->resetSkyPosition(); mSky->scaleSky(1); - mReflectionCamera->disableCustomNearClipPlane(); mReflectionCamera->disableReflection(); + mReflectionCamera->disableCustomNearClipPlane(); + mReflectionRenderActive = false; } } @@ -290,4 +293,27 @@ void Water::updateVisible() mReflectionTarget->setActive(mToggled && mActive && !mIsUnderwater); } +void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) +{ + // We don't want the sky to get clipped by custom near clip plane (the water plane) + if (queueGroupId < 20 && mReflectionRenderActive) + { + mReflectionCamera->disableCustomNearClipPlane(); + Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); + } +} + +void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation) +{ + if (queueGroupId < 20 && mReflectionRenderActive) + { + mReflectionCamera->enableCustomNearClipPlane(mWaterPlane); + Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); + } +} + +void Water::update() +{ +} + } // namespace diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index f14482e2b7..c8b8d311ed 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -11,7 +11,7 @@ namespace MWRender { class SkyManager; /// Water rendering - class Water : public Ogre::RenderTargetListener + class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener { static const int CELL_SIZE = 8192; Ogre::Camera *mCamera; @@ -27,11 +27,17 @@ namespace MWRender { bool mToggled; int mTop; + bool mReflectionRenderActive; + Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY); protected: void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + + void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); + void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation); + void updateVisible(); SkyManager* mSky; @@ -55,6 +61,7 @@ namespace MWRender { void setActive(bool active); void toggle(); + void update(); void setViewportBackground(const Ogre::ColourValue& bg);