diff --git a/CMakeLists.txt b/CMakeLists.txt index 6704fbf0b..399a595b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,10 +12,17 @@ set(GAME apps/openmw/main.cpp apps/openmw/engine.cpp) set(GAME_HEADER apps/openmw/mwinput/inputmanager.hpp apps/openmw/engine.hpp) source_group(game FILES ${GAME} ${GAME_HEADER}) -set(GAMEREND apps/openmw/mwrender/mwscene.cpp apps/openmw/mwrender/cell.cpp - apps/openmw/mwrender/interior.cpp) -set(GAMEREND_HEADER apps/openmw/mwrender/cell.hpp apps/openmw/mwrender/mwscene.hpp - apps/openmw/mwrender/interior.hpp apps/openmw/mwrender/playerpos.hpp) +set(GAMEREND + apps/openmw/mwrender/mwscene.cpp + apps/openmw/mwrender/cell.cpp + apps/openmw/mwrender/interior.cpp + apps/openmw/mwrender/sky.cpp) +set(GAMEREND_HEADER + apps/openmw/mwrender/cell.hpp + apps/openmw/mwrender/mwscene.hpp + apps/openmw/mwrender/interior.hpp + apps/openmw/mwrender/playerpos.hpp + apps/openmw/mwrender/sky.hpp) source_group(game_renderer FILES ${GAMEREND} ${GAMEREND_HEADER}) # set(GAMEINPUT) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 06d80bcc1..9b0fc4816 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -12,8 +12,13 @@ #include "apps/openmw/mwrender/interior.hpp" #include "mwinput/inputmanager.hpp" #include "apps/openmw/mwrender/playerpos.hpp" +#include "apps/openmw/mwrender/sky.hpp" -OMW::Engine::Engine() {} +OMW::Engine::Engine() + : mEnableSky (false) + , mpSkyManager (NULL) +{ +} // adjust name and load bsa @@ -76,6 +81,13 @@ void OMW::Engine::addMaster (const std::string& master) mMaster = master; } +// Enables sky rendering +// +void OMW::Engine::enableSky (bool bEnable) +{ + mEnableSky = bEnable; +} + // Initialise and enter main loop. void OMW::Engine::go() @@ -125,6 +137,10 @@ void OMW::Engine::go() // Used to control the player camera and position MWRender::PlayerPos player(scene.getCamera()); + // Optionally enable the sky + if (mEnableSky) + mpSkyManager = MWRender::SkyManager::create(mOgre.getWindow(), scene.getCamera()); + // This connects the cell data with the rendering scene. MWRender::InteriorCellRender rend(cell, scene); @@ -141,6 +157,8 @@ void OMW::Engine::go() // Start the main rendering loop mOgre.start(); + delete mpSkyManager; + std::cout << "\nThat's all for now!\n"; } diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index dbe70b4d8..8143c3ab8 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -7,6 +7,11 @@ #include "apps/openmw/mwrender/mwscene.hpp" +namespace MWRender +{ + class SkyManager; +} + namespace OMW { /// \brief Main engine class, that brings together all the components of OpenMW @@ -17,6 +22,9 @@ namespace OMW Render::OgreRenderer mOgre; std::string mCellName; std::string mMaster; + + bool mEnableSky; + MWRender::SkyManager* mpSkyManager; // not implemented Engine (const Engine&); @@ -47,6 +55,9 @@ namespace OMW /// - Currently OpenMW only supports one master at the same time. void addMaster (const std::string& master); + /// Enables rendering of the sky (off by default). + void enableSky (bool bEnable); + /// Initialise and enter main loop. void go(); }; diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 0c778f18d..635384ad5 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -15,30 +15,32 @@ using namespace std; bool parseOptions (int argc, char**argv, OMW::Engine& engine) { - boost::program_options::options_description desc ( + // Create a local alias for brevity + namespace bpo = boost::program_options; + + bpo::options_description desc ( "Syntax: openmw \nAllowed options"); desc.add_options() ("help", "print help message") - ("data", boost::program_options::value()->default_value ("data"), + ("data", bpo::value()->default_value ("data"), "set data directory") - ("start", boost::program_options::value()->default_value ("Beshara"), + ("start", bpo::value()->default_value ("Beshara"), "set initial cell (only interior cells supported at the moment") - ("master", boost::program_options::value()->default_value ("Morrowind"), + ("master", bpo::value()->default_value ("Morrowind"), "master file") + ("enablesky", "enable rendering of the sky") ; - boost::program_options::variables_map variables; + bpo::variables_map variables; std::ifstream configFile ("openmw.cfg"); - boost::program_options::store ( - boost::program_options::parse_command_line (argc, argv, desc), variables); - boost::program_options::notify (variables); + bpo::store ( bpo::parse_command_line (argc, argv, desc), variables ); + bpo::notify (variables); if (configFile.is_open()) - boost::program_options::store ( - boost::program_options::parse_config_file (configFile, desc), variables); + bpo::store ( bpo::parse_config_file (configFile, desc), variables); if (variables.count ("help")) { @@ -46,6 +48,8 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) return false; } + engine.enableSky(!!variables.count("enablesky")); + engine.setDataDir (variables["data"].as()); engine.setCell (variables["start"].as()); engine.addMaster (variables["master"].as()); diff --git a/apps/openmw/mwrender/mwscene.cpp b/apps/openmw/mwrender/mwscene.cpp index 2ad5e30ea..171bc108c 100644 --- a/apps/openmw/mwrender/mwscene.cpp +++ b/apps/openmw/mwrender/mwscene.cpp @@ -9,88 +9,8 @@ #include "OgreCamera.h" #include "OgreTextureManager.h" -#include "Caelum.h" - using namespace MWRender; using namespace Ogre; -using namespace Caelum; - -class MWWeatherFrameListener : public Ogre::FrameListener -{ -protected: - Caelum::CaelumSystem* mpCaelumSystem; - Ogre::SceneManager* mpScene; - float mfSpeedFactor; - bool mbPaused; - float mfTimeTillNextUpdate; - -public: - MWWeatherFrameListener(RenderWindow* pRenderWindow, Camera* pCamera) - : mpCaelumSystem (NULL) - , mpScene (NULL) - , mfSpeedFactor (1.0f) - , mbPaused (false) - , mfTimeTillNextUpdate (0.0f) - { - ConfigFile cf; - cf.load("resources.cfg"); - ResourceGroupManager::getSingleton().addResourceLocation(".", "FileSystem"); - - ConfigFile::SectionIterator seci = cf.getSectionIterator(); - - String secName, typeName, archName; - while (seci.hasMoreElements()) - { - secName = seci.peekNextKey(); - ConfigFile::SettingsMultiMap *settings = seci.getNext(); - ConfigFile::SettingsMultiMap::iterator i; - for (i = settings->begin(); i != settings->end(); ++i) - { - typeName = i->first; - archName = i->second; - ResourceGroupManager::getSingleton().addResourceLocation( - archName, typeName, secName); - } - } - - mpScene = pCamera->getSceneManager(); - - ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - - Caelum::CaelumSystem::CaelumComponent componentMask = CaelumSystem::CAELUM_COMPONENTS_DEFAULT; - componentMask = static_cast ( - //Caelum::CaelumSystem::CAELUM_COMPONENT_SUN | - //Caelum::CaelumSystem::CAELUM_COMPONENT_MOON | - //Caelum::CaelumSystem::CAELUM_COMPONENT_SKY_DOME | - //Caelum::CaelumSystem::CAELUM_COMPONENT_IMAGE_STARFIELD | - //Caelum::CaelumSystem::CAELUM_COMPONENT_POINT_STARFIELD | - Caelum::CaelumSystem::CAELUM_COMPONENT_CLOUDS | - 0); - componentMask = CaelumSystem::CAELUM_COMPONENTS_DEFAULT; - - mpCaelumSystem = new Caelum::CaelumSystem (Root::getSingletonPtr(), mpScene, componentMask); - mpCaelumSystem->setManageSceneFog(false); -// mpCaelumSystem->getCloudSystem()-> - - // Set time acceleration. - mpCaelumSystem->getUniversalClock ()->setTimeScale(512); - mfSpeedFactor = mpCaelumSystem->getUniversalClock ()->getTimeScale(); - - // Register caelum as a listener. - pRenderWindow->addListener(mpCaelumSystem); - Root::getSingletonPtr()->addFrameListener(mpCaelumSystem); - } - - ~MWWeatherFrameListener() - { - if (mpCaelumSystem) - { - mpCaelumSystem->shutdown (false); - mpCaelumSystem = NULL; - } - } - -}; MWScene::MWScene(Render::OgreRenderer &_rend) : rend(_rend) @@ -116,6 +36,8 @@ MWScene::MWScene(Render::OgreRenderer &_rend) // Set default mipmap level (NB some APIs ignore this) TextureManager::getSingleton().setDefaultNumMipmaps(5); + + // Load resources ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); @@ -130,17 +52,4 @@ MWScene::MWScene(Render::OgreRenderer &_rend) // For testing sceneMgr->setAmbientLight(ColourValue(1,1,1)); - - try - { - MWWeatherFrameListener* pWeather = new MWWeatherFrameListener (window, camera); - } - catch (Exception& e) - { - std::cout << "\nERROR: " << e.getFullDescription().c_str() << std::endl; - } - catch(std::exception &e) - { - std::cout << "\nERROR: " << e.what() << std::endl; - } } diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp new file mode 100755 index 000000000..ec3e8a1b7 --- /dev/null +++ b/apps/openmw/mwrender/sky.cpp @@ -0,0 +1,90 @@ +#include "sky.hpp" +#include "Caelum.h" + +namespace MWRender +{ + // + // Implements a Caelum sky with default settings. + // + // Note: this is intended as a temporary solution to provide some form of + // sky rendering. This code will obviously need significant tailoring to + // support fidelity with Morrowind's rendering. Before doing major work + // on this class, more research should be done to determine whether + // Caelum or another plug-in such as SkyX would be best for the long-term. + // + class CaelumManager : public SkyManager + { + protected: + Caelum::CaelumSystem* mpCaelumSystem; + + public: + CaelumManager (Ogre::RenderWindow* pRenderWindow, + Ogre::Camera* pCamera); + virtual ~CaelumManager (); + }; + + CaelumManager::CaelumManager (Ogre::RenderWindow* pRenderWindow, + Ogre::Camera* pCamera) + : mpCaelumSystem (NULL) + { + using namespace Ogre; + using namespace Caelum; + + assert(pCamera); + assert(pRenderWindow); + + // Load the Caelum resources + // + ResourceGroupManager::getSingleton().addResourceLocation("resources\\caelum", "FileSystem", "Caelum"); + ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + + // Load the Caelum resources + // + Ogre::SceneManager* pScene = pCamera->getSceneManager(); + Caelum::CaelumSystem::CaelumComponent componentMask = CaelumSystem::CAELUM_COMPONENTS_DEFAULT; + mpCaelumSystem = new Caelum::CaelumSystem (Root::getSingletonPtr(), pScene, componentMask); + + // Set time acceleration. + mpCaelumSystem->getUniversalClock()->setTimeScale(128); + + // Disable fog since OpenMW is handling OGRE fog elsewhere + mpCaelumSystem->setManageSceneFog(false); + + // Register Caelum as an OGRE listener + pRenderWindow->addListener(mpCaelumSystem); + Root::getSingletonPtr()->addFrameListener(mpCaelumSystem); + } + + CaelumManager::~CaelumManager() + { + if (mpCaelumSystem) + mpCaelumSystem->shutdown (false); + } + + /// Creates and connects the sky rendering component to OGRE. + /// + /// \return NULL on failure. + /// + SkyManager* SkyManager::create (Ogre::RenderWindow* pRenderWindow, + Ogre::Camera* pCamera) + { + SkyManager* pSkyManager = NULL; + + try + { + pSkyManager = new CaelumManager(pRenderWindow, pCamera); + } + catch (Ogre::Exception& e) + { + std::cout << "\nOGRE Exception when attempting to add sky: " + << e.getFullDescription().c_str() << std::endl; + } + catch (std::exception& e) + { + std::cout << "\nException when attempting to add sky: " + << e.what() << std::endl; + } + + return pSkyManager; + } +} diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp new file mode 100755 index 000000000..35b8cca74 --- /dev/null +++ b/apps/openmw/mwrender/sky.hpp @@ -0,0 +1,24 @@ +#ifndef _GAME_RENDER_SKY_H +#define _GAME_RENDER_SKY_H + +namespace Ogre +{ + class RenderWindow; + class Camera; +} + +namespace MWRender +{ + /// + /// Interface for the sky rendering system + /// + class SkyManager + { + public: + static SkyManager* create (Ogre::RenderWindow* pRenderWindow, + Ogre::Camera* pCamera); + virtual ~SkyManager() {} + }; +} + +#endif // _GAME_RENDER_SKY_H diff --git a/extern/caelum/CMakeLists.txt b/extern/caelum/CMakeLists.txt index 0c920e9da..cdc63af33 100755 --- a/extern/caelum/CMakeLists.txt +++ b/extern/caelum/CMakeLists.txt @@ -9,3 +9,49 @@ file(GLOB_RECURSE CAELUM_HDR include/*) set(SOURCES ${CAELUM_SRC} ${CAELUM_HDR}) add_library(caelum STATIC ${SOURCES}) +# +# Resources +# +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/AtmosphereDepth.png "${OpenMW_BINARY_DIR}/resources/caelum/AtmosphereDepth.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/CaelumGroundFog.cg "${OpenMW_BINARY_DIR}/resources/caelum/CaelumGroundFog.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/CaelumLayeredClouds.cg "${OpenMW_BINARY_DIR}/resources/caelum/CaelumLayeredClouds.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/CaelumPhaseMoon.cg "${OpenMW_BINARY_DIR}/resources/caelum/CaelumPhaseMoon.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/CaelumPointStarfield.cg "${OpenMW_BINARY_DIR}/resources/caelum/CaelumPointStarfield.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/CaelumSkyDome.cg "${OpenMW_BINARY_DIR}/resources/caelum/CaelumSkyDome.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/CloudCoverLookup.png "${OpenMW_BINARY_DIR}/resources/caelum/CloudCoverLookup.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/DepthComposer.cg "${OpenMW_BINARY_DIR}/resources/caelum/DepthComposer.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/DepthComposer.compositor "${OpenMW_BINARY_DIR}/resources/caelum/DepthComposer.compositor" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/DepthComposer.material "${OpenMW_BINARY_DIR}/resources/caelum/DepthComposer.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/DepthRender.program "${OpenMW_BINARY_DIR}/resources/caelum/DepthRender.program" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/EarthClearSky2.png "${OpenMW_BINARY_DIR}/resources/caelum/EarthClearSky2.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/GroundFog.material "${OpenMW_BINARY_DIR}/resources/caelum/GroundFog.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/GroundFog.program "${OpenMW_BINARY_DIR}/resources/caelum/GroundFog.program" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/Haze.program "${OpenMW_BINARY_DIR}/resources/caelum/Haze.program" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/LayeredClouds.material "${OpenMW_BINARY_DIR}/resources/caelum/LayeredClouds.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/MinimalCompositorVP.cg "${OpenMW_BINARY_DIR}/resources/caelum/MinimalCompositorVP.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/MinimalCompositorVP.program "${OpenMW_BINARY_DIR}/resources/caelum/MinimalCompositorVP.program" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/moon.material "${OpenMW_BINARY_DIR}/resources/caelum/moon.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/moon_disc.dds "${OpenMW_BINARY_DIR}/resources/caelum/moon_disc.dds" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/noise1.dds "${OpenMW_BINARY_DIR}/resources/caelum/noise1.dds" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/noise2.dds "${OpenMW_BINARY_DIR}/resources/caelum/noise2.dds" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/noise3.dds "${OpenMW_BINARY_DIR}/resources/caelum/noise3.dds" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/noise4.dds "${OpenMW_BINARY_DIR}/resources/caelum/noise4.dds" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/PointStarfield.material "${OpenMW_BINARY_DIR}/resources/caelum/PointStarfield.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/Precipitation.cg "${OpenMW_BINARY_DIR}/resources/caelum/Precipitation.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/Precipitation.compositor "${OpenMW_BINARY_DIR}/resources/caelum/Precipitation.compositor" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/Precipitation.material "${OpenMW_BINARY_DIR}/resources/caelum/Precipitation.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/precipitation_drizzle.png "${OpenMW_BINARY_DIR}/resources/caelum/precipitation_drizzle.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/precipitation_hail.png "${OpenMW_BINARY_DIR}/resources/caelum/precipitation_hail.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/precipitation_icecrystals.png "${OpenMW_BINARY_DIR}/resources/caelum/precipitation_icecrystals.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/precipitation_icepellets.png "${OpenMW_BINARY_DIR}/resources/caelum/precipitation_icepellets.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/precipitation_rain.png "${OpenMW_BINARY_DIR}/resources/caelum/precipitation_rain.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/precipitation_smallhail.png "${OpenMW_BINARY_DIR}/resources/caelum/precipitation_smallhail.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/precipitation_snow.png "${OpenMW_BINARY_DIR}/resources/caelum/precipitation_snow.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/precipitation_snowgrains.png "${OpenMW_BINARY_DIR}/resources/caelum/precipitation_snowgrains.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/SkyDome.material "${OpenMW_BINARY_DIR}/resources/caelum/SkyDome.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/sphere.mesh "${OpenMW_BINARY_DIR}/resources/caelum/sphere.mesh" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/Starfield.jpg "${OpenMW_BINARY_DIR}/resources/caelum/Starfield.jpg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/Starfield.material "${OpenMW_BINARY_DIR}/resources/caelum/Starfield.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/Sun.material "${OpenMW_BINARY_DIR}/resources/caelum/Sun.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/SunGradient.png "${OpenMW_BINARY_DIR}/resources/caelum/SunGradient.png" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/sun_disc.png "${OpenMW_BINARY_DIR}/resources/caelum/sun_disc.png" COPYONLY)