mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 00:26:39 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/zinnschlag/openmw into initocfg
Conflicts: apps/openmw/main.cpp
This commit is contained in:
		
						commit
						57ae1bdc43
					
				
					 26 changed files with 662 additions and 212 deletions
				
			
		| 
						 | 
				
			
			@ -223,6 +223,9 @@ endif (APPLE)
 | 
			
		|||
 | 
			
		||||
# 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
 | 
			
		||||
    "${OpenMW_BINARY_DIR}/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 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}/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/files/fixedpath.hpp>
 | 
			
		||||
#include <components/files/configurationmanager.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include <components/nifbullet/bullet_nif_loader.hpp>
 | 
			
		||||
#include <components/nifogre/ogre_nif_loader.hpp>
 | 
			
		||||
| 
						 | 
				
			
			@ -321,6 +322,29 @@ void OMW::Engine::go()
 | 
			
		|||
    {
 | 
			
		||||
        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()),
 | 
			
		||||
        mCfgMgr.getOgreConfigPath().string(),
 | 
			
		||||
        mCfgMgr.getLogPath().string(),
 | 
			
		||||
| 
						 | 
				
			
			@ -415,6 +439,9 @@ void OMW::Engine::go()
 | 
			
		|||
    // Start the main rendering loop
 | 
			
		||||
    mOgre->start();
 | 
			
		||||
 | 
			
		||||
    // Save user settings
 | 
			
		||||
    settings.saveUser(settingspath);
 | 
			
		||||
 | 
			
		||||
    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(), "")
 | 
			
		||||
            ->multitoken(), "plugin file(s)")
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        ("fps", bpo::value<int>()->implicit_value(1)
 | 
			
		||||
            ->default_value(0), "fps counter detail (0 = off, 1 = fps counter, 2 = full detail)")
 | 
			
		||||
 | 
			
		||||
        ("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")
 | 
			
		||||
 | 
			
		||||
        ("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>());
 | 
			
		||||
 | 
			
		||||
    // other settings
 | 
			
		||||
    engine.showFPS(variables["fps"].as<int>());
 | 
			
		||||
    engine.setDebugMode(variables["debug"].as<bool>());
 | 
			
		||||
    engine.setSoundUsage(!variables["nosound"].as<bool>());
 | 
			
		||||
    engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -528,6 +528,13 @@ namespace MWDialogue
 | 
			
		|||
        mChoice = -1;
 | 
			
		||||
        mIsInChoice = false;
 | 
			
		||||
        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)
 | 
			
		||||
| 
						 | 
				
			
			@ -563,13 +570,7 @@ namespace MWDialogue
 | 
			
		|||
 | 
			
		||||
        mActor = actor;
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //initialise the GUI
 | 
			
		||||
        mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue);
 | 
			
		||||
