Merge branch 'master' of https://github.com/zinnschlag/openmw into initocfg

Conflicts:
	apps/openmw/main.cpp
actorid
Sebastian Wick 13 years ago
commit 57ae1bdc43

@ -223,6 +223,9 @@ endif (APPLE)
# Other files # Other files
configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
"${OpenMW_BINARY_DIR}/settings-default.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
"${OpenMW_BINARY_DIR}/openmw.cfg") "${OpenMW_BINARY_DIR}/openmw.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
@ -303,6 +306,7 @@ if(DPKG_PROGRAM)
INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
#Install global configuration files #Install global configuration files
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")

@ -20,6 +20,7 @@
#include <components/esm/esm_reader.hpp> #include <components/esm/esm_reader.hpp>
#include <components/files/fixedpath.hpp> #include <components/files/fixedpath.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include <components/settings/settings.hpp>
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bullet_nif_loader.hpp>
#include <components/nifogre/ogre_nif_loader.hpp> #include <components/nifogre/ogre_nif_loader.hpp>
@ -321,6 +322,29 @@ void OMW::Engine::go()
{ {
boost::filesystem::create_directories(configPath); boost::filesystem::create_directories(configPath);
} }
// Create the settings manager and load default settings file
Settings::Manager settings;
const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg";
const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg";
// prefer local
if (boost::filesystem::exists(localdefault))
settings.loadDefault(localdefault);
else if (boost::filesystem::exists(globaldefault))
settings.loadDefault(globaldefault);
// load user settings if they exist, otherwise just load the default settings as user settings
const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg";
if (boost::filesystem::exists(settingspath))
settings.loadUser(settingspath);
else if (boost::filesystem::exists(localdefault))
settings.loadUser(localdefault);
else if (boost::filesystem::exists(globaldefault))
settings.loadUser(globaldefault);
mFpsLevel = settings.getInt("fps", "HUD");
mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()), mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()),
mCfgMgr.getOgreConfigPath().string(), mCfgMgr.getOgreConfigPath().string(),
mCfgMgr.getLogPath().string(), mCfgMgr.getLogPath().string(),
@ -415,6 +439,9 @@ void OMW::Engine::go()
// Start the main rendering loop // Start the main rendering loop
mOgre->start(); mOgre->start();
// Save user settings
settings.saveUser(settingspath);
std::cout << "Quitting peacefully.\n"; std::cout << "Quitting peacefully.\n";
} }

@ -123,10 +123,14 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
("plugin", bpo::value<StringsVector>()->default_value(StringsVector(), "") ("plugin", bpo::value<StringsVector>()->default_value(StringsVector(), "")
->multitoken(), "plugin file(s)") ->multitoken(), "plugin file(s)")
<<<<<<< HEAD
("fps", bpo::value<int>()->implicit_value(1) ("fps", bpo::value<int>()->implicit_value(1)
->default_value(0), "fps counter detail (0 = off, 1 = fps counter, 2 = full detail)") ->default_value(0), "fps counter detail (0 = off, 1 = fps counter, 2 = full detail)")
("anim-verbose", bpo::value<bool>()->implicit_value(true) ("anim-verbose", bpo::value<bool>()->implicit_value(true)
=======
("anim-verbose", boost::program_options::value<bool>()->implicit_value(true)
>>>>>>> e403c7158acfb118bed01a08a46431b24cff8747
->default_value(false), "output animation indices files") ->default_value(false), "output animation indices files")
("debug", bpo::value<bool>()->implicit_value(true) ("debug", bpo::value<bool>()->implicit_value(true)
@ -260,7 +264,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.setNewGame(variables["new-game"].as<bool>()); engine.setNewGame(variables["new-game"].as<bool>());
// other settings // other settings
engine.showFPS(variables["fps"].as<int>());
engine.setDebugMode(variables["debug"].as<bool>()); engine.setDebugMode(variables["debug"].as<bool>());
engine.setSoundUsage(!variables["nosound"].as<bool>()); engine.setSoundUsage(!variables["nosound"].as<bool>());
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>()); engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());

@ -528,6 +528,13 @@ namespace MWDialogue
mChoice = -1; mChoice = -1;
mIsInChoice = false; mIsInChoice = false;
mCompilerContext.setExtensions (&extensions); mCompilerContext.setExtensions (&extensions);
mDialogueMap.clear();
actorKnownTopics.clear();
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{
mDialogueMap[it->first] = it->second;
}
} }
void DialogueManager::addTopic(std::string topic) void DialogueManager::addTopic(std::string topic)
@ -563,13 +570,7 @@ namespace MWDialogue
mActor = actor; mActor = actor;
mDialogueMap.clear();
actorKnownTopics.clear(); actorKnownTopics.clear();
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{
mDialogueMap[it->first] = it->second;
}
//initialise the GUI //initialise the GUI
mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue); mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue);
@ -582,6 +583,7 @@ namespace MWDialogue
//greeting //greeting
bool greetingFound = false; bool greetingFound = false;
//ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; //ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{ {
ESM::Dialogue ndialogue = it->second; ESM::Dialogue ndialogue = it->second;

