diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 2d31cded9b..aaed9c7feb 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -23,7 +23,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const :mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mDebugging(engine) { mRendering.createScene("PlayerCam", 55, 5); - mSkyManager = MWRender::SkyManager::create(mRendering.getWindow(), mRendering.getCamera(), resDir); // Set default mipmap level (NB some APIs ignore this) TextureManager::getSingleton().setDefaultNumMipmaps(5); @@ -41,7 +40,9 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mMwRoot->pitch(Degree(-90)); mObjects.setMwRoot(mMwRoot); mActors.setMwRoot(mMwRoot); - + + mSkyManager = MWRender::SkyManager::create(mRendering.getWindow(), mRendering.getCamera(), mMwRoot, resDir); + //used to obtain ingame information of ogre objects (which are faced or selected) mRaySceneQuery = mRendering.getScene()->createRayQuery(Ray()); @@ -125,6 +126,8 @@ void RenderingManager::moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Ve void RenderingManager::update (float duration){ mActors.update (duration); + + mSkyManager->update(duration); } void RenderingManager::skyEnable () diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 95601d043f..eb77a96cff 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -1,8 +1,118 @@ #include "sky.hpp" #include "Caelum.h" +#include +#include +#include +#include + +#include + +using namespace Ogre; + namespace MWRender { + class MWSkyManager : public SkyManager + { + public: + MWSkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera); + virtual ~MWSkyManager(); + + virtual void update(float duration); + + virtual void enable(); + + virtual void disable(); + + virtual void setHour (double hour) {} + ///< will be called even when sky is disabled. + + virtual void setDate (int day, int month) {} + ///< will be called even when sky is disabled. + + virtual int getMasserPhase() const { return 0; } + ///< 0 new moon, 1 waxing or waning cresecent, 2 waxing or waning half, + /// 3 waxing or waning gibbous, 4 full moon + + virtual int getSecundaPhase() const { return 0; } + ///< 0 new moon, 1 waxing or waning cresecent, 2 waxing or waning half, + /// 3 waxing or waning gibbous, 4 full moon + + virtual void setMoonColour (bool red) {} + + private: + Camera* mCamera; + SceneNode* mRootNode; + SceneManager* mSceneMgr; + + MaterialPtr mCloudMaterial; + MaterialPtr mAtmosphereMaterial; + }; + + MWSkyManager::MWSkyManager (SceneNode* pMwRoot, Camera* pCamera) + { + mSceneMgr = pMwRoot->getCreator(); + mRootNode = pMwRoot->createChildSceneNode(); + + // Atmosphere + NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif"); + Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif"); + atmosphere_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY); + Ogre::SceneNode* atmosphere_node = mRootNode->createChildSceneNode(); + atmosphere_node->attachObject(atmosphere_ent); + mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial(); + + // Clouds + NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif"); + Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif"); + clouds_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY); + SceneNode* clouds_node = mRootNode->createChildSceneNode(); + clouds_node->attachObject(clouds_ent); + mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial(); + + // I'm not sure if the materials are being used by any other objects + // Make a unique "modifiable" copy of the materials to be sure + mCloudMaterial = mCloudMaterial->clone("Clouds"); + clouds_ent->getSubEntity(0)->setMaterial(mCloudMaterial); + mAtmosphereMaterial = mAtmosphereMaterial->clone("Atmosphere"); + atmosphere_ent->getSubEntity(0)->setMaterial(mAtmosphereMaterial); + + // Default atmosphere color: light blue + mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.235, 0.5, 0.73); + mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 1.0); + // Set up an UV scroll animation to move the clouds + mCloudMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setScrollAnimation(0.01f, 0.01f); + // Disable depth writing so that the sky does not cover any objects + mCloudMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); + mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); + // Alpha-blend the clouds with the atmosphere + mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); + + mCamera = pCamera; + mCamera->setFarClipDistance(50000.f); + } + MWSkyManager::~MWSkyManager() + { + } + + void MWSkyManager::update(float duration) + { + // Sync the position of the skydomes with the camera + /// \todo for some reason this is 1 frame delayed, which causes the skydome move funnily when the camera moves + mRootNode->_setDerivedPosition(mCamera->getParentSceneNode()->_getDerivedPosition()); + } + + void MWSkyManager::enable() + { + mRootNode->setVisible(true); + } + + void MWSkyManager::disable() + { + mRootNode->setVisible(false); + } + + // // Implements a Caelum sky with default settings. // @@ -23,6 +133,8 @@ namespace MWRender const boost::filesystem::path& resDir); virtual ~CaelumManager (); + virtual void update(float duration) {} + virtual void enable() {} virtual void disable() {} @@ -49,7 +161,6 @@ namespace MWRender const boost::filesystem::path& resDir) : mpCaelumSystem (NULL) { - using namespace Ogre; using namespace Caelum; assert(pCamera); @@ -92,13 +203,15 @@ namespace MWRender /// SkyManager* SkyManager::create (Ogre::RenderWindow* pRenderWindow, Ogre::Camera* pCamera, + Ogre::SceneNode* pMwRoot, const boost::filesystem::path& resDir) { SkyManager* pSkyManager = NULL; try { - pSkyManager = new CaelumManager(pRenderWindow, pCamera, resDir); + //pSkyManager = new CaelumManager(pRenderWindow, pCamera, resDir); + pSkyManager = new MWSkyManager(pMwRoot, pCamera); } catch (Ogre::Exception& e) { diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 446ed3f1c7..982c42e8cd 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -7,6 +7,7 @@ namespace Ogre { class RenderWindow; class Camera; + class SceneNode; } namespace MWRender @@ -19,9 +20,12 @@ namespace MWRender public: static SkyManager* create (Ogre::RenderWindow* pRenderWindow, Ogre::Camera* pCamera, + Ogre::SceneNode* pMwRoot, const boost::filesystem::path& resDir); virtual ~SkyManager() {} + virtual void update(float duration) = 0; + virtual void enable() = 0; virtual void disable() = 0;