| 
						 | 
				
			
			@ -582,6 +583,7 @@ namespace MWDialogue
 | 
			
		|||
        //greeting
 | 
			
		||||
        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;
 | 
			
		||||
        for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
 | 
			
		||||
        {
 | 
			
		||||
            ESM::Dialogue ndialogue = it->second;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -278,6 +278,7 @@ LocalMapBase::LocalMapBase()
 | 
			
		|||
    : mCurX(0)
 | 
			
		||||
    , mCurY(0)
 | 
			
		||||
    , mInterior(false)
 | 
			
		||||
    , mFogOfWar(true)
 | 
			
		||||
    , mLocalMap(NULL)
 | 
			
		||||
    , mPrefix()
 | 
			
		||||
    , mChanged(true)
 | 
			
		||||
| 
						 | 
				
			
			@ -297,6 +298,32 @@ void LocalMapBase::setCellPrefix(const std::string& prefix)
 | 
			
		|||
    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)
 | 
			
		||||
{
 | 
			
		||||
    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;
 | 
			
		||||
            mLayout->getWidget(box, name);
 | 
			
		||||
            MyGUI::ImageBox* fog;
 | 
			
		||||
            mLayout->getWidget(fog, name+"_fog");
 | 
			
		||||
 | 
			
		||||
            if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
 | 
			
		||||
                box->setImageTexture(image);
 | 
			
		||||
            else
 | 
			
		||||
                box->setImageTexture("black.png");
 | 
			
		||||
 | 
			
		||||
            if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0)
 | 
			
		||||
                fog->setImageTexture(image+"_fog");
 | 
			
		||||
            else
 | 
			
		||||
                fog->setImageTexture("black.png");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    mInterior = interior;
 | 
			
		||||
    mCurX = x;
 | 
			
		||||
    mCurY = y;
 | 
			
		||||
    mChanged = false;
 | 
			
		||||
    applyFogOfWar();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,12 +40,17 @@ namespace MWGui
 | 
			
		|||
    void setCellPrefix(const std::string& prefix);
 | 
			
		||||
    void setActiveCell(const int x, const int y, bool interior=false);
 | 
			
		||||
 | 
			
		||||
    void toggleFogOfWar();
 | 
			
		||||
 | 
			
		||||
  protected:
 | 
			
		||||
    int mCurX, mCurY;
 | 
			
		||||
    bool mInterior;
 | 
			
		||||
    MyGUI::ScrollView* mLocalMap;
 | 
			
		||||
    std::string mPrefix;
 | 
			
		||||
    bool mChanged;
 | 
			
		||||
    bool mFogOfWar;
 | 
			
		||||
 | 
			
		||||
    void applyFogOfWar();
 | 
			
		||||
 | 
			
		||||
    OEngine::GUI::Layout* mLayout;
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -455,3 +455,9 @@ void WindowManager::setPlayerDir(const float x, const float y)
 | 
			
		|||
    map->setPlayerDir(x,y);
 | 
			
		||||
    hud->setPlayerDir(x,y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WindowManager::toggleFogOfWar()
 | 
			
		||||
{
 | 
			
		||||
    map->toggleFogOfWar();
 | 
			
		||||
    hud->toggleFogOfWar();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -156,6 +156,8 @@ namespace MWGui
 | 
			
		|||
    void changeCell(MWWorld::Ptr::CellStore* cell); ///< change the active cell
 | 
			
		||||
    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 toggleFogOfWar();
 | 
			
		||||
    
 | 
			
		||||
    void setInteriorMapTexture(const int x, const int y);
 | 
			
		||||
    ///< set the index of the map texture that should be used (for interiors)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
#include "renderingmanager.hpp"
 | 
			
		||||
 | 
			
		||||
#include "../mwworld/environment.hpp"
 | 
			
		||||
#include "../mwworld/world.hpp"
 | 
			
		||||
#include "../mwgui/window_manager.hpp"
 | 
			
		||||
 | 
			
		||||
#include <OgreOverlayManager.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -10,16 +11,24 @@
 | 
			
		|||
using namespace MWRender;
 | 
			
		||||
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;
 | 
			
		||||
    mRenderingManager = rendering;
 | 
			
		||||
    mEnvironment = env;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    mCameraPosNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
 | 
			
		||||
    mCameraRotNode = mCameraPosNode->createChildSceneNode();
 | 
			
		||||
    mCameraNode = mCameraRotNode->createChildSceneNode();
 | 
			
		||||
 | 
			
		||||
    mCellCamera = mRendering->getScene()->createCamera("CellCamera");
 | 
			
		||||
    mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
 | 
			
		||||
    // look down -y
 | 
			
		||||
    const float sqrt0pt5 = 0.707106781;
 | 
			
		||||
    mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0));
 | 
			
		||||
 | 
			
		||||
    mCameraNode->attachObject(mCellCamera);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LocalMap::~LocalMap()
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +36,12 @@ LocalMap::~LocalMap()
 | 
			
		|||
    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()
 | 
			
		||||
{
 | 
			
		||||
    mBuffers.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -65,9 +80,6 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell)
 | 
			
		|||
    {
 | 
			
		||||
        Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().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;
 | 
			
		||||
        
 | 
			
		||||
        // divide into segments
 | 
			
		||||
| 
						 | 
				
			
			@ -90,11 +102,15 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
 | 
			
		|||
{
 | 
			
		||||
    mInterior = false;
 | 
			
		||||
 | 
			
		||||
    mCameraRotNode->setOrientation(Quaternion::IDENTITY);
 | 
			
		||||
 | 
			
		||||
    std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY);
 | 
			
		||||
 | 
			
		||||
    int x = cell->cell->data.gridX;
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -103,17 +119,41 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
 | 
			
		|||
{
 | 
			
		||||
    mInterior = true;
 | 
			
		||||
    mBounds = bounds;
 | 
			
		||||
    
 | 
			
		||||
    Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y);
 | 
			
		||||
    Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z);
 | 
			
		||||
    Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z);
 | 
			
		||||
 | 
			
		||||
    /// \todo why is this workaround needed?
 | 
			
		||||
    min *= 1.3;
 | 
			
		||||
    max *= 1.3;
 | 
			
		||||
    Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y);
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
 | 
			
		||||
    Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
 | 
			
		||||
 | 
			
		||||
    Vector2 length = max-min;
 | 
			
		||||
    Vector2 center(bounds.getCenter().x, bounds.getCenter().z);
 | 
			
		||||
 | 
			
		||||
    mCameraPosNode->setPosition(Vector3(center.x, 0, center.y));
 | 
			
		||||
 | 
			
		||||
    // divide into segments
 | 
			
		||||
    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 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));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -147,8 +187,9 @@ void LocalMap::render(const float x, const float y,
 | 
			
		|||
 | 
			
		||||
    // make everything visible
 | 
			
		||||
    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(0); // infinite
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -215,13 +256,14 @@ void LocalMap::render(const float x, const float y,
 | 
			
		|||
            //rtt->writeContentsToFile("./" + texture + ".jpg");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    mRenderingManager->enableLights();
 | 
			
		||||
 | 
			
		||||
    // re-enable fog
 | 
			
		||||
    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)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -232,7 +274,19 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
 | 
			
		|||
 | 
			
		||||
    // retrieve the x,y grid coordinates the player is in 
 | 
			
		||||
    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)
 | 
			
		||||
    {
 | 
			
		||||
        x = std::ceil(pos.x / sSize)-1;
 | 
			
		||||
| 
						 | 
				
			
			@ -242,9 +296,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
 | 
			
		||||
        min *= 1.3;
 | 
			
		||||
        
 | 
			
		||||
        x = std::ceil((pos.x - min.x)/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);
 | 
			
		||||
        v = 1-std::abs((pos.y + (sSize*y))/sSize);
 | 
			
		||||
        texName = "Cell_"+coordStr(x,y);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
 | 
			
		||||
        min *= 1.3;
 | 
			
		||||
 | 
			
		||||
        u = (pos.x - min.x - sSize*x)/sSize;
 | 
			
		||||
        v = (pos.y - min.y - sSize*y)/sSize;
 | 
			
		||||
 | 
			
		||||
        texName = mInteriorName + "_" + coordStr(x,y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mEnvironment->mWindowManager->setPlayerPos(u, v);
 | 
			
		||||
    mEnvironment->mWindowManager->setPlayerDir(direction.x, -direction.z);
 | 
			
		||||
    mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z);
 | 
			
		||||
 | 
			
		||||
    // explore radius (squared)
 | 
			
		||||
    const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,13 +12,15 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
namespace MWRender
 | 
			
		||||
{
 | 
			
		||||
    class RenderingManager;
 | 
			
		||||
 | 
			
		||||
    ///
 | 
			
		||||
    /// \brief Local map rendering
 | 
			
		||||
    ///
 | 
			
		||||
    class LocalMap
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        LocalMap(OEngine::Render::OgreRenderer*, MWWorld::Environment* env);
 | 
			
		||||
        LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering, MWWorld::Environment* env);
 | 
			
		||||
        ~LocalMap();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
| 
						 | 
				
			
			@ -44,9 +46,9 @@ namespace MWRender
 | 
			
		|||
         * @remarks This is used to draw a "fog of war" effect
 | 
			
		||||
         * to hide areas on the map the player has not discovered yet.
 | 
			
		||||
         * @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.
 | 
			
		||||
| 
						 | 
				
			
			@ -58,6 +60,7 @@ namespace MWRender
 | 
			
		|||
 | 
			
		||||
    private:
 | 
			
		||||
        OEngine::Render::OgreRenderer* mRendering;
 | 
			
		||||
        MWRender::RenderingManager* mRenderingManager;
 | 
			
		||||
        MWWorld::Environment* mEnvironment;
 | 
			
		||||
 | 
			
		||||
        // 1024*1024 pixels for a cell
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +76,12 @@ namespace MWRender
 | 
			
		|||
        static const int sSize = 8192;
 | 
			
		||||
 | 
			
		||||
        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,
 | 
			
		||||
                    const float zlow, const float zhigh,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#include <OgreSceneNode.h>
 | 
			
		||||
 | 
			
		||||
#include <components/nifogre/ogre_nif_loader.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace MWRender;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -88,18 +89,16 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
 | 
			
		|||
    NifOgre::NIFLoader::load(mesh);
 | 
			
		||||
    Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
    Ogre::Vector3 extents = ent->getBoundingBox().getSize();
 | 
			
		||||
    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
 | 
			
		||||
    if (ptr.getTypeName().find("Door") != std::string::npos)
 | 
			
		||||
        small = false;
 | 
			
		||||
*/
 | 
			
		||||
    const bool small = false;
 | 
			
		||||
 | 
			
		||||
    if (mBounds.find(ptr.getCell()) == mBounds.end())
 | 
			
		||||
        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());
 | 
			
		||||
    mBounds[ptr.getCell()].merge(bounds);
 | 
			
		||||
 | 
			
		||||
    if(!mIsStatic)
 | 
			
		||||
    if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects"))
 | 
			
		||||
    {
 | 
			
		||||
        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
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +130,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
 | 
			
		|||
                sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
 | 
			
		||||
                mStaticGeometrySmall[ptr.getCell()] = sg;
 | 
			
		||||
 | 
			
		||||
                sg->setRenderingDistance(2500); /// \todo config value
 | 
			
		||||
                sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); /// \todo config value
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                sg = mStaticGeometrySmall[ptr.getCell()];
 | 
			
		||||
