More efficient StateSetController, beginnings of sky rendering

This commit is contained in:
scrawl 2015-04-14 15:55:56 +02:00
parent 8c7c89a4aa
commit 5dd1ab24fe
18 changed files with 610 additions and 762 deletions

View file

@ -20,8 +20,8 @@ set(GAME_HEADER
source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender
actors objects renderingmanager animation
# debugging sky camera npcanimation creatureanimation activatoranimation
actors objects renderingmanager animation sky
# debugging camera npcanimation creatureanimation activatoranimation
# renderinginterface localmap occlusionquery water shadows
# characterpreview globalmap ripplesimulation refraction
# terrainstorage renderconst effectmanager weaponanimation
@ -68,8 +68,8 @@ add_openmw_dir (mwworld
cells localscripts customdata inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
contentloader esmloader actiontrap cellreflist cellref physicssystem
# weather projectilemanager
contentloader esmloader actiontrap cellreflist cellref physicssystem weather
# projectilemanager
)
add_openmw_dir (mwclass

View file

@ -499,9 +499,17 @@ void OMW::Engine::go()
//mViewer.setRealizeOperation(ico);
mViewer.realize();
std::cout << "realize took " << timer.time_m() << std::endl;
osg::Timer frameTimer;
while (!mViewer.done())
{
MWBase::Environment::get().getWorld()->update(0.f, false);
double dt = frameTimer.time_s();
frameTimer.setStartTick();
// frameRenderingQueued(dt);
MWBase::Environment::get().getWorld()->update(dt, false);
MWBase::Environment::get().getWorld()->advanceTime(
dt*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600);
mViewer.frame(/*simulationTime*/);
}

View file

@ -41,7 +41,7 @@ public:
~Objects();
/// @param animated Attempt to load separate keyframes from a .kf file matching the model file?
/// @param allowLight If false, no lights will be created, and particles systems will be cleared then frozen.
/// @param allowLight If false, no lights will be created, and particles systems will be removed.
void insertModel(const MWWorld::Ptr& ptr, const std::string &model, bool animated=false, bool allowLight=true);
void insertNPC(const MWWorld::Ptr& ptr);

View file

@ -13,11 +13,39 @@
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/statesetcontroller.hpp>
#include <components/esm/loadcell.hpp>
#include "sky.hpp"
namespace MWRender
{
class StateUpdater : public SceneUtil::StateSetController
{
public:
virtual void setDefaults(osg::StateSet *stateset)
{
osg::LightModel* lightModel = new osg::LightModel;
stateset->setAttribute(lightModel, osg::StateAttribute::ON);
}
virtual void apply(osg::StateSet* stateset, osg::NodeVisitor*)
{
osg::LightModel* lightModel = static_cast<osg::LightModel*>(stateset->getAttribute(osg::StateAttribute::LIGHTMODEL));
lightModel->setAmbientIntensity(mAmbientColor);
}
void setAmbientColor(osg::Vec4f col)
{
mAmbientColor = col;
}
private:
osg::Vec4f mAmbientColor;
};
RenderingManager::RenderingManager(osgViewer::Viewer &viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem)
: mViewer(viewer)
, mRootNode(rootNode)
@ -30,6 +58,8 @@ namespace MWRender
mObjects.reset(new Objects(mResourceSystem, lightRoot));
mSky.reset(new SkyManager(mRootNode, resourceSystem->getSceneManager()));
mViewer.setLightingMode(osgViewer::View::NO_LIGHT);
osg::ref_ptr<osg::LightSource> source = new osg::LightSource;
@ -38,17 +68,30 @@ namespace MWRender
mSunLight->setDiffuse(osg::Vec4f(0,0,0,1));
mSunLight->setAmbient(osg::Vec4f(0,0,0,1));
mSunLight->setConstantAttenuation(1.f);
source->setStateSetModes(*rootNode->getOrCreateStateSet(), osg::StateAttribute::ON);
lightRoot->addChild(source);
rootNode->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
rootNode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);
rootNode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
mRootNode->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
mRootNode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);
mRootNode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON);
mStateUpdater = new StateUpdater;
mRootNode->addUpdateCallback(mStateUpdater);
// for consistent benchmarks against the ogre branch. remove later
osg::CullStack::CullingMode cullingMode = viewer.getCamera()->getCullingMode();
cullingMode &= ~(osg::CullStack::SMALL_FEATURE_CULLING);
viewer.getCamera()->setCullingMode( cullingMode );
double fovy, aspect, zNear, zFar;
mViewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
fovy = 55.f;
mViewer.getCamera()->setProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
}
RenderingManager::~RenderingManager()
{
}
MWRender::Objects& RenderingManager::getObjects()
@ -66,21 +109,34 @@ namespace MWRender
return mResourceSystem;
}
void RenderingManager::setAmbientColour(const osg::Vec4f &colour)
{
mStateUpdater->setAmbientColor(colour);
}
void RenderingManager::configureAmbient(const ESM::Cell *cell)
{
osg::ref_ptr<osg::LightModel> lightmodel = new osg::LightModel;
lightmodel->setAmbientIntensity(SceneUtil::colourFromRGB(cell->mAmbi.mAmbient));
mRootNode->getOrCreateStateSet()->setAttributeAndModes(lightmodel, osg::StateAttribute::ON);
setAmbientColour(SceneUtil::colourFromRGB(cell->mAmbi.mAmbient));
mSunLight->setDiffuse(SceneUtil::colourFromRGB(cell->mAmbi.mSunlight));
mSunLight->setDirection(osg::Vec3f(1.f,-1.f,-1.f));
}
void RenderingManager::setSunColour(const osg::Vec4f &colour)
{
mSunLight->setDiffuse(colour);
}
void RenderingManager::setSunDirection(const osg::Vec3f &direction)
{
mSunLight->setDirection(direction*-1);
mSky->setSunDirection(direction*-1);
}
osg::Vec3f RenderingManager::getEyePos()
{
osg::Vec3d eye;
//mViewer.getCamera()->getViewMatrixAsLookAt(eye, center, up);
eye = mViewer.getCameraManipulator()->getMatrix().getTrans();
osg::Vec3d eye = mViewer.getCameraManipulator()->getMatrix().getTrans();
return eye;
}
@ -89,4 +145,19 @@ namespace MWRender
mObjects->removeCell(store);
}
void RenderingManager::setSkyEnabled(bool enabled)
{
mSky->setEnabled(enabled);
}
void RenderingManager::configureFog(float fogDepth, const osg::Vec4f &colour)
{
mViewer.getCamera()->setClearColor(colour);
}
SkyManager* RenderingManager::getSkyManager()
{
return mSky.get();
}
}