@ -278,6 +278,7 @@ LocalMapBase::LocalMapBase()
: mCurX(0) : mCurX(0)
, mCurY(0) , mCurY(0)
, mInterior(false) , mInterior(false)
, mFogOfWar(true)
, mLocalMap(NULL) , mLocalMap(NULL)
, mPrefix() , mPrefix()
, mChanged(true) , mChanged(true)
@ -297,6 +298,32 @@ void LocalMapBase::setCellPrefix(const std::string& prefix)
mChanged = true; mChanged = true;
} }
void LocalMapBase::toggleFogOfWar()
{
mFogOfWar = !mFogOfWar;
applyFogOfWar();
}
void LocalMapBase::applyFogOfWar()
{
for (int mx=0; mx<3; ++mx)
{
for (int my=0; my<3; ++my)
{
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
+ boost::lexical_cast<std::string>(my);
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1)));
MyGUI::ImageBox* fog;
mLayout->getWidget(fog, name+"_fog");
fog->setImageTexture(mFogOfWar ?
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
: "black.png" )
: "");
}
}
}
void LocalMapBase::setActiveCell(const int x, const int y, bool interior) void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
{ {
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
@ -312,23 +339,17 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
MyGUI::ImageBox* box; MyGUI::ImageBox* box;
mLayout->getWidget(box, name); mLayout->getWidget(box, name);
MyGUI::ImageBox* fog;
mLayout->getWidget(fog, name+"_fog");
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
box->setImageTexture(image); box->setImageTexture(image);
else else
box->setImageTexture("black.png"); box->setImageTexture("black.png");
if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0)
fog->setImageTexture(image+"_fog");
else
fog->setImageTexture("black.png");
} }
} }
mInterior = interior; mInterior = interior;
mCurX = x; mCurX = x;
mCurY = y; mCurY = y;
mChanged = false; mChanged = false;
applyFogOfWar();
} }

@ -40,12 +40,17 @@ namespace MWGui
void setCellPrefix(const std::string& prefix); void setCellPrefix(const std::string& prefix);
void setActiveCell(const int x, const int y, bool interior=false); void setActiveCell(const int x, const int y, bool interior=false);
void toggleFogOfWar();
protected: protected:
int mCurX, mCurY; int mCurX, mCurY;
bool mInterior; bool mInterior;
MyGUI::ScrollView* mLocalMap; MyGUI::ScrollView* mLocalMap;
std::string mPrefix; std::string mPrefix;
bool mChanged; bool mChanged;
bool mFogOfWar;
void applyFogOfWar();
OEngine::GUI::Layout* mLayout; OEngine::GUI::Layout* mLayout;
}; };

@ -455,3 +455,9 @@ void WindowManager::setPlayerDir(const float x, const float y)
map->setPlayerDir(x,y); map->setPlayerDir(x,y);
hud->setPlayerDir(x,y); hud->setPlayerDir(x,y);
} }
void WindowManager::toggleFogOfWar()
{
map->toggleFogOfWar();
hud->toggleFogOfWar();
}

@ -157,6 +157,8 @@ namespace MWGui
void setPlayerPos(const float x, const float y); ///< set player position in map space void setPlayerPos(const float x, const float y); ///< set player position in map space
void setPlayerDir(const float x, const float y); ///< set player view direction in map space void setPlayerDir(const float x, const float y); ///< set player view direction in map space
void toggleFogOfWar();
void setInteriorMapTexture(const int x, const int y); void setInteriorMapTexture(const int x, const int y);
///< set the index of the map texture that should be used (for interiors) ///< set the index of the map texture that should be used (for interiors)

@ -2,6 +2,7 @@
#include "renderingmanager.hpp" #include "renderingmanager.hpp"
#include "../mwworld/environment.hpp" #include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwgui/window_manager.hpp" #include "../mwgui/window_manager.hpp"
#include <OgreOverlayManager.h> #include <OgreOverlayManager.h>
@ -10,16 +11,24 @@
using namespace MWRender; using namespace MWRender;
using namespace Ogre; using namespace Ogre;
LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env) LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering, MWWorld::Environment* env) :
mInterior(false), mCellX(0), mCellY(0)
{ {
mRendering = rend; mRendering = rend;
mRenderingManager = rendering;
mEnvironment = env; mEnvironment = env;
mCameraPosNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
mCameraRotNode = mCameraPosNode->createChildSceneNode();
mCameraNode = mCameraRotNode->createChildSceneNode();
mCellCamera = mRendering->getScene()->createCamera("CellCamera"); mCellCamera = mRendering->getScene()->createCamera("CellCamera");
mCellCamera->setProjectionType(PT_ORTHOGRAPHIC); mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
// look down -y // look down -y
const float sqrt0pt5 = 0.707106781; const float sqrt0pt5 = 0.707106781;
mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0)); mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0));
mCameraNode->attachObject(mCellCamera);
} }
LocalMap::~LocalMap() LocalMap::~LocalMap()
@ -27,6 +36,12 @@ LocalMap::~LocalMap()
deleteBuffers(); deleteBuffers();
} }
const Ogre::Vector2 LocalMap::rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle)
{
return Vector2( Math::Cos(angle) * (p.x - c.x) - Math::Sin(angle) * (p.y - c.y) + c.x,
Math::Sin(angle) * (p.x - c.x) + Math::Cos(angle) * (p.y - c.y) + c.y);
}
void LocalMap::deleteBuffers() void LocalMap::deleteBuffers()
{ {
mBuffers.clear(); mBuffers.clear();
@ -65,9 +80,6 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell)
{ {
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
/// \todo why is this workaround needed?
min *= 1.3;
max *= 1.3;
Vector2 length = max-min; Vector2 length = max-min;
// divide into segments // divide into segments
@ -90,11 +102,15 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
{ {
mInterior = false; mInterior = false;
mCameraRotNode->setOrientation(Quaternion::IDENTITY);
std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY); std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY);
int x = cell->cell->data.gridX; int x = cell->cell->data.gridX;
int y = cell->cell->data.gridY; int y = cell->cell->data.gridY;
mCameraPosNode->setPosition(Vector3(0,0,0));
render((x+0.5)*sSize, (-y-0.5)*sSize, -10000, 10000, sSize, sSize, name); render((x+0.5)*sSize, (-y-0.5)*sSize, -10000, 10000, sSize, sSize, name);
} }
@ -104,16 +120,40 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
mInterior = true; mInterior = true;
mBounds = bounds; mBounds = bounds;
Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y); Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y);
Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z);
Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z); const Vector2& north = mEnvironment->mWorld->getNorthVector(cell);
Radian angle(std::atan2(-north.x, -north.y));
mAngle = angle.valueRadians();
mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0));
// rotate the cell and merge the rotated corners to the bounding box
Vector2 _center(bounds.getCenter().x, bounds.getCenter().z);
Vector3 _c1 = bounds.getCorner(AxisAlignedBox::NEAR_LEFT_BOTTOM);
Vector3 _c2 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM);
Vector3 _c3 = bounds.getCorner(AxisAlignedBox::NEAR_RIGHT_BOTTOM);
Vector3 _c4 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM);
Vector2 c1(_c1.x, _c1.z);
Vector2 c2(_c2.x, _c2.z);
Vector2 c3(_c3.x, _c3.z);
Vector2 c4(_c4.x, _c4.z);
c1 = rotatePoint(c1, _center, mAngle);
c2 = rotatePoint(c2, _center, mAngle);
c3 = rotatePoint(c3, _center, mAngle);
c4 = rotatePoint(c4, _center, mAngle);
mBounds.merge(Vector3(c1.x, 0, c1.y));
mBounds.merge(Vector3(c2.x, 0, c2.y));
mBounds.merge(Vector3(c3.x, 0, c3.y));
mBounds.merge(Vector3(c4.x, 0, c4.y));
Vector2 center(mBounds.getCenter().x, mBounds.getCenter().z);
/// \todo why is this workaround needed? Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
min *= 1.3; Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
max *= 1.3;
Vector2 length = max-min; Vector2 length = max-min;
Vector2 center(bounds.getCenter().x, bounds.getCenter().z);
mCameraPosNode->setPosition(Vector3(center.x, 0, center.y));
// divide into segments // divide into segments
const int segsX = std::ceil( length.x / sSize ); const int segsX = std::ceil( length.x / sSize );
@ -128,7 +168,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
Vector2 start = min + Vector2(sSize*x,sSize*y); Vector2 start = min + Vector2(sSize*x,sSize*y);
Vector2 newcenter = start + 4096; Vector2 newcenter = start + 4096;
render(newcenter.x, newcenter.y, z.y, z.x, sSize, sSize, render(newcenter.x - center.x, newcenter.y - center.y, z.y, z.x, sSize, sSize,
cell->cell->name + "_" + coordStr(x,y)); cell->cell->name + "_" + coordStr(x,y));
} }
} }
@ -147,8 +187,9 @@ void LocalMap::render(const float x, const float y,
// make everything visible // make everything visible
mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); mRendering->getScene()->setAmbientLight(ColourValue(1,1,1));
mRenderingManager->disableLights();
mCellCamera->setPosition(Vector3(x, zhigh+100000, y)); mCameraNode->setPosition(Vector3(x, zhigh+100000, y));
//mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
mCellCamera->setFarClipDistance(0); // infinite mCellCamera->setFarClipDistance(0); // infinite
@ -216,12 +257,13 @@ void LocalMap::render(const float x, const float y,
} }
} }
mRenderingManager->enableLights();
// re-enable fog // re-enable fog
mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd);
} }
void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction) void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation)
{ {
if (sFogOfWarSkip != 0) if (sFogOfWarSkip != 0)
{ {
@ -232,7 +274,19 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
// retrieve the x,y grid coordinates the player is in // retrieve the x,y grid coordinates the player is in
int x,y; int x,y;
Vector2 pos(position.x, position.z); Vector3 _pos(position.x, 0, position.z);
Vector2 pos(_pos.x, _pos.z);
if (mInterior)
{
pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle);
}
Vector3 playerdirection = -mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis();
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
if (!mInterior) if (!mInterior)
{ {
x = std::ceil(pos.x / sSize)-1; x = std::ceil(pos.x / sSize)-1;
@ -242,9 +296,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
} }
else else
{ {
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
min *= 1.3;
x = std::ceil((pos.x - min.x)/sSize)-1; x = std::ceil((pos.x - min.x)/sSize)-1;
y = std::ceil((pos.y - min.y)/sSize)-1; y = std::ceil((pos.y - min.y)/sSize)-1;
@ -259,20 +310,17 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
u = std::abs((pos.x - (sSize*x))/sSize); u = std::abs((pos.x - (sSize*x))/sSize);
v = 1-std::abs((pos.y + (sSize*y))/sSize); v = 1-std::abs((pos.y + (sSize*y))/sSize);
texName = "Cell_"+coordStr(x,y); texName = "Cell_"+coordStr(x,y);
} }
else else
{ {
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
min *= 1.3;
u = (pos.x - min.x - sSize*x)/sSize; u = (pos.x - min.x - sSize*x)/sSize;
v = (pos.y - min.y - sSize*y)/sSize; v = (pos.y - min.y - sSize*y)/sSize;
texName = mInteriorName + "_" + coordStr(x,y); texName = mInteriorName + "_" + coordStr(x,y);
} }
mEnvironment->mWindowManager->setPlayerPos(u, v); mEnvironment->mWindowManager->setPlayerPos(u, v);
mEnvironment->mWindowManager->setPlayerDir(direction.x, -direction.z); mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z);
// explore radius (squared) // explore radius (squared)
const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution;

@ -12,13 +12,15 @@ namespace MWWorld
namespace MWRender namespace MWRender
{ {
class RenderingManager;
/// ///
/// \brief Local map rendering /// \brief Local map rendering
/// ///
class LocalMap class LocalMap
{ {
public: public:
LocalMap(OEngine::Render::OgreRenderer*, MWWorld::Environment* env); LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering, MWWorld::Environment* env);
~LocalMap(); ~LocalMap();
/** /**
@ -44,9 +46,9 @@ namespace MWRender
* @remarks This is used to draw a "fog of war" effect * @remarks This is used to draw a "fog of war" effect
* to hide areas on the map the player has not discovered yet. * to hide areas on the map the player has not discovered yet.
* @param position (OGRE coordinates) * @param position (OGRE coordinates)
* @param view direction (OGRE coordinates) * @param camera orientation (OGRE coordinates)
*/ */
void updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction); void updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation);
/** /**
* Save the fog of war for the current cell to disk. * Save the fog of war for the current cell to disk.
@ -58,6 +60,7 @@ namespace MWRender
private: private:
OEngine::Render::OgreRenderer* mRendering; OEngine::Render::OgreRenderer* mRendering;
MWRender::RenderingManager* mRenderingManager;
MWWorld::Environment* mEnvironment; MWWorld::Environment* mEnvironment;
// 1024*1024 pixels for a cell // 1024*1024 pixels for a cell
@ -73,6 +76,12 @@ namespace MWRender
static const int sSize = 8192; static const int sSize = 8192;
Ogre::Camera* mCellCamera; Ogre::Camera* mCellCamera;
Ogre::SceneNode* mCameraNode;
Ogre::SceneNode* mCameraPosNode;
Ogre::SceneNode* mCameraRotNode;
float mAngle;
const Ogre::Vector2 rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle);
void render(const float x, const float y, void render(const float x, const float y,
const float zlow, const float zhigh, const float zlow, const float zhigh,

@ -3,6 +3,7 @@
#include <OgreSceneNode.h> #include <OgreSceneNode.h>
#include <components/nifogre/ogre_nif_loader.hpp> #include <components/nifogre/ogre_nif_loader.hpp>
#include <components/settings/settings.hpp>
using namespace MWRender; using namespace MWRender;
@ -88,18 +89,16 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
NifOgre::NIFLoader::load(mesh); NifOgre::NIFLoader::load(mesh);
Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh); Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh);
/*
Ogre::Vector3 extents = ent->getBoundingBox().getSize(); Ogre::Vector3 extents = ent->getBoundingBox().getSize();
extents *= insert->getScale(); extents *= insert->getScale();
// float size = std::max(std::max(extents.x, extents.y), extents.z); float size = std::max(std::max(extents.x, extents.y), extents.z);
bool small = (size < 250); /// \todo config value bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Objects");
// do not fade out doors. that will cause holes and look stupid // do not fade out doors. that will cause holes and look stupid
if (ptr.getTypeName().find("Door") != std::string::npos) if (ptr.getTypeName().find("Door") != std::string::npos)
small = false; small = false;
*/
const bool small = false;
if (mBounds.find(ptr.getCell()) == mBounds.end()) if (mBounds.find(ptr.getCell()) == mBounds.end())
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
@ -113,11 +112,11 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
bounds.scale(insert->getScale()); bounds.scale(insert->getScale());
mBounds[ptr.getCell()].merge(bounds); mBounds[ptr.getCell()].merge(bounds);
if(!mIsStatic) if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects"))
{ {
insert->attachObject(ent); insert->attachObject(ent);
ent->setRenderingDistance(small ? 2500 : 0); /// \todo config value ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); /// \todo config value
} }
else else
{ {
@ -131,7 +130,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
mStaticGeometrySmall[ptr.getCell()] = sg; mStaticGeometrySmall[ptr.getCell()] = sg;
sg->setRenderingDistance(2500); /// \todo config value sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); /// \todo config value
} }
else else
sg = mStaticGeometrySmall[ptr.getCell()]; sg = mStaticGeometrySmall[ptr.getCell()];
@ -169,6 +168,7 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f
assert(insert); assert(insert);
Ogre::Light *light = mRenderer.getScene()->createLight(); Ogre::Light *light = mRenderer.getScene()->createLight();
light->setDiffuseColour (r, g, b); light->setDiffuseColour (r, g, b);
mLights.push_back(light->getName());
float cval=0.0f, lval=0.0f, qval=0.0f; float cval=0.0f, lval=0.0f, qval=0.0f;
@ -274,3 +274,34 @@ Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell)
{ {
return mBounds[cell]; return mBounds[cell];
} }
void Objects::enableLights()
{
std::vector<std::string>::iterator it = mLights.begin();
while (it != mLights.end())
{
if (mMwRoot->getCreator()->hasLight(*it))
{
mMwRoot->getCreator()->getLight(*it)->setVisible(true);
++it;
}
else
it = mLights.erase(it);
}
}
void Objects::disableLights()
{
std::vector<std::string>::iterator it = mLights.begin();
while (it != mLights.end())
{
if (mMwRoot->getCreator()->hasLight(*it))
{
mMwRoot->getCreator()->getLight(*it)->setVisible(false);
++it;
}
else
it = mLights.erase(it);
}
}

@ -16,6 +16,7 @@ class Objects{
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry; std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry;
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall; std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall;
std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds; std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds;
std::vector<std::string> mLights;
Ogre::SceneNode* mMwRoot; Ogre::SceneNode* mMwRoot;
bool mIsStatic; bool mIsStatic;
static int uniqueID; static int uniqueID;
@ -44,6 +45,9 @@ public:
void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);
void insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius); void insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius);
void enableLights();
void disableLights();
Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*); Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*);
///< get a bounding box that encloses all objects in the specified cell ///< get a bounding box that encloses all objects in the specified cell

@ -12,6 +12,7 @@
#include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include <components/esm/loadstat.hpp> #include <components/esm/loadstat.hpp>
#include <components/settings/settings.hpp>
using namespace MWRender; using namespace MWRender;
@ -64,7 +65,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mSun = 0; mSun = 0;
mDebugging = new Debugging(mMwRoot, environment, engine); mDebugging = new Debugging(mMwRoot, environment, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, &environment); mLocalMap = new MWRender::LocalMap(&mRendering, this, &environment);
} }
RenderingManager::~RenderingManager () RenderingManager::~RenderingManager ()
@ -177,7 +178,7 @@ void RenderingManager::update (float duration){
mRendering.update(duration); mRendering.update(duration);
mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealDirection() ); mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() );
checkUnderwater(); checkUnderwater();
} }
@ -273,18 +274,14 @@ void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
{ {
/// \todo make the viewing distance and fog start/end configurable float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
// right now we load 3x3 cells, so the maximum viewing distance we float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
// can allow (to prevent objects suddenly popping up) equals: float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
// 8192 * 0.69
// ^ cell size ^ minimum density value used (clear weather)
float low = 5652.48 / density / 2.f;
float high = 5652.48 / density;
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high); mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
mRendering.getCamera()->setFarClipDistance ( high ); mRendering.getCamera()->setFarClipDistance ( max / density );
mRendering.getViewport()->setBackgroundColour (colour); mRendering.getViewport()->setBackgroundColour (colour);
} }
@ -411,4 +408,14 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell)
mLocalMap->saveFogOfWar(cell); mLocalMap->saveFogOfWar(cell);
} }
void RenderingManager::disableLights()
{
mObjects.disableLights();
}
void RenderingManager::enableLights()
{
mObjects.enableLights();
}
} // namespace } // namespace

