Delete remaining files that won't be of any use
parent
974fda5bde
commit
41cce5240f
@ -1,208 +0,0 @@
|
||||
#include "occlusionquery.hpp"
|
||||
|
||||
#include <OgreRenderSystem.h>
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreBillboardSet.h>
|
||||
#include <OgreHardwareOcclusionQuery.h>
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreSubEntity.h>
|
||||
#include <OgreMeshManager.h>
|
||||
#include <OgreMaterialManager.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreMesh.h>
|
||||
|
||||
#include "renderconst.hpp"
|
||||
|
||||
using namespace MWRender;
|
||||
using namespace Ogre;
|
||||
|
||||
OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) :
|
||||
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mActiveQuery(0),
|
||||
mBBQueryVisible(0), mBBQueryTotal(0), mSunNode(sunNode), mBBNodeReal(0),
|
||||
mSunVisibility(0),
|
||||
mWasVisible(false),
|
||||
mActive(false),
|
||||
mFirstFrame(true),
|
||||
mDoQuery(0),
|
||||
mRendering(renderer)
|
||||
{
|
||||
try {
|
||||
RenderSystem* renderSystem = Root::getSingleton().getRenderSystem();
|
||||
|
||||
mSunTotalAreaQuery = renderSystem->createHardwareOcclusionQuery();
|
||||
mSunVisibleAreaQuery = renderSystem->createHardwareOcclusionQuery();
|
||||
|
||||
mSupported = (mSunTotalAreaQuery != 0) && (mSunVisibleAreaQuery != 0);
|
||||
}
|
||||
catch (Ogre::Exception&)
|
||||
{
|
||||
mSupported = false;
|
||||
}
|
||||
|
||||
if (!mSupported)
|
||||
{
|
||||
std::cout << "Hardware occlusion queries not supported." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
|
||||
|
||||
static Ogre::Mesh* plane = MeshManager::getSingleton().createPlane("occlusionbillboard",
|
||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y).get();
|
||||
plane->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE);
|
||||
|
||||
mBBQueryTotal = mRendering->getScene()->createEntity("occlusionbillboard");
|
||||
mBBQueryTotal->setCastShadows(false);
|
||||
mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery);
|
||||
mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1);
|
||||
mBBQueryTotal->setMaterialName("QueryTotalPixels");
|
||||
mBBNodeReal->attachObject(mBBQueryTotal);
|
||||
|
||||
mBBQueryVisible = mRendering->getScene()->createEntity("occlusionbillboard");
|
||||
mBBQueryVisible->setCastShadows(false);
|
||||
mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery);
|
||||
mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1);
|
||||
mBBQueryVisible->setMaterialName("QueryVisiblePixels");
|
||||
mBBNodeReal->attachObject(mBBQueryVisible);
|
||||
|
||||
mRendering->getScene()->addRenderObjectListener(this);
|
||||
mRendering->getScene()->addRenderQueueListener(this);
|
||||
mDoQuery = true;
|
||||
}
|
||||
|
||||
OcclusionQuery::~OcclusionQuery()
|
||||
{
|
||||
mRendering->getScene()->removeRenderObjectListener (this);
|
||||
mRendering->getScene()->removeRenderQueueListener(this);
|
||||
|
||||
RenderSystem* renderSystem = Root::getSingleton().getRenderSystem();
|
||||
if (mSunTotalAreaQuery)
|
||||
renderSystem->destroyHardwareOcclusionQuery(mSunTotalAreaQuery);
|
||||
if (mSunVisibleAreaQuery)
|
||||
renderSystem->destroyHardwareOcclusionQuery(mSunVisibleAreaQuery);
|
||||
}
|
||||
|
||||
bool OcclusionQuery::supported()
|
||||
{
|
||||
return mSupported;
|
||||
}
|
||||
|
||||
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
|
||||
const LightList* pLightList, bool suppressRenderStateChanges)
|
||||
{
|
||||
if (!mActive) return;
|
||||
|
||||
// The following code activates and deactivates the occlusion queries
|
||||
// so that the queries only include the rendering of the intended meshes
|
||||
|
||||
// Close the last occlusion query
|
||||
// Each occlusion query should only last a single rendering
|
||||
if (mActiveQuery != NULL)
|
||||
{
|
||||
mActiveQuery->endOcclusionQuery();
|
||||
mActiveQuery = NULL;
|
||||
}
|
||||
|
||||
// Open a new occlusion query
|
||||
if (mDoQuery == true)
|
||||
{
|
||||
if (rend == mBBQueryTotal->getSubEntity(0))
|
||||
{
|
||||
mActiveQuery = mSunTotalAreaQuery;
|
||||
mWasVisible = true;
|
||||
}
|
||||
else if (rend == mBBQueryVisible->getSubEntity(0))
|
||||
{
|
||||
mActiveQuery = mSunVisibleAreaQuery;
|
||||
}
|
||||
}
|
||||
|
||||
if (mActiveQuery != NULL)
|
||||
mActiveQuery->beginOcclusionQuery();
|
||||
}
|
||||
|
||||
void OcclusionQuery::renderQueueEnded(uint8 queueGroupId, const String& invocation, bool& repeatThisInvocation)
|
||||
{
|
||||
if (!mActive) return;
|
||||
|
||||
if (mActiveQuery != NULL)
|
||||
{
|
||||
mActiveQuery->endOcclusionQuery();
|
||||
mActiveQuery = NULL;
|
||||
}
|
||||
/**
|
||||
* for every beginOcclusionQuery(), we want a respective pullOcclusionQuery() and vice versa
|
||||
* this also means that results can be wrong at other places if we pull, but beginOcclusionQuery() was never called
|
||||
* this can happen for example if the object that is tested is outside of the view frustum
|
||||
* to prevent this, check if the queries have been performed after everything has been rendered and if not, start them manually
|
||||
*/
|
||||
if (queueGroupId == RQG_SkiesLate)
|
||||
{
|
||||
if (mWasVisible == false && mDoQuery)
|
||||
{
|
||||
mSunTotalAreaQuery->beginOcclusionQuery();
|
||||
mSunTotalAreaQuery->endOcclusionQuery();
|
||||
mSunVisibleAreaQuery->beginOcclusionQuery();
|
||||
mSunVisibleAreaQuery->endOcclusionQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OcclusionQuery::update(float duration)
|
||||
{
|
||||
if (mFirstFrame)
|
||||
{
|
||||
// GLHardwareOcclusionQuery::isStillOutstanding doesn't seem to like getting called when nothing has been rendered yet
|
||||
mFirstFrame = false;
|
||||
return;
|
||||
}
|
||||
if (!mSupported) return;
|
||||
|
||||
mWasVisible = false;
|
||||
|
||||
// Adjust the position of the sun billboards according to camera viewing distance
|
||||
// we need to do this to make sure that _everything_ can occlude the sun
|
||||
float dist = mRendering->getCamera()->getFarClipDistance();
|
||||
if (dist==0) dist = 10000000;
|
||||
dist -= 1000; // bias
|
||||
dist /= 1000.f;
|
||||
if (mSunNode)
|
||||
{
|
||||
mBBNodeReal->setPosition(mSunNode->getPosition() * dist);
|
||||
mBBNodeReal->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-mBBNodeReal->getPosition().normalisedCopy()));
|
||||
mBBNodeReal->setScale(150.f*dist, 150.f*dist, 150.f*dist);
|
||||
}
|
||||
|
||||
// Stop occlusion queries until we get their information
|
||||
// (may not happen on the same frame they are requested in)
|
||||
mDoQuery = false;
|
||||
|
||||
if (!mSunTotalAreaQuery->isStillOutstanding()
|
||||
&& !mSunVisibleAreaQuery->isStillOutstanding())
|
||||
{
|
||||
unsigned int totalPixels;
|
||||
unsigned int visiblePixels;
|
||||
|
||||
mSunTotalAreaQuery->pullOcclusionQuery(&totalPixels);
|
||||
mSunVisibleAreaQuery->pullOcclusionQuery(&visiblePixels);
|
||||
|
||||
if (totalPixels == 0)
|
||||
{
|
||||
// probably outside of the view frustum
|
||||
mSunVisibility = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSunVisibility = float(visiblePixels) / float(totalPixels);
|
||||
if (mSunVisibility > 1) mSunVisibility = 1;
|
||||
}
|
||||
|
||||
mDoQuery = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OcclusionQuery::setSunNode(Ogre::SceneNode* node)
|
||||
{
|
||||
mSunNode = node;
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
#ifndef GAME_OCCLUSION_QUERY_H
|
||||
#define GAME_OCCLUSION_QUERY_H
|
||||
|
||||
#include <OgreRenderObjectListener.h>
|
||||
#include <OgreRenderQueueListener.h>
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class HardwareOcclusionQuery;
|
||||
class Entity;
|
||||
class SceneNode;
|
||||
}
|
||||
|
||||
#include <openengine/ogre/renderer.hpp>
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
///
|
||||
/// \brief Implements hardware occlusion queries on the GPU
|
||||
///
|
||||
class OcclusionQuery : public Ogre::RenderObjectListener, public Ogre::RenderQueueListener
|
||||
{
|
||||
public:
|
||||
OcclusionQuery(OEngine::Render::OgreRenderer*, Ogre::SceneNode* sunNode);
|
||||
~OcclusionQuery();
|
||||
|
||||
/**
|
||||
* @return true if occlusion queries are supported on the user's hardware
|
||||
*/
|
||||
bool supported();
|
||||
|
||||
/**
|
||||
* make sure to disable occlusion queries before updating unrelated render targets
|
||||
* @param active
|
||||
*/
|
||||
void setActive (bool active) { mActive = active; }
|
||||
|
||||
/**
|
||||
* per-frame update
|
||||
*/
|
||||
void update(float duration);
|
||||
|
||||
float getSunVisibility() const {return mSunVisibility;};
|
||||
|
||||
void setSunNode(Ogre::SceneNode* node);
|
||||
|
||||
private:
|
||||
Ogre::HardwareOcclusionQuery* mSunTotalAreaQuery;
|
||||
Ogre::HardwareOcclusionQuery* mSunVisibleAreaQuery;
|
||||
Ogre::HardwareOcclusionQuery* mActiveQuery;
|
||||
|
||||
Ogre::Entity* mBBQueryVisible;
|
||||
Ogre::Entity* mBBQueryTotal;
|
||||
|
||||
Ogre::SceneNode* mSunNode;
|
||||
Ogre::SceneNode* mBBNodeReal;
|
||||
float mSunVisibility;
|
||||
|
||||
bool mWasVisible;
|
||||
|
||||
bool mActive;
|
||||
bool mFirstFrame;
|
||||
|
||||
bool mSupported;
|
||||
bool mDoQuery;
|
||||
|
||||
OEngine::Render::OgreRenderer* mRendering;
|
||||
|
||||
protected:
|
||||
virtual void notifyRenderSingleObject(Ogre::Renderable* rend, const Ogre::Pass* pass, const Ogre::AutoParamDataSource* source,
|
||||
const Ogre::LightList* pLightList, bool suppressRenderStateChanges);
|
||||
|
||||
virtual void renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,169 +0,0 @@
|
||||
#include "ripplesimulation.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreParticleSystem.h>
|
||||
#include <OgreParticle.h>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwworld/fallback.hpp"
|
||||
|
||||
#include "renderconst.hpp"
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
|
||||
RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager, const MWWorld::Fallback* fallback)
|
||||
: mSceneMgr(mainSceneManager)
|
||||
, mParticleSystem(NULL)
|
||||
, mSceneNode(NULL)
|
||||
{
|
||||
mRippleLifeTime = fallback->getFallbackFloat("Water_RippleLifetime");
|
||||
mRippleRotSpeed = fallback->getFallbackFloat("Water_RippleRotSpeed");
|
||||
|
||||
// Unknown:
|
||||
// fallback=Water_RippleScale,0.15, 6.5
|
||||
// fallback=Water_RippleAlphas,0.7, 0.1, 0.01
|
||||
|
||||
// Instantiate from ripples.particle file
|
||||
mParticleSystem = mSceneMgr->createParticleSystem("openmw/Ripples", "openmw/Ripples");
|
||||
|
||||
mParticleSystem->setRenderQueueGroup(RQG_Ripples);
|
||||
mParticleSystem->setVisibilityFlags(RV_Effects);
|
||||
|
||||
int rippleFrameCount = fallback->getFallbackInt("Water_RippleFrameCount");
|
||||
std::string tex = fallback->getFallbackString("Water_RippleTexture");
|
||||
|
||||
sh::MaterialInstance* mat = sh::Factory::getInstance().getMaterialInstance("openmw/Ripple");
|
||||
mat->setProperty("anim_texture2", sh::makeProperty(new sh::StringValue(std::string("textures\\water\\") + tex + ".dds "
|
||||
+ Ogre::StringConverter::toString(rippleFrameCount)
|
||||
+ " "
|
||||
+ Ogre::StringConverter::toString(0.3))));
|
||||
|
||||
// seems to be required to allocate mFreeParticles. TODO: patch Ogre to handle this better
|
||||
mParticleSystem->_update(0.f);
|
||||
|
||||
mSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
|
||||
mSceneNode->attachObject(mParticleSystem);
|
||||
}
|
||||
|
||||
RippleSimulation::~RippleSimulation()
|
||||
{
|
||||
if (mParticleSystem)
|
||||
mSceneMgr->destroyParticleSystem(mParticleSystem);
|
||||
mParticleSystem = NULL;
|
||||
|
||||
if (mSceneNode)
|
||||
mSceneMgr->destroySceneNode(mSceneNode);
|
||||
mSceneNode = NULL;
|
||||
}
|
||||
|
||||
void RippleSimulation::update(float dt, Ogre::Vector2 position)
|
||||
{
|
||||
bool newParticle = false;
|
||||
for (std::vector<Emitter>::iterator it=mEmitters.begin(); it !=mEmitters.end(); ++it)
|
||||
{
|
||||
if (it->mPtr == MWBase::Environment::get().getWorld ()->getPlayerPtr())
|
||||
{
|
||||
// fetch a new ptr (to handle cell change etc)
|
||||
// for non-player actors this is done in updateObjectCell
|
||||
it->mPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
}
|
||||
Ogre::Vector3 currentPos (it->mPtr.getRefData().getPosition().pos);
|
||||
currentPos.z = 0;
|
||||
if ( (currentPos - it->mLastEmitPosition).length() > 10
|
||||
// Only emit when close to the water surface, not above it and not too deep in the water
|
||||
&& MWBase::Environment::get().getWorld ()->isUnderwater (it->mPtr.getCell(),
|
||||
Ogre::Vector3(it->mPtr.getRefData().getPosition().pos))
|
||||
&& !MWBase::Environment::get().getWorld()->isSubmerged(it->mPtr))
|
||||
{
|
||||
it->mLastEmitPosition = currentPos;
|
||||
|
||||
newParticle = true;
|
||||
Ogre::Particle* created = mParticleSystem->createParticle();
|
||||
if (!created)
|
||||
break; // TODO: cleanup the oldest particle to make room
|
||||
#if OGRE_VERSION >= (1 << 16 | 10 << 8 | 0)
|
||||
Ogre::Vector3& position = created->mPosition;
|
||||
Ogre::Vector3& direction = created->mDirection;
|
||||
Ogre::ColourValue& colour = created->mColour;
|
||||
float& totalTimeToLive = created->mTotalTimeToLive;
|
||||
float& timeToLive = created->mTimeToLive;
|
||||
Ogre::Radian& rotSpeed = created->mRotationSpeed;
|
||||
Ogre::Radian& rotation = created->mRotation;
|
||||
#else
|
||||
Ogre::Vector3& position = created->position;
|
||||
Ogre::Vector3& direction = created->direction;
|
||||
Ogre::ColourValue& colour = created->colour;
|
||||
float& totalTimeToLive = created->totalTimeToLive;
|
||||
float& timeToLive = created->timeToLive;
|
||||
Ogre::Radian& rotSpeed = created->rotationSpeed;
|
||||
Ogre::Radian& rotation = created->rotation;
|
||||
#endif
|
||||
timeToLive = totalTimeToLive = mRippleLifeTime;
|
||||
colour = Ogre::ColourValue(0.f, 0.f, 0.f, 0.7f); // Water_RippleAlphas.x?
|
||||
direction = Ogre::Vector3(0,0,0);
|
||||
position = currentPos;
|
||||
position.z = 0; // Z is set by the Scene Node
|
||||
rotSpeed = mRippleRotSpeed;
|
||||
rotation = Ogre::Radian(Ogre::Math::RangeRandom(-Ogre::Math::PI, Ogre::Math::PI));
|
||||
created->setDimensions(mParticleSystem->getDefaultWidth(), mParticleSystem->getDefaultHeight());
|
||||
}
|
||||
}
|
||||
|
||||
if (newParticle) // now apparently needs another update, otherwise it won't render in the first frame after a particle is created. TODO: patch Ogre to handle this better
|
||||
mParticleSystem->_update(0.f);
|
||||
}
|
||||
|
||||
void RippleSimulation::addEmitter(const MWWorld::Ptr& ptr, float scale, float force)
|
||||
{
|
||||
Emitter newEmitter;
|
||||
newEmitter.mPtr = ptr;
|
||||
newEmitter.mScale = scale;
|
||||
newEmitter.mForce = force;
|
||||
newEmitter.mLastEmitPosition = Ogre::Vector3(0,0,0);
|
||||
mEmitters.push_back (newEmitter);
|
||||
}
|
||||
|
||||
void RippleSimulation::removeEmitter (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
for (std::vector<Emitter>::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it)
|
||||
{
|
||||
if (it->mPtr == ptr)
|
||||
{
|
||||
mEmitters.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RippleSimulation::updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr)
|
||||
{
|
||||
for (std::vector<Emitter>::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it)
|
||||
{
|
||||
if (it->mPtr == old)
|
||||
{
|
||||
it->mPtr = ptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RippleSimulation::setWaterHeight(float height)
|
||||
{
|
||||
mSceneNode->setPosition(0,0,height);
|
||||
}
|
||||
|
||||
void RippleSimulation::clear()
|
||||
{
|
||||
mParticleSystem->clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
#ifndef RIPPLE_SIMULATION_H
|
||||
#define RIPPLE_SIMULATION_H
|
||||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class SceneManager;
|
||||
class ParticleSystem;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Fallback;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
|
||||
struct Emitter
|
||||
{
|
||||
MWWorld::Ptr mPtr;
|
||||
Ogre::Vector3 mLastEmitPosition;
|
||||
float mScale;
|
||||
float mForce;
|
||||
};
|
||||
|
||||
class RippleSimulation
|
||||
{
|
||||
public:
|
||||
RippleSimulation(Ogre::SceneManager* mainSceneManager, const MWWorld::Fallback* fallback);
|
||||
~RippleSimulation();
|
||||
|
||||
/// @param dt Time since the last frame
|
||||
/// @param position Position of the player
|
||||
void update(float dt, Ogre::Vector2 position);
|
||||
|
||||
/// adds an emitter, position will be tracked automatically
|
||||
void addEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f);
|
||||
void removeEmitter (const MWWorld::Ptr& ptr);
|
||||
void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
|
||||
|
||||
/// Change the height of the water surface, thus moving all ripples with it
|
||||
void setWaterHeight(float height);
|
||||
|
||||
/// Remove all active ripples
|
||||
void clear();
|
||||
|
||||
private:
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
Ogre::ParticleSystem* mParticleSystem;
|
||||
Ogre::SceneNode* mSceneNode;
|
||||
|
||||
std::vector<Emitter> mEmitters;
|
||||
|
||||
float mRippleLifeTime;
|
||||
float mRippleRotSpeed;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,187 +0,0 @@
|
||||
#include "shadows.hpp"
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
#include <openengine/ogre/renderer.hpp>
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreColourValue.h>
|
||||
#include <OgreShadowCameraSetupLiSPSM.h>
|
||||
#include <OgreShadowCameraSetupPSSM.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreRenderTexture.h>
|
||||
#include <OgreViewport.h>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
#include "renderconst.hpp"
|
||||
|
||||
using namespace Ogre;
|
||||
using namespace MWRender;
|
||||
|
||||
Shadows::Shadows(OEngine::Render::OgreRenderer* rend) :
|
||||
mRendering(rend), mSceneMgr(rend->getScene()), mPSSMSetup(NULL),
|
||||
mShadowFar(1000), mFadeStart(0.9f)
|
||||
{
|
||||
recreate();
|
||||
}
|
||||
|
||||
void Shadows::recreate()
|
||||
{
|
||||
bool enabled = Settings::Manager::getBool("enabled", "Shadows");
|
||||
|
||||
bool split = Settings::Manager::getBool("split", "Shadows");
|
||||
|
||||
sh::Factory::getInstance ().setGlobalSetting ("shadows", enabled && !split ? "true" : "false");
|
||||
sh::Factory::getInstance ().setGlobalSetting ("shadows_pssm", enabled && split ? "true" : "false");
|
||||
|
||||
if (!enabled)
|
||||
{
|
||||
mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
int texsize = Settings::Manager::getInt("texture size", "Shadows");
|
||||
mSceneMgr->setShadowTextureSize(texsize);
|
||||
|
||||
mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED);
|
||||
|
||||
// no point light shadows, i'm afraid. might revisit this with Deferred Shading
|
||||
mSceneMgr->setShadowTextureCountPerLightType(Light::LT_POINT, 0);
|
||||
|
||||
mSceneMgr->setShadowTextureCountPerLightType(Light::LT_DIRECTIONAL, split ? 3 : 1);
|
||||
mSceneMgr->setShadowTextureCount(split ? 3 : 1);
|
||||
|
||||
mSceneMgr->setShadowTextureSelfShadow(true);
|
||||
mSceneMgr->setShadowCasterRenderBackFaces(true);
|
||||
mSceneMgr->setShadowTextureCasterMaterial("openmw_shadowcaster_default");
|
||||
mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R);
|
||||
mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000000);
|
||||
|
||||
mShadowFar = Settings::Manager::getFloat(split ? "split shadow distance" : "shadow distance", "Shadows");
|
||||
mSceneMgr->setShadowFarDistance(mShadowFar);
|
||||
|
||||
mFadeStart = Settings::Manager::getFloat("fade start", "Shadows");
|
||||
|
||||
ShadowCameraSetupPtr shadowCameraSetup;
|
||||
if (split)
|
||||
{
|
||||
mPSSMSetup = new PSSMShadowCameraSetup();
|
||||
|
||||
// Make sure to keep this in sync with the camera's near clip distance!
|
||||
mPSSMSetup->setSplitPadding(mRendering->getCamera()->getNearClipDistance());
|
||||
|
||||
mPSSMSetup->calculateSplitPoints(3, mRendering->getCamera()->getNearClipDistance(), mShadowFar);
|
||||
|
||||
const Real adjustFactors[3] = {64, 64, 64};
|
||||
for (int i=0; i < 3; ++i)
|
||||
{
|
||||
mPSSMSetup->setOptimalAdjustFactor(i, adjustFactors[i]);
|
||||
/*if (i==0)
|
||||
mSceneMgr->setShadowTextureConfig(i, texsize, texsize, Ogre::PF_FLOAT32_R);
|
||||
else if (i ==1)
|
||||
mSceneMgr->setShadowTextureConfig(i, texsize/2, texsize/2, Ogre::PF_FLOAT32_R);
|
||||
else if (i ==2)
|
||||
mSceneMgr->setShadowTextureConfig(i, texsize/4, texsize/4, Ogre::PF_FLOAT32_R);*/
|
||||
}
|
||||
|
||||
// Populate from split point 1, not 0, since split 0 isn't useful (usually 0)
|
||||
const PSSMShadowCameraSetup::SplitPointList& splitPointList = getPSSMSetup()->getSplitPoints();
|
||||
sh::Vector3* splitPoints = new sh::Vector3(splitPointList[1], splitPointList[2], splitPointList[3]);
|
||||
|
||||
sh::Factory::getInstance ().setSharedParameter ("pssmSplitPoints", sh::makeProperty<sh::Vector3>(splitPoints));
|
||||
|
||||
shadowCameraSetup = ShadowCameraSetupPtr(mPSSMSetup);
|
||||
}
|
||||
else
|
||||
{
|
||||
LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup();
|
||||
lispsmSetup->setOptimalAdjustFactor(64);
|
||||
//lispsmSetup->setCameraLightDirectionThreshold(Degree(0));
|
||||
//lispsmSetup->setUseAggressiveFocusRegion(false);
|
||||
shadowCameraSetup = ShadowCameraSetupPtr(lispsmSetup);
|
||||
}
|
||||
mSceneMgr->setShadowCameraSetup(shadowCameraSetup);
|
||||
|
||||
sh::Vector4* shadowFar_fadeStart = new sh::Vector4(mShadowFar, mFadeStart * mShadowFar, 0, 0);
|
||||
sh::Factory::getInstance ().setSharedParameter ("shadowFar_fadeStart", sh::makeProperty<sh::Vector4>(shadowFar_fadeStart));
|
||||
|
||||
// Set visibility mask for the shadow render textures
|
||||
int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows")
|
||||
+ (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows")
|
||||
+ RV_Misc * Settings::Manager::getBool("misc shadows", "Shadows")
|
||||
+ RV_Terrain * (Settings::Manager::getBool("terrain shadows", "Shadows"));
|
||||
for (int i = 0; i < (split ? 3 : 1); ++i)
|
||||
{
|
||||
TexturePtr shadowTexture = mSceneMgr->getShadowTexture(i);
|
||||
Viewport* vp = shadowTexture->getBuffer()->getRenderTarget()->getViewport(0);
|
||||
vp->setVisibilityMask(visibilityMask);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// --------------------------- Debug overlays to display the content of shadow maps -----------------------------------
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
if (Settings::Manager::getBool("debug", "Shadows"))
|
||||
{
|
||||
OverlayManager& mgr = OverlayManager::getSingleton();
|
||||
Overlay* overlay;
|
||||
|
||||
// destroy if already exists
|
||||
if ((overlay = mgr.getByName("DebugOverlay")))
|
||||
mgr.destroy(overlay);
|
||||
|
||||
overlay = mgr.create("DebugOverlay");
|
||||
for (size_t i = 0; i < (split ? 3 : 1); ++i) {
|
||||
TexturePtr tex = mRendering->getScene()->getShadowTexture(i);
|
||||
|
||||
// Set up a debug panel to display the shadow
|
||||
|
||||
if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + StringConverter::toString(i)))
|
||||
MaterialManager::getSingleton().remove("Ogre/DebugTexture" + StringConverter::toString(i));
|
||||
MaterialPtr debugMat = MaterialManager::getSingleton().create(
|
||||
"Ogre/DebugTexture" + StringConverter::toString(i),
|
||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
|
||||
debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
||||
TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
|
||||
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
|
||||
|
||||
OverlayContainer* debugPanel;
|
||||
|
||||
// destroy container if exists
|
||||
try
|
||||
{
|
||||
if ((debugPanel =
|
||||
static_cast<OverlayContainer*>(
|
||||
mgr.getOverlayElement("Ogre/DebugTexPanel" + StringConverter::toString(i)
|
||||
))))
|
||||
mgr.destroyOverlayElement(debugPanel);
|
||||
}
|
||||
catch (Ogre::Exception&) {}
|
||||
|
||||
debugPanel = (OverlayContainer*)
|
||||
(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
|
||||
debugPanel->_setPosition(0.8, i*0.25);
|
||||
debugPanel->_setDimensions(0.2, 0.24);
|
||||
debugPanel->setMaterialName(debugMat->getName());
|
||||
debugPanel->show();
|
||||
overlay->add2D(debugPanel);
|
||||
overlay->show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OverlayManager& mgr = OverlayManager::getSingleton();
|
||||
Overlay* overlay;
|
||||
|
||||
if ((overlay = mgr.getByName("DebugOverlay")))
|
||||
mgr.destroy(overlay);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
PSSMShadowCameraSetup* Shadows::getPSSMSetup()
|
||||
{
|
||||
return mPSSMSetup;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
#ifndef GAME_SHADOWS_H
|
||||
#define GAME_SHADOWS_H
|
||||
|
||||
// forward declares
|
||||
namespace Ogre
|
||||
{
|
||||
class SceneManager;
|
||||
class PSSMShadowCameraSetup;
|
||||
}
|
||||
namespace OEngine{
|
||||
namespace Render{
|
||||
class OgreRenderer;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class Shadows
|
||||
{
|
||||
public:
|
||||
Shadows(OEngine::Render::OgreRenderer* rend);
|
||||
|
||||
void recreate();
|
||||
|
||||
Ogre::PSSMShadowCameraSetup* getPSSMSetup();
|
||||
|
||||
protected:
|
||||
OEngine::Render::OgreRenderer* mRendering;
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
|
||||
Ogre::PSSMShadowCameraSetup* mPSSMSetup;
|
||||
float mShadowFar;
|
||||
float mFadeStart;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue