1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-22 12:53:52 +00:00

fixed the sky reflection issue

This commit is contained in:
scrawl 2012-04-19 01:08:26 +02:00
parent 046ef39c4a
commit aa4a1b675f
4 changed files with 47 additions and 10 deletions

View file

@ -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)

View file

@ -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){

View file

@ -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

View file

@ -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);