@ -109,6 +109,9 @@ class RenderingManager: private RenderingInterface {
void sunEnable(); void sunEnable();
void sunDisable(); void sunDisable();
void disableLights();
void enableLights();
bool occlusionQuerySupported() { return mOcclusionQuery->supported(); }; bool occlusionQuerySupported() { return mOcclusionQuery->supported(); };
OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; }; OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; };

@ -746,6 +746,7 @@ void SkyManager::setGlare(const float glare)
Vector3 SkyManager::getRealSunPos() Vector3 SkyManager::getRealSunPos()
{ {
if (!mCreated) return Vector3(0,0,0);
return mSun->getNode()->_getDerivedPosition(); return mSun->getNode()->_getDerivedPosition();
} }

@ -36,7 +36,7 @@ THE SOFTWARE.
#include "OgreHardwarePixelBuffer.h" #include "OgreHardwarePixelBuffer.h"
#include "OgreShadowCameraSetupPSSM.h" #include "OgreShadowCameraSetupPSSM.h"
#define POINTLIGHTS #include <components/settings/settings.hpp>
namespace Ogre namespace Ogre
{ {
@ -222,19 +222,7 @@ namespace Ogre
} }
int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const
{ {
#ifndef POINTLIGHTS return Settings::Manager::getInt("num lights", "Terrain");
return 1;
#else
// number of supported lights depends on the number of available constant registers,
// which in turn depends on the shader profile used
if (GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0")
|| GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0")
|| GpuProgramManager::getSingleton().isSyntaxSupported("fp40")
)
return 32;
else
return 8;
#endif
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
MaterialPtr TerrainMaterialGeneratorB::SM2Profile::generate(const Terrain* terrain) MaterialPtr TerrainMaterialGeneratorB::SM2Profile::generate(const Terrain* terrain)
@ -565,6 +553,7 @@ namespace Ogre
{ {
params->setNamedAutoConstant("lightPosObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i); params->setNamedAutoConstant("lightPosObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
params->setNamedAutoConstant("lightDiffuseColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i); params->setNamedAutoConstant("lightDiffuseColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
if (prof->getNumberOfLightsSupported() > 1)
params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
//params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i); //params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i);
} }
@ -980,10 +969,9 @@ namespace Ogre
//"uniform float3 lightSpecularColour"<<i<<",\n" //"uniform float3 lightSpecularColour"<<i<<",\n"
; ;
#ifdef POINTLIGHTS if (prof->getNumberOfLightsSupported() > 1)
outStream << outStream <<
"uniform float4 lightAttenuation"<<i<<",\n"; "uniform float4 lightAttenuation"<<i<<",\n";
#endif
} }
@ -1130,10 +1118,9 @@ namespace Ogre
} }
else else
{ {
#ifdef POINTLIGHTS if (prof->getNumberOfLightsSupported() > 1)
outStream << "float d; \n" outStream << "float d; \n"
"float attn; \n"; "float attn; \n";
#endif
outStream << outStream <<
" eyeDir = normalize(eyeDir); \n"; " eyeDir = normalize(eyeDir); \n";
@ -1144,13 +1131,12 @@ namespace Ogre
outStream << " float3 halfAngle"<<i<<" = normalize(lightDir"<<i<<" + eyeDir);\n" outStream << " float3 halfAngle"<<i<<" = normalize(lightDir"<<i<<" + eyeDir);\n"
" float4 litRes"<<i<<" = lit(dot(normalize(lightDir"<<i<<"), normal), dot(halfAngle"<<i<<", normal), scaleBiasSpecular.z);\n"; " float4 litRes"<<i<<" = lit(dot(normalize(lightDir"<<i<<"), normal), dot(halfAngle"<<i<<", normal), scaleBiasSpecular.z);\n";
#ifdef POINTLIGHTS if (prof->getNumberOfLightsSupported() > 1)
outStream << outStream <<
// pre-multiply light color with attenuation factor // pre-multiply light color with attenuation factor
"d = length( lightDir"<<i<<" ); \n" "d = length( lightDir"<<i<<" ); \n"
"attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n" "attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
"lightDiffuseColour"<<i<<" *= attn; \n"; "lightDiffuseColour"<<i<<" *= attn; \n";
#endif
} }
} }
} }

