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 <OgreHardwarePixelBuffer.h>
|
||||||
#include <OgreRenderTarget.h>
|
#include <OgreRenderTarget.h>
|
||||||
#include <OgreViewport.h>
|
#include <OgreViewport.h>
|
||||||
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
#include "renderconst.hpp"
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
|
@ -14,9 +15,13 @@ namespace MWRender
|
||||||
|
|
||||||
Refraction::Refraction(Ogre::Camera *parentCamera)
|
Refraction::Refraction(Ogre::Camera *parentCamera)
|
||||||
: mParentCamera(parentCamera)
|
: mParentCamera(parentCamera)
|
||||||
|
, mRenderActive(false)
|
||||||
|
, mIsUnderwater(false)
|
||||||
{
|
{
|
||||||
mCamera = mParentCamera->getSceneManager()->createCamera("RefractionCamera");
|
mCamera = mParentCamera->getSceneManager()->createCamera("RefractionCamera");
|
||||||
|
|
||||||
|
mParentCamera->getSceneManager()->addRenderQueueListener(this);
|
||||||
|
|
||||||
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual("WaterRefraction",
|
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);
|
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);
|
Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera);
|
||||||
vp->setOverlaysEnabled(false);
|
vp->setOverlaysEnabled(false);
|
||||||
vp->setShadowsEnabled(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");
|
vp->setMaterialScheme("water_reflection");
|
||||||
mRenderTarget->setAutoUpdated(true);
|
mRenderTarget->setAutoUpdated(true);
|
||||||
mRenderTarget->addListener(this);
|
mRenderTarget->addListener(this);
|
||||||
|
@ -47,17 +52,42 @@ namespace MWRender
|
||||||
mCamera->setAspectRatio(mParentCamera->getAspectRatio());
|
mCamera->setAspectRatio(mParentCamera->getAspectRatio());
|
||||||
mCamera->setFOVy(mParentCamera->getFOVy());
|
mCamera->setFOVy(mParentCamera->getFOVy());
|
||||||
|
|
||||||
mCamera->enableCustomNearClipPlane(mNearClipPlane);
|
mRenderActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
|
void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
|
||||||
{
|
{
|
||||||
|
mRenderActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Refraction::setHeight(float height)
|
void Refraction::setHeight(float height)
|
||||||
{
|
{
|
||||||
mNearClipPlane = Ogre::Plane( -Ogre::Vector3(0,1,0), -(height + 5));
|
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 <OgrePlane.h>
|
||||||
#include <OgreRenderTargetListener.h>
|
#include <OgreRenderTargetListener.h>
|
||||||
|
#include <OgreRenderQueueListener.h>
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
|
@ -13,7 +14,7 @@ namespace Ogre
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
|
||||||
class Refraction : public Ogre::RenderTargetListener
|
class Refraction : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -23,12 +24,20 @@ namespace MWRender
|
||||||
void setHeight (float height);
|
void setHeight (float height);
|
||||||
void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
|
void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
|
||||||
void postRenderTargetUpdate(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:
|
private:
|
||||||
Ogre::Camera* mParentCamera;
|
Ogre::Camera* mParentCamera;
|
||||||
Ogre::Camera* mCamera;
|
Ogre::Camera* mCamera;
|
||||||
Ogre::RenderTarget* mRenderTarget;
|
Ogre::RenderTarget* mRenderTarget;
|
||||||
Ogre::Plane mNearClipPlane;
|
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 (queueGroupId < 20 && mRenderActive)
|
||||||
{
|
{
|
||||||
if (!mIsUnderwater)
|
// this trick does not seem to work well for extreme angles
|
||||||
mCamera->enableCustomNearClipPlane(mErrorPlane);
|
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane);
|
||||||
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
|
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,6 +159,7 @@ void PlaneReflection::setHeight (float height)
|
||||||
{
|
{
|
||||||
mWaterPlane = Plane(Ogre::Vector3(0,1,0), height);
|
mWaterPlane = Plane(Ogre::Vector3(0,1,0), height);
|
||||||
mErrorPlane = Plane(Ogre::Vector3(0,1,0), height - 5);
|
mErrorPlane = Plane(Ogre::Vector3(0,1,0), height - 5);
|
||||||
|
mErrorPlaneUnderwater = Plane(Ogre::Vector3(0,-1,0), -height - 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaneReflection::setActive (bool active)
|
void PlaneReflection::setActive (bool active)
|
||||||
|
@ -348,6 +349,8 @@ Water::updateUnderwater(bool underwater)
|
||||||
|
|
||||||
if (mReflection)
|
if (mReflection)
|
||||||
mReflection->setUnderwater (mIsUnderwater);
|
mReflection->setUnderwater (mIsUnderwater);
|
||||||
|
if (mRefraction)
|
||||||
|
mRefraction->setUnderwater (mIsUnderwater);
|
||||||
|
|
||||||
updateVisible();
|
updateVisible();
|
||||||
}
|
}
|
||||||
|
@ -377,6 +380,8 @@ void Water::setViewportBackground(const ColourValue& bg)
|
||||||
{
|
{
|
||||||
if (mReflection)
|
if (mReflection)
|
||||||
mReflection->setViewportBackground(bg);
|
mReflection->setViewportBackground(bg);
|
||||||
|
if (mRefraction)
|
||||||
|
mRefraction->setViewportBackground(bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::updateVisible()
|
void Water::updateVisible()
|
||||||
|
|
|
@ -89,6 +89,7 @@ namespace MWRender {
|
||||||
SkyManager* mSky;
|
SkyManager* mSky;
|
||||||
Ogre::Plane mWaterPlane;
|
Ogre::Plane mWaterPlane;
|
||||||
Ogre::Plane mErrorPlane;
|
Ogre::Plane mErrorPlane;
|
||||||
|
Ogre::Plane mErrorPlaneUnderwater;
|
||||||
bool mRenderActive;
|
bool mRenderActive;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue