forked from teamnwah/openmw-tes3coop
Near clip plane corrections
This commit is contained in:
parent
d213ff680f
commit
de90b911c9
4 changed files with 51 additions and 6 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -89,6 +89,7 @@ namespace MWRender {
|
|||
SkyManager* mSky;
|
||||
Ogre::Plane mWaterPlane;
|
||||
Ogre::Plane mErrorPlane;
|
||||
Ogre::Plane mErrorPlaneUnderwater;
|
||||
bool mRenderActive;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue