diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index cc3464c64..29cfe33fe 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -12,7 +12,8 @@ using namespace Ogre; OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) : mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0), mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false), - mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false) + mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false), + mBBNode(0) { mRendering = renderer; mSunNode = sunNode; @@ -52,7 +53,8 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod matQueryVisible->setCullingMode(CULL_NONE); matQueryVisible->setManualCullingMode(MANUAL_CULL_NONE); - mBBNode = mSunNode->getParentSceneNode()->createChildSceneNode(); + if (sunNode) + mBBNode = mSunNode->getParentSceneNode()->createChildSceneNode(); mObjectNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); @@ -182,10 +184,13 @@ void OcclusionQuery::update(float duration) if (dist==0) dist = 10000000; dist -= 1000; // bias dist /= 1000.f; - mBBNode->setPosition(mSunNode->getPosition() * dist); - mBBNode->setScale(dist, dist, dist); - mBBNodeReal->setPosition(mBBNode->_getDerivedPosition()); - mBBNodeReal->setScale(mBBNode->getScale()); + if (mBBNode) + { + mBBNode->setPosition(mSunNode->getPosition() * dist); + mBBNode->setScale(dist, dist, dist); + mBBNodeReal->setPosition(mBBNode->_getDerivedPosition()); + mBBNodeReal->setScale(mBBNode->getScale()); + } // Stop occlusion queries until we get their information // (may not happen on the same frame they are requested in) @@ -245,6 +250,13 @@ bool OcclusionQuery::occlusionTestPending() return (mQuerySingleObjectRequested || mQuerySingleObjectStarted); } +void OcclusionQuery::setSunNode(Ogre::SceneNode* node) +{ + mSunNode = node; + if (!mBBNode) + mBBNode = node->getParentSceneNode()->createChildSceneNode(); +} + bool OcclusionQuery::getTestResult() { assert( !occlusionTestPending() diff --git a/apps/openmw/mwrender/occlusionquery.hpp b/apps/openmw/mwrender/occlusionquery.hpp index ebdc51311..b655c8e46 100644 --- a/apps/openmw/mwrender/occlusionquery.hpp +++ b/apps/openmw/mwrender/occlusionquery.hpp @@ -53,6 +53,8 @@ namespace MWRender float getSunVisibility() const {return mSunVisibility;}; + void setSunNode(Ogre::SceneNode* node); + private: Ogre::HardwareOcclusionQuery* mSunTotalAreaQuery; Ogre::HardwareOcclusionQuery* mSunVisibleAreaQuery; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 3d715b3d3..bbddd325a 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -201,6 +201,8 @@ void RenderingManager::skyEnable () { if(mSkyManager) mSkyManager->enable(); + + mOcclusionQuery->setSunNode(mSkyManager->getSunNode()); } void RenderingManager::skyDisable () diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 265008e34..23b44d1f3 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -325,14 +325,17 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera, MWWorld::Environmen , mSunEnabled(true) , mMasserEnabled(true) , mSecundaEnabled(true) + , mCreated(false) { - mViewport = pCamera->getViewport(); mSceneMgr = pMwRoot->getCreator(); mRootNode = pCamera->getParentSceneNode()->createChildSceneNode(); mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates mRootNode->setInheritOrientation(false); +} +void SkyManager::create() +{ /// \todo preload all the textures and meshes that are used for sky rendering // Create overlay used for thunderstorm @@ -562,6 +565,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera, MWWorld::Environmen mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(""); + + mCreated = true; } SkyManager::~SkyManager() @@ -574,11 +579,13 @@ SkyManager::~SkyManager() int SkyManager::getMasserPhase() const { + if (!mCreated) return 0; return mMasser->getPhaseInt(); } int SkyManager::getSecundaPhase() const { + if (!mCreated) return 0; return mSecunda->getPhaseInt(); } @@ -631,6 +638,9 @@ void SkyManager::update(float duration) void SkyManager::enable() { + if (!mCreated) + create(); + mRootNode->setVisible(true); mEnabled = true; } @@ -654,6 +664,7 @@ void SkyManager::setCloudsOpacity(float opacity) void SkyManager::setWeather(const MWWorld::WeatherResult& weather) { + if (!mCreated) return; if (mClouds != weather.mCloudTexture) { mCloudMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("textures\\"+weather.mCloudTexture); @@ -750,17 +761,20 @@ void SkyManager::sunDisable() void SkyManager::setSunDirection(const Vector3& direction) { + if (!mCreated) return; mSun->setPosition(direction); mSunGlare->setPosition(direction); } void SkyManager::setMasserDirection(const Vector3& direction) { + if (!mCreated) return; mMasser->setPosition(direction); } void SkyManager::setSecundaDirection(const Vector3& direction) { + if (!mCreated) return; mSecunda->setPosition(direction); } @@ -786,6 +800,7 @@ void SkyManager::secundaDisable() void SkyManager::setThunder(const float factor) { + if (!mCreated) return; if (factor > 0.f) { mThunderOverlay->show(); @@ -818,5 +833,6 @@ void SkyManager::setDate(int day, int month) Ogre::SceneNode* SkyManager::getSunNode() { + if (!mCreated) return 0; return mSun->getNode(); } diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 508af7673..baf5933cb 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -112,6 +112,9 @@ namespace MWRender void update(float duration); + void create(); + ///< no need to call this, automatically done on first enable() + void enable(); void disable(); @@ -164,8 +167,10 @@ namespace MWRender void setGlare(const float glare); Ogre::Vector3 getRealSunPos(); - + private: + bool mCreated; + MWWorld::Environment* mEnvironment; float mHour; int mDay; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 6f03fa37f..a48cc7e72 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -146,10 +146,10 @@ namespace MWWorld mRendering->skySetDate (mGlobalVariables->getInt ("day"), mGlobalVariables->getInt ("month")); - mRendering->getSkyManager()->enable(); + mRendering->skyEnable(); } else - mRendering->getSkyManager()->disable(); + mRendering->skyDisable(); } World::World (OEngine::Render::OgreRenderer& renderer,