View file

@ -31,20 +31,36 @@ namespace ESM
namespace MWRender
{
class StateUpdater;
class SkyManager;
class RenderingManager : public MWRender::RenderingInterface
{
public:
RenderingManager(osgViewer::Viewer& viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem);
~RenderingManager();
MWRender::Objects& getObjects();
MWRender::Actors& getActors();
Resource::ResourceSystem* getResourceSystem();
void setAmbientColour(const osg::Vec4f& colour);
void setSunDirection(const osg::Vec3f& direction);
void setSunColour(const osg::Vec4f& colour);
void configureAmbient(const ESM::Cell* cell);
void configureFog(float fogDepth, const osg::Vec4f& colour);
void removeCell(const MWWorld::CellStore* store);
void setSkyEnabled(bool enabled);
SkyManager* getSkyManager();
osg::Vec3f getEyePos();
private:
@ -55,6 +71,12 @@ namespace MWRender
osg::ref_ptr<osg::Light> mSunLight;
std::auto_ptr<Objects> mObjects;
std::auto_ptr<SkyManager> mSky;
osg::ref_ptr<StateUpdater> mStateUpdater;
void operator = (const RenderingManager&);
RenderingManager(const RenderingManager&);
};
}

File diff suppressed because it is too large Load diff

View file