@ -127,5 +127,6 @@ op 0x2000141: GetWaterLevel
op 0x2000142: SetWaterLevel op 0x2000142: SetWaterLevel
op 0x2000143: ModWaterLevel op 0x2000143: ModWaterLevel
op 0x2000144: ToggleWater, twa op 0x2000144: ToggleWater, twa
op 0x2000145: TogglePathgrid op 0x2000145: ToggleFogOfWar (tfow)
opcodes 0x2000146-0x3ffffff unused op 0x2000146: TogglePathgrid
opcodes 0x2000147-0x3ffffff unused

@ -67,6 +67,19 @@ namespace MWScript
} }
}; };
class OpToggleFogOfWar : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
context.getEnvironment().mWindowManager->toggleFogOfWar();
}
};
const int opcodeEnableBirthMenu = 0x200000e; const int opcodeEnableBirthMenu = 0x200000e;
const int opcodeEnableClassMenu = 0x200000f; const int opcodeEnableClassMenu = 0x200000f;
const int opcodeEnableNameMenu = 0x2000010; const int opcodeEnableNameMenu = 0x2000010;
@ -79,6 +92,7 @@ namespace MWScript
const int opcodeEnableRest = 0x2000017; const int opcodeEnableRest = 0x2000017;
const int opcodeShowRestMenu = 0x2000018; const int opcodeShowRestMenu = 0x2000018;
const int opcodeGetButtonPressed = 0x2000137; const int opcodeGetButtonPressed = 0x2000137;
const int opcodeToggleFogOfWar = 0x2000145;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -100,6 +114,9 @@ namespace MWScript
extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu); extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu);
extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed); extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed);
extensions.registerInstruction ("togglefogofwar", "", opcodeToggleFogOfWar);
extensions.registerInstruction ("tfow", "", opcodeToggleFogOfWar);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -135,6 +152,8 @@ namespace MWScript
new OpShowDialogue (MWGui::GM_Rest)); new OpShowDialogue (MWGui::GM_Rest));
interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed); interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed);
interpreter.installSegment5 (opcodeToggleFogOfWar, new OpToggleFogOfWar);
} }
} }
} }

