Near clip plane corrections

This commit is contained in:
scrawl 2013-02-12 20:56:00 +01:00
parent d213ff680f
commit de90b911c9
4 changed files with 51 additions and 6 deletions

View file

@ -6,6 +6,7 @@
#include <OgreHardwarePixelBuffer.h>
#include <OgreRenderTarget.h>
#include <OgreViewport.h>
#include <OgreRoot.h>
#include "renderconst.hpp"
@ -14,9 +15,13 @@ namespace MWRender
Refraction::Refraction(Ogre::Camera *parentCamera)
: mParentCamera(parentCamera)
, mRenderActive(false)
, mIsUnderwater(false)
{
mCamera = mParentCamera->getSceneManager()->createCamera("RefractionCamera");
mParentCamera->getSceneManager()->addRenderQueueListener(this);
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual("WaterRefraction",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
@ -24,7 +29,7 @@ namespace MWRender
Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera);
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain);
vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky);
vp->setMaterialScheme("water_reflection");
mRenderTarget->setAutoUpdated(true);
mRenderTarget->addListener(this);
@ -47,17 +52,42 @@ namespace MWRender
mCamera->setAspectRatio(mParentCamera->getAspectRatio());
mCamera->setFOVy(mParentCamera->getFOVy());
mCamera->enableCustomNearClipPlane(mNearClipPlane);
mRenderActive = true;
}
void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
mRenderActive = false;
}
void Refraction::setHeight(float height)
{
mNearClipPlane = Ogre::Plane( -Ogre::Vector3(0,1,0), -(height + 5));
mNearClipPlaneUnderwater = Ogre::Plane( Ogre::Vector3(0,1,0), height - 5);
}
void Refraction::setViewportBackground (Ogre::ColourValue colour)
{
mRenderTarget->getViewport (0)->setBackgroundColour (colour);
}
void Refraction::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 && mRenderActive)
{
mCamera->disableCustomNearClipPlane();
Ogre::Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
}
}
void Refraction::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
{
if (queueGroupId < 20 && mRenderActive)
{
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane);
Ogre::Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
}
}
}

View file

@ -3,6 +3,7 @@
#include <OgrePlane.h>
#include <OgreRenderTargetListener.h>
#include <OgreRenderQueueListener.h>
namespace Ogre
{
@ -13,7 +14,7 @@ namespace Ogre
namespace MWRender
{
class Refraction : public Ogre::RenderTargetListener
class Refraction : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener
{
public:
@ -23,12 +24,20 @@ namespace MWRender
void setHeight (float height);
void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void setViewportBackground(Ogre::ColourValue colour);
void setUnderwater(bool underwater) {mIsUnderwater = underwater;}
void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation);
void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation);
private:
Ogre::Camera* mParentCamera;
Ogre::Camera* mCamera;
Ogre::RenderTarget* mRenderTarget;
Ogre::Plane mNearClipPlane;
Ogre::Plane mNearClipPlaneUnderwater;
bool mRenderActive;
bool mIsUnderwater;
};
}

View file

@ -124,8 +124,8 @@ void PlaneReflection::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::St
{
if (queueGroupId < 20 && mRenderActive)
{
if (!mIsUnderwater)
mCamera->enableCustomNearClipPlane(mErrorPlane);
// this trick does not seem to work well for extreme angles
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
}
}
@ -159,6 +159,7 @@ void PlaneReflection::setHeight (float height)
{
mWaterPlane = Plane(Ogre::Vector3(0,1,0), height);
mErrorPlane = Plane(Ogre::Vector3(0,1,0), height - 5);
mErrorPlaneUnderwater = Plane(Ogre::Vector3(0,-1,0), -height - 5);
}
void PlaneReflection::setActive (bool active)
@ -348,6 +349,8 @@ Water::updateUnderwater(bool underwater)
if (mReflection)
mReflection->setUnderwater (mIsUnderwater);
if (mRefraction)
mRefraction->setUnderwater (mIsUnderwater);
updateVisible();
}
@ -377,6 +380,8 @@ void Water::setViewportBackground(const ColourValue& bg)
{
if (mReflection)
mReflection->setViewportBackground(bg);
if (mRefraction)
mRefraction->setViewportBackground(bg);
}
void Water::updateVisible()

View file

@ -89,6 +89,7 @@ namespace MWRender {
SkyManager* mSky;
Ogre::Plane mWaterPlane;
Ogre::Plane mErrorPlane;
Ogre::Plane mErrorPlaneUnderwater;
bool mRenderActive;
};