@ -1,128 +1,35 @@
#ifndef GAME_RENDER_SKY_H
#define GAME_RENDER_SKY_H
#include <vector>
#include <OgreVector3.h>
#include <OgreString.h>
#include <OgreMaterial.h>
#include <OgreColourValue.h>
#include <OgreHighLevelGpuProgram.h>
#include <extern/shiny/Main/Factory.hpp>
#include <components/nifogre/ogrenifloader.hpp>
#ifndef OPENMW_MWRENDER_SKY_H
#define OPENMW_MWRENDER_SKY_H
#include <osg/ref_ptr>
#include "../mwworld/weather.hpp"
namespace Ogre
namespace osg
{
class Group;
class Node;
class Material;
}
namespace Resource
{
class RenderWindow;
class SceneNode;
class Camera;
class Viewport;
class SceneManager;
class Entity;
class BillboardSet;
class TextureUnitState;
}
namespace MWRender
{
class BillboardObject : public sh::MaterialInstanceListener
{
public:
BillboardObject( const Ogre::String& textureName,
const float size,
const Ogre::Vector3& position,
Ogre::SceneNode* rootNode,
const std::string& material
);
void requestedConfiguration (sh::MaterialInstance* m, const std::string& configuration);
void createdConfiguration (sh::MaterialInstance* m, const std::string& configuration);
virtual ~BillboardObject() {}
void setColour(const Ogre::ColourValue& pColour);
void setPosition(const Ogre::Vector3& pPosition);
void setVisible(const bool visible);
void setRenderQueue(unsigned int id);
void setVisibilityFlags(int flags);
void setSize(const float size);
Ogre::Vector3 getPosition() const;
void setVisibility(const float visibility);
Ogre::SceneNode* getNode();
protected:
float mVisibility;
Ogre::ColourValue mColour;
Ogre::SceneNode* mNode;
sh::MaterialInstance* mMaterial;
Ogre::Entity* mEntity;
};
/*
* The moons need a seperate class because of their shader (which allows them to be partially transparent)
*/
class Moon : public BillboardObject
{
public:
Moon( const Ogre::String& textureName,
const float size,
const Ogre::Vector3& position,
Ogre::SceneNode* rootNode,
const std::string& material
);
virtual ~Moon() {}
enum Phase
{
Phase_New = 0,
Phase_WaxingCrescent,
Phase_WaxingHalf,
Phase_WaxingGibbous,
Phase_Full,
Phase_WaningGibbous,
Phase_WaningHalf,
Phase_WaningCrescent
};
enum Type
{
Type_Masser = 0,
Type_Secunda
};
void setPhase(const Phase& phase);
void setType(const Type& type);
unsigned int getPhaseInt() const;
private:
Type mType;
Phase mPhase;
};
class AtmosphereUpdater;
class SkyManager
{
public:
SkyManager(Ogre::SceneNode* root, Ogre::Camera* pCamera);
SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager);
~SkyManager();
/// Attach weather particle effects to this scene node (should be the Camera's parent node)
void attachToNode(Ogre::SceneNode* sceneNode);
void update(float duration);
void enable();
void disable();
void setEnabled(bool enabled);
void setHour (double hour);
///< will be called even when sky is disabled.
@ -143,8 +50,6 @@ namespace MWRender
void setWeather(const MWWorld::WeatherResult& weather);
Ogre::SceneNode* getSunNode();
void sunEnable();
void sunDisable();
@ -153,7 +58,7 @@ namespace MWRender
void setStormDirection(const Ogre::Vector3& direction);
void setSunDirection(const Ogre::Vector3& direction, bool is_night);
void setSunDirection(const osg::Vec3f& direction);
void setMasserDirection(const Ogre::Vector3& direction);
@ -173,7 +78,6 @@ namespace MWRender
void setGlare(const float glare);
void setGlareEnabled(bool enabled);
Ogre::Vector3 getRealSunPos();
private:
void create();
@ -182,6 +86,22 @@ namespace MWRender
void updateRain(float dt);
void clearRain();
Resource::SceneManager* mSceneManager;
osg::ref_ptr<osg::Group> mRootNode;
osg::ref_ptr<osg::Node> mParticleEffect;
osg::ref_ptr<osg::Node> mCloudNode;
osg::ref_ptr<osg::Node> mAtmosphereDay;
osg::ref_ptr<osg::Node> mAtmosphereNight;
osg::ref_ptr<AtmosphereUpdater> mAtmosphereUpdater;
osg::ref_ptr<osg::PositionAttitudeTransform> mSunTransform;
bool mCreated;
bool mMoonRed;
@ -194,26 +114,6 @@ namespace MWRender
float mCloudAnimationTimer;
BillboardObject* mSun;
BillboardObject* mSunGlare;
Moon* mMasser;
Moon* mSecunda;
Ogre::Camera* mCamera;
Ogre::SceneNode* mRootNode;
Ogre::SceneManager* mSceneMgr;
Ogre::SceneNode* mAtmosphereDay;
Ogre::SceneNode* mAtmosphereNight;
Ogre::SceneNode* mCloudNode;
std::vector<NifOgre::ObjectScenePtr> mObjects;
Ogre::SceneNode* mParticleNode;
NifOgre::ObjectScenePtr mParticle;
std::map<Ogre::SceneNode*, NifOgre::ObjectScenePtr> mRainModels;
float mRainTimer;
Ogre::Vector3 mStormDirection;
@ -225,14 +125,12 @@ namespace MWRender
float mCloudOpacity;
float mCloudSpeed;
float mStarsOpacity;
Ogre::ColourValue mCloudColour;
Ogre::ColourValue mSkyColour;
Ogre::ColourValue mFogColour;
osg::Vec4f mCloudColour;
osg::Vec4f mSkyColour;
osg::Vec4f mFogColour;
std::string mCurrentParticleEffect;
Ogre::Light* mLightning;
float mRemainingTransitionTime;
float mGlare; // target

View file

@ -1,5 +1,7 @@
#include "fallback.hpp"
#include "boost/lexical_cast.hpp"
#include <boost/lexical_cast.hpp>
namespace MWWorld
{
Fallback::Fallback(const std::map<std::string,std::string>& fallback):mFallbackMap(fallback)
@ -39,11 +41,11 @@ namespace MWWorld
else
return boost::lexical_cast<bool>(fallback);
}
Ogre::ColourValue Fallback::getFallbackColour(const std::string& fall) const
osg::Vec4f Fallback::getFallbackColour(const std::string& fall) const
{
std::string sum=getFallbackString(fall);
if(sum.empty())
return Ogre::ColourValue(0,0,0);
return osg::Vec4f(0.f,0.f,0.f,1.f);
else
{
std::string ret[3];
@ -53,7 +55,7 @@ namespace MWWorld
else if (sum[i] != ' ') ret[j]+=sum[i];
}
return Ogre::ColourValue(boost::lexical_cast<int>(ret[0])/255.f,boost::lexical_cast<int>(ret[1])/255.f,boost::lexical_cast<int>(ret[2])/255.f);
return osg::Vec4f(boost::lexical_cast<int>(ret[0])/255.f,boost::lexical_cast<int>(ret[1])/255.f,boost::lexical_cast<int>(ret[2])/255.f, 1.f);
}
}
}

