mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-06 00:55:50 +00:00
e197f5318b
conversion from 'const float' to 'int', possible loss of data conversion from 'double' to 'int', possible loss of data conversion from 'float' to 'int', possible loss of data
111 lines
4.4 KiB
C++
111 lines
4.4 KiB
C++
#include "refraction.hpp"
|
|
|
|
#include <OgreCamera.h>
|
|
#include <OgreTextureManager.h>
|
|
#include <OgreSceneManager.h>
|
|
#include <OgreHardwarePixelBuffer.h>
|
|
#include <OgreRenderTarget.h>
|
|
#include <OgreViewport.h>
|
|
#include <OgreRoot.h>
|
|
#include <OgreRenderTexture.h>
|
|
#include <OgreSceneNode.h>
|
|
|
|
#include <extern/shiny/Main/Factory.hpp>
|
|
|
|
#include "renderconst.hpp"
|
|
|
|
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);
|
|
|
|
mRenderTarget = texture->getBuffer()->getRenderTarget();
|
|
Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera);
|
|
vp->setOverlaysEnabled(false);
|
|
vp->setShadowsEnabled(false);
|
|
vp->setVisibilityMask(RV_Refraction);
|
|
vp->setMaterialScheme("water_refraction");
|
|
vp->setBackgroundColour (Ogre::ColourValue(0.090195f, 0.115685f, 0.12745f));
|
|
mRenderTarget->setAutoUpdated(true);
|
|
mRenderTarget->addListener(this);
|
|
}
|
|
|
|
Refraction::~Refraction()
|
|
{
|
|
mRenderTarget->removeListener(this);
|
|
Ogre::TextureManager::getSingleton().remove("WaterRefraction");
|
|
mParentCamera->getSceneManager()->destroyCamera(mCamera);
|
|
mParentCamera->getSceneManager()->removeRenderQueueListener(this);
|
|
}
|
|
|
|
void Refraction::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
|
|
{
|
|
if (mParentCamera->isAttached())
|
|
mParentCamera->getParentSceneNode ()->needUpdate ();
|
|
mCamera->setOrientation(mParentCamera->getDerivedOrientation());
|
|
mCamera->setPosition(mParentCamera->getDerivedPosition());
|
|
mCamera->setNearClipDistance(mParentCamera->getNearClipDistance());
|
|
mCamera->setFarClipDistance(mParentCamera->getFarClipDistance());
|
|
mCamera->setAspectRatio(mParentCamera->getAspectRatio());
|
|
mCamera->setFOVy(mParentCamera->getFOVy());
|
|
|
|
// for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane.
|
|
// since all we are interested in is depth, we only need the third row of the matrix.
|
|
Ogre::Matrix4 projMatrix = mCamera->getProjectionMatrixWithRSDepth () * mCamera->getViewMatrix ();
|
|
sh::Vector4* row3 = new sh::Vector4(projMatrix[2][0], projMatrix[2][1], projMatrix[2][2], projMatrix[2][3]);
|
|
sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty<sh::Vector4> (row3));
|
|
|
|
// enable clip plane here to take advantage of CPU culling for overwater or underwater objects
|
|
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane);
|
|
|
|
mRenderActive = true;
|
|
}
|
|
|
|
void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
|
|
{
|
|
mCamera->disableCustomNearClipPlane ();
|
|
mRenderActive = false;
|
|
}
|
|
|
|
void Refraction::setHeight(float height)
|
|
{
|
|
mNearClipPlane = Ogre::Plane( -Ogre::Vector3(0,0,1), -(height + 5));
|
|
mNearClipPlaneUnderwater = Ogre::Plane( Ogre::Vector3(0,0,1), height - 5);
|
|
}
|
|
|
|
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());
|
|
}
|
|
}
|
|
|
|
void Refraction::setActive(bool active)
|
|
{
|
|
mRenderTarget->setActive(active);
|
|
}
|
|
|
|
}
|