| 
						 | 
				
			
			@ -169,6 +168,7 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f
 | 
			
		|||
    assert(insert);
 | 
			
		||||
    Ogre::Light *light = mRenderer.getScene()->createLight();
 | 
			
		||||
    light->setDiffuseColour (r, g, b);
 | 
			
		||||
    mLights.push_back(light->getName());
 | 
			
		||||
 | 
			
		||||
    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];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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*> mStaticGeometrySmall;
 | 
			
		||||
    std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds;
 | 
			
		||||
    std::vector<std::string> mLights;
 | 
			
		||||
    Ogre::SceneNode* mMwRoot;
 | 
			
		||||
    bool mIsStatic;
 | 
			
		||||
    static int uniqueID;
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +45,9 @@ public:
 | 
			
		|||
    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 enableLights();
 | 
			
		||||
    void disableLights();
 | 
			
		||||
 | 
			
		||||
    Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*);
 | 
			
		||||
    ///< 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/ptr.hpp"
 | 
			
		||||
#include <components/esm/loadstat.hpp>
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
using namespace MWRender;
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +65,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
 | 
			
		|||
    mSun = 0;
 | 
			
		||||
 | 
			
		||||
    mDebugging = new Debugging(mMwRoot, environment, engine);
 | 
			
		||||
    mLocalMap = new MWRender::LocalMap(&mRendering, &environment);
 | 
			
		||||
    mLocalMap = new MWRender::LocalMap(&mRendering, this, &environment);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RenderingManager::~RenderingManager ()
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +178,7 @@ void RenderingManager::update (float duration){
 | 
			
		|||
 | 
			
		||||
    mRendering.update(duration);
 | 
			
		||||
 | 
			
		||||
    mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealDirection() );
 | 
			
		||||
    mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() );
 | 
			
		||||
 | 
			
		||||
    checkUnderwater();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -273,18 +274,14 @@ void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
 | 
			
		|||
 | 
			
		||||
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
 | 
			
		||||
  // can allow (to prevent objects suddenly popping up) equals:
 | 
			
		||||
  // 8192            * 0.69
 | 
			
		||||
  //   ^ cell size    ^ minimum density value used (clear weather)
 | 
			
		||||
  float low = 5652.48 / density / 2.f;
 | 
			
		||||
  float high = 5652.48 / density;
 | 
			
		||||
  float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
 | 
			
		||||
  float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
 | 
			
		||||
 | 
			
		||||
  mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
 | 
			
		||||
 | 
			
		||||
  mRendering.getCamera()->setFarClipDistance ( high );
 | 
			
		||||
  mRendering.getCamera()->setFarClipDistance ( max / density );
 | 
			
		||||
  mRendering.getViewport()->setBackgroundColour (colour);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -411,4 +408,14 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell)
 | 
			
		|||
    mLocalMap->saveFogOfWar(cell);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RenderingManager::disableLights()
 | 
			
		||||
{
 | 
			
		||||
    mObjects.disableLights();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RenderingManager::enableLights()
 | 
			
		||||
{
 | 
			
		||||
    mObjects.enableLights();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,6 +109,9 @@ class RenderingManager: private RenderingInterface {
 | 
			
		|||
    void sunEnable();
 | 
			
		||||
    void sunDisable();
 | 
			
		||||
 | 
			
		||||
    void disableLights();
 | 
			
		||||
    void enableLights();
 | 
			
		||||
 | 
			
		||||
    bool occlusionQuerySupported() { return mOcclusionQuery->supported(); };
 | 
			
		||||
    OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -746,6 +746,7 @@ void SkyManager::setGlare(const float glare)
 | 
			
		|||
 | 
			
		||||
Vector3 SkyManager::getRealSunPos()
 | 
			
		||||
{
 | 
			
		||||
    if (!mCreated) return Vector3(0,0,0);
 | 
			
		||||
    return mSun->getNode()->_getDerivedPosition();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ THE SOFTWARE.
 | 
			
		|||
#include "OgreHardwarePixelBuffer.h"
 | 
			
		||||
#include "OgreShadowCameraSetupPSSM.h"
 | 
			
		||||
 | 
			
		||||
#define POINTLIGHTS
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
namespace Ogre
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -220,22 +220,10 @@ namespace Ogre
 | 
			
		|||
		
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
        int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const
 | 
			
		||||
        {
 | 
			
		||||
                #ifndef POINTLIGHTS
 | 
			
		||||
                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
 | 
			
		||||
        }
 | 
			
		||||
    int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const
 | 
			
		||||
    {
 | 
			
		||||
        return Settings::Manager::getInt("num lights", "Terrain");
 | 
			
		||||
    }
 | 
			
		||||
	//---------------------------------------------------------------------
 | 
			
		||||
	MaterialPtr TerrainMaterialGeneratorB::SM2Profile::generate(const Terrain* terrain)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -565,7 +553,8 @@ namespace Ogre
 | 
			
		|||
                {
 | 
			
		||||
                        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("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
 | 
			
		||||
                        if (prof->getNumberOfLightsSupported() > 1)
 | 
			
		||||
                            params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
 | 
			
		||||
                        //params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i);
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
| 
						 | 
				
			
			@ -980,10 +969,9 @@ namespace Ogre
 | 
			
		|||
			//"uniform float3 lightSpecularColour"<<i<<",\n"
 | 
			
		||||
                        ;
 | 
			
		||||
 | 
			
		||||
                        #ifdef POINTLIGHTS
 | 
			
		||||
                        outStream <<
 | 
			
		||||
                        "uniform float4 lightAttenuation"<<i<<",\n";
 | 
			
		||||
                        #endif
 | 
			
		||||
                        if (prof->getNumberOfLightsSupported() > 1)
 | 
			
		||||
                            outStream <<
 | 
			
		||||
                            "uniform float4 lightAttenuation"<<i<<",\n";
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1130,10 +1118,9 @@ namespace Ogre
 | 
			
		|||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
                                #ifdef POINTLIGHTS
 | 
			
		||||
                                outStream << "float d; \n"
 | 
			
		||||
                                if (prof->getNumberOfLightsSupported() > 1)
 | 
			
		||||
                                    outStream << "float d; \n"
 | 
			
		||||
                                             "float attn; \n";
 | 
			
		||||
                                #endif
 | 
			
		||||
 | 
			
		||||
                                outStream <<
 | 
			
		||||
                                "      eyeDir = normalize(eyeDir); \n";
 | 
			
		||||
| 
						 | 
				
			
			@ -1144,13 +1131,12 @@ namespace Ogre
 | 
			
		|||
                                        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";
 | 
			
		||||
 | 
			
		||||
                                        #ifdef POINTLIGHTS
 | 
			
		||||
                                    if (prof->getNumberOfLightsSupported() > 1)
 | 
			
		||||
                                        outStream <<
 | 
			
		||||
                                        // pre-multiply light color with attenuation factor
 | 
			
		||||
                                           "d = length( lightDir"<<i<<" ); \n"
 | 
			
		||||
                                           "attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
 | 
			
		||||
                                           "lightDiffuseColour"<<i<<" *= attn; \n";
 | 
			
		||||
                                        #endif
 | 
			
		||||
                                }
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,5 +127,6 @@ op 0x2000141: GetWaterLevel
 | 
			
		|||
op 0x2000142: SetWaterLevel
 | 
			
		||||
op 0x2000143: ModWaterLevel
 | 
			
		||||
op 0x2000144: ToggleWater, twa
 | 
			
		||||
op 0x2000145: TogglePathgrid
 | 
			
		||||
opcodes 0x2000146-0x3ffffff unused
 | 
			
		||||
op 0x2000145: ToggleFogOfWar (tfow)
 | 
			
		||||
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 opcodeEnableClassMenu = 0x200000f;
 | 
			
		||||
        const int opcodeEnableNameMenu = 0x2000010;
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +92,7 @@ namespace MWScript
 | 
			
		|||
        const int opcodeEnableRest = 0x2000017;
 | 
			
		||||
        const int opcodeShowRestMenu = 0x2000018;
 | 
			
		||||
        const int opcodeGetButtonPressed = 0x2000137;
 | 
			
		||||
        const int opcodeToggleFogOfWar = 0x2000145;
 | 
			
		||||
 | 
			
		||||
        void registerExtensions (Compiler::Extensions& extensions)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +114,9 @@ namespace MWScript
 | 
			
		|||
            extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu);
 | 
			
		||||
 | 
			
		||||
            extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed);
 | 
			
		||||
 | 
			
		||||
            extensions.registerInstruction ("togglefogofwar", "", opcodeToggleFogOfWar);
 | 
			
		||||
            extensions.registerInstruction ("tfow", "", opcodeToggleFogOfWar);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void installOpcodes (Interpreter::Interpreter& interpreter)
 | 
			
		||||
| 
						 | 
				
			
			@ -135,6 +152,8 @@ namespace MWScript
 | 
			
		|||
                new OpShowDialogue (MWGui::GM_Rest));
 | 
			
		||||
 | 
			
		||||
            interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed);
 | 
			
		||||
 | 
			
		||||
            interpreter.installSegment5 (opcodeToggleFogOfWar, new OpToggleFogOfWar);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -217,7 +217,7 @@ namespace MWScript
 | 
			
		|||
        const int opcodeFadeOut = 0x200013d;
 | 
			
		||||
        const int opcodeFadeTo = 0x200013e;
 | 
			
		||||
        const int opcodeToggleWater = 0x2000144;
 | 
			
		||||
        const int opcodeTogglePathgrid = 0x2000145;
 | 
			
		||||
        const int opcodeTogglePathgrid = 0x2000146;
 | 
			
		||||
 | 
			
		||||
        void registerExtensions (Compiler::Extensions& extensions)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -886,6 +886,18 @@ namespace MWWorld
 | 
			
		|||
        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)
 | 
			
		||||
    {
 | 
			
		||||
        mRendering->setWaterHeight(height);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -146,6 +146,9 @@ namespace MWWorld
 | 
			
		|||
            bool isCellExterior() 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) const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,10 @@ project (Components)
 | 
			
		|||
 | 
			
		||||