View file

@ -4,7 +4,7 @@
#include <map>
#include <string>
#include <OgreColourValue.h>
#include <osg/Vec4f>
namespace MWWorld
{
@ -17,7 +17,7 @@ namespace MWWorld
float getFallbackFloat(const std::string& fall) const;
int getFallbackInt(const std::string& fall) const;
bool getFallbackBool(const std::string& fall) const;
Ogre::ColourValue getFallbackColour(const std::string& fall) const;
osg::Vec4f getFallbackColour(const std::string& fall) const;
};
}
#endif

View file

@ -13,16 +13,15 @@
#include "../mwsound/sound.hpp"
//#include "../mwrender/renderingmanager.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "../mwrender/sky.hpp"
#include "player.hpp"
#include "esmstore.hpp"
#include "fallback.hpp"
#include "cellstore.hpp"
using namespace Ogre;
using namespace MWWorld;
using namespace MWSound;
namespace
{
@ -31,7 +30,7 @@ namespace
return x * (1-factor) + y * factor;
}
Ogre::ColourValue lerp (const Ogre::ColourValue& x, const Ogre::ColourValue& y, float factor)
osg::Vec4f lerp (const osg::Vec4f& x, const osg::Vec4f& y, float factor)
{
return x * (1-factor) + y * factor;
}
@ -196,7 +195,7 @@ WeatherManager::~WeatherManager()
stopSounds();
}
void WeatherManager::setWeather(const String& weather, bool instant)
void WeatherManager::setWeather(const std::string& weather, bool instant)
{
if (weather == mCurrentWeather && mNextWeather == "")
{
@ -224,7 +223,7 @@ void WeatherManager::setWeather(const String& weather, bool instant)
mFirstUpdate = false;
}
void WeatherManager::setResult(const String& weatherType)
void WeatherManager::setResult(const std::string& weatherType)
{
const Weather& current = mWeatherSettings[weatherType];
@ -387,8 +386,8 @@ void WeatherManager::update(float duration, bool paused)
const bool exterior = (world->isCellExterior() || world->isCellQuasiExterior());
if (!exterior)
{
mRendering->skyDisable();
mRendering->getSkyManager()->setLightningStrength(0.f);
mRendering->setSkyEnabled(false);
//mRendering->getSkyManager()->setLightningStrength(0.f);
stopSounds();
return;
}
@ -421,16 +420,16 @@ void WeatherManager::update(float duration, bool paused)
mStormDirection = (playerPos - redMountainPos);
mStormDirection.z = 0;
mRendering->getSkyManager()->setStormDirection(mStormDirection);
//mRendering->getSkyManager()->setStormDirection(mStormDirection);
}
mRendering->configureFog(mResult.mFogDepth, mResult.mFogColor);
// disable sun during night
if (mHour >= mNightStart || mHour <= mSunriseTime)
mRendering->getSkyManager()->sunDisable();
else
mRendering->getSkyManager()->sunEnable();
//if (mHour >= mNightStart || mHour <= mSunriseTime)
//mRendering->getSkyManager()->sunDisable();
//else
//mRendering->getSkyManager()->sunEnable();
// Update the sun direction. Run it east to west at a fixed angle from overhead.
// The sun's speed at day and night may differ, since mSunriseTime and mNightStart
@ -455,11 +454,11 @@ void WeatherManager::update(float duration, bool paused)
theta = M_PI * (adjustedHour - adjustedNightStart) / nightDuration;
}
Vector3 final(
osg::Vec3f final(
static_cast<float>(cos(theta)),
-0.268f, // approx tan( -15 degrees )
static_cast<float>(sin(theta)));
mRendering->setSunDirection( final, is_night );
mRendering->setSunDirection( final * -1 );
}
/*
@ -484,20 +483,20 @@ void WeatherManager::update(float duration, bool paused)
if (moonHeight != 0)
{
int facing = (moonHeight <= 1) ? 1 : -1;
Vector3 masser(
osg::Vec3f masser(
(moonHeight - 1) * facing,
(1 - moonHeight) * facing,
moonHeight);
Vector3 secunda(
osg::Vec3f secunda(
(moonHeight - 1) * facing * 1.25f,
(1 - moonHeight) * facing * 0.8f,
moonHeight);
mRendering->getSkyManager()->setMasserDirection(masser);
mRendering->getSkyManager()->setSecundaDirection(secunda);
mRendering->getSkyManager()->masserEnable();
mRendering->getSkyManager()->secundaEnable();
//mRendering->getSkyManager()->setMasserDirection(masser);
//mRendering->getSkyManager()->setSecundaDirection(secunda);
//mRendering->getSkyManager()->masserEnable();
//mRendering->getSkyManager()->secundaEnable();
float angle = (1-moonHeight) * 90.f * facing;
float masserHourFade = calculateHourFade("Masser");
@ -508,13 +507,13 @@ void WeatherManager::update(float duration, bool paused)
masserAngleFade *= masserHourFade;
secundaAngleFade *= secundaHourFade;
mRendering->getSkyManager()->setMasserFade(masserAngleFade);
mRendering->getSkyManager()->setSecundaFade(secundaAngleFade);
//mRendering->getSkyManager()->setMasserFade(masserAngleFade);
//mRendering->getSkyManager()->setSecundaFade(secundaAngleFade);
}
else
{
mRendering->getSkyManager()->masserDisable();
mRendering->getSkyManager()->secundaDisable();
//mRendering->getSkyManager()->masserDisable();
//mRendering->getSkyManager()->secundaDisable();
}
if (!paused)
@ -540,13 +539,13 @@ void WeatherManager::update(float duration, bool paused)
}
mThunderFlash -= duration;
if (mThunderFlash > 0)
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
else
//if (mThunderFlash > 0)
//mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
//else
{
mThunderChanceNeeded = static_cast<float>(OEngine::Misc::Rng::rollDice(100));
mThunderChance = 0;
mRendering->getSkyManager()->setLightningStrength( 0.f );
//mRendering->getSkyManager()->setLightningStrength( 0.f );
}
}
else
@ -557,19 +556,19 @@ void WeatherManager::update(float duration, bool paused)
{
mThunderFlash = mThunderThreshold;
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
//mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
mThunderSoundDelay = 0.25;
}
}
}
else
mRendering->getSkyManager()->setLightningStrength(0.f);
//else
//mRendering->getSkyManager()->setLightningStrength(0.f);
}
mRendering->setAmbientColour(mResult.mAmbientColor);
mRendering->sunEnable(false);
//mRendering->sunEnable(false);
mRendering->setSunColour(mResult.mSunColor);
mRendering->getSkyManager()->setWeather(mResult);
@ -850,3 +849,8 @@ Ogre::Vector3 WeatherManager::getStormDirection() const
{
return mStormDirection;
}
void WeatherManager::advanceTime(double hours)
{
mTimePassed += hours*3600;
}

View file

@ -6,6 +6,7 @@
#include <OgreColourValue.h>
#include <OgreVector3.h>
#include <osg/Vec4f>
#include "../mwbase/soundmanager.hpp"
@ -37,15 +38,15 @@ namespace MWWorld
std::string mNextCloudTexture;
float mCloudBlendFactor;
Ogre::ColourValue mFogColor;
osg::Vec4f mFogColor;
Ogre::ColourValue mAmbientColor;
osg::Vec4f mAmbientColor;
Ogre::ColourValue mSkyColor;
osg::Vec4f mSkyColor;
Ogre::ColourValue mSunColor;
osg::Vec4f mSunColor;
Ogre::ColourValue mSunDiscColor;
osg::Vec4f mSunDiscColor;
float mFogDepth;
@ -80,25 +81,25 @@ namespace MWWorld
std::string mCloudTexture;
// Sky (atmosphere) colors
Ogre::ColourValue mSkySunriseColor,
osg::Vec4f mSkySunriseColor,
mSkyDayColor,
mSkySunsetColor,
mSkyNightColor;
// Fog colors
Ogre::ColourValue mFogSunriseColor,
osg::Vec4f mFogSunriseColor,
mFogDayColor,
mFogSunsetColor,
mFogNightColor;
// Ambient lighting colors
Ogre::ColourValue mAmbientSunriseColor,
osg::Vec4f mAmbientSunriseColor,
mAmbientDayColor,
mAmbientSunsetColor,
mAmbientNightColor;
// Sun (directional) lighting colors
Ogre::ColourValue mSunSunriseColor,
osg::Vec4f mSunSunriseColor,
mSunDayColor,
mSunSunsetColor,
mSunNightColor;
@ -108,7 +109,7 @@ namespace MWWorld
mLandFogNightDepth;
// Color modulation for the sun itself during sunset (not completely sure)
Ogre::ColourValue mSunDiscSunsetColor;
osg::Vec4f mSunDiscSunsetColor;
// Duration of weather transition (in days)
float mTransitionDelta;
@ -185,10 +186,7 @@ namespace MWWorld
Ogre::Vector3 getStormDirection() const;
void advanceTime(double hours)
{
mTimePassed += hours*3600;
}
void advanceTime(double hours);
unsigned int getWeatherID() const;

View file

@ -131,18 +131,16 @@ namespace MWWorld
void World::adjustSky()
{
#if 0
if (mSky && (isCellExterior() || isCellQuasiExterior()))
{
mRendering->skySetHour (mGlobalVariables["gamehour"].getFloat());
mRendering->skySetDate (mGlobalVariables["day"].getInteger(),
mGlobalVariables["month"].getInteger());
//mRendering->skySetHour (mGlobalVariables["gamehour"].getFloat());
//mRendering->skySetDate (mGlobalVariables["day"].getInteger(),
// mGlobalVariables["month"].getInteger());
mRendering->skyEnable();
mRendering->setSkyEnabled(true);
}
else
mRendering->skyDisable();
#endif
mRendering->setSkyEnabled(false);
}
World::World (
@ -171,7 +169,7 @@ namespace MWWorld
//mPhysEngine->setSceneManager(renderer.getScene());
//mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback);
mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback);
mEsm.resize(contentFiles.size());
Loading::Listener* listener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
@ -267,9 +265,9 @@ namespace MWWorld
// mPhysics->toggleCollisionMode();
// we don't want old weather to persist on a new game
//delete mWeatherManager;
//mWeatherManager = 0;
//mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback);
delete mWeatherManager;
mWeatherManager = 0;
mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback);
if (!mStartupScript.empty())
MWBase::Environment::get().getWindowManager()->executeInConsole(mStartupScript);
@ -277,7 +275,7 @@ namespace MWWorld
void World::clear()
{
//mWeatherManager->clear();
mWeatherManager->clear();
//mRendering->clear();
#if 0
mProjectileManager->clear();
@ -348,7 +346,7 @@ namespace MWWorld
mCells.write (writer, progress);
mGlobalVariables.write (writer, progress);
mPlayer->write (writer, progress);
//mWeatherManager->write (writer, progress);
mWeatherManager->write (writer, progress);
#if 0
mProjectileManager->write (writer, progress);
#endif
@ -378,7 +376,7 @@ namespace MWWorld
if (!mStore.readRecord (reader, type) &&
!mGlobalVariables.readRecord (reader, type) &&
!mPlayer->readRecord (reader, type) &&
//!mWeatherManager->readRecord (reader, type) &&
!mWeatherManager->readRecord (reader, type) &&
!mCells.readRecord (reader, type, contentFileMap)
#if 0
&& !mProjectileManager->readRecord (reader, type)
@ -479,7 +477,7 @@ namespace MWWorld
// Must be cleared before mRendering is destroyed
mProjectileManager->clear();
#endif
//delete mWeatherManager;
delete mWeatherManager;
delete mWorldScene;
delete mRendering;
//delete mPhysics;
@ -819,7 +817,7 @@ namespace MWWorld
{
MWBase::Environment::get().getMechanicsManager()->advanceTime(static_cast<float>(hours * 3600));
//mWeatherManager->advanceTime (hours);
mWeatherManager->advanceTime (hours);
hours += mGlobalVariables["gamehour"].getFloat();
@ -845,7 +843,7 @@ namespace MWWorld
//mRendering->skySetHour (hour);
//mWeatherManager->setHour(static_cast<float>(hour));
mWeatherManager->setHour(static_cast<float>(hour));
if (days>0)
setDay (days + mGlobalVariables["day"].getInteger());
@ -1604,11 +1602,11 @@ namespace MWWorld
void World::update (float duration, bool paused)
{
/*
if (mGoToJail && !paused)
goToJail();
updateWeather(duration, paused);
/*
if (!paused)
doPhysics (duration);
@ -1731,17 +1729,17 @@ namespace MWWorld
int World::getCurrentWeather() const
{
return 0;//mWeatherManager->getWeatherID();
return mWeatherManager->getWeatherID();
}
void World::changeWeather(const std::string& region, const unsigned int id)
{
//mWeatherManager->changeWeather(region, id);
mWeatherManager->changeWeather(region, id);
}
void World::modRegion(const std::string &regionid, const std::vector<char> &chances)
{
//mWeatherManager->modRegion(regionid, chances);
mWeatherManager->modRegion(regionid, chances);
}
Ogre::Vector2 World::getNorthVector (CellStore* cell)
@ -2975,10 +2973,10 @@ namespace MWWorld
if (mPlayer->wasTeleported())
{
mPlayer->setTeleported(false);
//mWeatherManager->switchToNextWeather(true);
mWeatherManager->switchToNextWeather(true);
}
//mWeatherManager->update(duration, paused);
mWeatherManager->update(duration, paused);
}
struct AddDetectedReference

View file

@ -81,7 +81,7 @@ namespace MWWorld
MWWorld::Fallback mFallback;
MWRender::RenderingManager* mRendering;
//MWWorld::WeatherManager* mWeatherManager;
MWWorld::WeatherManager* mWeatherManager;
MWWorld::Scene *mWorldScene;
MWWorld::Player *mPlayer;

View file

@ -39,7 +39,7 @@ add_component_dir (resource
)
add_component_dir (sceneutil
clone attach lightmanager visitor util
clone attach lightmanager visitor util statesetcontroller
)
add_component_dir (nif

View file

@ -142,4 +142,14 @@ namespace Resource
}
}
const VFS::Manager* SceneManager::getVFS() const
{
return mVFS;
}
Resource::TextureManager* SceneManager::getTextureManager()
{
return mTextureManager;
}
}

View file

@ -55,6 +55,10 @@ namespace Resource
/// in cases where multiple contexts are used over the lifetime of the application.
void releaseGLObjects(osg::State* state);
const VFS::Manager* getVFS() const;
Resource::TextureManager* getTextureManager();
private:
const VFS::Manager* mVFS;
Resource::TextureManager* mTextureManager;

View file

@ -0,0 +1,31 @@
#include "statesetcontroller.hpp"
#include <osg/Node>
namespace SceneUtil
{
void StateSetController::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (!mStateSets[0])
{
// first time setup
osg::StateSet* src = node->getOrCreateStateSet();
for (int i=0; i<2; ++i) // Using SHALLOW_COPY for StateAttributes, if users want to modify it is their responsibility to set a non-shared one first
// This can be done conveniently in user implementations of the setDefaults() method
{
mStateSets[i] = static_cast<osg::StateSet*>(osg::clone(src, osg::CopyOp::SHALLOW_COPY));
setDefaults(mStateSets[i]);
}
}
// Swap to make the StateSet in [0] writable, [1] is now the StateSet that was queued by the last frame
std::swap(mStateSets[0], mStateSets[1]);
node->setStateSet(mStateSets[0]);
apply(mStateSets[0], nv);
traverse(node, nv);
}
}

View file

@ -0,0 +1,39 @@
#ifndef OPENMW_COMPONENTS_SCENEUTIL_STATESETCONTROLLER_H
#define OPENMW_COMPONENTS_SCENEUTIL_STATESETCONTROLLER_H
#include <osg/NodeCallback>
namespace SceneUtil
{
/// @brief Implements efficient pre-frame updating of StateSets.
/// @par With a naive update there would be race conditions when the OSG draw thread of the last frame
/// queues up a StateSet that we want to modify for the next frame. To solve this we could set the StateSet to
/// DYNAMIC data variance but that would undo all the benefits of the threading model - having the cull and draw
/// traversals run in parallel can yield up to 200% framerates.
/// @par Race conditions are prevented using a "double buffering" scheme - we have two StateSets that take turns,
/// the first StateSet is the one we can write to, the second is the one currently in use by the draw traversal of the last frame.
/// After a frame is completed the places are swapped.
/// @par Must be set as UpdateCallback on a Node.
class StateSetController : public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
protected:
/// Apply state - to override in derived classes
/// @note Due to the double buffering approach you *have* to apply all state
/// even if it has not changed since the last frame.
virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) = 0;
/// Set default state - optionally override in derived classes
/// @par May be used e.g. to allocate StateAttributes.
virtual void setDefaults(osg::StateSet* stateset) {}
private:
osg::ref_ptr<osg::StateSet> mStateSets[2];
};
}
#endif