@ -217,7 +217,7 @@ namespace MWScript
const int opcodeFadeOut = 0x200013d; const int opcodeFadeOut = 0x200013d;
const int opcodeFadeTo = 0x200013e; const int opcodeFadeTo = 0x200013e;
const int opcodeToggleWater = 0x2000144; const int opcodeToggleWater = 0x2000144;
const int opcodeTogglePathgrid = 0x2000145; const int opcodeTogglePathgrid = 0x2000146;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {

@ -886,6 +886,18 @@ namespace MWWorld
return mRendering->getFader(); return mRendering->getFader();
} }
Ogre::Vector2 World::getNorthVector(Ptr::CellStore* cell)
{
ESMS::CellRefList<ESM::Static, MWWorld::RefData> statics = cell->statics;
ESMS::LiveCellRef<ESM::Static, MWWorld::RefData>* ref = statics.find("northmarker");
if (!ref)
return Vector2(0, 1);
Ogre::SceneNode* node = ref->mData.getBaseNode();
Vector3 dir = node->_getDerivedOrientation().yAxis();
Vector2 d = Vector2(dir.x, dir.z);
return d;
}
void World::setWaterHeight(const float height) void World::setWaterHeight(const float height)
{ {
mRendering->setWaterHeight(height); mRendering->setWaterHeight(height);

@ -146,6 +146,9 @@ namespace MWWorld
bool isCellExterior() const; bool isCellExterior() const;
bool isCellQuasiExterior() const; bool isCellQuasiExterior() const;
Ogre::Vector2 getNorthVector(Ptr::CellStore* cell);
///< get north vector (OGRE coordinates) for given interior cell
Globals::Data& getGlobalVariable (const std::string& name); Globals::Data& getGlobalVariable (const std::string& name);
Globals::Data getGlobalVariable (const std::string& name) const; Globals::Data getGlobalVariable (const std::string& name) const;

@ -2,6 +2,10 @@ project (Components)
# source files # source files
add_component_dir (settings
settings
)
add_component_dir (bsa add_component_dir (bsa
bsa_archive bsa_file bsa_archive bsa_file
) )

@ -25,6 +25,7 @@
#include "ogre_nif_loader.hpp" #include "ogre_nif_loader.hpp"
#include <components/settings/settings.hpp>
typedef unsigned char ubyte; typedef unsigned char ubyte;
@ -299,6 +300,8 @@ void NIFLoader::createMaterial(const String &name,
material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]); material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]);
material->setShininess(glossiness); material->setShininess(glossiness);
if (Settings::Manager::getBool("shaders", "Objects"))
{
// Create shader for the material // Create shader for the material
// vertex // vertex
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
@ -349,12 +352,7 @@ void NIFLoader::createMaterial(const String &name,
// not work perfectly for objects batched together (they will all use the same // not work perfectly for objects batched together (they will all use the same
// lights). to work around this, we are simply pushing the maximum number // lights). to work around this, we are simply pushing the maximum number
// of lights here in order to minimize disappearing lights. // of lights here in order to minimize disappearing lights.
float num_lights; int num_lights = Settings::Manager::getInt("num lights", "Objects");
if (GpuProgramManager::getSingleton().isSyntaxSupported("fp40") ||
GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0"))
num_lights = 8 /* 32 */;
else
num_lights = 8;
// fragment // fragment
HighLevelGpuProgramPtr fragment; HighLevelGpuProgramPtr fragment;
@ -432,6 +430,7 @@ void NIFLoader::createMaterial(const String &name,
fragment = mgr.getByName("main_fp"); fragment = mgr.getByName("main_fp");
material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName()); material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName());
} }
}
// Takes a name and adds a unique part to it. This is just used to // Takes a name and adds a unique part to it. This is just used to
// make sure that all materials are given unique names. // make sure that all materials are given unique names.

