diff --git a/esm_store/cell_store.cpp b/esm_store/cell_store.cpp index 4383f932f..5bad6e10f 100644 --- a/esm_store/cell_store.cpp +++ b/esm_store/cell_store.cpp @@ -9,27 +9,29 @@ void CellStore::loadInt(const std::string &name, const ESMStore &store, ESMReade { cout << "loading cell '" << name << "'\n"; - const Cell *ref = store.cells.findInt(name); + cell = store.cells.findInt(name); - if(ref == NULL) + if(cell == NULL) throw str_exception("Cell not found - " + name); - loadRefs(*ref, store, esm); + loadRefs(store, esm); } void CellStore::loadExt(int X, int Y, const ESMStore &store, ESMReader &esm) { } -void CellStore::loadRefs(const Cell &cell, const ESMStore &store, ESMReader &esm) +void CellStore::loadRefs(const ESMStore &store, ESMReader &esm) { + assert (cell); + // Reopen the ESM reader and seek to the right position. - cell.restore(esm); + cell->restore(esm); CellRef ref; // Get each reference in turn - while(cell.getNextRef(esm, ref)) + while(cell->getNextRef(esm, ref)) { int rec = store.find(ref.refID); diff --git a/esm_store/cell_store.hpp b/esm_store/cell_store.hpp index 8dd2fa92a..87d33d041 100644 --- a/esm_store/cell_store.hpp +++ b/esm_store/cell_store.hpp @@ -68,6 +68,10 @@ namespace ESMS /// A storage struct for one single cell reference. struct CellStore { + CellStore() : cell (0) {} + + const ESM::Cell *cell; + // Lists for each individual object type CellRefList activators; CellRefList potions; @@ -98,7 +102,7 @@ namespace ESMS void loadExt(int X, int Y, const ESMStore &data, ESMReader &esm); private: - void loadRefs(const Cell &cell, const ESMStore &data, ESMReader &esm); + void loadRefs(const ESMStore &data, ESMReader &esm); }; } diff --git a/game/mwrender/interior.cpp b/game/mwrender/interior.cpp index 0c45dffbc..a4d9985b6 100644 --- a/game/mwrender/interior.cpp +++ b/game/mwrender/interior.cpp @@ -78,6 +78,63 @@ std::string InteriorCellRender::insertEnd() return handle; } +// configure lighting according to cell + +void InteriorCellRender::configureAmbient() +{ + ambientColor.setAsRGBA (cell.cell->ambi.ambient); + setAmbientMode(); + + if (cell.cell->data.flags & ESM::Cell::QuasiEx) + { + // Create a "sun" that shines light downwards. It doesn't look + // completely right, but leave it for now. + Ogre::Light *light = scene.getMgr()->createLight(); + Ogre::ColourValue colour; + colour.setAsRGBA (cell.cell->ambi.sunlight); + light->setDiffuseColour (colour); + light->setType(Ogre::Light::LT_DIRECTIONAL); + light->setDirection(0,-1,0); + // TODO: update position on regular basis or attach to camera scene node + } +} + +// configure fog according to cell + +void InteriorCellRender::configureFog() +{ + Ogre::ColourValue color; + color.setAsRGBA (cell.cell->ambi.fog); + + float high = 1000; + float low = 100; + + scene.getMgr()->setFog (FOG_LINEAR, color, 0, low, high); + scene.getCamera()->setFarClipDistance (high + 10); + scene.getViewport()->setBackgroundColour (color); +} + +void InteriorCellRender::setAmbientMode() +{ + switch (ambientMode) + { + case 0: + + scene.getMgr()->setAmbientLight(ambientColor); + break; + + case 1: + + scene.getMgr()->setAmbientLight(0.7*ambientColor + 0.3*ColourValue(1,1,1)); + break; + + case 2: + + scene.getMgr()->setAmbientLight(ColourValue(1,1,1)); + break; + } +} + void InteriorCellRender::show() { // If already loaded, just make the cell visible. @@ -89,6 +146,9 @@ void InteriorCellRender::show() base = scene.getRoot()->createChildSceneNode(); + configureAmbient(); + configureFog(); + insertCell(cell); } @@ -109,6 +169,25 @@ void InteriorCellRender::destroy() base = NULL; } +// Switch through lighting modes. + +void InteriorCellRender::toggleLight() +{ + if (ambientMode==2) + ambientMode = 0; + else + ++ambientMode; + + switch (ambientMode) + { + case 0: std::cout << "Setting lights to normal\n"; break; + case 1: std::cout << "Turning the lights up\n"; break; + case 2: std::cout << "Turning the lights to full\n"; break; + } + + setAmbientMode(); +} + // Magic function from the internets. Might need this later. /* void Scene::DestroyAllAttachedMovableObjects( SceneNode* i_pSceneNode ) diff --git a/game/mwrender/interior.hpp b/game/mwrender/interior.hpp index 3612fc98a..44878e114 100644 --- a/game/mwrender/interior.hpp +++ b/game/mwrender/interior.hpp @@ -4,6 +4,8 @@ #include "cell.hpp" #include "esm_store/cell_store.hpp" +#include "OgreColourValue.h" + namespace Ogre { class SceneNode; @@ -32,6 +34,11 @@ namespace MWRender Ogre::SceneNode *insert; + // 0 normal, 1 more bright, 2 max + int ambientMode; + + Ogre::ColourValue ambientColor; + /// start inserting a new reference. virtual void insertBegin (const ESM::CellRef &ref); @@ -44,10 +51,18 @@ namespace MWRender /// finish inserting a new reference and return a handle to it. virtual std::string insertEnd(); + /// configure lighting according to cell + void configureAmbient(); + + /// configure fog according to cell + void configureFog(); + + void setAmbientMode(); + public: InteriorCellRender(const ESMS::CellStore &_cell, MWScene &_scene) - : cell(_cell), scene(_scene), base(NULL), insert(NULL) {} + : cell(_cell), scene(_scene), base(NULL), insert(NULL), ambientMode (0) {} virtual ~InteriorCellRender() { destroy(); } @@ -60,6 +75,9 @@ namespace MWRender /// Destroy all rendering objects connected with this cell. void destroy(); + + /// Switch through lighting modes. + void toggleLight(); }; } diff --git a/game/mwrender/mwscene.cpp b/game/mwrender/mwscene.cpp index 76eba7ebd..960a50b2c 100644 --- a/game/mwrender/mwscene.cpp +++ b/game/mwrender/mwscene.cpp @@ -28,8 +28,6 @@ MWScene::MWScene(Render::OgreRenderer &_rend) // Create one viewport, entire window vp = window->addViewport(camera); - // Give the backround a healthy shade of green - vp->setBackgroundColour(ColourValue(0,0.1,0)); // Alter the camera aspect ratio to match the viewport camera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight())); diff --git a/game/mwrender/mwscene.hpp b/game/mwrender/mwscene.hpp index bd110faf5..724d4cb10 100644 --- a/game/mwrender/mwscene.hpp +++ b/game/mwrender/mwscene.hpp @@ -35,6 +35,8 @@ namespace MWRender Ogre::SceneNode *getRoot() { return mwRoot; } Ogre::SceneManager *getMgr() { return sceneMgr; } + Ogre::Camera *getCamera() { return camera; } + Ogre::Viewport *getViewport() { return vp; } }; }