# source files
 | 
			
		||||
 | 
			
		||||
add_component_dir (settings
 | 
			
		||||
    settings
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
add_component_dir (bsa
 | 
			
		||||
    bsa_archive bsa_file
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@
 | 
			
		|||
 | 
			
		||||
#include "ogre_nif_loader.hpp"
 | 
			
		||||
 | 
			
		||||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
typedef unsigned char ubyte;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -299,138 +300,136 @@ void NIFLoader::createMaterial(const String &name,
 | 
			
		|||
    material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]);
 | 
			
		||||
    material->setShininess(glossiness);
 | 
			
		||||
 | 
			
		||||
    // Create shader for the material
 | 
			
		||||
    // vertex
 | 
			
		||||
    HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
 | 
			
		||||
 | 
			
		||||
    HighLevelGpuProgramPtr vertex;
 | 
			
		||||
    if (mgr.getByName("main_vp").isNull())
 | 
			
		||||
    if (Settings::Manager::getBool("shaders", "Objects"))
 | 
			
		||||
    {
 | 
			
		||||
        vertex = mgr.createProgram("main_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
 | 
			
		||||
            "cg", GPT_VERTEX_PROGRAM);
 | 
			
		||||
        vertex->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1");
 | 
			
		||||
        vertex->setParameter("entry_point", "main_vp");
 | 
			
		||||
        StringUtil::StrStreamType outStream;
 | 
			
		||||
        outStream <<
 | 
			
		||||
        "void main_vp(	\n"
 | 
			
		||||
        "	float4 position : POSITION,	\n"
 | 
			
		||||
        "   float4 normal : NORMAL, \n"
 | 
			
		||||
        "   float4 colour : COLOR, \n"
 | 
			
		||||
        "   in float2 uv : TEXCOORD0, \n"
 | 
			
		||||
        "   out float2 oUV : TEXCOORD0, \n"
 | 
			
		||||
        "	out float4 oPosition : POSITION,	\n"
 | 
			
		||||
        "   out float4 oPositionObjSpace : TEXCOORD1, \n"
 | 
			
		||||
        "   out float4 oNormal : TEXCOORD2, \n"
 | 
			
		||||
        "   out float oFogValue : TEXCOORD3, \n"
 | 
			
		||||
        "   out float4 oVertexColour : TEXCOORD4, \n"
 | 
			
		||||
        "   uniform float4 fogParams, \n"
 | 
			
		||||
        "	uniform float4x4 worldViewProj	\n"
 | 
			
		||||
        ")	\n"
 | 
			
		||||
        "{	\n"
 | 
			
		||||
        "   oVertexColour = colour; \n"
 | 
			
		||||
        "   oUV = uv; \n"
 | 
			
		||||
        "   oNormal = normal; \n"
 | 
			
		||||
        "	oPosition = mul( worldViewProj, position );  \n"
 | 
			
		||||
        "   oFogValue = saturate((oPosition.z - fogParams.y) * fogParams.w); \n"
 | 
			
		||||
        "   oPositionObjSpace = position; \n"
 | 
			
		||||
        "}";
 | 
			
		||||
        vertex->setSource(outStream.str());
 | 
			
		||||
        vertex->load();
 | 
			
		||||
        vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
 | 
			
		||||
        vertex->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        vertex = mgr.getByName("main_vp");
 | 
			
		||||
    material->getTechnique(0)->getPass(0)->setVertexProgram(vertex->getName());
 | 
			
		||||
        // Create shader for the material
 | 
			
		||||
        // vertex
 | 
			
		||||
        HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
 | 
			
		||||
 | 
			
		||||
    // the number of lights to support.
 | 
			
		||||
    // when rendering an object, OGRE automatically picks the lights that are
 | 
			
		||||
    // closest to the object being rendered. unfortunately this mechanism does
 | 
			
		||||
    // 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
 | 
			
		||||
    // of lights here in order to minimize disappearing lights.
 | 
			
		||||
    float num_lights;
 | 
			
		||||
    if (GpuProgramManager::getSingleton().isSyntaxSupported("fp40") ||
 | 
			
		||||
        GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0"))
 | 
			
		||||
        num_lights = 8 /* 32 */;
 | 
			
		||||
    else
 | 
			
		||||
        num_lights = 8;
 | 
			
		||||
 | 
			
		||||
    // fragment
 | 
			
		||||
    HighLevelGpuProgramPtr fragment;
 | 
			
		||||
    if (mgr.getByName("main_fp").isNull())
 | 
			
		||||
    {
 | 
			
		||||
        fragment = mgr.createProgram("main_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
 | 
			
		||||
            "cg", GPT_FRAGMENT_PROGRAM);
 | 
			
		||||
        fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1");
 | 
			
		||||
        fragment->setParameter("entry_point", "main_fp");
 | 
			
		||||
        StringUtil::StrStreamType outStream;
 | 
			
		||||
        outStream <<
 | 
			
		||||
        "void main_fp(	\n"
 | 
			
		||||
        "   in float2 uv : TEXCOORD0, \n"
 | 
			
		||||
        "	out float4 oColor    : COLOR, \n"
 | 
			
		||||
        "   uniform sampler2D texture : TEXUNIT0, \n"
 | 
			
		||||
        "   float4 positionObjSpace : TEXCOORD1, \n"
 | 
			
		||||
        "   float4 normal : TEXCOORD2, \n"
 | 
			
		||||
        "   float fogValue : TEXCOORD3, \n"
 | 
			
		||||
        "   float4 vertexColour : TEXCOORD4, \n"
 | 
			
		||||
        "   uniform float4 fogColour, \n";
 | 
			
		||||
 | 
			
		||||
        for (int i=0; i<num_lights; ++i)
 | 
			
		||||
        HighLevelGpuProgramPtr vertex;
 | 
			
		||||
        if (mgr.getByName("main_vp").isNull())
 | 
			
		||||
        {
 | 
			
		||||
            vertex = mgr.createProgram("main_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
 | 
			
		||||
                "cg", GPT_VERTEX_PROGRAM);
 | 
			
		||||
            vertex->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1");
 | 
			
		||||
            vertex->setParameter("entry_point", "main_vp");
 | 
			
		||||
            StringUtil::StrStreamType outStream;
 | 
			
		||||
            outStream <<
 | 
			
		||||
            "   uniform float4 lightDiffuse"<<i<<", \n"
 | 
			
		||||
            "   uniform float4 lightPositionObjSpace"<<i<<", \n"
 | 
			
		||||
            "   uniform float4 lightAttenuation"<<i<<", \n";
 | 
			
		||||
            "void main_vp(	\n"
 | 
			
		||||
            "	float4 position : POSITION,	\n"
 | 
			
		||||
            "   float4 normal : NORMAL, \n"
 | 
			
		||||
            "   float4 colour : COLOR, \n"
 | 
			
		||||
            "   in float2 uv : TEXCOORD0, \n"
 | 
			
		||||
            "   out float2 oUV : TEXCOORD0, \n"
 | 
			
		||||
            "	out float4 oPosition : POSITION,	\n"
 | 
			
		||||
            "   out float4 oPositionObjSpace : TEXCOORD1, \n"
 | 
			
		||||
            "   out float4 oNormal : TEXCOORD2, \n"
 | 
			
		||||
            "   out float oFogValue : TEXCOORD3, \n"
 | 
			
		||||
            "   out float4 oVertexColour : TEXCOORD4, \n"
 | 
			
		||||
            "   uniform float4 fogParams, \n"
 | 
			
		||||
            "	uniform float4x4 worldViewProj	\n"
 | 
			
		||||
            ")	\n"
 | 
			
		||||
            "{	\n"
 | 
			
		||||
            "   oVertexColour = colour; \n"
 | 
			
		||||
            "   oUV = uv; \n"
 | 
			
		||||
            "   oNormal = normal; \n"
 | 
			
		||||
            "	oPosition = mul( worldViewProj, position );  \n"
 | 
			
		||||
            "   oFogValue = saturate((oPosition.z - fogParams.y) * fogParams.w); \n"
 | 
			
		||||
            "   oPositionObjSpace = position; \n"
 | 
			
		||||
            "}";
 | 
			
		||||
            vertex->setSource(outStream.str());
 | 
			
		||||
            vertex->load();
 | 
			
		||||
            vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
 | 
			
		||||
            vertex->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
 | 
			
		||||
        }
 | 
			
		||||
        outStream <<
 | 
			
		||||
        "   uniform float4 lightAmbient, \n"
 | 
			
		||||
        "   uniform float4 ambient, \n"
 | 
			
		||||
        "   uniform float4 diffuse, \n"
 | 
			
		||||
        "   uniform float4 emissive \n"
 | 
			
		||||
        ")	\n"
 | 
			
		||||
        "{	\n"
 | 
			
		||||
        "   float4 tex =  tex2D(texture, uv); \n"
 | 
			
		||||
        "   float d; \n"
 | 
			
		||||
        "   float attn; \n"
 | 
			
		||||
        "   float3 lightColour = float3(0, 0, 0); \n";
 | 
			
		||||
        
 | 
			
		||||
        for (int i=0; i<num_lights; ++i)
 | 
			
		||||
        else
 | 
			
		||||
            vertex = mgr.getByName("main_vp");
 | 
			
		||||
        material->getTechnique(0)->getPass(0)->setVertexProgram(vertex->getName());
 | 
			
		||||
 | 
			
		||||
        // the number of lights to support.
 | 
			
		||||
        // when rendering an object, OGRE automatically picks the lights that are
 | 
			
		||||
        // closest to the object being rendered. unfortunately this mechanism does
 | 
			
		||||
        // 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
 | 
			
		||||
        // of lights here in order to minimize disappearing lights.
 | 
			
		||||
        int num_lights = Settings::Manager::getInt("num lights", "Objects");
 | 
			
		||||
 | 
			
		||||
        // fragment
 | 
			
		||||
        HighLevelGpuProgramPtr fragment;
 | 
			
		||||
        if (mgr.getByName("main_fp").isNull())
 | 
			
		||||
        {
 | 
			
		||||
            fragment = mgr.createProgram("main_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
 | 
			
		||||
                "cg", GPT_FRAGMENT_PROGRAM);
 | 
			
		||||
            fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1");
 | 
			
		||||
            fragment->setParameter("entry_point", "main_fp");
 | 
			
		||||
            StringUtil::StrStreamType outStream;
 | 
			
		||||
            outStream <<
 | 
			
		||||
            "   float3 lightDir"<<i<<" = lightPositionObjSpace"<<i<<".xyz - (positionObjSpace.xyz * lightPositionObjSpace"<<i<<".w); \n"
 | 
			
		||||
            "void main_fp(	\n"
 | 
			
		||||
            "   in float2 uv : TEXCOORD0, \n"
 | 
			
		||||
            "	out float4 oColor    : COLOR, \n"
 | 
			
		||||
            "   uniform sampler2D texture : TEXUNIT0, \n"
 | 
			
		||||
            "   float4 positionObjSpace : TEXCOORD1, \n"
 | 
			
		||||
            "   float4 normal : TEXCOORD2, \n"
 | 
			
		||||
            "   float fogValue : TEXCOORD3, \n"
 | 
			
		||||
            "   float4 vertexColour : TEXCOORD4, \n"
 | 
			
		||||
            "   uniform float4 fogColour, \n";
 | 
			
		||||
 | 
			
		||||
            // pre-multiply light color with attenuation factor
 | 
			
		||||
            "   d = length( lightDir"<<i<<" ); \n"
 | 
			
		||||
            "   attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
 | 
			
		||||
            "   lightDiffuse"<<i<<" *= attn; \n"
 | 
			
		||||
            for (int i=0; i<num_lights; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                outStream <<
 | 
			
		||||
                "   uniform float4 lightDiffuse"<<i<<", \n"
 | 
			
		||||
                "   uniform float4 lightPositionObjSpace"<<i<<", \n"
 | 
			
		||||
                "   uniform float4 lightAttenuation"<<i<<", \n";
 | 
			
		||||
            }
 | 
			
		||||
            outStream <<
 | 
			
		||||
            "   uniform float4 lightAmbient, \n"
 | 
			
		||||
            "   uniform float4 ambient, \n"
 | 
			
		||||
            "   uniform float4 diffuse, \n"
 | 
			
		||||
            "   uniform float4 emissive \n"
 | 
			
		||||
            ")	\n"
 | 
			
		||||
            "{	\n"
 | 
			
		||||
            "   float4 tex =  tex2D(texture, uv); \n"
 | 
			
		||||
            "   float d; \n"
 | 
			
		||||
            "   float attn; \n"
 | 
			
		||||
            "   float3 lightColour = float3(0, 0, 0); \n";
 | 
			
		||||
            
 | 
			
		||||
            for (int i=0; i<num_lights; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                outStream <<
 | 
			
		||||
                "   float3 lightDir"<<i<<" = lightPositionObjSpace"<<i<<".xyz - (positionObjSpace.xyz * lightPositionObjSpace"<<i<<".w); \n"
 | 
			
		||||
 | 
			
		||||
            "	lightColour.xyz += lit(dot(normalize(lightDir"<<i<<"), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
 | 
			
		||||
                // pre-multiply light color with attenuation factor
 | 
			
		||||
                "   d = length( lightDir"<<i<<" ); \n"
 | 
			
		||||
                "   attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
 | 
			
		||||
                "   lightDiffuse"<<i<<" *= attn; \n"
 | 
			
		||||
 | 
			
		||||
                "	lightColour.xyz += lit(dot(normalize(lightDir"<<i<<"), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            outStream <<
 | 
			
		||||
            "   float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
 | 
			
		||||
            "   oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n"
 | 
			
		||||
            "   oColor.a = tex.a * diffuse.a * vertexColour.a; \n"
 | 
			
		||||
            "}";
 | 
			
		||||
            fragment->setSource(outStream.str());
 | 
			
		||||
            fragment->load();
 | 
			
		||||
 | 
			
		||||
            for (int i=0; i<num_lights; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                fragment->getDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
 | 
			
		||||
                fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
 | 
			
		||||
                fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
 | 
			
		||||
            }
 | 
			
		||||
            fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
 | 
			
		||||
            fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
 | 
			
		||||
            fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
 | 
			
		||||
            fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
 | 
			
		||||
            fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        outStream <<
 | 
			
		||||
        "   float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
 | 
			
		||||
        "   oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n"
 | 
			
		||||
        "   oColor.a = tex.a * diffuse.a * vertexColour.a; \n"
 | 
			
		||||
        "}";
 | 
			
		||||
        fragment->setSource(outStream.str());
 | 
			
		||||
        fragment->load();
 | 
			
		||||
 | 
			
		||||
        for (int i=0; i<num_lights; ++i)
 | 
			
		||||
        {
 | 
			
		||||
            fragment->getDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
 | 
			
		||||
            fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
 | 
			
		||||
            fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
 | 
			
		||||
        }
 | 
			
		||||
        fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
 | 
			
		||||
        fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
 | 
			
		||||
        fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
 | 
			
		||||
        fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
 | 
			
		||||
        fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
 | 
			
		||||
        else
 | 
			
		||||
            fragment = mgr.getByName("main_fp");
 | 
			
		||||
        material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName());
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        fragment = mgr.getByName("main_fp");
 | 
			
		||||
    material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Takes a name and adds a unique part to it. This is just used to
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										158
									
								
								components/settings/settings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								components/settings/settings.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								components/settings/settings.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								components/settings/settings.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
							
								
								
									
										43
									
								
								files/settings-default.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								files/settings-default.cfg
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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…
	
		Reference in a new issue