@ -0,0 +1,158 @@
#include "settings.hpp"
#include <fstream>
#include <OgreResourceGroupManager.h>
#include <OgreStringConverter.h>
using namespace Settings;
Ogre::ConfigFile Manager::mFile = Ogre::ConfigFile();
Ogre::ConfigFile Manager::mDefaultFile = Ogre::ConfigFile();
CategorySettingVector Manager::mChangedSettings = CategorySettingVector();
CategorySettingValueMap Manager::mNewSettings = CategorySettingValueMap();
void Manager::loadUser (const std::string& file)
{
mFile.load(file);
}
void Manager::loadDefault (const std::string& file)
{
mDefaultFile.load(file);
}
void Manager::saveUser(const std::string& file)
{
std::fstream fout(file.c_str(), std::ios::out);
Ogre::ConfigFile::SectionIterator seci = mFile.getSectionIterator();
while (seci.hasMoreElements())
{
Ogre::String sectionName = seci.peekNextKey();
if (sectionName.length() > 0)
fout << '\n' << '[' << seci.peekNextKey() << ']' << '\n';
Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
fout << i->first.c_str() << " = " << i->second.c_str() << '\n';
}
CategorySettingValueMap::iterator it = mNewSettings.begin();
while (it != mNewSettings.end())
{
if (it->first.first == sectionName)
{
fout << it->first.second << " = " << it->second << '\n';
mNewSettings.erase(it++);
}
else
++it;
}
}
std::string category = "";
for (CategorySettingValueMap::iterator it = mNewSettings.begin();
it != mNewSettings.end(); ++it)
{
if (category != it->first.first)
{
category = it->first.first;
fout << '\n' << '[' << category << ']' << '\n';
}
fout << it->first.second << " = " << it->second << '\n';
}
}
const std::string Manager::getString (const std::string& setting, const std::string& category)
{
if (mNewSettings.find(std::make_pair(category, setting)) != mNewSettings.end())
return mNewSettings[std::make_pair(category, setting)];
std::string defaultval = mDefaultFile.getSetting(setting, category);
return mFile.getSetting(setting, category, defaultval);
}
const float Manager::getFloat (const std::string& setting, const std::string& category)
{
return Ogre::StringConverter::parseReal( getString(setting, category) );
}
const int Manager::getInt (const std::string& setting, const std::string& category)
{
return Ogre::StringConverter::parseInt( getString(setting, category) );
}
const bool Manager::getBool (const std::string& setting, const std::string& category)
{
return Ogre::StringConverter::parseBool( getString(setting, category) );
}
void Manager::setString (const std::string& setting, const std::string& category, const std::string& value)
{
CategorySetting s = std::make_pair(category, setting);
bool found=false;
try
{
Ogre::ConfigFile::SettingsIterator it = mFile.getSettingsIterator(category);
while (it.hasMoreElements())
{
Ogre::ConfigFile::SettingsMultiMap::iterator i = it.current();
if ((*i).first == setting)
{
if ((*i).second != value)
{
mChangedSettings.push_back(std::make_pair(category, setting));
(*i).second = value;
}
found = true;
}
it.getNext();
}
}
catch (Ogre::Exception&)
{}
if (!found)
{
if (mNewSettings.find(s) != mNewSettings.end())
{
if (mNewSettings[s] != value)
{
mChangedSettings.push_back(std::make_pair(category, setting));
mNewSettings[s] = value;
}
}
else
mNewSettings[s] = value;
}
}
void Manager::setInt (const std::string& setting, const std::string& category, const int value)
{
setString(setting, category, Ogre::StringConverter::toString(value));
}
void Manager::setFloat (const std::string& setting, const std::string& category, const float value)
{
setString(setting, category, Ogre::StringConverter::toString(value));
}
void Manager::setBool (const std::string& setting, const std::string& category, const bool value)
{
setString(setting, category, Ogre::StringConverter::toString(value));
}
const CategorySettingVector Manager::apply()
{
CategorySettingVector vec = mChangedSettings;
mChangedSettings.clear();
return vec;
}

@ -0,0 +1,52 @@
#ifndef _COMPONENTS_SETTINGS_H
#define _COMPONENTS_SETTINGS_H
#include <OgreConfigFile.h>
namespace Settings
{
typedef std::pair < std::string, std::string > CategorySetting;
typedef std::vector< std::pair<std::string, std::string> > CategorySettingVector;
typedef std::map < CategorySetting, std::string > CategorySettingValueMap;
///
/// \brief Settings management (can change during runtime)
///
class Manager
{
public:
static Ogre::ConfigFile mFile;
static Ogre::ConfigFile mDefaultFile;
static CategorySettingVector mChangedSettings;
///< tracks all the settings that were changed since the last apply() call
static CategorySettingValueMap mNewSettings;
///< tracks all the settings that are in the default file, but not in user file yet
void loadDefault (const std::string& file);
///< load file as the default settings (can be overridden by user settings)
void loadUser (const std::string& file);
///< load file as user settings
void saveUser (const std::string& file);
///< save user settings to file
static const CategorySettingVector apply();
///< returns the list of changed settings and then clears it
static const int getInt (const std::string& setting, const std::string& category);
static const float getFloat (const std::string& setting, const std::string& category);
static const std::string getString (const std::string& setting, const std::string& category);
static const bool getBool (const std::string& setting, const std::string& category);
static void setInt (const std::string& setting, const std::string& category, const int value);
static void setFloat (const std::string& setting, const std::string& category, const float value);
static void setString (const std::string& setting, const std::string& category, const std::string& value);
static void setBool (const std::string& setting, const std::string& category, const bool value);
};
}
#endif // _COMPONENTS_SETTINGS_H

@ -0,0 +1,43 @@
[HUD]
# FPS counter
# 0: not visible
# 1: basic FPS display
# 2: advanced FPS display (batches, triangles)
fps = 0
[Objects]
shaders = true
# Max. number of lights that affect objects. Setting to 1 will only reflect sunlight
# Note: has no effect when shaders are turned off
num lights = 8
# Use static geometry for static objects. Improves rendering speed.
use static geometry = true
[Viewing distance]
# Limit the rendering distance of small objects
limit small object distance = false
# Size below which an object is considered as small
small object size = 250
# Rendering distance for small objects
small object distance = 3500
# Max viewing distance at clear weather conditions
max viewing distance = 5600
# Distance at which fog starts (proportional to viewing distance)
fog start factor = 0.5
# Distance at which fog ends (proportional to viewing distance)
fog end factor = 1.0
[Terrain]
# Max. number of lights that affect the terrain. Setting to 1 will only reflect sunlight
num lights = 8
Loading…
Cancel
Save