1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-07-21 11:14:04 +00:00

Merge remote-tracking branch 'upstream/master' into opencsui

This commit is contained in:
Pieter van der Kloet 2013-03-07 03:02:03 +01:00
commit 9145fb210b
188 changed files with 4196 additions and 2195 deletions

View file

@ -112,14 +112,11 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
case '5': oper_str = ">="; break; case '5': oper_str = ">="; break;
} }
std::string value_str = "??"; std::ostringstream stream;
if (ss.mType == ESM::VT_Int) stream << ss.mValue;
value_str = str(boost::format("%d") % ss.mI);
else if (ss.mType == ESM::VT_Float)
value_str = str(boost::format("%f") % ss.mF);
std::string result = str(boost::format("%-12s %-32s %2s %s") std::string result = str(boost::format("%-12s %-32s %2s %s")
% type_str % func_str % oper_str % value_str); % type_str % func_str % oper_str % stream.str());
return result; return result;
} }
@ -713,31 +710,13 @@ void Record<ESM::Faction>::print()
template<> template<>
void Record<ESM::Global>::print() void Record<ESM::Global>::print()
{ {
// nothing to print (well, nothing that's correct anyway) std::cout << " " << mData.mValue << std::endl;
std::cout << " Type: " << mData.mType << std::endl;
std::cout << " Value: " << mData.mValue << std::endl;
} }
template<> template<>
void Record<ESM::GameSetting>::print() void Record<ESM::GameSetting>::print()
{ {
std::cout << " Value: "; std::cout << " " << mData.mValue << std::endl;
switch (mData.mType) {
case ESM::VT_String:
std::cout << "'" << mData.mStr << "' (std::string)";
break;
case ESM::VT_Float:
std::cout << mData.mF << " (float)";
break;
case ESM::VT_Int:
std::cout << mData.mI << " (int)";
break;
default:
std::cout << "unknown type";
}
} }
template<> template<>

View file

@ -91,6 +91,7 @@ bool GraphicsPage::setupOgre()
pluginDir = dir.absolutePath().toStdString(); pluginDir = dir.absolutePath().toStdString();
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mOgre); Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mOgre);
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mOgre);
Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mOgre); Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mOgre);
#ifdef ENABLE_PLUGIN_GL #ifdef ENABLE_PLUGIN_GL

View file

@ -116,8 +116,7 @@ void CSMDoc::Document::addOptionalGmsts()
{ {
ESM::GameSetting gmst; ESM::GameSetting gmst;
gmst.mId = sFloats[i]; gmst.mId = sFloats[i];
gmst.mF = 0; gmst.mValue.setType (ESM::VT_Float);
gmst.mType = ESM::VT_Float;
addOptionalGmst (gmst); addOptionalGmst (gmst);
} }
@ -125,8 +124,7 @@ void CSMDoc::Document::addOptionalGmsts()
{ {
ESM::GameSetting gmst; ESM::GameSetting gmst;
gmst.mId = sIntegers[i]; gmst.mId = sIntegers[i];
gmst.mI = 0; gmst.mValue.setType (ESM::VT_Int);
gmst.mType = ESM::VT_Long;
addOptionalGmst (gmst); addOptionalGmst (gmst);
} }
@ -134,8 +132,8 @@ void CSMDoc::Document::addOptionalGmsts()
{ {
ESM::GameSetting gmst; ESM::GameSetting gmst;
gmst.mId = sStrings[i]; gmst.mId = sStrings[i];
gmst.mStr = "<no text>"; gmst.mValue.setType (ESM::VT_String);
gmst.mType = ESM::VT_String; gmst.mValue.setString ("<no text>");
addOptionalGmst (gmst); addOptionalGmst (gmst);
} }
} }
@ -154,8 +152,7 @@ void CSMDoc::Document::addOptionalGlobals()
{ {
ESM::Global global; ESM::Global global;
global.mId = sGlobals[i]; global.mId = sGlobals[i];
global.mType = ESM::VT_Int; global.mValue.setType (ESM::VT_Long);
global.mValue = 0;
addOptionalGlobal (global); addOptionalGlobal (global);
} }
} }
@ -192,9 +189,14 @@ void CSMDoc::Document::createBase()
for (int i=0; sGlobals[i]; ++i) for (int i=0; sGlobals[i]; ++i)
{ {
ESM::Global record; ESM::Global record;
record.mId = sGlobals[i]; record.mId = sGlobals[i];
record.mValue = i==0 ? 1 : 0;
record.mType = ESM::VT_Float; record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Int);
if (i==0)
record.mValue.setInteger (1);
getData().getGlobals().add (record); getData().getGlobals().add (record);
} }
} }

View file

@ -30,7 +30,8 @@ namespace CSMWorld
Display_Integer, Display_Integer,
Display_Float, Display_Float,
Display_Var, Display_Var,
Display_VarType Display_GmstVarType,
Display_GlobalVarType
}; };
std::string mTitle; std::string mTitle;

View file

@ -12,13 +12,13 @@ namespace CSMWorld
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
return record.get().mValue; return record.get().mValue.getFloat();
} }
virtual void set (Record<ESXRecordT>& record, const QVariant& data) virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{ {
ESXRecordT record2 = record.get(); ESXRecordT record2 = record.get();
record2.mValue = data.toFloat(); record2.mValue.setFloat (data.toFloat());
record.setModified (record2); record.setModified (record2);
} }
@ -96,17 +96,17 @@ namespace CSMWorld
template<typename ESXRecordT> template<typename ESXRecordT>
struct VarTypeColumn : public Column<ESXRecordT> struct VarTypeColumn : public Column<ESXRecordT>
{ {
VarTypeColumn() : Column<ESXRecordT> ("Type", ColumnBase::Display_VarType) {} VarTypeColumn (ColumnBase::Display display) : Column<ESXRecordT> ("Type", display) {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
return static_cast<int> (record.get().mType); return static_cast<int> (record.get().mValue.getType());
} }
virtual void set (Record<ESXRecordT>& record, const QVariant& data) virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{ {
ESXRecordT record2 = record.get(); ESXRecordT record2 = record.get();
record2.mType = static_cast<ESM::VarType> (data.toInt()); record2.mValue.setType (static_cast<ESM::VarType> (data.toInt()));
record.setModified (record2); record.setModified (record2);
} }
@ -123,11 +123,21 @@ namespace CSMWorld
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
switch (record.get().mType) switch (record.get().mValue.getType())
{ {
case ESM::VT_String: return record.get().mStr.c_str(); break; case ESM::VT_String:
case ESM::VT_Int: return record.get().mI; break;
case ESM::VT_Float: return record.get().mF; break; return record.get().mValue.getString().c_str(); break;
case ESM::VT_Int:
case ESM::VT_Short:
case ESM::VT_Long:
return record.get().mValue.getInteger(); break;
case ESM::VT_Float:
return record.get().mValue.getFloat(); break;
default: return QVariant(); default: return QVariant();
} }
@ -137,11 +147,24 @@ namespace CSMWorld
{ {
ESXRecordT record2 = record.get(); ESXRecordT record2 = record.get();
switch (record2.mType) switch (record2.mValue.getType())
{ {
case ESM::VT_String: record2.mStr = data.toString().toUtf8().constData(); break; case ESM::VT_String:
case ESM::VT_Int: record2.mI = data.toInt(); break;
case ESM::VT_Float: record2.mF = data.toFloat(); break; record2.mValue.setString (data.toString().toUtf8().constData());
break;
case ESM::VT_Int:
case ESM::VT_Short:
case ESM::VT_Long:
record2.mValue.setInteger (data.toInt());
break;
case ESM::VT_Float:
record2.mValue.setFloat (data.toFloat());
break;
default: break; default: break;
} }

View file

@ -6,6 +6,7 @@
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <components/esm/esmreader.hpp> #include <components/esm/esmreader.hpp>
#include <components/esm/defs.hpp>
#include <components/esm/loadglob.hpp> #include <components/esm/loadglob.hpp>
#include "idtable.hpp" #include "idtable.hpp"
@ -26,12 +27,13 @@ CSMWorld::Data::Data()
mGlobals.addColumn (new StringIdColumn<ESM::Global>); mGlobals.addColumn (new StringIdColumn<ESM::Global>);
mGlobals.addColumn (new RecordStateColumn<ESM::Global>); mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
mGlobals.addColumn (new FixedRecordTypeColumn<ESM::Global> (UniversalId::Type_Global)); mGlobals.addColumn (new FixedRecordTypeColumn<ESM::Global> (UniversalId::Type_Global));
mGlobals.addColumn (new FloatValueColumn<ESM::Global>); mGlobals.addColumn (new VarTypeColumn<ESM::Global> (ColumnBase::Display_GlobalVarType));
mGlobals.addColumn (new VarValueColumn<ESM::Global>);
mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>); mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>);
mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>); mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>);
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst)); mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting>); mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>); mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);

View file

@ -35,8 +35,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
{ {
mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection;
mDelegateFactories->add (CSMWorld::ColumnBase::Display_VarType, mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType,
new CSVWorld::VarTypeDelegateFactory (ESM::VT_None, ESM::VT_String, ESM::VT_Int, ESM::VT_Float)); new CSVWorld::VarTypeDelegateFactory (ESM::VT_None, ESM::VT_String, ESM::VT_Int, ESM::VT_Float));
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType,
new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float));
} }
CSVDoc::ViewManager::~ViewManager() CSVDoc::ViewManager::~ViewManager()

View file

@ -85,7 +85,7 @@ void CSVWorld::VarTypeDelegateFactory::add (ESM::VarType type)
{ {
{ ESM::VT_None, "empty" }, { ESM::VT_None, "empty" },
{ ESM::VT_Short, "short" }, { ESM::VT_Short, "short" },
{ ESM::VT_Int, "long" }, { ESM::VT_Int, "integer" },
{ ESM::VT_Long, "long" }, { ESM::VT_Long, "long" },
{ ESM::VT_Float, "float" }, { ESM::VT_Float, "float" },
{ ESM::VT_String, "string" }, { ESM::VT_String, "string" },

View file

@ -1,6 +1,8 @@
#ifndef CSV_WORLD_VARTYPEDELEGATE_H #ifndef CSV_WORLD_VARTYPEDELEGATE_H
#define CSV_WORLD_VARTYPEDELEGATE_H #define CSV_WORLD_VARTYPEDELEGATE_H
#include <components/esm/variant.hpp>
#include "enumdelegate.hpp" #include "enumdelegate.hpp"
namespace CSVWorld namespace CSVWorld

View file

@ -16,7 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender add_openmw_dir (mwrender
renderingmanager debugging sky player animation npcanimation creatureanimation activatoranimation renderingmanager debugging sky player animation npcanimation creatureanimation activatoranimation
actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
compositors characterpreview externalrendering globalmap videoplayer compositors characterpreview externalrendering globalmap videoplayer ripplesimulation refraction
) )
add_openmw_dir (mwinput add_openmw_dir (mwinput
@ -30,7 +30,7 @@ add_openmw_dir (mwgui
formatting inventorywindow container hud countdialog tradewindow settingswindow formatting inventorywindow container hud countdialog tradewindow settingswindow
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue

View file

@ -9,11 +9,11 @@
#include <components/bsa/bsa_archive.hpp> #include <components/bsa/bsa_archive.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include <components/translation/translation.hpp> #include <components/translation/translation.hpp>
#include <components/nif/nif_file.hpp> #include <components/nif/niffile.hpp>
#include <components/nifoverrides/nifoverrides.hpp> #include <components/nifoverrides/nifoverrides.hpp>
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bulletnifloader.hpp>
#include <components/nifogre/ogre_nif_loader.hpp> #include <components/nifogre/ogrenifloader.hpp>
#include "mwinput/inputmanagerimp.hpp" #include "mwinput/inputmanagerimp.hpp"
@ -62,6 +62,13 @@ void OMW::Engine::setAnimationVerbose(bool animverbose)
{ {
} }
bool OMW::Engine::frameStarted (const Ogre::FrameEvent& evt)
{
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
MWBase::Environment::get().getWorld()->frameStarted(evt.timeSinceLastFrame);
return true;
}
bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
{ {
try try
@ -316,7 +323,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
addResourcesDirectory(mResDir / "mygui"); addResourcesDirectory(mResDir / "mygui");
addResourcesDirectory(mResDir / "water"); addResourcesDirectory(mResDir / "water");
addResourcesDirectory(mResDir / "gbuffer");
addResourcesDirectory(mResDir / "shadows"); addResourcesDirectory(mResDir / "shadows");
addZipResource(mResDir / "mygui" / "Obliviontt.zip"); addZipResource(mResDir / "mygui" / "Obliviontt.zip");
@ -444,7 +450,7 @@ void OMW::Engine::go()
// Save user settings // Save user settings
settings.saveUser(settingspath); settings.saveUser(settingspath);
std::cout << "Quitting peacefully.\n"; std::cout << "Quitting peacefully." << std::endl;
} }
void OMW::Engine::activate() void OMW::Engine::activate()

View file

@ -105,6 +105,7 @@ namespace OMW
void executeLocalScripts(); void executeLocalScripts();
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt); virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
virtual bool frameStarted (const Ogre::FrameEvent& evt);
/// Load settings from various files, returns the path to the user settings file /// Load settings from various files, returns the path to the user settings file
std::string loadSettings (Settings::Manager & settings); std::string loadSettings (Settings::Manager & settings);

View file

@ -314,6 +314,7 @@ namespace MWBase
/// \todo this does not belong here /// \todo this does not belong here
virtual void playVideo(const std::string& name, bool allowSkipping) = 0; virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
virtual void stopVideo() = 0; virtual void stopVideo() = 0;
virtual void frameStarted (float dt) = 0;
}; };
} }

View file

@ -365,11 +365,10 @@ namespace MWClass
fSwimRunAthleticsMult->getFloat(); fSwimRunAthleticsMult->getFloat();
moveSpeed = swimSpeed; moveSpeed = swimSpeed;
} }
else if(Npc::getStance(ptr, Run, false)) else if(Npc::getStance(ptr, Run, false) && !Npc::getStance(ptr, Sneak, false))
moveSpeed = runSpeed; moveSpeed = runSpeed;
else else
moveSpeed = walkSpeed; moveSpeed = walkSpeed;
if(getMovementSettings(ptr).mLeftRight != 0 && getMovementSettings(ptr).mForwardBackward == 0) if(getMovementSettings(ptr).mLeftRight != 0 && getMovementSettings(ptr).mForwardBackward == 0)
moveSpeed *= 0.75f; moveSpeed *= 0.75f;

View file

@ -20,6 +20,8 @@
#include "../mwrender/objects.hpp" #include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp" #include "../mwrender/renderinginterface.hpp"
#include "../mwmechanics/npcstats.hpp"
namespace MWClass namespace MWClass
{ {
void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -138,6 +140,23 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects); info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
// hide effects the player doesnt know about
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer();
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player);
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
int i=0;
for (MWGui::Widgets::SpellEffectList::iterator it = info.effects.begin(); it != info.effects.end(); ++it)
{
/// \todo this code is duplicated from mwclass/ingredient, put it in a helper function
it->mKnown = ( (i == 0 && alchemySkill >= 15)
|| (i == 1 && alchemySkill >= 30)
|| (i == 2 && alchemySkill >= 45)
|| (i == 3 && alchemySkill >= 60));
++i;
}
info.isPotion = true; info.isPotion = true;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {

View file

@ -31,14 +31,13 @@ namespace
template<typename T> template<typename T>
bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1) bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1)
{ {
if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int || if (select.mValue.getType()==ESM::VT_Int)
select.mType==ESM::VT_Long)
{ {
return selectCompareImp (select.mSelectRule[4], value1, select.mI); return selectCompareImp (select.mSelectRule[4], value1, select.mValue.getInteger());
} }
else if (select.mType==ESM::VT_Float) else if (select.mValue.getType()==ESM::VT_Float)
{ {
return selectCompareImp (select.mSelectRule[4], value1, select.mF); return selectCompareImp (select.mSelectRule[4], value1, select.mValue.getFloat());
} }
else else
throw std::runtime_error ( throw std::runtime_error (

View file

@ -237,7 +237,7 @@ namespace MWGui
Widgets::SpellEffectList _list = Widgets::MWEffectList::effectListFromESM(&list); Widgets::SpellEffectList _list = Widgets::MWEffectList::effectListFromESM(&list);
effectsWidget->setEffectList(_list); effectsWidget->setEffectList(_list);
std::vector<MyGUI::WidgetPtr> effectItems; std::vector<MyGUI::Widget*> effectItems;
effectsWidget->createEffectWidgets(effectItems, mEffectsBox, coord, false, 0); effectsWidget->createEffectWidgets(effectItems, mEffectsBox, coord, false, 0);
effectsWidget->setCoord(coord); effectsWidget->setCoord(coord);
} }

View file

@ -40,11 +40,11 @@ BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager)
mBirthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); mBirthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
mBirthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); mBirthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
MyGUI::ButtonPtr backButton; MyGUI::Button* backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked);
@ -55,7 +55,7 @@ BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager)
void BirthDialog::setNextButtonShow(bool shown) void BirthDialog::setNextButtonShow(bool shown)
{ {
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
if (shown) if (shown)
@ -82,7 +82,7 @@ void BirthDialog::setBirthId(const std::string &birthId)
if (boost::iequals(*mBirthList->getItemDataAt<std::string>(i), birthId)) if (boost::iequals(*mBirthList->getItemDataAt<std::string>(i), birthId))
{ {
mBirthList->setIndexSelected(i); mBirthList->setIndexSelected(i);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
break; break;
} }
@ -110,7 +110,7 @@ void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index)
if (_index == MyGUI::ITEM_NONE) if (_index == MyGUI::ITEM_NONE)
return; return;
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
const std::string *birthId = mBirthList->getItemDataAt<std::string>(_index); const std::string *birthId = mBirthList->getItemDataAt<std::string>(_index);
@ -159,7 +159,7 @@ void BirthDialog::updateBirths()
void BirthDialog::updateSpells() void BirthDialog::updateSpells()
{ {
for (std::vector<MyGUI::WidgetPtr>::iterator it = mSpellItems.begin(); it != mSpellItems.end(); ++it) for (std::vector<MyGUI::Widget*>::iterator it = mSpellItems.begin(); it != mSpellItems.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }

View file

@ -46,9 +46,9 @@ namespace MWGui
void updateSpells(); void updateSpells();
MyGUI::ListBox* mBirthList; MyGUI::ListBox* mBirthList;
MyGUI::WidgetPtr mSpellArea; MyGUI::Widget* mSpellArea;
MyGUI::ImageBox* mBirthImage; MyGUI::ImageBox* mBirthImage;
std::vector<MyGUI::WidgetPtr> mSpellItems; std::vector<MyGUI::Widget*> mSpellItems;
std::string mCurrentBirthId; std::string mCurrentBirthId;
}; };

View file

@ -31,11 +31,11 @@ GenerateClassResultDialog::GenerateClassResultDialog(MWBase::WindowManager& parW
getWidget(mClassImage, "ClassImage"); getWidget(mClassImage, "ClassImage");
getWidget(mClassName, "ClassName"); getWidget(mClassName, "ClassName");
MyGUI::ButtonPtr backButton; MyGUI::Button* backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked);
@ -97,11 +97,11 @@ PickClassDialog::PickClassDialog(MWBase::WindowManager& parWindowManager)
getWidget(mClassImage, "ClassImage"); getWidget(mClassImage, "ClassImage");
MyGUI::ButtonPtr backButton; MyGUI::Button* backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onOkClicked);
@ -111,7 +111,7 @@ PickClassDialog::PickClassDialog(MWBase::WindowManager& parWindowManager)
void PickClassDialog::setNextButtonShow(bool shown) void PickClassDialog::setNextButtonShow(bool shown)
{ {
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
if (shown) if (shown)
@ -138,7 +138,7 @@ void PickClassDialog::setClassId(const std::string &classId)
if (boost::iequals(*mClassList->getItemDataAt<std::string>(i), classId)) if (boost::iequals(*mClassList->getItemDataAt<std::string>(i), classId))
{ {
mClassList->setIndexSelected(i); mClassList->setIndexSelected(i);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
break; break;
} }
@ -166,7 +166,7 @@ void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index)
if (_index == MyGUI::ITEM_NONE) if (_index == MyGUI::ITEM_NONE)
return; return;
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
const std::string *classId = mClassList->getItemDataAt<std::string>(_index); const std::string *classId = mClassList->getItemDataAt<std::string>(_index);
@ -256,7 +256,7 @@ void InfoBoxDialog::fitToText(MyGUI::TextBox* widget)
widget->setSize(size); widget->setSize(size);
} }
void InfoBoxDialog::layoutVertically(MyGUI::WidgetPtr widget, int margin) void InfoBoxDialog::layoutVertically(MyGUI::Widget* widget, int margin)
{ {
size_t count = widget->getChildCount(); size_t count = widget->getChildCount();
int pos = 0; int pos = 0;
@ -264,7 +264,7 @@ void InfoBoxDialog::layoutVertically(MyGUI::WidgetPtr widget, int margin)
int width = 0; int width = 0;
for (unsigned i = 0; i < count; ++i) for (unsigned i = 0; i < count; ++i)
{ {
MyGUI::WidgetPtr child = widget->getChildAt(i); MyGUI::Widget* child = widget->getChildAt(i);
if (!child->getVisible()) if (!child->getVisible())
continue; continue;
@ -302,7 +302,7 @@ std::string InfoBoxDialog::getText() const
void InfoBoxDialog::setButtons(ButtonList &buttons) void InfoBoxDialog::setButtons(ButtonList &buttons)
{ {
for (std::vector<MyGUI::ButtonPtr>::iterator it = this->mButtons.begin(); it != this->mButtons.end(); ++it) for (std::vector<MyGUI::Button*>::iterator it = this->mButtons.begin(); it != this->mButtons.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }
@ -310,7 +310,7 @@ void InfoBoxDialog::setButtons(ButtonList &buttons)
mCurrentButton = -1; mCurrentButton = -1;
// TODO: The buttons should be generated from a template in the layout file, ie. cloning an existing widget // TODO: The buttons should be generated from a template in the layout file, ie. cloning an existing widget
MyGUI::ButtonPtr button; MyGUI::Button* button;
MyGUI::IntCoord coord = MyGUI::IntCoord(0, 0, mButtonBar->getWidth(), 10); MyGUI::IntCoord coord = MyGUI::IntCoord(0, 0, mButtonBar->getWidth(), 10);
ButtonList::const_iterator end = buttons.end(); ButtonList::const_iterator end = buttons.end();
for (ButtonList::const_iterator it = buttons.begin(); it != end; ++it) for (ButtonList::const_iterator it = buttons.begin(); it != end; ++it)
@ -342,11 +342,11 @@ int InfoBoxDialog::getChosenButton() const
return mCurrentButton; return mCurrentButton;
} }
void InfoBoxDialog::onButtonClicked(MyGUI::WidgetPtr _sender) void InfoBoxDialog::onButtonClicked(MyGUI::Widget* _sender)
{ {
std::vector<MyGUI::ButtonPtr>::const_iterator end = mButtons.end(); std::vector<MyGUI::Button*>::const_iterator end = mButtons.end();
int i = 0; int i = 0;
for (std::vector<MyGUI::ButtonPtr>::const_iterator it = mButtons.begin(); it != end; ++it) for (std::vector<MyGUI::Button*>::const_iterator it = mButtons.begin(); it != end; ++it)
{ {
if (*it == _sender) if (*it == _sender)
{ {
@ -376,10 +376,10 @@ ClassChoiceDialog::ClassChoiceDialog(MWBase::WindowManager& parWindowManager)
CreateClassDialog::CreateClassDialog(MWBase::WindowManager& parWindowManager) CreateClassDialog::CreateClassDialog(MWBase::WindowManager& parWindowManager)
: WindowModal("openmw_chargen_create_class.layout", parWindowManager) : WindowModal("openmw_chargen_create_class.layout", parWindowManager)
, mSpecDialog(nullptr) , mSpecDialog(NULL)
, mAttribDialog(nullptr) , mAttribDialog(NULL)
, mSkillDialog(nullptr) , mSkillDialog(NULL)
, mDescDialog(nullptr) , mDescDialog(NULL)
{ {
// Centre dialog // Centre dialog
center(); center();
@ -420,15 +420,15 @@ CreateClassDialog::CreateClassDialog(MWBase::WindowManager& parWindowManager)
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName); MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName);
MyGUI::ButtonPtr descriptionButton; MyGUI::Button* descriptionButton;
getWidget(descriptionButton, "DescriptionButton"); getWidget(descriptionButton, "DescriptionButton");
descriptionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionClicked); descriptionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionClicked);
MyGUI::ButtonPtr backButton; MyGUI::Button* backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onBackClicked); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onBackClicked);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onOkClicked);
@ -518,7 +518,7 @@ std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMinorSkills() const
void CreateClassDialog::setNextButtonShow(bool shown) void CreateClassDialog::setNextButtonShow(bool shown)
{ {
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
if (shown) if (shown)
@ -544,7 +544,7 @@ void CreateClassDialog::onDialogCancel()
mDescDialog = 0; mDescDialog = 0;
} }
void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) void CreateClassDialog::onSpecializationClicked(MyGUI::Widget* _sender)
{ {
delete mSpecDialog; delete mSpecDialog;
mSpecDialog = new SelectSpecializationDialog(mWindowManager); mSpecDialog = new SelectSpecializationDialog(mWindowManager);
@ -694,7 +694,7 @@ SelectSpecializationDialog::SelectSpecializationDialog(MWBase::WindowManager& pa
ToolTips::createSpecializationToolTip(mSpecialization1, magic, ESM::Class::Magic); ToolTips::createSpecializationToolTip(mSpecialization1, magic, ESM::Class::Magic);
ToolTips::createSpecializationToolTip(mSpecialization2, stealth, ESM::Class::Stealth); ToolTips::createSpecializationToolTip(mSpecialization2, stealth, ESM::Class::Stealth);
MyGUI::ButtonPtr cancelButton; MyGUI::Button* cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked);
@ -706,7 +706,7 @@ SelectSpecializationDialog::~SelectSpecializationDialog()
// widget controls // widget controls
void SelectSpecializationDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) void SelectSpecializationDialog::onSpecializationClicked(MyGUI::Widget* _sender)
{ {
if (_sender == mSpecialization0) if (_sender == mSpecialization0)
mSpecializationId = ESM::Class::Combat; mSpecializationId = ESM::Class::Combat;
@ -747,7 +747,7 @@ SelectAttributeDialog::SelectAttributeDialog(MWBase::WindowManager& parWindowMan
ToolTips::createAttributeToolTip(attribute, attribute->getAttributeId()); ToolTips::createAttributeToolTip(attribute, attribute->getAttributeId());
} }
MyGUI::ButtonPtr cancelButton; MyGUI::Button* cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked);
@ -840,7 +840,7 @@ SelectSkillDialog::SelectSkillDialog(MWBase::WindowManager& parWindowManager)
} }
} }
MyGUI::ButtonPtr cancelButton; MyGUI::Button* cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked);
@ -873,7 +873,7 @@ DescriptionDialog::DescriptionDialog(MWBase::WindowManager& parWindowManager)
getWidget(mTextEdit, "TextEdit"); getWidget(mTextEdit, "TextEdit");
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked);
okButton->setCaption(mWindowManager.getGameSettingString("sInputMenu1", "")); okButton->setCaption(mWindowManager.getGameSettingString("sInputMenu1", ""));

View file

@ -1,7 +1,7 @@
#ifndef MWGUI_CLASS_H #ifndef MWGUI_CLASS_H
#define MWGUI_CLASS_H #define MWGUI_CLASS_H
#include <MyGUI.h>
#include "widgets.hpp" #include "widgets.hpp"
#include "window_base.hpp" #include "window_base.hpp"
@ -35,17 +35,17 @@ namespace MWGui
EventHandle_Int eventButtonSelected; EventHandle_Int eventButtonSelected;
protected: protected:
void onButtonClicked(MyGUI::WidgetPtr _sender); void onButtonClicked(MyGUI::Widget* _sender);
private: private:
void fitToText(MyGUI::TextBox* widget); void fitToText(MyGUI::TextBox* widget);
void layoutVertically(MyGUI::WidgetPtr widget, int margin); void layoutVertically(MyGUI::Widget* widget, int margin);
int mCurrentButton; int mCurrentButton;
MyGUI::WidgetPtr mTextBox; MyGUI::Widget* mTextBox;
MyGUI::TextBox* mText; MyGUI::TextBox* mText;
MyGUI::WidgetPtr mButtonBar; MyGUI::Widget* mButtonBar;
std::vector<MyGUI::ButtonPtr> mButtons; std::vector<MyGUI::Button*> mButtons;
}; };
// Lets the player choose between 3 ways of creating a class // Lets the player choose between 3 ways of creating a class
@ -235,7 +235,7 @@ namespace MWGui
void onOkClicked(MyGUI::Widget* _sender); void onOkClicked(MyGUI::Widget* _sender);
private: private:
MyGUI::EditPtr mTextEdit; MyGUI::EditBox* mTextEdit;
}; };
class CreateClassDialog : public WindowModal class CreateClassDialog : public WindowModal
@ -265,7 +265,7 @@ namespace MWGui
void onOkClicked(MyGUI::Widget* _sender); void onOkClicked(MyGUI::Widget* _sender);
void onBackClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender);
void onSpecializationClicked(MyGUI::WidgetPtr _sender); void onSpecializationClicked(MyGUI::Widget* _sender);
void onSpecializationSelected(); void onSpecializationSelected();
void onAttributeClicked(Widgets::MWAttributePtr _sender); void onAttributeClicked(Widgets::MWAttributePtr _sender);
void onAttributeSelected(); void onAttributeSelected();
@ -280,7 +280,7 @@ namespace MWGui
void update(); void update();
private: private:
MyGUI::EditPtr mEditName; MyGUI::EditBox* mEditName;
MyGUI::TextBox* mSpecializationName; MyGUI::TextBox* mSpecializationName;
Widgets::MWAttributePtr mFavoriteAttribute0, mFavoriteAttribute1; Widgets::MWAttributePtr mFavoriteAttribute0, mFavoriteAttribute1;
Widgets::MWSkillPtr mMajorSkill[5]; Widgets::MWSkillPtr mMajorSkill[5];

View file

@ -216,7 +216,7 @@ namespace MWGui
} }
} }
void Console::keyPress(MyGUI::WidgetPtr _sender, void Console::keyPress(MyGUI::Widget* _sender,
MyGUI::KeyCode key, MyGUI::KeyCode key,
MyGUI::Char _char) MyGUI::Char _char)
{ {
@ -266,7 +266,7 @@ namespace MWGui
} }
} }
void Console::acceptCommand(MyGUI::EditPtr _sender) void Console::acceptCommand(MyGUI::EditBox* _sender)
{ {
const std::string &cm = command->getCaption(); const std::string &cm = command->getCaption();
if(cm.empty()) return; if(cm.empty()) return;

View file

@ -55,8 +55,8 @@ namespace MWGui
public: public:
MyGUI::EditPtr command; MyGUI::EditBox* command;
MyGUI::EditPtr history; MyGUI::EditBox* history;
typedef std::list<std::string> StringList; typedef std::list<std::string> StringList;
@ -95,11 +95,11 @@ namespace MWGui
private: private:
void keyPress(MyGUI::WidgetPtr _sender, void keyPress(MyGUI::Widget* _sender,
MyGUI::KeyCode key, MyGUI::KeyCode key,
MyGUI::Char _char); MyGUI::Char _char);
void acceptCommand(MyGUI::EditPtr _sender); void acceptCommand(MyGUI::EditBox* _sender);
std::string complete( std::string input, std::vector<std::string> &matches ); std::string complete( std::string input, std::vector<std::string> &matches );
}; };

View file

@ -14,7 +14,7 @@ namespace MWGui
ResourceImageSetPointerFix::ResourceImageSetPointerFix() : ResourceImageSetPointerFix::ResourceImageSetPointerFix() :
mImageSet(nullptr) mImageSet(NULL)
{ {
} }
@ -50,7 +50,7 @@ namespace MWGui
void ResourceImageSetPointerFix::setImage(MyGUI::ImageBox* _image) void ResourceImageSetPointerFix::setImage(MyGUI::ImageBox* _image)
{ {
if (mImageSet != nullptr) if (mImageSet != NULL)
_image->setItemResourceInfo(mImageSet->getIndexInfo(0, 0)); _image->setItemResourceInfo(mImageSet->getIndexInfo(0, 0));
} }

View file

@ -151,7 +151,7 @@ DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager)
getWidget(mTopicsList, "TopicsList"); getWidget(mTopicsList, "TopicsList");
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
MyGUI::ButtonPtr byeButton; MyGUI::Button* byeButton;
getWidget(byeButton, "ByeButton"); getWidget(byeButton, "ByeButton");
byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
@ -164,7 +164,7 @@ DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager)
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
{ {
MyGUI::ISubWidgetText* t = mHistory->getClient()->getSubWidgetText(); MyGUI::ISubWidgetText* t = mHistory->getClient()->getSubWidgetText();
if(t == nullptr) if(t == NULL)
return; return;
const MyGUI::IntPoint& lastPressed = MyGUI::InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left); const MyGUI::IntPoint& lastPressed = MyGUI::InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left);
@ -381,7 +381,7 @@ std::string DialogueWindow::parseText(const std::string& text)
std::vector<MWDialogue::HyperTextToken> hypertext = MWDialogue::ParseHyperText(text); std::vector<MWDialogue::HyperTextToken> hypertext = MWDialogue::ParseHyperText(text);
size_t historySize = 0; size_t historySize = 0;
if(mHistory->getClient()->getSubWidgetText() != nullptr) if(mHistory->getClient()->getSubWidgetText() != NULL)
{ {
historySize = mHistory->getOnlyText().size(); historySize = mHistory->getOnlyText().size();
} }

View file

@ -113,7 +113,7 @@ namespace MWGui
DialogueHistory* mHistory; DialogueHistory* mHistory;
Widgets::MWList* mTopicsList; Widgets::MWList* mTopicsList;
MyGUI::ProgressPtr mDispositionBar; MyGUI::ProgressPtr mDispositionBar;
MyGUI::EditPtr mDispositionText; MyGUI::EditBox* mDispositionText;
PersuasionDialog mPersuasionDialog; PersuasionDialog mPersuasionDialog;

View file

@ -1,7 +1,5 @@
#include "exposedwindow.hpp" #include "exposedwindow.hpp"
#include "MyGUI_Window.h"
namespace MWGui namespace MWGui
{ {
MyGUI::VectorWidgetPtr ExposedWindow::getSkinWidgetsByName (const std::string &name) MyGUI::VectorWidgetPtr ExposedWindow::getSkinWidgetsByName (const std::string &name)
@ -16,7 +14,7 @@ namespace MWGui
if (widgets.empty()) if (widgets.empty())
{ {
MYGUI_ASSERT( ! _throw, "widget name '" << _name << "' not found in skin of layout '" << getName() << "'"); MYGUI_ASSERT( ! _throw, "widget name '" << _name << "' not found in skin of layout '" << getName() << "'");
return nullptr; return NULL;
} }
else else
{ {

View file

@ -1,7 +1,7 @@
#ifndef MWGUI_EXPOSEDWINDOW_H #ifndef MWGUI_EXPOSEDWINDOW_H
#define MWGUI_EXPOSEDWINDOW_H #define MWGUI_EXPOSEDWINDOW_H
#include "MyGUI_Window.h" #include <MyGUI_Window.h>
namespace MWGui namespace MWGui
{ {

View file

@ -2,7 +2,9 @@
#include <cmath> #include <cmath>
#include <MyGUI.h> #include <MyGUI_Widget.h>
#include <MyGUI_RenderManager.h>
#include <MyGUI_PointerManager.h>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -19,6 +21,7 @@
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "container.hpp" #include "container.hpp"
#include "console.hpp" #include "console.hpp"
#include "spellicons.hpp"
using namespace MWGui; using namespace MWGui;
@ -32,7 +35,6 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
, mWeapStatus(NULL) , mWeapStatus(NULL)
, mSpellStatus(NULL) , mSpellStatus(NULL)
, mEffectBox(NULL) , mEffectBox(NULL)
, mEffect1(NULL)
, mMinimap(NULL) , mMinimap(NULL)
, mCompass(NULL) , mCompass(NULL)
, mCrosshair(NULL) , mCrosshair(NULL)
@ -86,9 +88,7 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
mSpellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); mSpellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
getWidget(mEffectBox, "EffectBox"); getWidget(mEffectBox, "EffectBox");
getWidget(mEffect1, "Effect1");
mEffectBoxBaseRight = viewSize.width - mEffectBox->getRight(); mEffectBoxBaseRight = viewSize.width - mEffectBox->getRight();
mEffectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
getWidget(mMinimapBox, "MiniMapBox"); getWidget(mMinimapBox, "MiniMapBox");
mMinimapBoxBaseRight = viewSize.width - mMinimapBox->getRight(); mMinimapBoxBaseRight = viewSize.width - mMinimapBox->getRight();
@ -107,13 +107,18 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
getWidget(mTriangleCounter, "TriangleCounter"); getWidget(mTriangleCounter, "TriangleCounter");
getWidget(mBatchCounter, "BatchCounter"); getWidget(mBatchCounter, "BatchCounter");
setEffect("icons\\s\\tx_s_chameleon.dds");
LocalMapBase::init(mMinimap, mCompass, this); LocalMapBase::init(mMinimap, mCompass, this);
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked); mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver); mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus); mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus);
mSpellIcons = new SpellIcons();
}
HUD::~HUD()
{
delete mSpellIcons;
} }
void HUD::setFpsLevel(int level) void HUD::setFpsLevel(int level)
@ -156,11 +161,6 @@ void HUD::setBatchCount(unsigned int count)
mBatchCounter->setCaption(boost::lexical_cast<std::string>(count)); mBatchCounter->setCaption(boost::lexical_cast<std::string>(count));
} }
void HUD::setEffect(const char *img)
{
mEffect1->setImageTexture(img);
}
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value) void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
{ {
static const char *ids[] = static const char *ids[] =
@ -542,3 +542,8 @@ void HUD::updatePositions()
mMapVisible = mMinimapBox->getVisible (); mMapVisible = mMinimapBox->getVisible ();
mEffectBox->setPosition((viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop()); mEffectBox->setPosition((viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop());
} }
void HUD::update()
{
mSpellIcons->updateWidgets(mEffectBox, true);
}

View file

@ -8,12 +8,13 @@
namespace MWGui namespace MWGui
{ {
class DragAndDrop; class DragAndDrop;
class SpellIcons;
class HUD : public OEngine::GUI::Layout, public LocalMapBase class HUD : public OEngine::GUI::Layout, public LocalMapBase
{ {
public: public:
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop); HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
void setEffect(const char *img); virtual ~HUD();
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value); void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
void setFPS(float fps); void setFPS(float fps);
void setTriangleCount(unsigned int count); void setTriangleCount(unsigned int count);
@ -43,6 +44,10 @@ namespace MWGui
bool getWorldMouseOver() { return mWorldMouseOver; } bool getWorldMouseOver() { return mWorldMouseOver; }
MyGUI::Widget* getEffectBox() { return mEffectBox; }
void update();
private: private:
MyGUI::ProgressPtr mHealth, mMagicka, mStamina; MyGUI::ProgressPtr mHealth, mMagicka, mStamina;
MyGUI::Widget* mHealthFrame; MyGUI::Widget* mHealthFrame;
@ -51,7 +56,6 @@ namespace MWGui
MyGUI::ProgressPtr mWeapStatus, mSpellStatus; MyGUI::ProgressPtr mWeapStatus, mSpellStatus;
MyGUI::Widget *mEffectBox, *mMinimapBox; MyGUI::Widget *mEffectBox, *mMinimapBox;
MyGUI::Button* mMinimapButton; MyGUI::Button* mMinimapButton;
MyGUI::ImageBox* mEffect1;
MyGUI::ScrollView* mMinimap; MyGUI::ScrollView* mMinimap;
MyGUI::ImageBox* mCompass; MyGUI::ImageBox* mCompass;
MyGUI::ImageBox* mCrosshair; MyGUI::ImageBox* mCrosshair;
@ -60,7 +64,7 @@ namespace MWGui
MyGUI::Widget* mDummy; MyGUI::Widget* mDummy;
MyGUI::WidgetPtr mFpsBox; MyGUI::Widget* mFpsBox;
MyGUI::TextBox* mFpsCounter; MyGUI::TextBox* mFpsCounter;
MyGUI::TextBox* mTriangleCounter; MyGUI::TextBox* mTriangleCounter;
MyGUI::TextBox* mBatchCounter; MyGUI::TextBox* mBatchCounter;
@ -85,6 +89,8 @@ namespace MWGui
bool mWorldMouseOver; bool mWorldMouseOver;
SpellIcons* mSpellIcons;
void onWorldClicked(MyGUI::Widget* _sender); void onWorldClicked(MyGUI::Widget* _sender);
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y); void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new); void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new);

View file

@ -1,7 +1,7 @@
#ifndef MWGUI_IMAGEBUTTON_H #ifndef MWGUI_IMAGEBUTTON_H
#define MWGUI_IMAGEBUTTON_H #define MWGUI_IMAGEBUTTON_H
#include "MyGUI_ImageBox.h" #include <MyGUI_ImageBox.h>
namespace MWGui namespace MWGui
{ {

View file

@ -160,11 +160,8 @@ namespace MWGui
// the "Take" button should not be visible. // the "Take" button should not be visible.
// NOTE: the take button is "reset" when the window opens, so we can safely do the following // NOTE: the take button is "reset" when the window opens, so we can safely do the following
// without screwing up future book windows // without screwing up future book windows
if (mDragAndDrop->mDraggedFrom == this) mWindowManager.getBookWindow()->setTakeButtonShow(false);
{ mWindowManager.getScrollWindow()->setTakeButtonShow(false);
mWindowManager.getBookWindow()->setTakeButtonShow(false);
mWindowManager.getScrollWindow()->setTakeButtonShow(false);
}
mDragAndDrop->mIsOnDragAndDrop = false; mDragAndDrop->mIsOnDragAndDrop = false;
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget); MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);

View file

@ -29,8 +29,8 @@ namespace MWGui
void notifyNextPage(MyGUI::Widget* _sender); void notifyNextPage(MyGUI::Widget* _sender);
void notifyPrevPage(MyGUI::Widget* _sender); void notifyPrevPage(MyGUI::Widget* _sender);
MyGUI::EditPtr mLeftTextWidget; MyGUI::EditBox* mLeftTextWidget;
MyGUI::EditPtr mRightTextWidget; MyGUI::EditBox* mRightTextWidget;
MWGui::ImageButton* mPrevBtn; MWGui::ImageButton* mPrevBtn;
MWGui::ImageButton* mNextBtn; MWGui::ImageButton* mNextBtn;
std::vector<std::string> mLeftPages; std::vector<std::string> mLeftPages;

View file

@ -1,6 +1,9 @@
#include "list.hpp" #include "list.hpp"
#include <MyGUI.h> #include <MyGUI_ScrollView.h>
#include <MyGUI_Gui.h>
#include <MyGUI_Button.h>
#include <MyGUI_ImageBox.h>
using namespace MWGui; using namespace MWGui;
using namespace MWGui::Widgets; using namespace MWGui::Widgets;

View file

@ -1,7 +1,12 @@
#ifndef MWGUI_LIST_HPP #ifndef MWGUI_LIST_HPP
#define MWGUI_LIST_HPP #define MWGUI_LIST_HPP
#include <MyGUI.h> #include <MyGUI_Widget.h>
namespace MyGUI
{
class ScrollView;
}
namespace MWGui namespace MWGui
{ {

View file

@ -19,6 +19,8 @@ namespace MWGui
void onResChange(int w, int h); void onResChange(int w, int h);
void updateWindow(Ogre::RenderWindow* rw) { mWindow = rw; }
private: private:
bool mFirstLoad; bool mFirstLoad;

View file

@ -247,7 +247,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
std::vector<std::string>::const_iterator it; std::vector<std::string>::const_iterator it;
for(it = buttons.begin(); it != buttons.end(); ++it) for(it = buttons.begin(); it != buttons.end(); ++it)
{ {
MyGUI::ButtonPtr button = mButtonsWidget->createWidget<MyGUI::Button>( MyGUI::Button* button = mButtonsWidget->createWidget<MyGUI::Button>(
MyGUI::WidgetStyle::Child, MyGUI::WidgetStyle::Child,
std::string("MW_Button"), std::string("MW_Button"),
dummyCoord, dummyCoord,
@ -301,7 +301,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
MyGUI::IntSize buttonSize(0, buttonHeight); MyGUI::IntSize buttonSize(0, buttonHeight);
int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding; int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding;
std::vector<MyGUI::ButtonPtr>::const_iterator button; std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button) for(button = mButtons.begin(); button != mButtons.end(); ++button)
{ {
buttonCord.left = left; buttonCord.left = left;
@ -349,7 +349,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
int top = textButtonPadding + buttonTopPadding + textSize.height; int top = textButtonPadding + buttonTopPadding + textSize.height;
std::vector<MyGUI::ButtonPtr>::const_iterator button; std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button) for(button = mButtons.begin(); button != mButtons.end(); ++button)
{ {
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2; buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
@ -371,7 +371,7 @@ void InteractiveMessageBox::enterPressed()
{ {
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}")); std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
std::vector<MyGUI::ButtonPtr>::const_iterator button; std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button) for(button = mButtons.begin(); button != mButtons.end(); ++button)
{ {
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok) if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
@ -393,7 +393,7 @@ void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
{ {
mMarkedToDelete = true; mMarkedToDelete = true;
int index = 0; int index = 0;
std::vector<MyGUI::ButtonPtr>::const_iterator button; std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button) for(button = mButtons.begin(); button != mButtons.end(); ++button)
{ {
if(*button == pressed) if(*button == pressed)

View file

@ -2,7 +2,6 @@
#define MWGUI_MESSAGE_BOX_H #define MWGUI_MESSAGE_BOX_H
#include <openengine/gui/layout.hpp> #include <openengine/gui/layout.hpp>
#include <MyGUI.h>
#include "window_base.hpp" #include "window_base.hpp"
@ -10,6 +9,13 @@
#undef MessageBox #undef MessageBox
namespace MyGUI
{
class Widget;
class Button;
class EditBox;
}
namespace MWGui namespace MWGui
{ {
class InteractiveMessageBox; class InteractiveMessageBox;
@ -61,7 +67,7 @@ namespace MWGui
MessageBoxManager& mMessageBoxManager; MessageBoxManager& mMessageBoxManager;
int mHeight; int mHeight;
const std::string& mMessage; const std::string& mMessage;
MyGUI::EditPtr mMessageWidget; MyGUI::EditBox* mMessageWidget;
int mFixedWidth; int mFixedWidth;
int mBottomPadding; int mBottomPadding;
int mNextBoxPadding; int mNextBoxPadding;
@ -81,9 +87,9 @@ namespace MWGui
void buttonActivated (MyGUI::Widget* _widget); void buttonActivated (MyGUI::Widget* _widget);
MessageBoxManager& mMessageBoxManager; MessageBoxManager& mMessageBoxManager;
MyGUI::EditPtr mMessageWidget; MyGUI::EditBox* mMessageWidget;
MyGUI::WidgetPtr mButtonsWidget; MyGUI::Widget* mButtonsWidget;
std::vector<MyGUI::ButtonPtr> mButtons; std::vector<MyGUI::Button*> mButtons;
int mTextButtonPadding; int mTextButtonPadding;
int mButtonPressed; int mButtonPressed;

View file

@ -41,7 +41,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate); mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate);
// Set up next/previous buttons // Set up next/previous buttons
MyGUI::ButtonPtr prevButton, nextButton; MyGUI::Button *prevButton, *nextButton;
setText("GenderChoiceT", mWindowManager.getGameSettingString("sRaceMenu2", "Change Sex")); setText("GenderChoiceT", mWindowManager.getGameSettingString("sRaceMenu2", "Change Sex"));
getWidget(prevButton, "PrevGenderButton"); getWidget(prevButton, "PrevGenderButton");
@ -73,11 +73,11 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
setText("SpellPowerT", mWindowManager.getGameSettingString("sRaceMenu7", "Specials")); setText("SpellPowerT", mWindowManager.getGameSettingString("sRaceMenu7", "Specials"));
getWidget(mSpellPowerList, "SpellPowerList"); getWidget(mSpellPowerList, "SpellPowerList");
MyGUI::ButtonPtr backButton; MyGUI::Button* backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked);
@ -89,7 +89,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
void RaceDialog::setNextButtonShow(bool shown) void RaceDialog::setNextButtonShow(bool shown)
{ {
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
if (shown) if (shown)
@ -134,7 +134,7 @@ void RaceDialog::setRaceId(const std::string &raceId)
if (boost::iequals(*mRaceList->getItemDataAt<std::string>(i), raceId)) if (boost::iequals(*mRaceList->getItemDataAt<std::string>(i), raceId))
{ {
mRaceList->setIndexSelected(i); mRaceList->setIndexSelected(i);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
break; break;
} }
@ -256,7 +256,7 @@ void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
if (_index == MyGUI::ITEM_NONE) if (_index == MyGUI::ITEM_NONE)
return; return;
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
const std::string *raceId = mRaceList->getItemDataAt<std::string>(_index); const std::string *raceId = mRaceList->getItemDataAt<std::string>(_index);
if (boost::iequals(mCurrentRaceId, *raceId)) if (boost::iequals(mCurrentRaceId, *raceId))
@ -331,7 +331,7 @@ void RaceDialog::updateRaces()
void RaceDialog::updateSkills() void RaceDialog::updateSkills()
{ {
for (std::vector<MyGUI::WidgetPtr>::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it) for (std::vector<MyGUI::Widget*>::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }
@ -369,7 +369,7 @@ void RaceDialog::updateSkills()
void RaceDialog::updateSpellPowers() void RaceDialog::updateSpellPowers()
{ {
for (std::vector<MyGUI::WidgetPtr>::iterator it = mSpellPowerItems.begin(); it != mSpellPowerItems.end(); ++it) for (std::vector<MyGUI::Widget*>::iterator it = mSpellPowerItems.begin(); it != mSpellPowerItems.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }

View file

@ -85,11 +85,11 @@ namespace MWGui
MyGUI::ListBox* mRaceList; MyGUI::ListBox* mRaceList;
MyGUI::ScrollBar* mHeadRotate; MyGUI::ScrollBar* mHeadRotate;
MyGUI::WidgetPtr mSkillList; MyGUI::Widget* mSkillList;
std::vector<MyGUI::WidgetPtr> mSkillItems; std::vector<MyGUI::Widget*> mSkillItems;
MyGUI::WidgetPtr mSpellPowerList; MyGUI::Widget* mSpellPowerList;
std::vector<MyGUI::WidgetPtr> mSpellPowerItems; std::vector<MyGUI::Widget*> mSpellPowerItems;
int mGenderIndex, mFaceIndex, mHairIndex; int mGenderIndex, mFaceIndex, mHairIndex;
int mFaceCount, mHairCount; int mFaceCount, mHairCount;

View file

@ -86,11 +86,11 @@ ReviewDialog::ReviewDialog(MWBase::WindowManager& parWindowManager)
mSkillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0))); mSkillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0)));
} }
MyGUI::ButtonPtr backButton; MyGUI::Button* backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
} }
@ -309,7 +309,7 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId
void ReviewDialog::updateSkillArea() void ReviewDialog::updateSkillArea()
{ {
for (std::vector<MyGUI::WidgetPtr>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it) for (std::vector<MyGUI::Widget*>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }

View file

@ -91,7 +91,7 @@ namespace MWGui
std::map<int, MyGUI::TextBox*> mSkillWidgetMap; std::map<int, MyGUI::TextBox*> mSkillWidgetMap;
std::string mName, mRaceId, mBirthSignId; std::string mName, mRaceId, mBirthSignId;
ESM::Class mKlass; ESM::Class mKlass;
std::vector<MyGUI::WidgetPtr> mSkillWidgets; //< Skills and other information std::vector<MyGUI::Widget*> mSkillWidgets; //< Skills and other information
}; };
} }
#endif #endif

View file

@ -2,6 +2,7 @@
#include <OgreRoot.h> #include <OgreRoot.h>
#include <OgreRenderSystem.h> #include <OgreRenderSystem.h>
#include <OgrePlugin.h>
#include <OgreString.h> #include <OgreString.h>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -77,6 +78,17 @@ namespace
{ {
return (Ogre::Root::getSingleton ().getRenderSystem ()->getName ().find("OpenGL") != std::string::npos) ? "glsl" : "hlsl"; return (Ogre::Root::getSingleton ().getRenderSystem ()->getName ().find("OpenGL") != std::string::npos) ? "glsl" : "hlsl";
} }
bool cgAvailable ()
{
Ogre::Root::PluginInstanceList list = Ogre::Root::getSingleton ().getInstalledPlugins ();
for (Ogre::Root::PluginInstanceList::const_iterator it = list.begin(); it != list.end(); ++it)
{
if ((*it)->getName() == "Cg Program Manager")
return true;
}
return false;
}
} }
namespace MWGui namespace MWGui
@ -109,6 +121,7 @@ namespace MWGui
getWidget(mReflectActorsButton, "ReflectActorsButton"); getWidget(mReflectActorsButton, "ReflectActorsButton");
getWidget(mReflectTerrainButton, "ReflectTerrainButton"); getWidget(mReflectTerrainButton, "ReflectTerrainButton");
getWidget(mShadersButton, "ShadersButton"); getWidget(mShadersButton, "ShadersButton");
getWidget(mShaderModeButton, "ShaderModeButton");
getWidget(mShadowsEnabledButton, "ShadowsEnabledButton"); getWidget(mShadowsEnabledButton, "ShadowsEnabledButton");
getWidget(mShadowsLargeDistance, "ShadowsLargeDistance"); getWidget(mShadowsLargeDistance, "ShadowsLargeDistance");
getWidget(mShadowsTextureSize, "ShadowsTextureSize"); getWidget(mShadowsTextureSize, "ShadowsTextureSize");
@ -116,22 +129,22 @@ namespace MWGui
getWidget(mStaticsShadows, "StaticsShadows"); getWidget(mStaticsShadows, "StaticsShadows");
getWidget(mMiscShadows, "MiscShadows"); getWidget(mMiscShadows, "MiscShadows");
getWidget(mShadowsDebug, "ShadowsDebug"); getWidget(mShadowsDebug, "ShadowsDebug");
getWidget(mUnderwaterButton, "UnderwaterButton");
getWidget(mControlsBox, "ControlsBox"); getWidget(mControlsBox, "ControlsBox");
getWidget(mResetControlsButton, "ResetControlsButton"); getWidget(mResetControlsButton, "ResetControlsButton");
getWidget(mInvertYButton, "InvertYButton"); getWidget(mInvertYButton, "InvertYButton");
getWidget(mUISensitivitySlider, "UISensitivitySlider"); getWidget(mUISensitivitySlider, "UISensitivitySlider");
getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider"); getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider");
getWidget(mGammaSlider, "GammaSlider"); getWidget(mRefractionButton, "RefractionButton");
mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mInvertYButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mInvertYButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked);
mUnderwaterButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled); mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled);
mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled);
mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mRefractionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mReflectTerrainButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectTerrainButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mReflectActorsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectActorsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
@ -144,7 +157,6 @@ namespace MWGui
mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected); mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
mGammaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
@ -202,14 +214,6 @@ namespace MWGui
getWidget(fovText, "FovText"); getWidget(fovText, "FovText");
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getFloat("field of view", "General"))) + ")"); fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getFloat("field of view", "General"))) + ")");
float gammaVal = (Settings::Manager::getFloat("gamma", "Video")-0.1f)/(3.f-0.1f);
mGammaSlider->setScrollPosition(gammaVal * (mGammaSlider->getScrollRange()-1));
MyGUI::TextBox* gammaText;
getWidget(gammaText, "GammaText");
std::stringstream gamma;
gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video");
gammaText->setCaption("Gamma (" + gamma.str() + ")");
float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0; float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0;
mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1)); mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1));
std::string tf = Settings::Manager::getString("texture filtering", "General"); std::string tf = Settings::Manager::getString("texture filtering", "General");
@ -230,10 +234,12 @@ namespace MWGui
mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect statics", "Water") ? "#{sOn}" : "#{sOff}"); mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect statics", "Water") ? "#{sOn}" : "#{sOff}");
mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}"); mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}");
mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}"); mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}");
mUnderwaterButton->setCaptionWithReplacing(Settings::Manager::getBool("underwater effect", "Water") ? "#{sOn}" : "#{sOff}");
mShadowsTextureSize->setCaption (Settings::Manager::getString ("texture size", "Shadows")); mShadowsTextureSize->setCaption (Settings::Manager::getString ("texture size", "Shadows"));
mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}"); //mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}");
mShadowsLargeDistance->setCaptionWithReplacing("#{sOff}");
mShadowsLargeDistance->setEnabled (false);
mShadowsEnabledButton->setCaptionWithReplacing(Settings::Manager::getBool("enabled", "Shadows") ? "#{sOn}" : "#{sOff}"); mShadowsEnabledButton->setCaptionWithReplacing(Settings::Manager::getBool("enabled", "Shadows") ? "#{sOn}" : "#{sOff}");
mActorShadows->setCaptionWithReplacing(Settings::Manager::getBool("actor shadows", "Shadows") ? "#{sOn}" : "#{sOff}"); mActorShadows->setCaptionWithReplacing(Settings::Manager::getBool("actor shadows", "Shadows") ? "#{sOn}" : "#{sOff}");
mStaticsShadows->setCaptionWithReplacing(Settings::Manager::getBool("statics shadows", "Shadows") ? "#{sOn}" : "#{sOff}"); mStaticsShadows->setCaptionWithReplacing(Settings::Manager::getBool("statics shadows", "Shadows") ? "#{sOn}" : "#{sOff}");
@ -250,26 +256,14 @@ namespace MWGui
mInvertYButton->setCaptionWithReplacing(Settings::Manager::getBool("invert y axis", "Input") ? "#{sOn}" : "#{sOff}"); mInvertYButton->setCaptionWithReplacing(Settings::Manager::getBool("invert y axis", "Input") ? "#{sOn}" : "#{sOff}");
std::string shaders; mShadersButton->setCaptionWithReplacing (Settings::Manager::getBool("shaders", "Objects") ? "#{sOn}" : "#{sOff}");
mShaderModeButton->setCaption (Settings::Manager::getString("shader mode", "General"));
mRefractionButton->setCaptionWithReplacing (Settings::Manager::getBool("refraction", "Water") ? "#{sOn}" : "#{sOff}");
if (!Settings::Manager::getBool("shaders", "Objects")) if (!Settings::Manager::getBool("shaders", "Objects"))
shaders = "off";
else
{ {
shaders = Settings::Manager::getString("shader mode", "General"); mRefractionButton->setEnabled(false);
}
mShadersButton->setCaption (shaders);
if (!MWRender::RenderingManager::waterShaderSupported())
{
mWaterShaderButton->setEnabled(false);
mReflectObjectsButton->setEnabled(false);
mReflectActorsButton->setEnabled(false);
mReflectTerrainButton->setEnabled(false);
}
if (shaders == "off")
{
mUnderwaterButton->setEnabled (false);
mShadowsEnabledButton->setEnabled(false); mShadowsEnabledButton->setEnabled(false);
} }
@ -385,12 +379,12 @@ namespace MWGui
} }
else else
{ {
if (_sender == mVSyncButton)
Settings::Manager::setBool("vsync", "Video", newState);
if (_sender == mWaterShaderButton) if (_sender == mWaterShaderButton)
Settings::Manager::setBool("shader", "Water", newState); Settings::Manager::setBool("shader", "Water", newState);
else if (_sender == mUnderwaterButton) else if (_sender == mRefractionButton)
{ Settings::Manager::setBool("refraction", "Water", newState);
Settings::Manager::setBool("underwater effect", "Water", newState);
}
else if (_sender == mReflectObjectsButton) else if (_sender == mReflectObjectsButton)
{ {
Settings::Manager::setBool("reflect misc", "Water", newState); Settings::Manager::setBool("reflect misc", "Water", newState);
@ -424,33 +418,44 @@ namespace MWGui
} }
} }
void SettingsWindow::onShadersToggled(MyGUI::Widget* _sender) void SettingsWindow::onShaderModeToggled(MyGUI::Widget* _sender)
{ {
std::string val = static_cast<MyGUI::Button*>(_sender)->getCaption(); std::string val = static_cast<MyGUI::Button*>(_sender)->getCaption();
if (val == "off") if (val == "cg")
{ {
val = hlslGlsl(); val = hlslGlsl();
} }
else if (val == hlslGlsl()) else if (cgAvailable ())
val = "cg"; val = "cg";
else
val = "off";
static_cast<MyGUI::Button*>(_sender)->setCaption(val); static_cast<MyGUI::Button*>(_sender)->setCaption(val);
if (val == "off") Settings::Manager::setString("shader mode", "General", val);
apply();
}
void SettingsWindow::onShadersToggled(MyGUI::Widget* _sender)
{
std::string on = mWindowManager.getGameSettingString("sOn", "On");
std::string off = mWindowManager.getGameSettingString("sOff", "On");
std::string val = static_cast<MyGUI::Button*>(_sender)->getCaption();
if (val == off)
val = on;
else
val = off;
static_cast<MyGUI::Button*>(_sender)->setCaptionWithReplacing (val);
if (val == off)
{ {
Settings::Manager::setBool("shaders", "Objects", false); Settings::Manager::setBool("shaders", "Objects", false);
// water shader not supported with object shaders off // refraction needs shaders to display underwater fog
mWaterShaderButton->setCaptionWithReplacing("#{sOff}"); mRefractionButton->setCaptionWithReplacing("#{sOff}");
mUnderwaterButton->setCaptionWithReplacing("#{sOff}"); mRefractionButton->setEnabled(false);
mWaterShaderButton->setEnabled(false);
mReflectObjectsButton->setEnabled(false); Settings::Manager::setBool("refraction", "Water", false);
mReflectActorsButton->setEnabled(false);
mReflectTerrainButton->setEnabled(false);
mUnderwaterButton->setEnabled(false);
Settings::Manager::setBool("shader", "Water", false);
Settings::Manager::setBool("underwater effect", "Water", false); Settings::Manager::setBool("underwater effect", "Water", false);
// shadows not supported // shadows not supported
@ -461,17 +466,13 @@ namespace MWGui
else else
{ {
Settings::Manager::setBool("shaders", "Objects", true); Settings::Manager::setBool("shaders", "Objects", true);
Settings::Manager::setString("shader mode", "General", val);
// re-enable // re-enable
if (MWRender::RenderingManager::waterShaderSupported()) mReflectObjectsButton->setEnabled(true);
{ mReflectActorsButton->setEnabled(true);
mWaterShaderButton->setEnabled(true); mReflectTerrainButton->setEnabled(true);
mReflectObjectsButton->setEnabled(true); mRefractionButton->setEnabled(true);
mReflectActorsButton->setEnabled(true);
mReflectTerrainButton->setEnabled(true);
}
mUnderwaterButton->setEnabled(true);
mShadowsEnabledButton->setEnabled(true); mShadowsEnabledButton->setEnabled(true);
} }
@ -521,15 +522,6 @@ namespace MWGui
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int((1-val) * sFovMin + val * sFovMax)) + ")"); fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int((1-val) * sFovMin + val * sFovMax)) + ")");
Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax); Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax);
} }
else if (scroller == mGammaSlider)
{
Settings::Manager::setFloat("gamma", "Video", (1-val) * 0.1f + val * 3.f);
MyGUI::TextBox* gammaText;
getWidget(gammaText, "GammaText");
std::stringstream gamma;
gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video");
gammaText->setCaption("Gamma (" + gamma.str() + ")");
}
else if (scroller == mAnisotropySlider) else if (scroller == mAnisotropySlider)
{ {
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")"); mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")");

View file

@ -40,7 +40,6 @@ namespace MWGui
MyGUI::Button* mFPSButton; MyGUI::Button* mFPSButton;
MyGUI::ScrollBar* mViewDistanceSlider; MyGUI::ScrollBar* mViewDistanceSlider;
MyGUI::ScrollBar* mFOVSlider; MyGUI::ScrollBar* mFOVSlider;
MyGUI::ScrollBar* mGammaSlider;
MyGUI::ScrollBar* mAnisotropySlider; MyGUI::ScrollBar* mAnisotropySlider;
MyGUI::Button* mTextureFilteringButton; MyGUI::Button* mTextureFilteringButton;
MyGUI::TextBox* mAnisotropyLabel; MyGUI::TextBox* mAnisotropyLabel;
@ -50,7 +49,8 @@ namespace MWGui
MyGUI::Button* mReflectActorsButton; MyGUI::Button* mReflectActorsButton;
MyGUI::Button* mReflectTerrainButton; MyGUI::Button* mReflectTerrainButton;
MyGUI::Button* mShadersButton; MyGUI::Button* mShadersButton;
MyGUI::Button* mUnderwaterButton; MyGUI::Button* mShaderModeButton;
MyGUI::Button* mRefractionButton;
MyGUI::Button* mShadowsEnabledButton; MyGUI::Button* mShadowsEnabledButton;
MyGUI::Button* mShadowsLargeDistance; MyGUI::Button* mShadowsLargeDistance;
@ -84,6 +84,7 @@ namespace MWGui
void onResolutionCancel(); void onResolutionCancel();
void onShadersToggled(MyGUI::Widget* _sender); void onShadersToggled(MyGUI::Widget* _sender);
void onShaderModeToggled(MyGUI::Widget* _sender);
void onShadowTextureSize(MyGUI::Widget* _sender); void onShadowTextureSize(MyGUI::Widget* _sender);
void onRebindAction(MyGUI::Widget* _sender); void onRebindAction(MyGUI::Widget* _sender);

View file

@ -94,9 +94,6 @@ namespace MWGui
mPtr = actor; mPtr = actor;
clearSpells(); clearSpells();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::Spells& playerSpells = MWWorld::Class::get (player).getCreatureStats (player).getSpells();
MWMechanics::Spells& merchantSpells = MWWorld::Class::get (actor).getCreatureStats (actor).getSpells(); MWMechanics::Spells& merchantSpells = MWWorld::Class::get (actor).getCreatureStats (actor).getSpells();
for (MWMechanics::Spells::TIterator iter = merchantSpells.begin(); iter!=merchantSpells.end(); ++iter) for (MWMechanics::Spells::TIterator iter = merchantSpells.begin(); iter!=merchantSpells.end(); ++iter)
@ -107,8 +104,8 @@ namespace MWGui
if (spell->mData.mType!=ESM::Spell::ST_Spell) if (spell->mData.mType!=ESM::Spell::ST_Spell)
continue; // don't try to sell diseases, curses or powers continue; // don't try to sell diseases, curses or powers
if (std::find (playerSpells.begin(), playerSpells.end(), *iter)!=playerSpells.end()) if (playerHasSpell(iter->first))
continue; // we have that spell already continue;
addSpell (iter->first); addSpell (iter->first);
} }
@ -118,6 +115,18 @@ namespace MWGui
mSpellsView->setCanvasSize (MyGUI::IntSize(mSpellsView->getWidth(), std::max(mSpellsView->getHeight(), mCurrentY))); mSpellsView->setCanvasSize (MyGUI::IntSize(mSpellsView->getWidth(), std::max(mSpellsView->getHeight(), mCurrentY)));
} }
bool SpellBuyingWindow::playerHasSpell(const std::string &id)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::Spells& playerSpells = MWWorld::Class::get (player).getCreatureStats (player).getSpells();
for (MWMechanics::Spells::TIterator it = playerSpells.begin(); it != playerSpells.end(); ++it)
{
if (Misc::StringUtils::ciEqual(id, it->first))
return true;
}
return false;
}
void SpellBuyingWindow::onSpellButtonClick(MyGUI::Widget* _sender) void SpellBuyingWindow::onSpellButtonClick(MyGUI::Widget* _sender)
{ {
int price = *_sender->getUserData<int>(); int price = *_sender->getUserData<int>();

View file

@ -47,6 +47,8 @@ namespace MWGui
void updateLabels(); void updateLabels();
virtual void onReferenceUnavailable(); virtual void onReferenceUnavailable();
bool playerHasSpell (const std::string& id);
}; };
} }

View file

@ -0,0 +1,293 @@
#include "spellicons.hpp"
#include <MyGUI_Widget.h>
#include <MyGUI_Gui.h>
#include <MyGUI_ImageBox.h>
#include <boost/lexical_cast.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwmechanics/activespells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "tooltips.hpp"
namespace MWGui
{
void SpellIcons::updateWidgets(MyGUI::Widget *parent, bool adjustSize)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
std::map <int, std::vector<MagicEffectInfo> > effects;
// add permanent item enchantments
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
MWWorld::ContainerStoreIterator it = store.getSlot(slot);
if (it == store.end())
continue;
std::string enchantment = MWWorld::Class::get(*it).getEnchantment(*it);
if (enchantment.empty())
continue;
const ESM::Enchantment* enchant = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(enchantment);
if (enchant->mData.mType != ESM::Enchantment::ConstantEffect)
continue;
const ESM::EffectList& list = enchant->mEffects;
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = list.mList.begin();
effectIt != list.mList.end(); ++effectIt)
{
const ESM::MagicEffect* magicEffect =
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::MagicEffect>().find(effectIt->mEffectID);
MagicEffectInfo effectInfo;
effectInfo.mSource = MWWorld::Class::get(*it).getName(*it);
effectInfo.mKey = MWMechanics::EffectKey (effectIt->mEffectID);
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)
effectInfo.mKey.mArg = effectIt->mSkill;
else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
effectInfo.mKey.mArg = effectIt->mAttribute;
// just using the min magnitude here, permanent enchantments with a random magnitude just wouldn't make any sense
effectInfo.mMagnitude = effectIt->mMagnMin;
effectInfo.mPermanent = true;
effects[effectIt->mEffectID].push_back (effectInfo);
}
}
// add permanent spells
const MWMechanics::Spells& spells = stats.getSpells();
for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(it->first);
// these are the spell types that are permanently in effect
if (!(spell->mData.mType == ESM::Spell::ST_Ability)
&& !(spell->mData.mType == ESM::Spell::ST_Disease)
&& !(spell->mData.mType == ESM::Spell::ST_Curse)
&& !(spell->mData.mType == ESM::Spell::ST_Blight))
continue;
const ESM::EffectList& list = spell->mEffects;
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = list.mList.begin();
effectIt != list.mList.end(); ++effectIt)
{
const ESM::MagicEffect* magicEffect =
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::MagicEffect>().find(effectIt->mEffectID);
MagicEffectInfo effectInfo;
effectInfo.mSource = getSpellDisplayName (it->first);
effectInfo.mKey = MWMechanics::EffectKey (effectIt->mEffectID);
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)
effectInfo.mKey.mArg = effectIt->mSkill;
else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
effectInfo.mKey.mArg = effectIt->mAttribute;
// just using the min magnitude here, permanent spells with a random magnitude just wouldn't make any sense
effectInfo.mMagnitude = effectIt->mMagnMin;
effectInfo.mPermanent = true;
effects[effectIt->mEffectID].push_back (effectInfo);
}
}
// add lasting effect spells/potions etc
const MWMechanics::ActiveSpells::TContainer& activeSpells = stats.getActiveSpells().getActiveSpells();
for (MWMechanics::ActiveSpells::TContainer::const_iterator it = activeSpells.begin();
it != activeSpells.end(); ++it)
{
const ESM::EffectList& list = getSpellEffectList(it->first);
float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor();
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = list.mList.begin();
effectIt != list.mList.end(); ++effectIt)
{
const ESM::MagicEffect* magicEffect =
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::MagicEffect>().find(effectIt->mEffectID);
MagicEffectInfo effectInfo;
effectInfo.mSource = getSpellDisplayName (it->first);
effectInfo.mKey = MWMechanics::EffectKey (effectIt->mEffectID);
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)
effectInfo.mKey.mArg = effectIt->mSkill;
else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
effectInfo.mKey.mArg = effectIt->mAttribute;
effectInfo.mMagnitude = effectIt->mMagnMin + (effectIt->mMagnMax-effectIt->mMagnMin) * it->second.second;
effectInfo.mRemainingTime = effectIt->mDuration +
(it->second.first - MWBase::Environment::get().getWorld()->getTimeStamp())*3600/timeScale;
// ingredients need special casing for their magnitude / duration
/// \todo duplicated from ActiveSpells, helper function?
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (it->first))
{
effectInfo.mRemainingTime = effectIt->mDuration * it->second.second +
(it->second.first - MWBase::Environment::get().getWorld()->getTimeStamp())*3600/timeScale;
effectInfo.mMagnitude = static_cast<int> (0.05*it->second.second / (0.1 * magicEffect->mData.mBaseCost));
}
effects[effectIt->mEffectID].push_back (effectInfo);
}
}
parent->setVisible(effects.size() != 0);
int w=2;
if (adjustSize)
{
int s = effects.size() * 16+4;
int diff = parent->getWidth() - s;
parent->setSize(s, parent->getHeight());
parent->setPosition(parent->getLeft()+diff, parent->getTop());
}
for (std::map <int, std::vector<MagicEffectInfo> >::const_iterator it = effects.begin(); it != effects.end(); ++it)
{
MyGUI::ImageBox* image;
if (mWidgetMap.find(it->first) == mWidgetMap.end())
image = parent->createWidget<MyGUI::ImageBox>
("ImageBox", MyGUI::IntCoord(w,2,16,16), MyGUI::Align::Default);
else
image = mWidgetMap[it->first];
mWidgetMap[it->first] = image;
image->setPosition(w,2);
image->setVisible(true);
const ESM::MagicEffect* effect =
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::MagicEffect>().find(it->first);
std::string icon = effect->mIcon;
icon[icon.size()-3] = 'd';
icon[icon.size()-2] = 'd';
icon[icon.size()-1] = 's';
icon = "icons\\" + icon;
image->setImageTexture(icon);
w += 16;
float remainingDuration = 0;
std::string sourcesDescription;
const float fadeTime = 5.f;
for (std::vector<MagicEffectInfo>::const_iterator effectIt = it->second.begin();
effectIt != it->second.end(); ++effectIt)
{
if (effectIt != it->second.begin())
sourcesDescription += "\n";
// if at least one of the effect sources is permanent, the effect will never wear off
if (effectIt->mPermanent)
remainingDuration = fadeTime;
else
remainingDuration = std::max(remainingDuration, effectIt->mRemainingTime);
sourcesDescription += effectIt->mSource;
if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill)
sourcesDescription += " (" +
MWBase::Environment::get().getWindowManager()->getGameSettingString(
ESM::Skill::sSkillNameIds[effectIt->mKey.mArg], "") + ")";
if (effect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
sourcesDescription += " (" +
MWBase::Environment::get().getWindowManager()->getGameSettingString(
ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")";
if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
{
std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "");
std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "");
sourcesDescription += ": " + boost::lexical_cast<std::string>(effectIt->mMagnitude);
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt);
}
}
std::string name = ESM::MagicEffect::effectIdToString (it->first);
ToolTipInfo tooltipInfo;
tooltipInfo.caption = "#{" + name + "}";
tooltipInfo.icon = effect->mIcon;
tooltipInfo.text = sourcesDescription;
tooltipInfo.imageSize = 16;
tooltipInfo.wordWrap = false;
image->setUserData(tooltipInfo);
image->setUserString("ToolTipType", "ToolTipInfo");
// Fade out during the last 5 seconds
image->setAlpha(std::min(remainingDuration/fadeTime, 1.f));
}
// hide inactive effects
for (std::map<int, MyGUI::ImageBox*>::iterator it = mWidgetMap.begin(); it != mWidgetMap.end(); ++it)
{
if (effects.find(it->first) == effects.end())
it->second->setVisible(false);
}
}
std::string SpellIcons::getSpellDisplayName (const std::string& id)
{
if (const ESM::Spell *spell =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search (id))
return spell->mName;
if (const ESM::Potion *potion =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Potion>().search (id))
return potion->mName;
if (const ESM::Ingredient *ingredient =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (id))
return ingredient->mName;
throw std::runtime_error ("ID " + id + " has no display name");
}
ESM::EffectList SpellIcons::getSpellEffectList (const std::string& id)
{
if (const ESM::Spell *spell =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search (id))
return spell->mEffects;
if (const ESM::Potion *potion =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Potion>().search (id))
return potion->mEffects;
if (const ESM::Ingredient *ingredient =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (id))
{
const ESM::MagicEffect *magicEffect =
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
ingredient->mData.mEffectID[0]);
ESM::ENAMstruct effect;
effect.mEffectID = ingredient->mData.mEffectID[0];
effect.mSkill = ingredient->mData.mSkills[0];
effect.mAttribute = ingredient->mData.mAttributes[0];
effect.mRange = 0;
effect.mArea = 0;
effect.mDuration = magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration ? 0 : 1;
effect.mMagnMin = 1;
effect.mMagnMax = 1;
ESM::EffectList result;
result.mList.push_back (effect);
return result;
}
throw std::runtime_error("ID " + id + " does not have effects");
}
}

View file

@ -0,0 +1,47 @@
#ifndef MWGUI_SPELLICONS_H
#define MWGUI_SPELLICONS_H
#include <string>
#include "../mwmechanics/magiceffects.hpp"
namespace MyGUI
{
class Widget;
class ImageBox;
}
namespace ESM
{
struct ENAMstruct;
struct EffectList;
}
namespace MWGui
{
// information about a single magic effect source as required for display in the tooltip
struct MagicEffectInfo
{
MagicEffectInfo() : mPermanent(false) {}
std::string mSource; // display name for effect source (e.g. potion name)
MWMechanics::EffectKey mKey;
int mMagnitude;
float mRemainingTime;
bool mPermanent; // the effect is permanent
};
class SpellIcons
{
public:
void updateWidgets(MyGUI::Widget* parent, bool adjustSize);
private:
std::string getSpellDisplayName (const std::string& id);
ESM::EffectList getSpellEffectList (const std::string& id);
std::map<int, MyGUI::ImageBox*> mWidgetMap;
};
}
#endif

View file

@ -19,6 +19,7 @@
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/spellsuccess.hpp" #include "../mwmechanics/spellsuccess.hpp"
#include "spellicons.hpp"
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "confirmationdialog.hpp" #include "confirmationdialog.hpp"
@ -51,6 +52,8 @@ namespace MWGui
, mHeight(0) , mHeight(0)
, mWidth(0) , mWidth(0)
{ {
mSpellIcons = new SpellIcons();
getWidget(mSpellView, "SpellView"); getWidget(mSpellView, "SpellView");
getWidget(mEffectBox, "EffectsBox"); getWidget(mEffectBox, "EffectsBox");
@ -61,6 +64,11 @@ namespace MWGui
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SpellWindow::onWindowResize); mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SpellWindow::onWindowResize);
} }
SpellWindow::~SpellWindow()
{
delete mSpellIcons;
}
void SpellWindow::onPinToggled() void SpellWindow::onPinToggled()
{ {
mWindowManager.setSpellVisibility(!mPinned); mWindowManager.setSpellVisibility(!mPinned);
@ -73,6 +81,8 @@ namespace MWGui
void SpellWindow::updateSpells() void SpellWindow::updateSpells()
{ {
mSpellIcons->updateWidgets(mEffectBox, false);
const int spellHeight = 18; const int spellHeight = 18;
mHeight = 0; mHeight = 0;

View file

@ -5,10 +5,13 @@
namespace MWGui namespace MWGui
{ {
class SpellIcons;
class SpellWindow : public WindowPinnableBase class SpellWindow : public WindowPinnableBase
{ {
public: public:
SpellWindow(MWBase::WindowManager& parWindowManager); SpellWindow(MWBase::WindowManager& parWindowManager);
virtual ~SpellWindow();
void updateSpells(); void updateSpells();
@ -33,6 +36,8 @@ namespace MWGui
virtual void onPinToggled(); virtual void onPinToggled();
virtual void open(); virtual void open();
SpellIcons* mSpellIcons;
}; };
} }

View file

@ -67,7 +67,7 @@ StatsWindow::StatsWindow (MWBase::WindowManager& parWindowManager)
for (int i = 0; i < ESM::Skill::Length; ++i) for (int i = 0; i < ESM::Skill::Length; ++i)
{ {
mSkillValues.insert(std::pair<int, MWMechanics::Stat<float> >(i, MWMechanics::Stat<float>())); mSkillValues.insert(std::pair<int, MWMechanics::Stat<float> >(i, MWMechanics::Stat<float>()));
mSkillWidgetMap.insert(std::pair<int, MyGUI::TextBox*>(i, (MyGUI::TextBox*)nullptr)); mSkillWidgetMap.insert(std::pair<int, MyGUI::TextBox*>(i, (MyGUI::TextBox*)NULL));
} }
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget); MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget);
@ -419,7 +419,7 @@ void StatsWindow::updateSkillArea()
{ {
mChanged = false; mChanged = false;
for (std::vector<MyGUI::WidgetPtr>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it) for (std::vector<MyGUI::Widget*>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it)
{ {
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }

View file

@ -67,11 +67,11 @@ namespace MWGui
SkillList mMajorSkills, mMinorSkills, mMiscSkills; SkillList mMajorSkills, mMinorSkills, mMiscSkills;
std::map<int, MWMechanics::Stat<float> > mSkillValues; std::map<int, MWMechanics::Stat<float> > mSkillValues;
std::map<int, MyGUI::TextBox*> mSkillWidgetMap; std::map<int, MyGUI::TextBox*> mSkillWidgetMap;
std::map<std::string, MyGUI::WidgetPtr> mFactionWidgetMap; std::map<std::string, MyGUI::Widget*> mFactionWidgetMap;
FactionList mFactions; ///< Stores a list of factions and the current rank FactionList mFactions; ///< Stores a list of factions and the current rank
std::string mBirthSignId; std::string mBirthSignId;
int mReputation, mBounty; int mReputation, mBounty;
std::vector<MyGUI::WidgetPtr> mSkillWidgets; //< Skills and other information std::vector<MyGUI::Widget*> mSkillWidgets; //< Skills and other information
std::set<std::string> mExpelled; std::set<std::string> mExpelled;
bool mChanged; bool mChanged;

View file

@ -13,7 +13,7 @@ TextInputDialog::TextInputDialog(MWBase::WindowManager& parWindowManager)
getWidget(mTextEdit, "TextEdit"); getWidget(mTextEdit, "TextEdit");
mTextEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted); mTextEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted);
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked);
@ -23,7 +23,7 @@ TextInputDialog::TextInputDialog(MWBase::WindowManager& parWindowManager)
void TextInputDialog::setNextButtonShow(bool shown) void TextInputDialog::setNextButtonShow(bool shown)
{ {
MyGUI::ButtonPtr okButton; MyGUI::Button* okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
if (shown) if (shown)

View file

@ -30,7 +30,7 @@ namespace MWGui
void onTextAccepted(MyGUI::Edit* _sender); void onTextAccepted(MyGUI::Edit* _sender);
private: private:
MyGUI::EditPtr mTextEdit; MyGUI::EditBox* mTextEdit;
}; };
} }
#endif #endif

View file

@ -127,9 +127,7 @@ void ToolTips::onFrame(float frameDuration)
Widget* focus = InputManager::getInstance().getMouseFocusWidget(); Widget* focus = InputManager::getInstance().getMouseFocusWidget();
if (focus == 0) if (focus == 0)
{
return; return;
}
IntSize tooltipSize; IntSize tooltipSize;
@ -168,6 +166,10 @@ void ToolTips::onFrame(float frameDuration)
mFocusObject = *focus->getUserData<MWWorld::Ptr>(); mFocusObject = *focus->getUserData<MWWorld::Ptr>();
tooltipSize = getToolTipViaPtr(false); tooltipSize = getToolTipViaPtr(false);
} }
else if (type == "ToolTipInfo")
{
tooltipSize = createToolTip(*focus->getUserData<MWGui::ToolTipInfo>());
}
else if (type == "AvatarItemSelection") else if (type == "AvatarItemSelection")
{ {
MyGUI::IntCoord avatarPos = mWindowManager->getInventoryWindow ()->getAvatarScreenCoord (); MyGUI::IntCoord avatarPos = mWindowManager->getInventoryWindow ()->getAvatarScreenCoord ();
@ -363,7 +365,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
std::string caption = info.caption; std::string caption = info.caption;
std::string image = info.icon; std::string image = info.icon;
int imageSize = (image != "") ? 32 : 0; int imageSize = (image != "") ? info.imageSize : 0;
std::string text = info.text; std::string text = info.text;
// remove the first newline (easier this way) // remove the first newline (easier this way)
@ -403,7 +405,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
EditBox* captionWidget = mDynamicToolTipBox->createWidget<EditBox>("NormalText", IntCoord(0, 0, 300, 300), Align::Left | Align::Top, "ToolTipCaption"); EditBox* captionWidget = mDynamicToolTipBox->createWidget<EditBox>("NormalText", IntCoord(0, 0, 300, 300), Align::Left | Align::Top, "ToolTipCaption");
captionWidget->setProperty("Static", "true"); captionWidget->setProperty("Static", "true");
captionWidget->setCaption(caption); captionWidget->setCaptionWithReplacing(caption);
IntSize captionSize = captionWidget->getTextSize(); IntSize captionSize = captionWidget->getTextSize();
int captionHeight = std::max(caption != "" ? captionSize.height : 0, imageSize); int captionHeight = std::max(caption != "" ? captionSize.height : 0, imageSize);
@ -411,7 +413,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
EditBox* textWidget = mDynamicToolTipBox->createWidget<EditBox>("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText"); EditBox* textWidget = mDynamicToolTipBox->createWidget<EditBox>("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText");
textWidget->setProperty("Static", "true"); textWidget->setProperty("Static", "true");
textWidget->setProperty("MultiLine", "true"); textWidget->setProperty("MultiLine", "true");
textWidget->setProperty("WordWrap", "true"); textWidget->setProperty("WordWrap", info.wordWrap ? "true" : "false");
textWidget->setCaptionWithReplacing(text); textWidget->setCaptionWithReplacing(text);
textWidget->setTextAlign(Align::HCenter | Align::Top); textWidget->setTextAlign(Align::HCenter | Align::Top);
IntSize textSize = textWidget->getTextSize(); IntSize textSize = textWidget->getTextSize();
@ -439,7 +441,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
effectsWidget->setWindowManager(mWindowManager); effectsWidget->setWindowManager(mWindowManager);
effectsWidget->setEffectList(info.effects); effectsWidget->setEffectList(info.effects);
std::vector<MyGUI::WidgetPtr> effectItems; std::vector<MyGUI::Widget*> effectItems;
effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, info.isPotion ? Widgets::MWEffectList::EF_NoTarget : 0); effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, info.isPotion ? Widgets::MWEffectList::EF_NoTarget : 0);
totalSize.height += coord.top-6; totalSize.height += coord.top-6;
totalSize.width = std::max(totalSize.width, coord.width); totalSize.width = std::max(totalSize.width, coord.width);
@ -459,7 +461,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
enchantWidget->setWindowManager(mWindowManager); enchantWidget->setWindowManager(mWindowManager);
enchantWidget->setEffectList(Widgets::MWEffectList::effectListFromESM(&enchant->mEffects)); enchantWidget->setEffectList(Widgets::MWEffectList::effectListFromESM(&enchant->mEffects));
std::vector<MyGUI::WidgetPtr> enchantEffectItems; std::vector<MyGUI::Widget*> enchantEffectItems;
int flag = (enchant->mData.mType == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0; int flag = (enchant->mData.mType == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0;
enchantWidget->createEffectWidgets(enchantEffectItems, enchantArea, coord, true, flag); enchantWidget->createEffectWidgets(enchantEffectItems, enchantArea, coord, true, flag);
totalSize.height += coord.top-6; totalSize.height += coord.top-6;

View file

@ -15,11 +15,14 @@ namespace MWGui
public: public:
ToolTipInfo() ToolTipInfo()
: isPotion(false) : isPotion(false)
, imageSize(32)
, wordWrap(true)
{} {}
std::string caption; std::string caption;
std::string text; std::string text;
std::string icon; std::string icon;
int imageSize;
// enchantment (for cloth, armor, weapons) // enchantment (for cloth, armor, weapons)
std::string enchant; std::string enchant;
@ -28,6 +31,7 @@ namespace MWGui
Widgets::SpellEffectList effects; Widgets::SpellEffectList effects;
bool isPotion; // potions do not show target in the tooltip bool isPotion; // potions do not show target in the tooltip
bool wordWrap;
}; };
class ToolTips : public OEngine::GUI::Layout class ToolTips : public OEngine::GUI::Layout

View file

@ -64,6 +64,7 @@ namespace MWGui
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onCancelButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onCancelButtonClicked);
mOfferButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onOfferButtonClicked); mOfferButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onOfferButtonClicked);
mMaxSaleButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onMaxSaleButtonClicked);
mIncreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onIncreaseButtonPressed); mIncreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onIncreaseButtonPressed);
mIncreaseButton->eventMouseButtonReleased += MyGUI::newDelegate(this, &TradeWindow::onBalanceButtonReleased); mIncreaseButton->eventMouseButtonReleased += MyGUI::newDelegate(this, &TradeWindow::onBalanceButtonReleased);
mDecreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onDecreaseButtonPressed); mDecreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onDecreaseButtonPressed);
@ -191,21 +192,7 @@ namespace MWGui
} }
// check if the merchant can afford this // check if the merchant can afford this
int merchantgold; if (mCurrentBalance > 0 && getMerchantGold() < mCurrentBalance)
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
{
MWWorld::LiveCellRef<ESM::NPC>* ref = mPtr.get<ESM::NPC>();
if (ref->mBase->mNpdt52.mGold == -10)
merchantgold = ref->mBase->mNpdt12.mGold;
else
merchantgold = ref->mBase->mNpdt52.mGold;
}
else // ESM::Creature
{
MWWorld::LiveCellRef<ESM::Creature>* ref = mPtr.get<ESM::Creature>();
merchantgold = ref->mBase->mData.mGold;
}
if (mCurrentBalance > 0 && merchantgold < mCurrentBalance)
{ {
// user notification // user notification
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
@ -293,6 +280,12 @@ namespace MWGui
mWindowManager.removeGuiMode(GM_Barter); mWindowManager.removeGuiMode(GM_Barter);
} }
void TradeWindow::onMaxSaleButtonClicked(MyGUI::Widget* _sender)
{
mCurrentBalance = getMerchantGold();
updateLabels();
}
void TradeWindow::onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) void TradeWindow::onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{ {
mBalanceButtonsState = BBS_Increase; mBalanceButtonsState = BBS_Increase;
@ -341,22 +334,7 @@ namespace MWGui
mTotalBalance->setCaption(boost::lexical_cast<std::string>(-mCurrentBalance)); mTotalBalance->setCaption(boost::lexical_cast<std::string>(-mCurrentBalance));
} }
int merchantgold; mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast<std::string>(getMerchantGold()));
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
{
MWWorld::LiveCellRef<ESM::NPC>* ref = mPtr.get<ESM::NPC>();
if (ref->mBase->mNpdt52.mGold == -10)
merchantgold = ref->mBase->mNpdt12.mGold;
else
merchantgold = ref->mBase->mNpdt52.mGold;
}
else // ESM::Creature
{
MWWorld::LiveCellRef<ESM::Creature>* ref = mPtr.get<ESM::Creature>();
merchantgold = ref->mBase->mData.mGold;
}
mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast<std::string>(merchantgold));
} }
std::vector<MWWorld::Ptr> TradeWindow::getEquippedItems() std::vector<MWWorld::Ptr> TradeWindow::getEquippedItems()
@ -468,4 +446,25 @@ namespace MWGui
mWindowManager.removeGuiMode(GM_Barter); mWindowManager.removeGuiMode(GM_Barter);
mWindowManager.removeGuiMode(GM_Dialogue); mWindowManager.removeGuiMode(GM_Dialogue);
} }
int TradeWindow::getMerchantGold()
{
int merchantGold;
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
{
MWWorld::LiveCellRef<ESM::NPC>* ref = mPtr.get<ESM::NPC>();
if (ref->mBase->mNpdt52.mGold == -10)
merchantGold = ref->mBase->mNpdt12.mGold;
else
merchantGold = ref->mBase->mNpdt52.mGold;
}
else // ESM::Creature
{
MWWorld::LiveCellRef<ESM::Creature>* ref = mPtr.get<ESM::Creature>();
merchantGold = ref->mBase->mData.mGold;
}
return merchantGold;
}
} }

View file

@ -74,6 +74,7 @@ namespace MWGui
void onFilterChanged(MyGUI::Widget* _sender); void onFilterChanged(MyGUI::Widget* _sender);
void onOfferButtonClicked(MyGUI::Widget* _sender); void onOfferButtonClicked(MyGUI::Widget* _sender);
void onCancelButtonClicked(MyGUI::Widget* _sender); void onCancelButtonClicked(MyGUI::Widget* _sender);
void onMaxSaleButtonClicked(MyGUI::Widget* _sender);
void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
@ -93,6 +94,9 @@ namespace MWGui
void updateLabels(); void updateLabels();
virtual void onReferenceUnavailable(); virtual void onReferenceUnavailable();
private:
int getMerchantGold();
}; };
} }

View file

@ -2,6 +2,9 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <MyGUI_ProgressBar.h>
#include <MyGUI_ImageBox.h>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
@ -31,10 +34,10 @@ void MWGui::Widgets::fixTexturePath(std::string &path)
/* MWSkill */ /* MWSkill */
MWSkill::MWSkill() MWSkill::MWSkill()
: mManager(nullptr) : mManager(NULL)
, mSkillId(ESM::Skill::Length) , mSkillId(ESM::Skill::Length)
, mSkillNameWidget(nullptr) , mSkillNameWidget(NULL)
, mSkillValueWidget(nullptr) , mSkillValueWidget(NULL)
{ {
} }
@ -103,7 +106,7 @@ void MWSkill::initialiseOverride()
assignWidget(mSkillNameWidget, "StatName"); assignWidget(mSkillNameWidget, "StatName");
assignWidget(mSkillValueWidget, "StatValue"); assignWidget(mSkillValueWidget, "StatValue");
MyGUI::ButtonPtr button; MyGUI::Button* button;
assignWidget(button, "StatNameButton"); assignWidget(button, "StatNameButton");
if (button) if (button)
{ {
@ -123,10 +126,10 @@ void MWSkill::initialiseOverride()
/* MWAttribute */ /* MWAttribute */
MWAttribute::MWAttribute() MWAttribute::MWAttribute()
: mManager(nullptr) : mManager(NULL)
, mId(-1) , mId(-1)
, mAttributeNameWidget(nullptr) , mAttributeNameWidget(NULL)
, mAttributeValueWidget(nullptr) , mAttributeValueWidget(NULL)
{ {
} }
@ -195,7 +198,7 @@ void MWAttribute::initialiseOverride()
assignWidget(mAttributeNameWidget, "StatName"); assignWidget(mAttributeNameWidget, "StatName");
assignWidget(mAttributeValueWidget, "StatValue"); assignWidget(mAttributeValueWidget, "StatValue");
MyGUI::ButtonPtr button; MyGUI::Button* button;
assignWidget(button, "StatNameButton"); assignWidget(button, "StatNameButton");
if (button) if (button)
{ {
@ -215,8 +218,8 @@ void MWAttribute::initialiseOverride()
/* MWSpell */ /* MWSpell */
MWSpell::MWSpell() MWSpell::MWSpell()
: mWindowManager(nullptr) : mWindowManager(NULL)
, mSpellNameWidget(nullptr) , mSpellNameWidget(NULL)
{ {
} }
@ -226,7 +229,7 @@ void MWSpell::setSpellId(const std::string &spellId)
updateWidgets(); updateWidgets();
} }
void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags) void MWSpell::createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, int flags)
{ {
const MWWorld::ESMStore &store = const MWWorld::ESMStore &store =
MWBase::Environment::get().getWorld()->getStore(); MWBase::Environment::get().getWorld()->getStore();
@ -234,7 +237,7 @@ void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI:
const ESM::Spell *spell = store.get<ESM::Spell>().search(mId); const ESM::Spell *spell = store.get<ESM::Spell>().search(mId);
MYGUI_ASSERT(spell, "spell with id '" << mId << "' not found"); MYGUI_ASSERT(spell, "spell with id '" << mId << "' not found");
MWSpellEffectPtr effect = nullptr; MWSpellEffectPtr effect = NULL;
std::vector<ESM::ENAMstruct>::const_iterator end = spell->mEffects.mList.end(); std::vector<ESM::ENAMstruct>::const_iterator end = spell->mEffects.mList.end();
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != end; ++it) for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != end; ++it)
{ {
@ -286,7 +289,7 @@ MWSpell::~MWSpell()
/* MWEffectList */ /* MWEffectList */
MWEffectList::MWEffectList() MWEffectList::MWEffectList()
: mWindowManager(nullptr) : mWindowManager(NULL)
, mEffectList(0) , mEffectList(0)
{ {
} }
@ -297,11 +300,11 @@ void MWEffectList::setEffectList(const SpellEffectList& list)
updateWidgets(); updateWidgets();
} }
void MWEffectList::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, bool center, int flags) void MWEffectList::createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, bool center, int flags)
{ {
// We don't know the width of all the elements beforehand, so we do it in // We don't know the width of all the elements beforehand, so we do it in
// 2 steps: first, create all widgets and check their width.... // 2 steps: first, create all widgets and check their width....
MWSpellEffectPtr effect = nullptr; MWSpellEffectPtr effect = NULL;
int maxwidth = coord.width; int maxwidth = coord.width;
for (SpellEffectList::iterator it=mEffectList.begin(); for (SpellEffectList::iterator it=mEffectList.begin();
@ -320,7 +323,7 @@ void MWEffectList::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, M
} }
// ... then adjust the size for all widgets // ... then adjust the size for all widgets
for (std::vector<MyGUI::WidgetPtr>::iterator it = effects.begin(); it != effects.end(); ++it) for (std::vector<MyGUI::Widget*>::iterator it = effects.begin(); it != effects.end(); ++it)
{ {
effect = static_cast<MWSpellEffectPtr>(*it); effect = static_cast<MWSpellEffectPtr>(*it);
bool needcenter = center && (maxwidth > effect->getRequestedWidth()); bool needcenter = center && (maxwidth > effect->getRequestedWidth());
@ -375,9 +378,9 @@ SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects)
/* MWSpellEffect */ /* MWSpellEffect */
MWSpellEffect::MWSpellEffect() MWSpellEffect::MWSpellEffect()
: mWindowManager(nullptr) : mWindowManager(NULL)
, mImageWidget(nullptr) , mImageWidget(NULL)
, mTextWidget(nullptr) , mTextWidget(NULL)
, mRequestedWidth(0) , mRequestedWidth(0)
{ {
} }
@ -421,17 +424,7 @@ void MWSpellEffect::updateWidgets()
} }
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
{ {
static const char *attributes[8] = { spellLine += " " + mWindowManager->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], "");
"sAttributeStrength",
"sAttributeIntelligence",
"sAttributeWillpower",
"sAttributeAgility",
"sAttributeSpeed",
"sAttributeEndurance",
"sAttributePersonality",
"sAttributeLuck"
};
spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], "");
} }
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
@ -495,9 +488,9 @@ void MWSpellEffect::initialiseOverride()
MWDynamicStat::MWDynamicStat() MWDynamicStat::MWDynamicStat()
: mValue(0) : mValue(0)
, mMax(1) , mMax(1)
, mTextWidget(nullptr) , mTextWidget(NULL)
, mBarWidget(nullptr) , mBarWidget(NULL)
, mBarTextWidget(nullptr) , mBarTextWidget(NULL)
{ {
} }

View file

@ -2,11 +2,17 @@
#define MWGUI_WIDGETS_H #define MWGUI_WIDGETS_H
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include <MyGUI.h>
#include "../mwmechanics/stat.hpp" #include "../mwmechanics/stat.hpp"
#include <MyGUI_Widget.h>
#include <MyGUI_TextBox.h>
#include <MyGUI_Button.h>
namespace MyGUI
{
class ImageBox;
}
namespace MWBase namespace MWBase
{ {
class WindowManager; class WindowManager;
@ -118,7 +124,8 @@ namespace MWGui
MWBase::WindowManager *mManager; MWBase::WindowManager *mManager;
ESM::Skill::SkillEnum mSkillId; ESM::Skill::SkillEnum mSkillId;
SkillValue mValue; SkillValue mValue;
MyGUI::WidgetPtr mSkillNameWidget, mSkillValueWidget; MyGUI::Widget* mSkillNameWidget;
MyGUI::Widget* mSkillValueWidget;
}; };
typedef MWSkill* MWSkillPtr; typedef MWSkill* MWSkillPtr;
@ -160,7 +167,8 @@ namespace MWGui
MWBase::WindowManager *mManager; MWBase::WindowManager *mManager;
int mId; int mId;
AttributeValue mValue; AttributeValue mValue;
MyGUI::WidgetPtr mAttributeNameWidget, mAttributeValueWidget; MyGUI::Widget* mAttributeNameWidget;
MyGUI::Widget* mAttributeValueWidget;
}; };
typedef MWAttribute* MWAttributePtr; typedef MWAttribute* MWAttributePtr;
@ -186,7 +194,7 @@ namespace MWGui
* @param spell category, if this is 0, this means the spell effects are permanent and won't display e.g. duration * @param spell category, if this is 0, this means the spell effects are permanent and won't display e.g. duration
* @param various flags, see MWEffectList::EffectFlags * @param various flags, see MWEffectList::EffectFlags
*/ */
void createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags); void createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, int flags);
const std::string &getSpellId() const { return mId; } const std::string &getSpellId() const { return mId; }
@ -230,7 +238,7 @@ namespace MWGui
* @param center the effect widgets horizontally * @param center the effect widgets horizontally
* @param various flags, see MWEffectList::EffectFlags * @param various flags, see MWEffectList::EffectFlags
*/ */
void createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, bool center, int flags); void createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, bool center, int flags);
protected: protected:
virtual ~MWEffectList(); virtual ~MWEffectList();

View file

@ -3,7 +3,7 @@
#include <cassert> #include <cassert>
#include <iterator> #include <iterator>
#include "MyGUI_UString.h" #include <MyGUI_UString.h>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include <openengine/gui/manager.hpp> #include <openengine/gui/manager.hpp>
@ -54,14 +54,16 @@
#include "imagebutton.hpp" #include "imagebutton.hpp"
#include "exposedwindow.hpp" #include "exposedwindow.hpp"
#include "cursor.hpp" #include "cursor.hpp"
#include "spellicons.hpp"
using namespace MWGui; using namespace MWGui;
WindowManager::WindowManager( WindowManager::WindowManager(
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *ogre,
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
Translation::Storage& translationDataStorage) Translation::Storage& translationDataStorage)
: mGuiManager(NULL) : mGuiManager(NULL)
, mRendering(ogre)
, mHud(NULL) , mHud(NULL)
, mMap(NULL) , mMap(NULL)
, mMenu(NULL) , mMenu(NULL)
@ -112,7 +114,7 @@ WindowManager::WindowManager(
, mTranslationDataStorage (translationDataStorage) , mTranslationDataStorage (translationDataStorage)
{ {
// Set up the GUI system // Set up the GUI system
mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath); mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath);
mGui = mGuiManager->getGui(); mGui = mGuiManager->getGui();
//Register own widgets with MyGUI //Register own widgets with MyGUI
@ -177,15 +179,14 @@ WindowManager::WindowManager(
mEnchantingDialog = new EnchantingDialog(*this); mEnchantingDialog = new EnchantingDialog(*this);
mTrainingWindow = new TrainingWindow(*this); mTrainingWindow = new TrainingWindow(*this);
mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this);
mLoadingScreen->onResChange (w,h); mLoadingScreen->onResChange (w,h);
mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows",""); mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows","");
mCursor = new Cursor(); mCursor = new Cursor();
// The HUD is always on mHud->setVisible(mHudEnabled);
mHud->setVisible(true);
mCharGen = new CharacterCreation(this); mCharGen = new CharacterCreation(this);
@ -270,6 +271,8 @@ void WindowManager::update()
mHud->setTriangleCount(mTriangleCount); mHud->setTriangleCount(mTriangleCount);
mHud->setBatchCount(mBatchCount); mHud->setBatchCount(mBatchCount);
mHud->update();
mCursor->update(); mCursor->update();
} }
@ -299,7 +302,7 @@ void WindowManager::updateVisible()
mEnchantingDialog->setVisible(false); mEnchantingDialog->setVisible(false);
mTrainingWindow->setVisible(false); mTrainingWindow->setVisible(false);
mHud->setVisible(true); mHud->setVisible(mHudEnabled);
// Mouse is visible whenever we're not in game mode // Mouse is visible whenever we're not in game mode
mCursor->setVisible(isGuiMode()); mCursor->setVisible(isGuiMode());
@ -584,7 +587,7 @@ void WindowManager::messageBox (const std::string& message, const std::vector<st
else else
mMessageBoxManager->createMessageBox(message); mMessageBoxManager->createMessageBox(message);
} }
else else
{ {
mMessageBoxManager->createInteractiveMessageBox(message, buttons); mMessageBoxManager->createInteractiveMessageBox(message, buttons);
@ -607,8 +610,9 @@ std::string WindowManager::getGameSettingString(const std::string &id, const std
const ESM::GameSetting *setting = const ESM::GameSetting *setting =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().search(id); MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().search(id);
if (setting && setting->mType == ESM::VT_String) if (setting && setting->mValue.getType()==ESM::VT_String)
return setting->getString(); return setting->mValue.getString();
return default_; return default_;
} }
@ -789,8 +793,8 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r
const ESM::GameSetting *setting = const ESM::GameSetting *setting =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(tag); MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(tag);
if (setting && setting->mType == ESM::VT_String) if (setting && setting->mValue.getType()==ESM::VT_String)
_result = setting->getString(); _result = setting->mValue.getString();
else else
_result = tag; _result = tag;
} }
@ -802,6 +806,7 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI")); mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI"));
bool changeRes = false; bool changeRes = false;
bool windowRecreated = false;
for (Settings::CategorySettingVector::const_iterator it = changed.begin(); for (Settings::CategorySettingVector::const_iterator it = changed.begin();
it != changed.end(); ++it) it != changed.end(); ++it)
{ {
@ -811,6 +816,8 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
{ {
changeRes = true; changeRes = true;
} }
else if (it->first == "Video" && it->second == "vsync")
windowRecreated = true;
else if (it->first == "HUD" && it->second == "crosshair") else if (it->first == "HUD" && it->second == "crosshair")
mCrosshairEnabled = Settings::Manager::getBool ("crosshair", "HUD"); mCrosshairEnabled = Settings::Manager::getBool ("crosshair", "HUD");
else if (it->first == "GUI" && it->second == "subtitles") else if (it->first == "GUI" && it->second == "subtitles")
@ -834,6 +841,11 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y)); mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y));
mInputBlocker->setSize(MyGUI::IntSize(x,y)); mInputBlocker->setSize(MyGUI::IntSize(x,y));
} }
if (windowRecreated)
{
mGuiManager->updateWindow (mRendering->getWindow ());
mLoadingScreen->updateWindow (mRendering->getWindow ());
}
} }
void WindowManager::pushGuiMode(GuiMode mode) void WindowManager::pushGuiMode(GuiMode mode)
@ -1050,7 +1062,6 @@ void WindowManager::notifyInputActionBound ()
allowMouse(); allowMouse();
} }
void WindowManager::showCrosshair (bool show) void WindowManager::showCrosshair (bool show)
{ {
mHud->setCrosshairVisible (show && mCrosshairEnabled); mHud->setCrosshairVisible (show && mCrosshairEnabled);

View file

@ -73,6 +73,7 @@ namespace MWGui
class EnchantingDialog; class EnchantingDialog;
class TrainingWindow; class TrainingWindow;
class Cursor; class Cursor;
class SpellIcons;
class WindowManager : public MWBase::WindowManager class WindowManager : public MWBase::WindowManager
{ {
@ -231,6 +232,7 @@ namespace MWGui
private: private:
OEngine::GUI::MyGUIManager *mGuiManager; OEngine::GUI::MyGUIManager *mGuiManager;
OEngine::Render::OgreRenderer *mRendering;
HUD *mHud; HUD *mHud;
MapWindow *mMap; MapWindow *mMap;
MainMenu *mMenu; MainMenu *mMenu;

View file

@ -42,9 +42,11 @@ namespace MWInput
, mMouseX(ogre.getWindow()->getWidth ()/2.f) , mMouseX(ogre.getWindow()->getWidth ()/2.f)
, mMouseY(ogre.getWindow()->getHeight ()/2.f) , mMouseY(ogre.getWindow()->getHeight ()/2.f)
, mMouseWheel(0) , mMouseWheel(0)
, mUserFile(userFile)
, mDragDrop(false) , mDragDrop(false)
, mGuiCursorEnabled(false) , mGuiCursorEnabled(false)
, mDebug(debug)
, mUserFile(userFile)
, mUserFileExists(userFileExists)
, mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mInvertY (Settings::Manager::getBool("invert y axis", "Input"))
, mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input"))
, mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input")) , mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input"))
@ -54,7 +56,7 @@ namespace MWInput
, mTimeIdle(0.f) , mTimeIdle(0.f)
, mOverencumberedMessageDelay(0.f) , mOverencumberedMessageDelay(0.f)
{ {
Ogre::RenderWindow* window = ogre.getWindow (); Ogre::RenderWindow* window = mOgre.getWindow ();
size_t windowHnd; size_t windowHnd;
resetIdleTime(); resetIdleTime();
@ -69,7 +71,7 @@ namespace MWInput
// Set non-exclusive mouse and keyboard input if the user requested // Set non-exclusive mouse and keyboard input if the user requested
// it. // it.
if (debug) if (mDebug)
{ {
#if defined OIS_WIN32_PLATFORM #if defined OIS_WIN32_PLATFORM
pl.insert(std::make_pair(std::string("w32_mouse"), pl.insert(std::make_pair(std::string("w32_mouse"),
@ -116,7 +118,7 @@ namespace MWInput
MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs); MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs);
std::string file = userFileExists ? userFile : ""; std::string file = mUserFileExists ? mUserFile : "";
mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
loadKeyDefaults(); loadKeyDefaults();
@ -191,9 +193,6 @@ namespace MWInput
case A_AutoMove: case A_AutoMove:
toggleAutoMove (); toggleAutoMove ();
break; break;
case A_ToggleSneak:
/// \todo implement
break;
case A_ToggleWalk: case A_ToggleWalk:
toggleWalking (); toggleWalking ();
break; break;
@ -242,7 +241,7 @@ namespace MWInput
case A_ToggleHUD: case A_ToggleHUD:
mWindows.toggleHud(); mWindows.toggleHud();
break; break;
} }
} }
} }
@ -306,13 +305,13 @@ namespace MWInput
else else
mPlayer.setForwardBackward (0); mPlayer.setForwardBackward (0);
mPlayer.setSneak(actionIsActive(A_Sneak));
if (actionIsActive(A_Jump) && mControlSwitch["playerjumping"]) if (actionIsActive(A_Jump) && mControlSwitch["playerjumping"])
{ {
mPlayer.setUpDown (1); mPlayer.setUpDown (1);
triedToMove = true; triedToMove = true;
} }
else if (actionIsActive(A_Crouch))
mPlayer.setUpDown (-1);
else else
mPlayer.setUpDown (0); mPlayer.setUpDown (0);
@ -362,7 +361,7 @@ namespace MWInput
actionIsActive(A_MoveLeft) || actionIsActive(A_MoveLeft) ||
actionIsActive(A_MoveRight) || actionIsActive(A_MoveRight) ||
actionIsActive(A_Jump) || actionIsActive(A_Jump) ||
actionIsActive(A_Crouch) || actionIsActive(A_Sneak) ||
actionIsActive(A_TogglePOV)) actionIsActive(A_TogglePOV))
{ {
resetIdleTime(); resetIdleTime();
@ -747,7 +746,7 @@ namespace MWInput
defaultKeyBindings[A_QuickKeysMenu] = OIS::KC_F1; defaultKeyBindings[A_QuickKeysMenu] = OIS::KC_F1;
defaultKeyBindings[A_Console] = OIS::KC_F2; defaultKeyBindings[A_Console] = OIS::KC_F2;
defaultKeyBindings[A_Run] = OIS::KC_LSHIFT; defaultKeyBindings[A_Run] = OIS::KC_LSHIFT;
defaultKeyBindings[A_Crouch] = OIS::KC_LCONTROL; defaultKeyBindings[A_Sneak] = OIS::KC_LCONTROL;
defaultKeyBindings[A_AutoMove] = OIS::KC_Q; defaultKeyBindings[A_AutoMove] = OIS::KC_Q;
defaultKeyBindings[A_Jump] = OIS::KC_E; defaultKeyBindings[A_Jump] = OIS::KC_E;
defaultKeyBindings[A_Journal] = OIS::KC_J; defaultKeyBindings[A_Journal] = OIS::KC_J;
@ -814,7 +813,7 @@ namespace MWInput
descriptions[A_ToggleSpell] = "sReady_Magic"; descriptions[A_ToggleSpell] = "sReady_Magic";
descriptions[A_Console] = "sConsoleTitle"; descriptions[A_Console] = "sConsoleTitle";
descriptions[A_Run] = "sRun"; descriptions[A_Run] = "sRun";
descriptions[A_Crouch] = "sCrouch_Sneak"; descriptions[A_Sneak] = "sCrouch_Sneak";
descriptions[A_AutoMove] = "sAuto_Run"; descriptions[A_AutoMove] = "sAuto_Run";
descriptions[A_Jump] = "sJump"; descriptions[A_Jump] = "sJump";
descriptions[A_Journal] = "sJournal"; descriptions[A_Journal] = "sJournal";
@ -863,7 +862,7 @@ namespace MWInput
ret.push_back(A_MoveRight); ret.push_back(A_MoveRight);
ret.push_back(A_TogglePOV); ret.push_back(A_TogglePOV);
ret.push_back(A_Run); ret.push_back(A_Run);
ret.push_back(A_Crouch); ret.push_back(A_Sneak);
ret.push_back(A_Activate); ret.push_back(A_Activate);
ret.push_back(A_ToggleWeapon); ret.push_back(A_ToggleWeapon);
ret.push_back(A_ToggleSpell); ret.push_back(A_ToggleSpell);

View file

@ -150,6 +150,8 @@ namespace MWInput
float mMouseX; float mMouseX;
float mMouseY; float mMouseY;
int mMouseWheel; int mMouseWheel;
bool mDebug;
bool mUserFileExists;
std::map<std::string, bool> mControlSwitch; std::map<std::string, bool> mControlSwitch;
@ -214,9 +216,9 @@ namespace MWInput
A_CycleSpellRight, A_CycleSpellRight,
A_CycleWeaponLeft,//Cycling through weapons A_CycleWeaponLeft,//Cycling through weapons
A_CycleWeaponRight, A_CycleWeaponRight,
A_ToggleSneak, //Toggles Sneak, add Push-Sneak later A_ToggleSneak, //Toggles Sneak
A_ToggleWalk, //Toggle Walking/Running A_ToggleWalk, //Toggle Walking/Running
A_Crouch, A_Sneak,
A_QuickSave, A_QuickSave,
A_QuickLoad, A_QuickLoad,

View file

@ -62,7 +62,7 @@ namespace MWMechanics
for (TIterator iter (begin()); iter!=end(); ++iter) for (TIterator iter (begin()); iter!=end(); ++iter)
{ {
std::pair<ESM::EffectList, bool> effects = getEffectList (iter->first); std::pair<ESM::EffectList, std::pair<bool, bool> > effects = getEffectList (iter->first);
const MWWorld::TimeStamp& start = iter->second.first; const MWWorld::TimeStamp& start = iter->second.first;
float magnitude = iter->second.second; float magnitude = iter->second.second;
@ -74,7 +74,7 @@ namespace MWMechanics
{ {
int duration = iter->mDuration; int duration = iter->mDuration;
if (effects.second) if (effects.second.first)
duration *= magnitude; duration *= magnitude;
MWWorld::TimeStamp end = start; MWWorld::TimeStamp end = start;
@ -85,7 +85,7 @@ namespace MWMechanics
{ {
EffectParam param; EffectParam param;
if (effects.second) if (effects.second.first)
{ {
const ESM::MagicEffect *magicEffect = const ESM::MagicEffect *magicEffect =
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find ( MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
@ -113,15 +113,15 @@ namespace MWMechanics
} }
} }
std::pair<ESM::EffectList, bool> ActiveSpells::getEffectList (const std::string& id) const std::pair<ESM::EffectList, std::pair<bool, bool> > ActiveSpells::getEffectList (const std::string& id) const
{ {
if (const ESM::Spell *spell = if (const ESM::Spell *spell =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search (id)) MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search (id))
return std::make_pair (spell->mEffects, false); return std::make_pair (spell->mEffects, std::make_pair(false, false));
if (const ESM::Potion *potion = if (const ESM::Potion *potion =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Potion>().search (id)) MWBase::Environment::get().getWorld()->getStore().get<ESM::Potion>().search (id))
return std::make_pair (potion->mEffects, false); return std::make_pair (potion->mEffects, std::make_pair(false, true));
if (const ESM::Ingredient *ingredient = if (const ESM::Ingredient *ingredient =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (id)) MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (id))
@ -140,11 +140,12 @@ namespace MWMechanics
effect.mMagnMin = 1; effect.mMagnMin = 1;
effect.mMagnMax = 1; effect.mMagnMax = 1;
std::pair<ESM::EffectList, bool> result; std::pair<ESM::EffectList, std::pair<bool, bool> > result;
result.second.second = true;
result.second.first = true;
result.first.mList.push_back (effect); result.first.mList.push_back (effect);
result.second = true;
return result; return result;
} }
@ -157,7 +158,8 @@ namespace MWMechanics
bool ActiveSpells::addSpell (const std::string& id, const MWWorld::Ptr& actor) bool ActiveSpells::addSpell (const std::string& id, const MWWorld::Ptr& actor)
{ {
std::pair<ESM::EffectList, bool> effects = getEffectList (id); std::pair<ESM::EffectList, std::pair<bool, bool> > effects = getEffectList (id);
bool stacks = effects.second.second;
bool found = false; bool found = false;
@ -178,7 +180,7 @@ namespace MWMechanics
float random = static_cast<float> (std::rand()) / RAND_MAX; float random = static_cast<float> (std::rand()) / RAND_MAX;
if (effects.second) if (effects.second.first)
{ {
// ingredient -> special treatment required. // ingredient -> special treatment required.
const CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor); const CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
@ -194,7 +196,7 @@ namespace MWMechanics
random *= 0.25 * x; random *= 0.25 * x;
} }
if (iter==mSpells.end()) if (iter==mSpells.end() || stacks)
mSpells.insert (std::make_pair (id, mSpells.insert (std::make_pair (id,
std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random))); std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random)));
else else
@ -236,7 +238,7 @@ namespace MWMechanics
double ActiveSpells::timeToExpire (const TIterator& iterator) const double ActiveSpells::timeToExpire (const TIterator& iterator) const
{ {
std::pair<ESM::EffectList, bool> effects = getEffectList (iterator->first); std::pair<ESM::EffectList, std::pair<bool, bool> > effects = getEffectList (iterator->first);
int duration = 0; int duration = 0;
@ -247,7 +249,7 @@ namespace MWMechanics
duration = iter->mDuration; duration = iter->mDuration;
} }
if (effects.second) if (effects.second.first)
duration *= iterator->second.second; duration *= iterator->second.second;
double scaledDuration = duration * double scaledDuration = duration *
@ -274,4 +276,9 @@ namespace MWMechanics
} }
return false; return false;
} }
const ActiveSpells::TContainer& ActiveSpells::getActiveSpells() const
{
return mSpells;
}
} }

View file

@ -30,7 +30,7 @@ namespace MWMechanics
{ {
public: public:
typedef std::map<std::string, std::pair<MWWorld::TimeStamp, float> > TContainer; typedef std::multimap<std::string, std::pair<MWWorld::TimeStamp, float> > TContainer;
typedef TContainer::const_iterator TIterator; typedef TContainer::const_iterator TIterator;
private: private:
@ -44,7 +44,8 @@ namespace MWMechanics
void rebuildEffects() const; void rebuildEffects() const;
std::pair<ESM::EffectList, bool> getEffectList (const std::string& id) const; std::pair<ESM::EffectList, std::pair<bool, bool> > getEffectList (const std::string& id) const;
///< @return (EffectList, (isIngredient, stacks))
public: public:
@ -63,6 +64,8 @@ namespace MWMechanics
const MagicEffects& getMagicEffects() const; const MagicEffects& getMagicEffects() const;
const TContainer& getActiveSpells() const;
TIterator begin() const; TIterator begin() const;
TIterator end() const; TIterator end() const;

View file

@ -46,6 +46,7 @@ static const struct {
{ CharState_Idle8, "idle8" }, { CharState_Idle8, "idle8" },
{ CharState_Idle9, "idle9" }, { CharState_Idle9, "idle9" },
{ CharState_IdleSwim, "idleswim" }, { CharState_IdleSwim, "idleswim" },
{ CharState_IdleSneak, "idlesneak" },
{ CharState_WalkForward, "walkforward" }, { CharState_WalkForward, "walkforward" },
{ CharState_WalkBack, "walkback" }, { CharState_WalkBack, "walkback" },
@ -67,6 +68,11 @@ static const struct {
{ CharState_SwimRunLeft, "swimrunleft" }, { CharState_SwimRunLeft, "swimrunleft" },
{ CharState_SwimRunRight, "swimrunright" }, { CharState_SwimRunRight, "swimrunright" },
{ CharState_SneakForward, "sneakforward" },
{ CharState_SneakBack, "sneakback" },
{ CharState_SneakLeft, "sneakleft" },
{ CharState_SneakRight, "sneakright" },
{ CharState_Jump, "jump" }, { CharState_Jump, "jump" },
{ CharState_Death1, "death1" }, { CharState_Death1, "death1" },
@ -176,6 +182,7 @@ Ogre::Vector3 CharacterController::update(float duration)
bool onground = world->isOnGround(mPtr); bool onground = world->isOnGround(mPtr);
bool inwater = world->isSwimming(mPtr); bool inwater = world->isSwimming(mPtr);
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak);
speed = cls.getSpeed(mPtr); speed = cls.getSpeed(mPtr);
/* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except /* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except
@ -201,31 +208,30 @@ Ogre::Vector3 CharacterController::update(float duration)
if(std::abs(vec.x/2.0f) > std::abs(vec.y) && speed > 0.0f) if(std::abs(vec.x/2.0f) > std::abs(vec.y) && speed > 0.0f)
{ {
if(vec.x > 0.0f) if(vec.x > 0.0f)
setState(isrunning ? setState(inwater ? (isrunning ? CharState_SwimRunRight : CharState_SwimWalkRight)
(inwater ? CharState_SwimRunRight : CharState_RunRight) : : (sneak ? CharState_SneakRight : (isrunning ? CharState_RunRight : CharState_WalkRight)), true);
(inwater ? CharState_SwimWalkRight : CharState_WalkRight), true);
else if(vec.x < 0.0f) else if(vec.x < 0.0f)
setState(isrunning ? setState(inwater ? (isrunning ? CharState_SwimRunLeft : CharState_SwimWalkLeft)
(inwater ? CharState_SwimRunLeft: CharState_RunLeft) : : (sneak ? CharState_SneakLeft : (isrunning ? CharState_RunLeft : CharState_WalkLeft)), true);
(inwater ? CharState_SwimWalkLeft : CharState_WalkLeft), true);
// Apply any forward/backward movement manually // Apply any forward/backward movement manually
movement.y += vec.y * (speed*duration); movement.y += vec.y * (speed*duration);
} }
else if(vec.y != 0.0f && speed > 0.0f) else if(vec.y != 0.0f && speed > 0.0f)
{ {
if(vec.y > 0.0f) if(vec.y > 0.0f)
setState(isrunning ? setState(inwater ? (isrunning ? CharState_SwimRunForward : CharState_SwimWalkForward)
(inwater ? CharState_SwimRunForward : CharState_RunForward) : : (sneak ? CharState_SneakForward : (isrunning ? CharState_RunForward : CharState_WalkForward)), true);
(inwater ? CharState_SwimWalkForward : CharState_WalkForward), true);
else if(vec.y < 0.0f) else if(vec.y < 0.0f)
setState(isrunning ? setState(inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack)
(inwater ? CharState_SwimRunBack : CharState_RunBack) : : (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack)), true);
(inwater ? CharState_SwimWalkBack : CharState_WalkBack), true);
// Apply any sideways movement manually // Apply any sideways movement manually
movement.x += vec.x * (speed*duration); movement.x += vec.x * (speed*duration);
} }
else if(mAnimQueue.size() == 0) else if(mAnimQueue.size() == 0)
setState((inwater ? CharState_IdleSwim : CharState_Idle), true); setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true);
} }
if(mAnimation && !mSkipAnim) if(mAnimation && !mSkipAnim)

View file

@ -25,6 +25,7 @@ enum CharacterState {
CharState_Idle8, CharState_Idle8,
CharState_Idle9, CharState_Idle9,
CharState_IdleSwim, CharState_IdleSwim,
CharState_IdleSneak,
CharState_WalkForward, CharState_WalkForward,
CharState_WalkBack, CharState_WalkBack,
@ -46,6 +47,11 @@ enum CharacterState {
CharState_SwimRunLeft, CharState_SwimRunLeft,
CharState_SwimRunRight, CharState_SwimRunRight,
CharState_SneakForward,
CharState_SneakBack,
CharState_SneakLeft,
CharState_SneakRight,
CharState_Jump, CharState_Jump,
/* Death states must be last! */ /* Death states must be last! */

View file

@ -26,9 +26,9 @@ namespace MWMechanics
return mBase; return mBase;
} }
const T& getModified() const T getModified() const
{ {
return mModified; return std::max(static_cast<T>(0), mModified);
} }
T getModifier() const T getModifier() const
@ -108,7 +108,7 @@ namespace MWMechanics
return mStatic.getBase(); return mStatic.getBase();
} }
const T& getModified() const T getModified() const
{ {
return mStatic.getModified(); return mStatic.getModified();
} }

View file

@ -30,24 +30,13 @@ ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
{ {
Ogre::Entity *ent = mEntityList.mEntities[i]; Ogre::Entity *ent = mEntityList.mEntities[i];
bool transparent = false; for(unsigned int j=0; j < ent->getNumSubEntities(); ++j)
for(unsigned int j=0;!transparent && j < ent->getNumSubEntities(); ++j)
{ {
Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial(); Ogre::SubEntity* subEnt = ent->getSubEntity(j);
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
transparent = pass->isTransparent();
}
}
} }
ent->setVisibilityFlags(RV_Misc); ent->setVisibilityFlags(RV_Misc);
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
} }
setAnimationSource(mesh); setAnimationSource(mesh);
} }

View file

@ -6,6 +6,8 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "animation.hpp" #include "animation.hpp"
#include "activatoranimation.hpp" #include "activatoranimation.hpp"
#include "creatureanimation.hpp" #include "creatureanimation.hpp"
@ -72,6 +74,7 @@ void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv)
NpcAnimation* anim = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), inv, RV_Actors); NpcAnimation* anim = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), inv, RV_Actors);
delete mAllActors[ptr]; delete mAllActors[ptr];
mAllActors[ptr] = anim; mAllActors[ptr] = anim;
mRendering->addWaterRippleEmitter (ptr);
} }
void Actors::insertCreature (const MWWorld::Ptr& ptr) void Actors::insertCreature (const MWWorld::Ptr& ptr)
{ {
@ -79,6 +82,7 @@ void Actors::insertCreature (const MWWorld::Ptr& ptr)
CreatureAnimation* anim = new CreatureAnimation(ptr); CreatureAnimation* anim = new CreatureAnimation(ptr);
delete mAllActors[ptr]; delete mAllActors[ptr];
mAllActors[ptr] = anim; mAllActors[ptr] = anim;
mRendering->addWaterRippleEmitter (ptr);
} }
void Actors::insertActivator (const MWWorld::Ptr& ptr) void Actors::insertActivator (const MWWorld::Ptr& ptr)
{ {
@ -90,6 +94,8 @@ void Actors::insertActivator (const MWWorld::Ptr& ptr)
bool Actors::deleteObject (const MWWorld::Ptr& ptr) bool Actors::deleteObject (const MWWorld::Ptr& ptr)
{ {
mRendering->removeWaterRippleEmitter (ptr);
delete mAllActors[ptr]; delete mAllActors[ptr];
mAllActors.erase(ptr); mAllActors.erase(ptr);
@ -120,6 +126,7 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store)
{ {
if(iter->first.getCell() == store) if(iter->first.getCell() == store)
{ {
mRendering->removeWaterRippleEmitter (iter->first);
delete iter->second; delete iter->second;
mAllActors.erase(iter++); mAllActors.erase(iter++);
} }
@ -172,6 +179,8 @@ void Actors::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
anim->updatePtr(cur); anim->updatePtr(cur);
mAllActors[cur] = anim; mAllActors[cur] = anim;
} }
mRendering->updateWaterRippleEmitterPtr (old, cur);
} }
} }

View file

@ -13,6 +13,7 @@ namespace MWWorld
namespace MWRender namespace MWRender
{ {
class Animation; class Animation;
class RenderingManager;
class Actors class Actors
{ {
@ -20,13 +21,17 @@ namespace MWRender
typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap; typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap;
OEngine::Render::OgreRenderer &mRend; OEngine::Render::OgreRenderer &mRend;
MWRender::RenderingManager* mRendering;
Ogre::SceneNode* mRootNode; Ogre::SceneNode* mRootNode;
CellSceneNodeMap mCellSceneNodes; CellSceneNodeMap mCellSceneNodes;
PtrAnimationMap mAllActors; PtrAnimationMap mAllActors;
public: public:
Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {} Actors(OEngine::Render::OgreRenderer& _rend, MWRender::RenderingManager* rendering)
: mRend(_rend)
, mRendering(rendering)
{}
~Actors(); ~Actors();
void setRootNode(Ogre::SceneNode* root); void setRootNode(Ogre::SceneNode* root);

View file

@ -1,7 +1,7 @@
#ifndef _GAME_RENDER_ANIMATION_H #ifndef _GAME_RENDER_ANIMATION_H
#define _GAME_RENDER_ANIMATION_H #define _GAME_RENDER_ANIMATION_H
#include <components/nifogre/ogre_nif_loader.hpp> #include <components/nifogre/ogrenifloader.hpp>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"

View file

@ -40,6 +40,15 @@ namespace MWRender
void CharacterPreview::setup () void CharacterPreview::setup ()
{ {
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC); mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
/// \todo Read the fallback values from INIImporter (Inventory:Directional*)
Ogre::Light* l = mSceneMgr->createLight();
l->setType (Ogre::Light::LT_DIRECTIONAL);
l->setDirection (Ogre::Vector3(0.3, -0.7, 0.3));
l->setDiffuseColour (Ogre::ColourValue(1,1,1));
mSceneMgr->setAmbientLight (Ogre::ColourValue(0.5, 0.5, 0.5));
mCamera = mSceneMgr->createCamera (mName); mCamera = mSceneMgr->createCamera (mName);
mCamera->setAspectRatio (float(mSizeX) / float(mSizeY)); mCamera->setAspectRatio (float(mSizeX) / float(mSizeY));
@ -51,7 +60,7 @@ namespace MWRender
mNode = renderRoot->createChildSceneNode(); mNode = renderRoot->createChildSceneNode();
mAnimation = new NpcAnimation(mCharacter, mNode, mAnimation = new NpcAnimation(mCharacter, mNode,
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), RV_PlayerPreview); MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0, renderHeadOnly());
mNode->setVisible (false); mNode->setVisible (false);
@ -73,8 +82,6 @@ namespace MWRender
mViewport->setOverlaysEnabled(false); mViewport->setOverlaysEnabled(false);
mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0)); mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0));
mViewport->setShadowsEnabled(false); mViewport->setShadowsEnabled(false);
mViewport->setMaterialScheme("local_map");
mViewport->setVisibilityMask (RV_PlayerPreview);
mRenderTarget->setActive(true); mRenderTarget->setActive(true);
mRenderTarget->setAutoUpdated (false); mRenderTarget->setAutoUpdated (false);
@ -95,7 +102,7 @@ namespace MWRender
delete mAnimation; delete mAnimation;
mAnimation = new NpcAnimation(mCharacter, mNode, mAnimation = new NpcAnimation(mCharacter, mNode,
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), RV_PlayerPreview); MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0, renderHeadOnly());
mNode->setVisible (false); mNode->setVisible (false);
@ -111,6 +118,7 @@ namespace MWRender
InventoryPreview::InventoryPreview(MWWorld::Ptr character) InventoryPreview::InventoryPreview(MWWorld::Ptr character)
: CharacterPreview(character, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 65, -180), Ogre::Vector3(0,65,0)) : CharacterPreview(character, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 65, -180), Ogre::Vector3(0,65,0))
, mSelectionBuffer(NULL)
{ {
} }
@ -143,7 +151,8 @@ namespace MWRender
void InventoryPreview::onSetup () void InventoryPreview::onSetup ()
{ {
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview); if (!mSelectionBuffer)
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0);
mAnimation->play("inventoryhandtohand", "start", "stop", false); mAnimation->play("inventoryhandtohand", "start", "stop", false);
} }
@ -152,7 +161,7 @@ namespace MWRender
RaceSelectionPreview::RaceSelectionPreview() RaceSelectionPreview::RaceSelectionPreview()
: CharacterPreview(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), : CharacterPreview(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(),
512, 512, "CharacterHeadPreview", Ogre::Vector3(0, 120, -35), Ogre::Vector3(0,125,0)) 512, 512, "CharacterHeadPreview", Ogre::Vector3(0, 6, -35), Ogre::Vector3(0,125,0))
, mRef(&mBase) , mRef(&mBase)
{ {
mBase = *mCharacter.get<ESM::NPC>()->mBase; mBase = *mCharacter.get<ESM::NPC>()->mBase;
@ -164,6 +173,8 @@ namespace MWRender
mAnimation->runAnimation(0.0f); mAnimation->runAnimation(0.0f);
mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL); mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL);
updateCamera();
mNode->setVisible (true); mNode->setVisible (true);
mRenderTarget->update(); mRenderTarget->update();
mNode->setVisible (false); mNode->setVisible (false);
@ -180,5 +191,17 @@ namespace MWRender
void RaceSelectionPreview::onSetup () void RaceSelectionPreview::onSetup ()
{ {
mAnimation->play("idle", "start", "stop", false); mAnimation->play("idle", "start", "stop", false);
updateCamera();
}
void RaceSelectionPreview::updateCamera()
{
Ogre::Vector3 scale = mNode->getScale();
Ogre::Vector3 headOffset = mAnimation->getHeadNode()->_getDerivedPosition();
headOffset = mNode->convertLocalToWorldPosition(headOffset);
mCamera->setPosition(headOffset + mPosition * scale);
mCamera->lookAt(headOffset + mPosition*Ogre::Vector3(0,1,0) * scale);
} }
} }

View file

@ -36,6 +36,8 @@ namespace MWRender
virtual void rebuild(); virtual void rebuild();
protected: protected:
virtual bool renderHeadOnly() { return false; }
Ogre::TexturePtr mTexture; Ogre::TexturePtr mTexture;
Ogre::RenderTarget* mRenderTarget; Ogre::RenderTarget* mRenderTarget;
Ogre::Viewport* mViewport; Ogre::Viewport* mViewport;
@ -82,6 +84,12 @@ namespace MWRender
ESM::NPC mBase; ESM::NPC mBase;
MWWorld::LiveCellRef<ESM::NPC> mRef; MWWorld::LiveCellRef<ESM::NPC> mRef;
protected:
virtual bool renderHeadOnly() { return true; }
void updateCamera();
public: public:
RaceSelectionPreview(); RaceSelectionPreview();

View file

@ -31,23 +31,11 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
Ogre::Entity *ent = mEntityList.mEntities[i]; Ogre::Entity *ent = mEntityList.mEntities[i];
ent->setVisibilityFlags(RV_Actors); ent->setVisibilityFlags(RV_Actors);
bool transparent = false; for(unsigned int j=0; j < ent->getNumSubEntities(); ++j)
for(unsigned int j=0;!transparent && j < ent->getNumSubEntities(); ++j)
{ {
Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial(); Ogre::SubEntity* subEnt = ent->getSubEntity(j);
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
transparent = pass->isTransparent();
}
}
} }
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
} }
std::vector<std::string> names; std::vector<std::string> names;

View file

@ -1,6 +1,5 @@
#include "localmap.hpp" #include "localmap.hpp"
#include <OgreOverlayManager.h>
#include <OgreMaterialManager.h> #include <OgreMaterialManager.h>
#include <OgreHardwarePixelBuffer.h> #include <OgreHardwarePixelBuffer.h>
@ -30,6 +29,12 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag
mCellCamera->setProjectionType(PT_ORTHOGRAPHIC); mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
mCameraNode->attachObject(mCellCamera); mCameraNode->attachObject(mCellCamera);
mLight = mRendering->getScene()->createLight();
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
mLight->setDirection (Ogre::Vector3(0.3, 0.3, -0.7));
mLight->setVisible (false);
mLight->setDiffuseColour (ColourValue(0.7,0.7,0.7));
} }
LocalMap::~LocalMap() LocalMap::~LocalMap()
@ -191,22 +196,24 @@ void LocalMap::render(const float x, const float y,
const float zlow, const float zhigh, const float zlow, const float zhigh,
const float xw, const float yw, const std::string& texture) const float xw, const float yw, const std::string& texture)
{ {
// disable fog
// changing FOG_MODE is not a solution when using shaders, thus we have to push linear start/end
const float fStart = mRendering->getScene()->getFogStart();
const float fEnd = mRendering->getScene()->getFogEnd();
const ColourValue& clr = mRendering->getScene()->getFogColour();
mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, 1000000, 10000000);
// make everything visible
mRendering->getScene()->setAmbientLight(ColourValue(1,1,1));
mRenderingManager->disableLights();
mCameraNode->setPosition(Vector3(x, y, zhigh+100000));
//mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
mCellCamera->setFarClipDistance(0); // infinite mCellCamera->setFarClipDistance(0); // infinite
mCellCamera->setOrthoWindow(xw, yw); mCellCamera->setOrthoWindow(xw, yw);
mCameraNode->setPosition(Vector3(x, y, zhigh+100000));
// disable fog (only necessary for fixed function, the shader based
// materials already do this through local_map material configuration)
float oldFogStart = mRendering->getScene()->getFogStart();
float oldFogEnd = mRendering->getScene()->getFogEnd();
Ogre::ColourValue oldFogColour = mRendering->getScene()->getFogColour();
mRendering->getScene()->setFog(FOG_NONE);
// set up lighting
Ogre::ColourValue oldAmbient = mRendering->getScene()->getAmbientLight();
mRendering->getScene()->setAmbientLight(Ogre::ColourValue(0.3, 0.3, 0.3));
mRenderingManager->disableLights(true);
mLight->setVisible(true);
TexturePtr tex; TexturePtr tex;
// try loading from memory // try loading from memory
@ -231,14 +238,13 @@ void LocalMap::render(const float x, const float y,
TU_RENDERTARGET); TU_RENDERTARGET);
RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); RenderTarget* rtt = tex->getBuffer()->getRenderTarget();
rtt->setAutoUpdated(false); rtt->setAutoUpdated(false);
Viewport* vp = rtt->addViewport(mCellCamera); Viewport* vp = rtt->addViewport(mCellCamera);
vp->setOverlaysEnabled(false); vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false); vp->setShadowsEnabled(false);
vp->setBackgroundColour(ColourValue(0, 0, 0)); vp->setBackgroundColour(ColourValue(0, 0, 0));
vp->setVisibilityMask(RV_Map); vp->setVisibilityMask(RV_Map);
// use fallback techniques without shadows and without mrt
vp->setMaterialScheme("local_map"); vp->setMaterialScheme("local_map");
rtt->update(); rtt->update();
@ -272,11 +278,12 @@ void LocalMap::render(const float x, const float y,
//rtt->writeContentsToFile("./" + texture + ".jpg"); //rtt->writeContentsToFile("./" + texture + ".jpg");
} }
} }
mRenderingManager->enableLights(true);
mRenderingManager->enableLights(); mLight->setVisible(false);
// re-enable fog // re-enable fog
mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); mRendering->getScene()->setFog(FOG_LINEAR, oldFogColour, 0, oldFogStart, oldFogEnd);
mRendering->getScene()->setAmbientLight(oldAmbient);
} }
void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y) void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y)

View file

@ -4,6 +4,7 @@
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include <OgreAxisAlignedBox.h> #include <OgreAxisAlignedBox.h>
#include <OgreColourValue.h>
namespace MWWorld namespace MWWorld
{ {
@ -90,6 +91,9 @@ namespace MWRender
Ogre::SceneNode* mCameraPosNode; Ogre::SceneNode* mCameraPosNode;
Ogre::SceneNode* mCameraRotNode; Ogre::SceneNode* mCameraRotNode;
// directional light from a fixed angle
Ogre::Light* mLight;
float mAngle; float mAngle;
const Ogre::Vector2 rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle); const Ogre::Vector2 rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle);

View file

@ -54,7 +54,7 @@ NpcAnimation::~NpcAnimation()
} }
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags) NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags, bool headOnly)
: Animation(ptr), : Animation(ptr),
mStateID(-1), mStateID(-1),
mTimeToChange(0), mTimeToChange(0),
@ -70,7 +70,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
mPants(inv.end()), mPants(inv.end()),
mGloveL(inv.end()), mGloveL(inv.end()),
mGloveR(inv.end()), mGloveR(inv.end()),
mSkirtIter(inv.end()) mSkirtIter(inv.end()),
mHeadOnly(headOnly)
{ {
mNpc = mPtr.get<ESM::NPC>()->mBase; mNpc = mPtr.get<ESM::NPC>()->mBase;
@ -104,25 +105,14 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
Ogre::Entity *base = mEntityList.mEntities[i]; Ogre::Entity *base = mEntityList.mEntities[i];
base->getUserObjectBindings().setUserAny(Ogre::Any(-1)); base->getUserObjectBindings().setUserAny(Ogre::Any(-1));
base->setVisibilityFlags(mVisibilityFlags); if (mVisibilityFlags != 0)
base->setVisibilityFlags(mVisibilityFlags);
bool transparent = false; for(unsigned int j=0; j < base->getNumSubEntities(); ++j)
for(unsigned int j=0;!transparent && j < base->getNumSubEntities();++j)
{ {
Ogre::MaterialPtr mat = base->getSubEntity(j)->getMaterial(); Ogre::SubEntity* subEnt = base->getSubEntity(j);
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
transparent = pass->isTransparent();
}
}
} }
base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
} }
std::vector<std::string> skelnames(1, smodel); std::vector<std::string> skelnames(1, smodel);
@ -226,7 +216,7 @@ void NpcAnimation::updateParts(bool forceupdate)
if(!forceupdate) if(!forceupdate)
return; return;
for(size_t i = 0;i < slotlistsize;i++) for(size_t i = 0;i < slotlistsize && !mHeadOnly;i++)
{ {
MWWorld::ContainerStoreIterator iter = inv.getSlot(slotlist[i].slot); MWWorld::ContainerStoreIterator iter = inv.getSlot(slotlist[i].slot);
@ -263,6 +253,9 @@ void NpcAnimation::updateParts(bool forceupdate)
if(mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1) if(mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1)
addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1, mHairModel); addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1, mHairModel);
if (mHeadOnly)
return;
static const struct { static const struct {
ESM::PartReferenceType type; ESM::PartReferenceType type;
const char name[2][12]; const char name[2][12];
@ -322,25 +315,14 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int
for(size_t i = 0;i < parts.size();i++) for(size_t i = 0;i < parts.size();i++)
{ {
parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group)); parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
parts[i]->setVisibilityFlags(mVisibilityFlags); if (mVisibilityFlags != 0)
parts[i]->setVisibilityFlags(mVisibilityFlags);
bool transparent = false; for(unsigned int j=0; j < parts[i]->getNumSubEntities(); ++j)
for(unsigned int j=0;!transparent && j < parts[i]->getNumSubEntities();++j)
{ {
Ogre::MaterialPtr mat = parts[i]->getSubEntity(j)->getMaterial(); Ogre::SubEntity* subEnt = parts[i]->getSubEntity(j);
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
transparent = pass->isTransparent();
}
}
} }
parts[i]->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
} }
if(entities.mSkelBase) if(entities.mSkelBase)
{ {
@ -471,4 +453,9 @@ void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::
} }
} }
Ogre::Node* NpcAnimation::getHeadNode()
{
return mEntityList.mSkelBase->getSkeleton()->getBone("Bip01 Head");
}
} }

View file

@ -39,6 +39,7 @@ private:
std::string mHeadModel; std::string mHeadModel;
std::string mHairModel; std::string mHairModel;
std::string mBodyPrefix; std::string mBodyPrefix;
bool mHeadOnly;
float mTimeToChange; float mTimeToChange;
MWWorld::ContainerStoreIterator mRobe; MWWorld::ContainerStoreIterator mRobe;
@ -73,11 +74,13 @@ private:
public: public:
NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node,
MWWorld::InventoryStore& inv, int visibilityFlags); MWWorld::InventoryStore& inv, int visibilityFlags, bool headOnly=false);
virtual ~NpcAnimation(); virtual ~NpcAnimation();
virtual Ogre::Vector3 runAnimation(float timepassed); virtual Ogre::Vector3 runAnimation(float timepassed);
Ogre::Node* getHeadNode();
void forceUpdate() void forceUpdate()
{ updateParts(true); } { updateParts(true); }
}; };

View file

@ -7,7 +7,7 @@
#include <OgreSubEntity.h> #include <OgreSubEntity.h>
#include <OgreStaticGeometry.h> #include <OgreStaticGeometry.h>
#include <components/nifogre/ogre_nif_loader.hpp> #include <components/nifogre/ogrenifloader.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
@ -129,36 +129,28 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
mBounds[ptr.getCell()].merge(bounds); mBounds[ptr.getCell()].merge(bounds);
bool transparent = false; bool anyTransparency = false;
for(size_t i = 0;!transparent && i < entities.mEntities.size();i++) for(size_t i = 0;!anyTransparency && i < entities.mEntities.size();i++)
{ {
Ogre::Entity *ent = entities.mEntities[i]; Ogre::Entity *ent = entities.mEntities[i];
for(unsigned int i=0;!transparent && i < ent->getNumSubEntities(); ++i) for(unsigned int i=0;!anyTransparency && i < ent->getNumSubEntities(); ++i)
{ {
Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial(); anyTransparency = ent->getSubEntity(i)->getMaterial()->isTransparent();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
transparent = pass->isTransparent();
}
}
} }
} }
if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent) if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || anyTransparency)
{ {
for(size_t i = 0;i < entities.mEntities.size();i++) for(size_t i = 0;i < entities.mEntities.size();i++)
{ {
Ogre::Entity *ent = entities.mEntities[i]; Ogre::Entity *ent = entities.mEntities[i];
for(unsigned int i=0; i < ent->getNumSubEntities(); ++i)
{
Ogre::SubEntity* subEnt = ent->getSubEntity(i);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
} }
} }
else else
@ -203,7 +195,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool
sg->setCastShadows(true); sg->setCastShadows(true);
sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); sg->setRenderQueueGroup(RQG_Main);
std::vector<Ogre::Entity*>::reverse_iterator iter = entities.mEntities.rbegin(); std::vector<Ogre::Entity*>::reverse_iterator iter = entities.mEntities.rbegin();
while(iter != entities.mEntities.rend()) while(iter != entities.mEntities.rend())
@ -264,17 +256,16 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, Ogre::Entity* skelBase, Ogre
info.time = Ogre::Math::RangeRandom(-500, +500); info.time = Ogre::Math::RangeRandom(-500, +500);
info.phase = Ogre::Math::RangeRandom(-500, +500); info.phase = Ogre::Math::RangeRandom(-500, +500);
// adjust the lights depending if we're in an interior or exterior cell // changed to linear to look like morrowind
// quadratic means the light intensity falls off quite fast, resulting in a
// dark, atmospheric environment (perfect for exteriors)
// for interiors, we want more "warm" lights, so use linear attenuation.
bool quadratic = false; bool quadratic = false;
/*
if (!lightOutQuadInLin) if (!lightOutQuadInLin)
quadratic = lightQuadratic; quadratic = lightQuadratic;
else else
{ {
quadratic = !info.interior; quadratic = !info.interior;
} }
*/
if (!quadratic) if (!quadratic)
{ {

View file

@ -15,8 +15,8 @@ using namespace Ogre;
OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) : OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) :
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0), mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0),
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false), mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false), mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false),
mBBNode(0) mBBNode(0), mActive(false)
{ {
mRendering = renderer; mRendering = renderer;
mSunNode = sunNode; mSunNode = sunNode;
@ -94,6 +94,9 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
OcclusionQuery::~OcclusionQuery() OcclusionQuery::~OcclusionQuery()
{ {
mRendering->getScene()->removeRenderObjectListener (this);
mRendering->getScene()->removeRenderQueueListener(this);
RenderSystem* renderSystem = Root::getSingleton().getRenderSystem(); RenderSystem* renderSystem = Root::getSingleton().getRenderSystem();
if (mSunTotalAreaQuery) renderSystem->destroyHardwareOcclusionQuery(mSunTotalAreaQuery); if (mSunTotalAreaQuery) renderSystem->destroyHardwareOcclusionQuery(mSunTotalAreaQuery);
if (mSunVisibleAreaQuery) renderSystem->destroyHardwareOcclusionQuery(mSunVisibleAreaQuery); if (mSunVisibleAreaQuery) renderSystem->destroyHardwareOcclusionQuery(mSunVisibleAreaQuery);
@ -108,8 +111,10 @@ bool OcclusionQuery::supported()
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
const LightList* pLightList, bool suppressRenderStateChanges) const LightList* pLightList, bool suppressRenderStateChanges)
{ {
if (!mActive) return;
// The following code activates and deactivates the occlusion queries // The following code activates and deactivates the occlusion queries
// so that the queries only include the rendering of their intended targets // so that the queries only include the rendering of the intended meshes
// Close the last occlusion query // Close the last occlusion query
// Each occlusion query should only last a single rendering // Each occlusion query should only last a single rendering
@ -146,6 +151,8 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass
void OcclusionQuery::renderQueueEnded(uint8 queueGroupId, const String& invocation, bool& repeatThisInvocation) void OcclusionQuery::renderQueueEnded(uint8 queueGroupId, const String& invocation, bool& repeatThisInvocation)
{ {
if (!mActive) return;
if (mActiveQuery != NULL) if (mActiveQuery != NULL)
{ {
mActiveQuery->endOcclusionQuery(); mActiveQuery->endOcclusionQuery();
@ -247,6 +254,8 @@ void OcclusionQuery::occlusionTest(const Ogre::Vector3& position, Ogre::SceneNod
mObjectNode->setScale( Vector3(1,1,1)*(position - mRendering->getCamera()->getRealPosition()).length() ); mObjectNode->setScale( Vector3(1,1,1)*(position - mRendering->getCamera()->getRealPosition()).length() );
mQuerySingleObjectRequested = true; mQuerySingleObjectRequested = true;
mDoQuery = true;
} }
bool OcclusionQuery::occlusionTestPending() bool OcclusionQuery::occlusionTestPending()

View file

@ -29,6 +29,12 @@ namespace MWRender
*/ */
bool supported(); bool supported();
/**
* make sure to disable occlusion queries before updating unrelated render targets
* @param active
*/
void setActive (bool active) { mActive = active; }
/** /**
* per-frame update * per-frame update
*/ */
@ -85,9 +91,10 @@ namespace MWRender
bool mTestResult; bool mTestResult;
bool mActive;
bool mSupported; bool mSupported;
bool mDoQuery; bool mDoQuery;
bool mDoQuery2;
bool mQuerySingleObjectRequested; bool mQuerySingleObjectRequested;
bool mQuerySingleObjectStarted; bool mQuerySingleObjectStarted;

View file

@ -0,0 +1,107 @@
#include "refraction.hpp"
#include <OgreCamera.h>
#include <OgreTextureManager.h>
#include <OgreSceneManager.h>
#include <OgreHardwarePixelBuffer.h>
#include <OgreRenderTarget.h>
#include <OgreViewport.h>
#include <OgreRoot.h>
#include <extern/shiny/Main/Factory.hpp>
#include "renderconst.hpp"
namespace MWRender
{
Refraction::Refraction(Ogre::Camera *parentCamera)
: mParentCamera(parentCamera)
, mRenderActive(false)
, mIsUnderwater(false)
{
mCamera = mParentCamera->getSceneManager()->createCamera("RefractionCamera");
mParentCamera->getSceneManager()->addRenderQueueListener(this);
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual("WaterRefraction",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
mRenderTarget = texture->getBuffer()->getRenderTarget();
Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera);
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky);
vp->setMaterialScheme("water_refraction");
vp->setBackgroundColour (Ogre::ColourValue(0.18039, 0.23137, 0.25490));
mRenderTarget->setAutoUpdated(true);
mRenderTarget->addListener(this);
}
Refraction::~Refraction()
{
mRenderTarget->removeListener(this);
Ogre::TextureManager::getSingleton().remove("WaterRefraction");
mParentCamera->getSceneManager()->destroyCamera(mCamera);
mParentCamera->getSceneManager()->removeRenderQueueListener(this);
}
void Refraction::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
mParentCamera->getParentSceneNode ()->needUpdate ();
mCamera->setOrientation(mParentCamera->getDerivedOrientation());
mCamera->setPosition(mParentCamera->getDerivedPosition());
mCamera->setNearClipDistance(mParentCamera->getNearClipDistance());
mCamera->setFarClipDistance(mParentCamera->getFarClipDistance());
mCamera->setAspectRatio(mParentCamera->getAspectRatio());
mCamera->setFOVy(mParentCamera->getFOVy());
// for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane.
// since all we are interested in is depth, we only need the third row of the matrix.
Ogre::Matrix4 projMatrix = mCamera->getProjectionMatrixWithRSDepth () * mCamera->getViewMatrix ();
sh::Vector4* row3 = new sh::Vector4(projMatrix[2][0], projMatrix[2][1], projMatrix[2][2], projMatrix[2][3]);
sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty<sh::Vector4> (row3));
// enable clip plane here to take advantage of CPU culling for overwater or underwater objects
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane);
mRenderActive = true;
}
void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
mCamera->disableCustomNearClipPlane ();
mRenderActive = false;
}
void Refraction::setHeight(float height)
{
mNearClipPlane = Ogre::Plane( -Ogre::Vector3(0,0,1), -(height + 5));
mNearClipPlaneUnderwater = Ogre::Plane( Ogre::Vector3(0,0,1), height - 5);
}
void Refraction::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation)
{
// We don't want the sky to get clipped by custom near clip plane (the water plane)
if (queueGroupId < 20 && mRenderActive)
{
mCamera->disableCustomNearClipPlane();
Ogre::Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
}
}
void Refraction::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
{
if (queueGroupId < 20 && mRenderActive)
{
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane);
Ogre::Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
}
}
void Refraction::setActive(bool active)
{
mRenderTarget->setActive(active);
}
}

View file

@ -0,0 +1,45 @@
#ifndef MWRENDER_REFRACTION_H
#define MWRENDER_REFRACTION_H
#include <OgrePlane.h>
#include <OgreRenderTargetListener.h>
#include <OgreRenderQueueListener.h>
namespace Ogre
{
class Camera;
class RenderTarget;
}
namespace MWRender
{
class Refraction : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener
{
public:
Refraction(Ogre::Camera* parentCamera);
~Refraction();
void setHeight (float height);
void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void setUnderwater(bool underwater) {mIsUnderwater = underwater;}
void setActive (bool active);
void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation);
void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation);
private:
Ogre::Camera* mParentCamera;
Ogre::Camera* mCamera;
Ogre::RenderTarget* mRenderTarget;
Ogre::Plane mNearClipPlane;
Ogre::Plane mNearClipPlaneUnderwater;
bool mRenderActive;
bool mIsUnderwater;
};
}
#endif

View file

@ -20,7 +20,7 @@ enum RenderQueueGroups
RQG_UnderWater = Ogre::RENDER_QUEUE_4, RQG_UnderWater = Ogre::RENDER_QUEUE_4,
RQG_Water = Ogre::RENDER_QUEUE_7+1, RQG_Water = RQG_Alpha,
// Sky late (sun & sun flare) // Sky late (sun & sun flare)
RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE
@ -54,9 +54,10 @@ enum VisibilityFlags
RV_OcclusionQuery = 256, RV_OcclusionQuery = 256,
RV_PlayerPreview = 512, RV_Debug = 512,
RV_Debug = 1024, // overlays, we only want these on the main render target
RV_Overlay = 1024,
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water
}; };

View file

@ -49,7 +49,12 @@ namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine)
: mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine) : mRendering(_rend)
, mObjects(mRendering)
, mActors(mRendering, this)
, mAmbientMode(0)
, mSunEnabled(0)
, mPhysicsEngine(engine)
{ {
// select best shader mode // select best shader mode
bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos);
@ -65,6 +70,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
mRendering.setWindowEventListener(this); mRendering.setWindowEventListener(this);
mRendering.getWindow()->addListener(this);
mCompositors = new Compositors(mRendering.getViewport()); mCompositors = new Compositors(mRendering.getViewport());
mWater = 0; mWater = 0;
@ -93,7 +100,9 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mFactory->loadAllFiles(); mFactory->loadAllFiles();
// Set default mipmap level (NB some APIs ignore this) // Set default mipmap level (NB some APIs ignore this)
TextureManager::getSingleton().setDefaultNumMipmaps(Settings::Manager::getInt("num mipmaps", "General")); // Mipmap generation is currently disabled because it causes issues on Intel/AMD
//TextureManager::getSingleton().setDefaultNumMipmaps(Settings::Manager::getInt("num mipmaps", "General"));
TextureManager::getSingleton().setDefaultNumMipmaps(0);
// Set default texture filtering options // Set default texture filtering options
TextureFilterOptions tfo; TextureFilterOptions tfo;
@ -114,30 +123,25 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
//mRendering.getScene()->setCameraRelativeRendering(true); //mRendering.getScene()->setCameraRelativeRendering(true);
// disable unsupported effects // disable unsupported effects
//const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
if (!waterShaderSupported())
Settings::Manager::setBool("shader", "Water", false);
if (!Settings::Manager::getBool("shaders", "Objects")) if (!Settings::Manager::getBool("shaders", "Objects"))
Settings::Manager::setBool("enabled", "Shadows", false); Settings::Manager::setBool("enabled", "Shadows", false);
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));
sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false");
sh::Factory::getInstance ().setGlobalSetting ("fog", "true"); sh::Factory::getInstance ().setGlobalSetting ("fog", "true");
sh::Factory::getInstance ().setGlobalSetting ("lighting", "true");
sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects")); sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects"));
sh::Factory::getInstance ().setGlobalSetting ("terrain_num_lights", Settings::Manager::getString ("num lights", "Terrain")); sh::Factory::getInstance ().setGlobalSetting ("terrain_num_lights", Settings::Manager::getString ("num lights", "Terrain"));
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water"));
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");
sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false");
sh::Factory::getInstance ().setSharedParameter ("viewportBackground", sh::makeProperty<sh::Vector3> (new sh::Vector3(0,0,0)));
sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(0.0))); sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(0.0)));
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2))); sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2)));
sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6))); sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6)));
sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty<sh::FloatValue>(new sh::FloatValue( sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false");
Settings::Manager::getFloat ("gamma", "Video")))); sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false");
sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty<sh::Vector4> (new sh::Vector4(0,0,0,0)));
applyCompositors(); applyCompositors();
@ -166,11 +170,14 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mDebugging = new Debugging(mRootNode, engine); mDebugging = new Debugging(mRootNode, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this); mLocalMap = new MWRender::LocalMap(&mRendering, this);
mWater = new MWRender::Water(mRendering.getCamera(), this);
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
} }
RenderingManager::~RenderingManager () RenderingManager::~RenderingManager ()
{ {
mRendering.getWindow()->removeListener(this);
mRendering.removeWindowEventListener(this); mRendering.removeWindowEventListener(this);
delete mPlayer; delete mPlayer;
@ -214,15 +221,12 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store)
void RenderingManager::removeWater () void RenderingManager::removeWater ()
{ {
if(mWater){ mWater->setActive(false);
mWater->setActive(false);
}
} }
void RenderingManager::toggleWater() void RenderingManager::toggleWater()
{ {
if (mWater) mWater->toggle();
mWater->toggle();
} }
void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store) void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
@ -270,28 +274,31 @@ bool RenderingManager::rotateObject( const MWWorld::Ptr &ptr, Ogre::Vector3 &rot
if (!isPlayer && isActive) if (!isPlayer && isActive)
{ {
Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X); Ogre::Quaternion xr(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yr(Ogre::Radian(rot.y), Ogre::Vector3::UNIT_Y); Ogre::Quaternion yr(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y);
Ogre::Quaternion zr(Ogre::Radian(rot.z), Ogre::Vector3::UNIT_Z); Ogre::Quaternion zr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
Ogre::Quaternion newo = adjust ? (xr * yr * zr) * ptr.getRefData().getBaseNode()->getOrientation() : xr * yr * zr;
rot.x = newo.x; Ogre::Quaternion xref(Ogre::Radian(-ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::UNIT_X);
rot.y = newo.y; Ogre::Quaternion yref(Ogre::Radian(-ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::UNIT_Y);
rot.z = newo.z; Ogre::Quaternion zref(Ogre::Radian(-ptr.getRefData().getPosition().rot[2]), Ogre::Vector3::UNIT_Z);
Ogre::Quaternion newo = adjust ? (xr * yr * zr) * (xref*yref*zref) : xr * yr * zr;
Ogre::Matrix3 mat;
newo.ToRotationMatrix(mat);
Ogre::Radian ax,ay,az;
mat.ToEulerAnglesXYZ(ax,ay,az);
rot.x = -ax.valueRadians();
rot.y = -ay.valueRadians();
rot.z = -az.valueRadians();
ptr.getRefData().getBaseNode()->setOrientation(newo); ptr.getRefData().getBaseNode()->setOrientation(newo);
} }
else if(isPlayer) else if(isPlayer)
{ {
rot.x = mPlayer->getPitch(); rot.x = -mPlayer->getPitch();
rot.z = mPlayer->getYaw(); rot.z = mPlayer->getYaw();
} }
else if (adjust)
{
// Stored and passed in radians
float *f = ptr.getRefData().getPosition().rot;
rot.x += f[0];
rot.y += f[1];
rot.z += f[2];
}
return force; return force;
} }
@ -313,6 +320,18 @@ RenderingManager::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &
void RenderingManager::update (float duration, bool paused) void RenderingManager::update (float duration, bool paused)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld();
// player position
MWWorld::RefData &data =
MWBase::Environment::get()
.getWorld()
->getPlayer()
.getPlayer()
.getRefData();
float *_playerPos = data.getPosition().pos;
Ogre::Vector3 playerPos(_playerPos[0], _playerPos[1], _playerPos[2]);
Ogre::Vector3 orig, dest; Ogre::Vector3 orig, dest;
mPlayer->setCameraDistance(); mPlayer->setCameraDistance();
if (!mPlayer->getPosition(orig, dest)) { if (!mPlayer->getPosition(orig, dest)) {
@ -326,19 +345,23 @@ void RenderingManager::update (float duration, bool paused)
mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false); mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false);
} }
} }
mOcclusionQuery->update(duration); mOcclusionQuery->update(duration);
mVideoPlayer->update (); mVideoPlayer->update ();
mRendering.update(duration); mRendering.update(duration);
Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f);
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();
applyFog(world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam));
if(paused) if(paused)
{ {
Ogre::ControllerManager::getSingleton().setTimeFactor(0.f);
return; return;
} }
Ogre::ControllerManager::getSingleton().setTimeFactor(
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);
mPlayer->update(duration); mPlayer->update(duration);
@ -350,38 +373,33 @@ void RenderingManager::update (float duration, bool paused)
mSkyManager->setGlare(mOcclusionQuery->getSunVisibility()); mSkyManager->setGlare(mOcclusionQuery->getSunVisibility());
MWWorld::RefData &data =
MWBase::Environment::get()
.getWorld()
->getPlayer()
.getPlayer()
.getRefData();
float *fpos = data.getPosition().pos;
// only for LocalMap::updatePlayer()
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
Ogre::SceneNode *node = data.getBaseNode(); Ogre::SceneNode *node = data.getBaseNode();
//Ogre::Quaternion orient = //Ogre::Quaternion orient =
//node->convertLocalToWorldOrientation(node->_getDerivedOrientation()); //node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
Ogre::Quaternion orient = Ogre::Quaternion orient =
node->_getDerivedOrientation(); node->_getDerivedOrientation();
mLocalMap->updatePlayer(pos, orient); mLocalMap->updatePlayer(playerPos, orient);
if (mWater) { mWater->updateUnderwater(
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); world->isUnderwater(
world->getPlayer().getPlayer().getCell(),
cam)
);
MWBase::World *world = MWBase::Environment::get().getWorld(); mWater->update(duration, playerPos);
}
mWater->updateUnderwater( void RenderingManager::preRenderTargetUpdate(const RenderTargetEvent &evt)
world->isUnderwater( {
world->getPlayer().getPlayer().getCell(), mOcclusionQuery->setActive(true);
cam) }
);
mWater->update(duration); void RenderingManager::postRenderTargetUpdate(const RenderTargetEvent &evt)
} {
// deactivate queries to make sure we aren't getting false results from several misc render targets
// (will be reactivated at the bottom of this method)
mOcclusionQuery->setActive(false);
} }
void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store) void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
@ -393,10 +411,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
|| ((store->mCell->isExterior()) || ((store->mCell->isExterior())
&& !lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land. && !lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land.
{ {
if(mWater == 0) mWater->changeCell(store->mCell);
mWater = new MWRender::Water(mRendering.getCamera(), this, store->mCell);
else
mWater->changeCell(store->mCell);
mWater->setActive(true); mWater->setActive(true);
} }
else else
@ -405,8 +420,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
void RenderingManager::setWaterHeight(const float height) void RenderingManager::setWaterHeight(const float height)
{ {
if (mWater) mWater->setHeight(height);
mWater->setHeight(height);
} }
void RenderingManager::skyEnable () void RenderingManager::skyEnable ()
@ -491,31 +505,34 @@ void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell)
color.setAsABGR (mCell.mCell->mAmbi.mFog); color.setAsABGR (mCell.mCell->mAmbi.mFog);
configureFog(mCell.mCell->mAmbi.mFogDensity, color); configureFog(mCell.mCell->mAmbi.mFogDensity, color);
if (mWater)
mWater->setViewportBackground (Ogre::ColourValue(0.8f, 0.9f, 1.0f));
} }
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
{ {
mFogColour = colour;
float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance"); float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance"); mFogStart = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance"); mFogEnd = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
mRendering.getCamera()->setFarClipDistance ( max / density );
mRendering.getViewport()->setBackgroundColour (colour);
if (mWater)
mWater->setViewportBackground (colour);
sh::Factory::getInstance ().setSharedParameter ("viewportBackground",
sh::makeProperty<sh::Vector3> (new sh::Vector3(colour.r, colour.g, colour.b)));
mRendering.getCamera()->setFarClipDistance ( Settings::Manager::getFloat("max viewing distance", "Viewing distance") / density );
} }
void RenderingManager::applyFog (bool underwater)
{
if (!underwater)
{
mRendering.getScene()->setFog (FOG_LINEAR, mFogColour, 0, mFogStart, mFogEnd);
mRendering.getViewport()->setBackgroundColour (mFogColour);
mWater->setViewportBackground (mFogColour);
}
else
{
mRendering.getScene()->setFog (FOG_LINEAR, Ogre::ColourValue(0.18039, 0.23137, 0.25490), 0, 0, 1000);
mRendering.getViewport()->setBackgroundColour (Ogre::ColourValue(0.18039, 0.23137, 0.25490));
mWater->setViewportBackground (Ogre::ColourValue(0.18039, 0.23137, 0.25490));
}
}
void RenderingManager::setAmbientMode() void RenderingManager::setAmbientMode()
{ {
@ -588,22 +605,28 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour)
mTerrainManager->setAmbient(colour); mTerrainManager->setAmbient(colour);
} }
void RenderingManager::sunEnable() void RenderingManager::sunEnable(bool real)
{ {
// Don't disable the light, as the shaders assume the first light to be directional. if (real && mSun) mSun->setVisible(true);
//if (mSun) mSun->setVisible(true); else
mSunEnabled = true; {
// Don't disable the light, as the shaders assume the first light to be directional.
mSunEnabled = true;
}
} }
void RenderingManager::sunDisable() void RenderingManager::sunDisable(bool real)
{ {
// Don't disable the light, as the shaders assume the first light to be directional. if (real && mSun) mSun->setVisible(false);
//if (mSun) mSun->setVisible(false); else
mSunEnabled = false;
if (mSun)
{ {
mSun->setDiffuseColour(ColourValue(0,0,0)); // Don't disable the light, as the shaders assume the first light to be directional.
mSun->setSpecularColour(ColourValue(0,0,0)); mSunEnabled = false;
if (mSun)
{
mSun->setDiffuseColour(ColourValue(0,0,0));
mSun->setSpecularColour(ColourValue(0,0,0));
}
} }
} }
@ -633,21 +656,16 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell)
mLocalMap->saveFogOfWar(cell); mLocalMap->saveFogOfWar(cell);
} }
void RenderingManager::disableLights() void RenderingManager::disableLights(bool sun)
{ {
mObjects.disableLights(); mObjects.disableLights();
sunDisable(); sunDisable(sun);
} }
void RenderingManager::enableLights() void RenderingManager::enableLights(bool sun)
{ {
mObjects.enableLights(); mObjects.enableLights();
sunEnable(); sunEnable(sun);
}
const bool RenderingManager::useMRT()
{
return Settings::Manager::getBool("shader", "Water");
} }
Shadows* RenderingManager::getShadows() Shadows* RenderingManager::getShadows()
@ -714,6 +732,7 @@ Compositors* RenderingManager::getCompositors()
void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings)
{ {
bool changeRes = false; bool changeRes = false;
bool rebuild = false; // rebuild static geometry (necessary after any material changes)
for (Settings::CategorySettingVector::const_iterator it=settings.begin(); for (Settings::CategorySettingVector::const_iterator it=settings.begin();
it != settings.end(); ++it) it != settings.end(); ++it)
{ {
@ -749,25 +768,19 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
else if (it->second == "shader" && it->first == "Water") else if (it->second == "shader" && it->first == "Water")
{ {
applyCompositors(); applyCompositors();
sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false");
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");
mObjects.rebuildStaticGeometry (); rebuild = true;
mRendering.getViewport ()->setClearEveryFrame (true); mRendering.getViewport ()->setClearEveryFrame (true);
} }
else if (it->second == "underwater effect" && it->first == "Water") else if (it->second == "refraction" && it->first == "Water")
{ {
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water")); sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false");
mObjects.rebuildStaticGeometry (); rebuild = true;
} }
else if (it->second == "shaders" && it->first == "Objects") else if (it->second == "shaders" && it->first == "Objects")
{ {
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));
mObjects.rebuildStaticGeometry (); rebuild = true;
}
else if (it->second == "gamma" && it->first == "Video")
{
sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(
Settings::Manager::getFloat ("gamma", "Video"))));
} }
else if (it->second == "shader mode" && it->first == "General") else if (it->second == "shader mode" && it->first == "General")
{ {
@ -780,13 +793,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
else else
lang = sh::Language_CG; lang = sh::Language_CG;
sh::Factory::getInstance ().setCurrentLanguage (lang); sh::Factory::getInstance ().setCurrentLanguage (lang);
mObjects.rebuildStaticGeometry (); rebuild = true;
} }
else if (it->first == "Shadows") else if (it->first == "Shadows")
{ {
mShadows->recreate (); mShadows->recreate ();
mObjects.rebuildStaticGeometry (); rebuild = true;
} }
} }
@ -802,8 +815,10 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y);
} }
if (mWater) mWater->processChangedSettings(settings);
mWater->processChangedSettings(settings);
if (rebuild)
mObjects.rebuildStaticGeometry();
} }
void RenderingManager::setMenuTransparency(float val) void RenderingManager::setMenuTransparency(float val)
@ -824,13 +839,12 @@ void RenderingManager::windowResized(Ogre::RenderWindow* rw)
mRendering.adjustViewport(); mRendering.adjustViewport();
mCompositors->recreate(); mCompositors->recreate();
mWater->assignTextures();
mVideoPlayer->setResolution (rw->getWidth(), rw->getHeight()); mVideoPlayer->setResolution (rw->getWidth(), rw->getHeight());
const Settings::CategorySettingVector& changed = Settings::Manager::apply(); const Settings::CategorySettingVector& changed = Settings::Manager::apply();
MWBase::Environment::get().getInputManager()->processChangedSettings(changed); //FIXME MWBase::Environment::get().getInputManager()->processChangedSettings(changed);
MWBase::Environment::get().getWindowManager()->processChangedSettings(changed); // FIXME MWBase::Environment::get().getWindowManager()->processChangedSettings(changed);
} }
void RenderingManager::windowClosed(Ogre::RenderWindow* rw) void RenderingManager::windowClosed(Ogre::RenderWindow* rw)
@ -838,27 +852,8 @@ void RenderingManager::windowClosed(Ogre::RenderWindow* rw)
Ogre::Root::getSingleton ().queueEndRendering (); Ogre::Root::getSingleton ().queueEndRendering ();
} }
bool RenderingManager::waterShaderSupported()
{
const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects"))
return false;
return true;
}
void RenderingManager::applyCompositors() void RenderingManager::applyCompositors()
{ {
mCompositors->removeAll();
if (useMRT())
{
mCompositors->addCompositor("gbuffer", 0);
mCompositors->setCompositorEnabled("gbuffer", true);
mCompositors->addCompositor("gbufferFinalizer", 2);
mCompositors->setCompositorEnabled("gbufferFinalizer", true);
}
if (mWater)
mWater->assignTextures();
} }
void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned int &batches) void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned int &batches)
@ -887,6 +882,8 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors
); );
mPlayer->setAnimation(anim); mPlayer->setAnimation(anim);
mWater->removeEmitter (ptr);
mWater->addEmitter (ptr);
} }
void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw)
@ -930,4 +927,24 @@ void RenderingManager::stopVideo()
mVideoPlayer->stopVideo (); mVideoPlayer->stopVideo ();
} }
void RenderingManager::addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale, float force)
{
mWater->addEmitter (ptr, scale, force);
}
void RenderingManager::removeWaterRippleEmitter (const MWWorld::Ptr& ptr)
{
mWater->removeEmitter (ptr);
}
void RenderingManager::updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr)
{
mWater->updateEmitterPtr(old, ptr);
}
void RenderingManager::frameStarted(float dt)
{
mWater->frameStarted(dt);
}
} // namespace } // namespace

View file

@ -11,6 +11,8 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <OgreRenderTargetListener.h>
#include "renderinginterface.hpp" #include "renderinginterface.hpp"
#include "objects.hpp" #include "objects.hpp"
@ -48,7 +50,7 @@ namespace MWRender
class VideoPlayer; class VideoPlayer;
class Animation; class Animation;
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener, public Ogre::RenderTargetListener {
private: private:
@ -103,8 +105,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void removeWater(); void removeWater();
static const bool useMRT();
void preCellChange (MWWorld::CellStore* store); void preCellChange (MWWorld::CellStore* store);
///< this event is fired immediately before changing cell ///< this event is fired immediately before changing cell
@ -133,11 +133,15 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void setAmbientColour(const Ogre::ColourValue& colour); void setAmbientColour(const Ogre::ColourValue& colour);
void setSunColour(const Ogre::ColourValue& colour); void setSunColour(const Ogre::ColourValue& colour);
void setSunDirection(const Ogre::Vector3& direction); void setSunDirection(const Ogre::Vector3& direction);
void sunEnable(); void sunEnable(bool real); ///< @param real whether or not to really disable the sunlight (otherwise just set diffuse to 0)
void sunDisable(); void sunDisable(bool real);
void disableLights(); void disableLights(bool sun); ///< @param sun whether or not to really disable the sunlight (otherwise just set diffuse to 0)
void enableLights(); void enableLights(bool sun);
void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
bool occlusionQuerySupported() { return mOcclusionQuery->supported(); } bool occlusionQuerySupported() { return mOcclusionQuery->supported(); }
OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; } OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; }
@ -159,6 +163,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void skySetMoonColour (bool red); void skySetMoonColour (bool red);
void configureAmbient(MWWorld::CellStore &mCell); void configureAmbient(MWWorld::CellStore &mCell);
void addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f);
void removeWaterRippleEmitter (const MWWorld::Ptr& ptr);
void updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
void requestMap (MWWorld::CellStore* cell); void requestMap (MWWorld::CellStore* cell);
///< request the local map for a cell ///< request the local map for a cell
@ -176,8 +184,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
Ogre::Viewport* getViewport() { return mRendering.getViewport(); } Ogre::Viewport* getViewport() { return mRendering.getViewport(); }
static bool waterShaderSupported();
void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y); void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y);
///< see MWRender::LocalMap::getInteriorMapPosition ///< see MWRender::LocalMap::getInteriorMapPosition
@ -190,6 +196,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void playVideo(const std::string& name, bool allowSkipping); void playVideo(const std::string& name, bool allowSkipping);
void stopVideo(); void stopVideo();
void frameStarted(float dt);
protected: protected:
virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowResized(Ogre::RenderWindow* rw);
@ -200,6 +207,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
sh::Factory* mFactory; sh::Factory* mFactory;
void setAmbientMode(); void setAmbientMode();
void applyFog(bool underwater);
void setMenuTransparency(float val); void setMenuTransparency(float val);
@ -230,6 +238,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
Ogre::SceneNode *mRootNode; Ogre::SceneNode *mRootNode;
Ogre::ColourValue mFogColour;
float mFogStart;
float mFogEnd;
OEngine::Physic::PhysicEngine* mPhysicsEngine; OEngine::Physic::PhysicEngine* mPhysicsEngine;
MWRender::Player *mPlayer; MWRender::Player *mPlayer;

View file

@ -0,0 +1,263 @@
#include "ripplesimulation.hpp"
#include <OgreTextureManager.h>
#include <OgreStringConverter.h>
#include <OgreHardwarePixelBuffer.h>
#include <OgreRoot.h>
#include <extern/shiny/Main/Factory.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
namespace MWRender
{
RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager)
: mMainSceneMgr(mainSceneManager),
mTime(0),
mCurrentFrameOffset(0,0),
mPreviousFrameOffset(0,0),
mRippleCenter(0,0),
mTextureSize(512),
mRippleAreaLength(1000),
mImpulseSize(20),
mTexelOffset(0,0),
mFirstUpdate(true)
{
Ogre::AxisAlignedBox aabInf;
aabInf.setInfinite();
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
mCamera = mSceneMgr->createCamera("RippleCamera");
mRectangle = new Ogre::Rectangle2D(true);
mRectangle->setBoundingBox(aabInf);
mRectangle->setCorners(-1.0, 1.0, 1.0, -1.0, false);
Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
node->attachObject(mRectangle);
mImpulse = new Ogre::Rectangle2D(true);
mImpulse->setCorners(-0.1, 0.1, 0.1, -0.1, false);
mImpulse->setBoundingBox(aabInf);
mImpulse->setMaterial("AddImpulse");
Ogre::SceneNode* impulseNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
impulseNode->attachObject(mImpulse);
//float w=0.05;
for (int i=0; i<4; ++i)
{
Ogre::TexturePtr texture;
if (i != 3)
texture = Ogre::TextureManager::getSingleton().createManual("RippleHeight" + Ogre::StringConverter::toString(i),
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mTextureSize, mTextureSize, 1, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
else
texture = Ogre::TextureManager::getSingleton().createManual("RippleNormal",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mTextureSize, mTextureSize, 1, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
Ogre::RenderTexture* rt = texture->getBuffer()->getRenderTarget();
rt->removeAllViewports();
rt->addViewport(mCamera);
rt->setAutoUpdated(false);
rt->getViewport(0)->setClearEveryFrame(false);
// debug overlay
/*
Ogre::Rectangle2D* debugOverlay = new Ogre::Rectangle2D(true);
debugOverlay->setCorners(w*2-1, 0.9, (w+0.18)*2-1, 0.4, false);
w += 0.2;
debugOverlay->setBoundingBox(aabInf);
Ogre::SceneNode* debugNode = mMainSceneMgr->getRootSceneNode()->createChildSceneNode();
debugNode->attachObject(debugOverlay);
Ogre::MaterialPtr debugMaterial = Ogre::MaterialManager::getSingleton().create("RippleDebug" + Ogre::StringConverter::toString(i),
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
if (i != 3)
debugMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("RippleHeight" + Ogre::StringConverter::toString(i));
else
debugMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("RippleNormal");
debugMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
debugOverlay->setMaterial("RippleDebug" + Ogre::StringConverter::toString(i));
*/
mRenderTargets[i] = rt;
mTextures[i] = texture;
}
sh::Factory::getInstance().setSharedParameter("rippleTextureSize", sh::makeProperty<sh::Vector4>(
new sh::Vector4(1.0/512, 1.0/512, 512, 512)));
sh::Factory::getInstance().setSharedParameter("rippleCenter", sh::makeProperty<sh::Vector3>(
new sh::Vector3(0, 0, 0)));
sh::Factory::getInstance().setSharedParameter("rippleAreaLength", sh::makeProperty<sh::FloatValue>(
new sh::FloatValue(mRippleAreaLength)));
}
RippleSimulation::~RippleSimulation()
{
delete mRectangle;
Ogre::Root::getSingleton().destroySceneManager(mSceneMgr);
}
void RippleSimulation::update(float dt, Ogre::Vector2 position)
{
// try to keep 20 fps
mTime += dt;
while (mTime >= 1/20.0 || mFirstUpdate)
{
mPreviousFrameOffset = mCurrentFrameOffset;
mCurrentFrameOffset = position - mRippleCenter;
// add texel offsets from previous frame.
mCurrentFrameOffset += mTexelOffset;
mTexelOffset = Ogre::Vector2(std::fmod(mCurrentFrameOffset.x, 1.0f/mTextureSize),
std::fmod(mCurrentFrameOffset.y, 1.0f/mTextureSize));
// now subtract new offset in order to snap to texels
mCurrentFrameOffset -= mTexelOffset;
// texture coordinate space
mCurrentFrameOffset /= mRippleAreaLength;
mRippleCenter = position;
addImpulses();
waterSimulation();
heightMapToNormalMap();
swapHeightMaps();
if (!mFirstUpdate)
mTime -= 1/20.0;
else
mFirstUpdate = false;
}
sh::Factory::getInstance().setSharedParameter("rippleCenter", sh::makeProperty<sh::Vector3>(
new sh::Vector3(mRippleCenter.x + mTexelOffset.x, mRippleCenter.y + mTexelOffset.y, 0)));
}
void RippleSimulation::addImpulses()
{
mRectangle->setVisible(false);
mImpulse->setVisible(true);
/// \todo it should be more efficient to render all emitters at once
for (std::vector<Emitter>::iterator it=mEmitters.begin(); it !=mEmitters.end(); ++it)
{
if (it->mPtr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ())
{
// fetch a new ptr (to handle cell change etc)
// for non-player actors this is done in updateObjectCell
it->mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
}
float* _currentPos = it->mPtr.getRefData().getPosition().pos;
Ogre::Vector3 currentPos (_currentPos[0], _currentPos[1], _currentPos[2]);
if ( (currentPos - it->mLastEmitPosition).length() > 2
&& MWBase::Environment::get().getWorld ()->isUnderwater (it->mPtr.getCell(), currentPos))
{
it->mLastEmitPosition = currentPos;
Ogre::Vector2 pos (currentPos.x, currentPos.y);
pos -= mRippleCenter;
pos /= mRippleAreaLength;
float size = mImpulseSize / mRippleAreaLength;
mImpulse->setCorners(pos.x-size, pos.y+size, pos.x+size, pos.y-size, false);
// don't render if we are offscreen
if (pos.x - size >= 1.0 || pos.y+size <= -1.0 || pos.x+size <= -1.0 || pos.y-size >= 1.0)
continue;
mRenderTargets[1]->update();
}
}
mImpulse->setVisible(false);
mRectangle->setVisible(true);
}
void RippleSimulation::waterSimulation()
{
mRectangle->setMaterial("HeightmapSimulation");
sh::Factory::getInstance().setTextureAlias("Heightmap0", mTextures[0]->getName());
sh::Factory::getInstance().setTextureAlias("Heightmap1", mTextures[1]->getName());
sh::Factory::getInstance().setSharedParameter("currentFrameOffset", sh::makeProperty<sh::Vector3>(
new sh::Vector3(mCurrentFrameOffset.x, mCurrentFrameOffset.y, 0)));
sh::Factory::getInstance().setSharedParameter("previousFrameOffset", sh::makeProperty<sh::Vector3>(
new sh::Vector3(mPreviousFrameOffset.x, mPreviousFrameOffset.y, 0)));
mRenderTargets[2]->update();
}
void RippleSimulation::heightMapToNormalMap()
{
mRectangle->setMaterial("HeightToNormalMap");
sh::Factory::getInstance().setTextureAlias("Heightmap2", mTextures[2]->getName());
mRenderTargets[TEX_NORMAL]->update();
}
void RippleSimulation::swapHeightMaps()
{
// 0 -> 1 -> 2 to 2 -> 0 ->1
Ogre::RenderTexture* tmp = mRenderTargets[0];
Ogre::TexturePtr tmp2 = mTextures[0];
mRenderTargets[0] = mRenderTargets[1];
mTextures[0] = mTextures[1];
mRenderTargets[1] = mRenderTargets[2];
mTextures[1] = mTextures[2];
mRenderTargets[2] = tmp;
mTextures[2] = tmp2;
}
void RippleSimulation::addEmitter(const MWWorld::Ptr& ptr, float scale, float force)
{
Emitter newEmitter;
newEmitter.mPtr = ptr;
newEmitter.mScale = scale;
newEmitter.mForce = force;
newEmitter.mLastEmitPosition = Ogre::Vector3(0,0,0);
mEmitters.push_back (newEmitter);
}
void RippleSimulation::removeEmitter (const MWWorld::Ptr& ptr)
{
for (std::vector<Emitter>::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it)
{
if (it->mPtr == ptr)
{
mEmitters.erase(it);
return;
}
}
}
void RippleSimulation::updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr)
{
for (std::vector<Emitter>::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it)
{
if (it->mPtr == old)
{
it->mPtr = ptr;
return;
}
}
}
}

View file

@ -0,0 +1,85 @@
#ifndef RIPPLE_SIMULATION_H
#define RIPPLE_SIMULATION_H
#include <OgreTexture.h>
#include <OgreMaterial.h>
#include <OgreVector2.h>
#include <OgreVector3.h>
#include "../mwworld/ptr.hpp"
namespace Ogre
{
class RenderTexture;
class Camera;
class SceneManager;
class Rectangle2D;
}
namespace MWRender
{
struct Emitter
{
MWWorld::Ptr mPtr;
Ogre::Vector3 mLastEmitPosition;
float mScale;
float mForce;
};
class RippleSimulation
{
public:
RippleSimulation(Ogre::SceneManager* mainSceneManager);
~RippleSimulation();
void update(float dt, Ogre::Vector2 position);
/// adds an emitter, position will be tracked automatically
void addEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f);
void removeEmitter (const MWWorld::Ptr& ptr);
void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
private:
std::vector<Emitter> mEmitters;
Ogre::RenderTexture* mRenderTargets[4];
Ogre::TexturePtr mTextures[4];
int mTextureSize;
float mRippleAreaLength;
float mImpulseSize;
bool mFirstUpdate;
Ogre::Camera* mCamera;
// own scenemanager to render our simulation
Ogre::SceneManager* mSceneMgr;
Ogre::Rectangle2D* mRectangle;
// scenemanager to create the debug overlays on
Ogre::SceneManager* mMainSceneMgr;
static const int TEX_NORMAL = 3;
Ogre::Rectangle2D* mImpulse;
void addImpulses();
void heightMapToNormalMap();
void waterSimulation();
void swapHeightMaps();
float mTime;
Ogre::Vector2 mRippleCenter;
Ogre::Vector2 mTexelOffset;
Ogre::Vector2 mCurrentFrameOffset;
Ogre::Vector2 mPreviousFrameOffset;
};
}
#endif

View file

@ -9,9 +9,6 @@
#include <OgreShadowCameraSetupPSSM.h> #include <OgreShadowCameraSetupPSSM.h>
#include <OgreHardwarePixelBuffer.h> #include <OgreHardwarePixelBuffer.h>
#include <OgreOverlayContainer.h>
#include <OgreOverlayManager.h>
#include <extern/shiny/Main/Factory.hpp> #include <extern/shiny/Main/Factory.hpp>
#include "renderconst.hpp" #include "renderconst.hpp"
@ -33,8 +30,8 @@ void Shadows::recreate()
// Split shadow maps are currently disabled because the terrain cannot cope with them // Split shadow maps are currently disabled because the terrain cannot cope with them
// (Too many texture units) Solution would be a multi-pass terrain material // (Too many texture units) Solution would be a multi-pass terrain material
bool split = Settings::Manager::getBool("split", "Shadows"); //bool split = Settings::Manager::getBool("split", "Shadows");
//const bool split = false; const bool split = false;
sh::Factory::getInstance ().setGlobalSetting ("shadows", enabled && !split ? "true" : "false"); sh::Factory::getInstance ().setGlobalSetting ("shadows", enabled && !split ? "true" : "false");
sh::Factory::getInstance ().setGlobalSetting ("shadows_pssm", enabled && split ? "true" : "false"); sh::Factory::getInstance ().setGlobalSetting ("shadows_pssm", enabled && split ? "true" : "false");
@ -125,6 +122,7 @@ void Shadows::recreate()
// -------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------
// --------------------------- Debug overlays to display the content of shadow maps ----------------------------------- // --------------------------- Debug overlays to display the content of shadow maps -----------------------------------
// -------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------
/*
if (Settings::Manager::getBool("debug", "Shadows")) if (Settings::Manager::getBool("debug", "Shadows"))
{ {
OverlayManager& mgr = OverlayManager::getSingleton(); OverlayManager& mgr = OverlayManager::getSingleton();
@ -181,6 +179,7 @@ void Shadows::recreate()
if ((overlay = mgr.getByName("DebugOverlay"))) if ((overlay = mgr.getByName("DebugOverlay")))
mgr.destroy(overlay); mgr.destroy(overlay);
} }
*/
} }
PSSMShadowCameraSetup* Shadows::getPSSMSetup() PSSMShadowCameraSetup* Shadows::getPSSMSetup()

View file

@ -14,7 +14,7 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <components/nifogre/ogre_nif_loader.hpp> #include <components/nifogre/ogrenifloader.hpp>
#include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp> #include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp>
@ -254,6 +254,7 @@ void SkyManager::create()
sh::Factory::getInstance().setSharedParameter ("nightFade", sh::Factory::getInstance().setSharedParameter ("nightFade",
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
sh::Factory::getInstance().setSharedParameter ("atmosphereColour", sh::makeProperty<sh::Vector4>(new sh::Vector4(0,0,0,1))); sh::Factory::getInstance().setSharedParameter ("atmosphereColour", sh::makeProperty<sh::Vector4>(new sh::Vector4(0,0,0,1)));
sh::Factory::getInstance().setSharedParameter ("horizonColour", sh::makeProperty<sh::Vector4>(new sh::Vector4(0,0,0,1)));
sh::Factory::getInstance().setTextureAlias ("cloud_texture_1", ""); sh::Factory::getInstance().setTextureAlias ("cloud_texture_1", "");
sh::Factory::getInstance().setTextureAlias ("cloud_texture_2", ""); sh::Factory::getInstance().setTextureAlias ("cloud_texture_2", "");
@ -279,6 +280,9 @@ void SkyManager::create()
mSunGlare->setRenderQueue(RQG_SkiesLate); mSunGlare->setRenderQueue(RQG_SkiesLate);
mSunGlare->setVisibilityFlags(RV_NoReflection); mSunGlare->setVisibilityFlags(RV_NoReflection);
Ogre::AxisAlignedBox aabInf;
aabInf.setInfinite ();
// Stars // Stars
mAtmosphereNight = mRootNode->createChildSceneNode(); mAtmosphereNight = mRootNode->createChildSceneNode();
NifOgre::EntityList entities = NifOgre::Loader::createEntities(mAtmosphereNight, "meshes\\sky_night_01.nif"); NifOgre::EntityList entities = NifOgre::Loader::createEntities(mAtmosphereNight, "meshes\\sky_night_01.nif");
@ -288,6 +292,7 @@ void SkyManager::create()
night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1); night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
night1_ent->setVisibilityFlags(RV_Sky); night1_ent->setVisibilityFlags(RV_Sky);
night1_ent->setCastShadows(false); night1_ent->setCastShadows(false);
night1_ent->getMesh()->_setBounds (aabInf);
for (unsigned int j=0; j<night1_ent->getNumSubEntities(); ++j) for (unsigned int j=0; j<night1_ent->getNumSubEntities(); ++j)
{ {
@ -313,8 +318,12 @@ void SkyManager::create()
atmosphere_ent->setCastShadows(false); atmosphere_ent->setCastShadows(false);
atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly); atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
atmosphere_ent->setVisibilityFlags(RV_Sky); atmosphere_ent->setVisibilityFlags(RV_Sky);
for(unsigned int j = 0;j < atmosphere_ent->getNumSubEntities();j++) for(unsigned int j = 0;j < atmosphere_ent->getNumSubEntities();j++)
atmosphere_ent->getSubEntity (j)->setMaterialName("openmw_atmosphere"); atmosphere_ent->getSubEntity (j)->setMaterialName("openmw_atmosphere");
// Using infinite AAB here to prevent being clipped by the custom near clip plane used for reflections/refractions
atmosphere_ent->getMesh()->_setBounds (aabInf);
} }
@ -329,6 +338,8 @@ void SkyManager::create()
for(unsigned int j = 0;j < clouds_ent->getNumSubEntities();j++) for(unsigned int j = 0;j < clouds_ent->getNumSubEntities();j++)
clouds_ent->getSubEntity(j)->setMaterialName("openmw_clouds"); clouds_ent->getSubEntity(j)->setMaterialName("openmw_clouds");
clouds_ent->setCastShadows(false); clouds_ent->setCastShadows(false);
// Using infinite AAB here to prevent being clipped by the custom near clip plane used for reflections/refractions
clouds_ent->getMesh()->_setBounds (aabInf);
} }
mCreated = true; mCreated = true;
@ -362,7 +373,7 @@ void SkyManager::update(float duration)
mRootNode->setPosition(mCamera->getDerivedPosition()); mRootNode->setPosition(mCamera->getDerivedPosition());
// UV Scroll the clouds // UV Scroll the clouds
mCloudAnimationTimer += duration * mCloudSpeed * (MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f); mCloudAnimationTimer += duration * mCloudSpeed;
sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer", sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer",
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mCloudAnimationTimer))); sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mCloudAnimationTimer)));
@ -476,6 +487,13 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
weather.mSkyColor.r, weather.mSkyColor.g, weather.mSkyColor.b, weather.mSkyColor.a))); weather.mSkyColor.r, weather.mSkyColor.g, weather.mSkyColor.b, weather.mSkyColor.a)));
} }
if (mFogColour != weather.mFogColor)
{
mFogColour = weather.mFogColor;
sh::Factory::getInstance().setSharedParameter ("horizonColour", sh::makeProperty<sh::Vector4>(new sh::Vector4(
weather.mFogColor.r, weather.mFogColor.g, weather.mFogColor.b, weather.mFogColor.a)));
}
mCloudSpeed = weather.mCloudSpeed; mCloudSpeed = weather.mCloudSpeed;
if (weather.mNight && mStarsOpacity != weather.mNightFade) if (weather.mNight && mStarsOpacity != weather.mNightFade)
@ -583,6 +601,10 @@ void SkyManager::setLightningStrength(const float factor)
else else
mLightning->setVisible(false); mLightning->setVisible(false);
} }
void SkyManager::setLightningEnabled(bool enabled)
{
/// \todo
}
void SkyManager::setLightningDirection(const Ogre::Vector3& dir) void SkyManager::setLightningDirection(const Ogre::Vector3& dir)
{ {

View file

@ -167,6 +167,7 @@ namespace MWRender
void setLightningStrength(const float factor); void setLightningStrength(const float factor);
void setLightningDirection(const Ogre::Vector3& dir); void setLightningDirection(const Ogre::Vector3& dir);
void setLightningEnabled(bool enabled); ///< disable prior to map render
void setGlare(const float glare); void setGlare(const float glare);
void setGlareEnabled(bool enabled); void setGlareEnabled(bool enabled);
@ -210,6 +211,7 @@ namespace MWRender
float mStarsOpacity; float mStarsOpacity;
Ogre::ColourValue mCloudColour; Ogre::ColourValue mCloudColour;
Ogre::ColourValue mSkyColour; Ogre::ColourValue mSkyColour;
Ogre::ColourValue mFogColour;
Ogre::Light* mLightning; Ogre::Light* mLightning;

View file

@ -40,9 +40,10 @@ namespace MWRender
->getActiveProfile(); ->getActiveProfile();
mActiveProfile = static_cast<TerrainMaterial::Profile*>(activeProfile); mActiveProfile = static_cast<TerrainMaterial::Profile*>(activeProfile);
//The pixel error should be as high as possible without it being noticed // We don't want any pixel error at all. Really, LOD makes no sense here - morrowind uses 65x65 verts in one cell,
//as it governs how fast mesh quality decreases. // so applying LOD is most certainly slower than doing no LOD at all.
mTerrainGlobals->setMaxPixelError(8); // Setting this to 0 seems to cause glitches though. :/
mTerrainGlobals->setMaxPixelError(1);
mTerrainGlobals->setLayerBlendMapSize(32); mTerrainGlobals->setLayerBlendMapSize(32);

View file

@ -119,10 +119,6 @@ namespace MWRender
shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow"))); shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow")));
} }
// caustics
sh::MaterialInstanceTextureUnit* caustics = p->createTextureUnit ("causticMap");
caustics->setProperty ("direct_texture", sh::makeProperty<sh::StringValue> (new sh::StringValue("water_nm.png")));
p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty<sh::StringValue>(new sh::StringValue( p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty<sh::StringValue>(new sh::StringValue(
Ogre::StringConverter::toString(numBlendTextures + numLayers + 2)))); Ogre::StringConverter::toString(numBlendTextures + numLayers + 2))));
@ -153,9 +149,8 @@ namespace MWRender
--freeTextureUnits; --freeTextureUnits;
// colourmap // colourmap
--freeTextureUnits; --freeTextureUnits;
freeTextureUnits -= 3; // shadow PSSM // shadow
--freeTextureUnits;
--freeTextureUnits; // caustics
// each layer needs 1.25 units (1xdiffusespec, 0.25xblend) // each layer needs 1.25 units (1xdiffusespec, 0.25xblend)
return static_cast<Ogre::uint8>(freeTextureUnits / (1.25f)); return static_cast<Ogre::uint8>(freeTextureUnits / (1.25f));

View file

@ -67,6 +67,7 @@ namespace MWRender
void setGlobalColourMapEnabled(bool enabled); void setGlobalColourMapEnabled(bool enabled);
void setGlobalColourMap (Ogre::Terrain* terrain, const std::string& name); void setGlobalColourMap (Ogre::Terrain* terrain, const std::string& name);
virtual void setLightmapEnabled(bool) {}
private: private:
sh::MaterialInstance* mMaterial; sh::MaterialInstance* mMaterial;

View file

@ -17,6 +17,8 @@
#include "../mwsound/sound_decoder.hpp" #include "../mwsound/sound_decoder.hpp"
#include "../mwsound/sound.hpp" #include "../mwsound/sound.hpp"
#include "renderconst.hpp"
#ifdef _WIN32 #ifdef _WIN32
#include <BaseTsd.h> #include <BaseTsd.h>
@ -1067,9 +1069,9 @@ VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr)
mBackgroundNode->attachObject(mBackgroundRectangle); mBackgroundNode->attachObject(mBackgroundRectangle);
mRectangle->setVisible(false); mRectangle->setVisible(false);
mRectangle->setVisibilityFlags(0x1); mRectangle->setVisibilityFlags(RV_Overlay);
mBackgroundRectangle->setVisible(false); mBackgroundRectangle->setVisible(false);
mBackgroundRectangle->setVisibilityFlags(0x1); mBackgroundRectangle->setVisibilityFlags(RV_Overlay);
} }
VideoPlayer::~VideoPlayer() VideoPlayer::~VideoPlayer()

View file

@ -4,17 +4,12 @@
#include <OgreEntity.h> #include <OgreEntity.h>
#include <OgreMeshManager.h> #include <OgreMeshManager.h>
#include <OgreHardwarePixelBuffer.h> #include <OgreHardwarePixelBuffer.h>
#include <OgreCompositorManager.h>
#include <OgreCompositorInstance.h>
#include <OgreCompositorChain.h>
#include <OgreRoot.h> #include <OgreRoot.h>
#include <OgreOverlayManager.h>
#include <OgreOverlayContainer.h>
#include <OgreOverlayElement.h>
#include "sky.hpp" #include "sky.hpp"
#include "renderingmanager.hpp" #include "renderingmanager.hpp"
#include "compositors.hpp" #include "ripplesimulation.hpp"
#include "refraction.hpp"
#include <extern/shiny/Main/Factory.hpp> #include <extern/shiny/Main/Factory.hpp>
#include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp> #include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp>
@ -27,18 +22,185 @@ using namespace Ogre;
namespace MWRender namespace MWRender
{ {
Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) : CubeReflection::CubeReflection(Ogre::SceneManager* sceneManager)
mCamera (camera), mSceneManager (camera->getSceneManager()), : Reflection(sceneManager)
mIsUnderwater(false), mVisibilityFlags(0),
mReflectionTarget(0), mActive(1), mToggled(1),
mReflectionRenderActive(false), mRendering(rend),
mWaterTimer(0.f)
{ {
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton ().createManual("CubeReflection",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_CUBE_MAP,
512,512, 0, PF_R8G8B8, TU_RENDERTARGET);
mCamera = mSceneMgr->createCamera ("CubeCamera");
mCamera->setNearClipDistance (5);
mCamera->setFarClipDistance (1000);
for (int face = 0; face < 6; ++face)
{
mRenderTargets[face] = texture->getBuffer (face)->getRenderTarget();
mRenderTargets[face]->removeAllViewports ();
Viewport* vp = mRenderTargets[face]->addViewport (mCamera);
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setMaterialScheme ("water_reflection");
mRenderTargets[face]->setAutoUpdated(false);
/*
Vector3 lookAt(0,0,0), up(0,0,0), right(0,0,0);
switch(face)
{
case 0: lookAt.x =-1; up.y = 1; right.z = 1; break; // +X
case 1: lookAt.x = 1; up.y = 1; right.z =-1; break; // -X
case 2: lookAt.y =-1; up.z = 1; right.x = 1; break; // +Y
case 3: lookAt.y = 1; up.z =-1; right.x = 1; break; // -Y
case 4: lookAt.z = 1; up.y = 1; right.x =-1; break; // +Z
case 5: lookAt.z =-1; up.y = 1; right.x =-1; break; // -Z
}
Quaternion orient(right, up, lookAt);
mCamera->setOrientation(orient);
*/
}
}
CubeReflection::~CubeReflection ()
{
Ogre::TextureManager::getSingleton ().remove("CubeReflection");
mSceneMgr->destroyCamera (mCamera);
}
void CubeReflection::update ()
{
mParentCamera->getParentSceneNode ()->needUpdate ();
mCamera->setPosition(mParentCamera->getDerivedPosition());
}
// --------------------------------------------------------------------------------------------------------------------------------
PlaneReflection::PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* sky)
: Reflection(sceneManager)
, mSky(sky)
, mRenderActive(false)
{
mCamera = mSceneMgr->createCamera ("PlaneReflectionCamera");
mSceneMgr->addRenderQueueListener(this);
mTexture = TextureManager::getSingleton().createManual("WaterReflection",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 512, 512, 0, PF_R8G8B8, TU_RENDERTARGET);
mRenderTarget = mTexture->getBuffer()->getRenderTarget();
Viewport* vp = mRenderTarget->addViewport(mCamera);
vp->setOverlaysEnabled(false);
vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f));
vp->setShadowsEnabled(false);
vp->setMaterialScheme("water_reflection");
mRenderTarget->addListener(this);
mRenderTarget->setActive(true);
mRenderTarget->setAutoUpdated(true);
sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mTexture->getName());
}
PlaneReflection::~PlaneReflection ()
{
mRenderTarget->removeListener (this);
mSceneMgr->destroyCamera (mCamera);
mSceneMgr->removeRenderQueueListener(this);
TextureManager::getSingleton ().remove("WaterReflection");
}
void PlaneReflection::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation)
{
// We don't want the sky to get clipped by custom near clip plane (the water plane)
if (queueGroupId < 20 && mRenderActive)
{
mCamera->disableCustomNearClipPlane();
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
}
}
void PlaneReflection::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
{
if (queueGroupId < 20 && mRenderActive)
{
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
}
}
void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
mParentCamera->getParentSceneNode ()->needUpdate ();
mCamera->setOrientation(mParentCamera->getDerivedOrientation());
mCamera->setPosition(mParentCamera->getDerivedPosition());
mCamera->setNearClipDistance(mParentCamera->getNearClipDistance());
mCamera->setFarClipDistance(mParentCamera->getFarClipDistance());
mCamera->setAspectRatio(mParentCamera->getAspectRatio());
mCamera->setFOVy(mParentCamera->getFOVy());
mRenderActive = true;
Vector3 pos = mParentCamera->getRealPosition();
pos.y = (mWaterPlane).d*2 - pos.y;
mSky->setSkyPosition(pos);
mCamera->enableReflection(mWaterPlane);
// for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane.
// since all we are interested in is depth, we only need the third row of the matrix.
Ogre::Matrix4 projMatrix = mCamera->getProjectionMatrixWithRSDepth () * mCamera->getViewMatrix ();
sh::Vector4* row3 = new sh::Vector4(projMatrix[2][0], projMatrix[2][1], projMatrix[2][2], projMatrix[2][3]);
sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty<sh::Vector4> (row3));
// enable clip plane here to take advantage of CPU culling for overwater or underwater objects
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane);
}
void PlaneReflection::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
mSky->resetSkyPosition();
mCamera->disableReflection();
mCamera->disableCustomNearClipPlane();
mRenderActive = false;
}
void PlaneReflection::setHeight (float height)
{
mWaterPlane = Plane(Ogre::Vector3(0,0,1), height);
mErrorPlane = Plane(Ogre::Vector3(0,0,1), height - 5);
mErrorPlaneUnderwater = Plane(Ogre::Vector3(0,0,-1), -height - 5);
}
void PlaneReflection::setActive (bool active)
{
mRenderTarget->setActive(active);
}
void PlaneReflection::setViewportBackground(Ogre::ColourValue colour)
{
mRenderTarget->getViewport (0)->setBackgroundColour (colour);
}
void PlaneReflection::setVisibilityMask (int flags)
{
mRenderTarget->getViewport (0)->setVisibilityMask (flags);
}
// --------------------------------------------------------------------------------------------------------------------------------
Water::Water (Ogre::Camera *camera, RenderingManager* rend) :
mCamera (camera), mSceneMgr (camera->getSceneManager()),
mIsUnderwater(false), mVisibilityFlags(0),
mActive(1), mToggled(1),
mRendering(rend),
mWaterTimer(0.f),
mReflection(NULL),
mRefraction(NULL),
mSimulation(NULL),
mPlayer(0,0)
{
mSimulation = new RippleSimulation(mSceneMgr);
mSky = rend->getSkyManager(); mSky = rend->getSkyManager();
mMaterial = MaterialManager::getSingleton().getByName("Water"); mMaterial = MaterialManager::getSingleton().getByName("Water");
mTop = cell->mWater; mTop = 0;
mIsUnderwater = false; mIsUnderwater = false;
@ -46,19 +208,13 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Y); MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Y);
mWater = mSceneManager->createEntity("water"); mWater = mSceneMgr->createEntity("water");
mWater->setVisibilityFlags(RV_Water); mWater->setVisibilityFlags(RV_Water);
mWater->setRenderQueueGroup(RQG_Water);
mWater->setCastShadows(false); mWater->setCastShadows(false);
mWater->setRenderQueueGroup(RQG_Alpha);
mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); mWaterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mReflectionCamera = mSceneManager->createCamera("ReflectionCamera");
if(!(cell->mData.mFlags & cell->Interior))
{
mWaterNode->setPosition(getSceneNodeCoordinates(cell->mData.mX, cell->mData.mY));
}
mWaterNode->attachObject(mWater); mWaterNode->attachObject(mWater);
applyRTT(); applyRTT();
@ -66,26 +222,11 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
mWater->setMaterial(mMaterial); mWater->setMaterial(mMaterial);
/*
Ogre::Entity* underwaterDome = mSceneManager->createEntity ("underwater_dome.mesh");
underwaterDome->setRenderQueueGroup (RQG_UnderWater);
mUnderwaterDome = mSceneManager->getRootSceneNode ()->createChildSceneNode ();
mUnderwaterDome->attachObject (underwaterDome);
mUnderwaterDome->setScale(10000,10000,10000);
mUnderwaterDome->setVisible(false);
underwaterDome->setMaterialName("Underwater_Dome");
*/
mSceneManager->addRenderQueueListener(this);
assignTextures();
setHeight(mTop); setHeight(mTop);
sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water"); sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water");
m->setListener (this); m->setListener (this);
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
// ---------------------------------- reflection debug overlay ---------------------------------- // ---------------------------------- reflection debug overlay ----------------------------------
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
@ -146,12 +287,12 @@ Water::~Water()
{ {
MeshManager::getSingleton().remove("water"); MeshManager::getSingleton().remove("water");
if (mReflectionTarget)
mReflectionTexture->getBuffer()->getRenderTarget()->removeListener(this);
mWaterNode->detachObject(mWater); mWaterNode->detachObject(mWater);
mSceneManager->destroyEntity(mWater); mSceneMgr->destroyEntity(mWater);
mSceneManager->destroySceneNode(mWaterNode); mSceneMgr->destroySceneNode(mWaterNode);
delete mReflection;
delete mRefraction;
} }
void Water::changeCell(const ESM::Cell* cell) void Water::changeCell(const ESM::Cell* cell)
@ -168,10 +309,12 @@ void Water::setHeight(const float height)
{ {
mTop = height; mTop = height;
mWaterPlane = Plane(Vector3::UNIT_Z, height); mWaterPlane = Plane(Vector3::UNIT_Z, -height);
// small error due to reflection texture size & reflection distortion if (mReflection)
mErrorPlane = Plane(Vector3::UNIT_Z, height - 5); mReflection->setHeight(height);
if (mRefraction)
mRefraction->setHeight(height);
mWaterNode->setPosition(0, 0, height); mWaterNode->setPosition(0, 0, height);
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height))); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height)));
@ -194,6 +337,11 @@ Water::updateUnderwater(bool underwater)
mWater->isVisible() && mWater->isVisible() &&
mCamera->getPolygonMode() == Ogre::PM_SOLID; mCamera->getPolygonMode() == Ogre::PM_SOLID;
if (mReflection)
mReflection->setUnderwater (mIsUnderwater);
if (mRefraction)
mRefraction->setUnderwater (mIsUnderwater);
updateVisible(); updateVisible();
} }
@ -202,129 +350,63 @@ Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY)
return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), gridY * CELL_SIZE + (CELL_SIZE / 2), mTop); return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), gridY * CELL_SIZE + (CELL_SIZE / 2), mTop);
} }
void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
{
if (evt.source == mReflectionTarget)
{
mCamera->getParentSceneNode ()->needUpdate ();
mReflectionCamera->setOrientation(mCamera->getDerivedOrientation());
mReflectionCamera->setPosition(mCamera->getDerivedPosition());
mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance());
mReflectionCamera->setFarClipDistance(mCamera->getFarClipDistance());
mReflectionCamera->setAspectRatio(mCamera->getAspectRatio());
mReflectionCamera->setFOVy(mCamera->getFOVy());
mReflectionRenderActive = true;
Vector3 pos = mCamera->getRealPosition();
pos.z = mTop*2 - pos.z;
mSky->setSkyPosition(pos);
mReflectionCamera->enableReflection(mWaterPlane);
}
}
void Water::postRenderTargetUpdate(const RenderTargetEvent& evt)
{
if (evt.source == mReflectionTarget)
{
mSky->resetSkyPosition();
mReflectionCamera->disableReflection();
mReflectionCamera->disableCustomNearClipPlane();
mReflectionRenderActive = false;
}
}
void Water::assignTextures()
{
if (Settings::Manager::getBool("shader", "Water"))
{
CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mRendering->getViewport())->getCompositor("gbuffer");
TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0);
sh::Factory::getInstance ().setTextureAlias ("WaterRefraction", colorTexture->getName());
TexturePtr depthTexture = compositor->getTextureInstance("mrt_output", 1);
sh::Factory::getInstance ().setTextureAlias ("SceneDepth", depthTexture->getName());
}
}
void Water::setViewportBackground(const ColourValue& bg) void Water::setViewportBackground(const ColourValue& bg)
{ {
if (mReflectionTarget) if (mReflection)
mReflectionTarget->getViewport(0)->setBackgroundColour(bg); mReflection->setViewportBackground(bg);
} }
void Water::updateVisible() void Water::updateVisible()
{ {
mWater->setVisible(mToggled && mActive); mWater->setVisible(mToggled && mActive);
if (mReflectionTarget) if (mReflection)
mReflectionTarget->setActive(mToggled && mActive); mReflection->setActive(mToggled && mActive);
if (mRefraction)
mRefraction->setActive(mToggled && mActive);
} }
void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) void Water::update(float dt, Ogre::Vector3 player)
{ {
// We don't want the sky to get clipped by custom near clip plane (the water plane) mWaterTimer += dt;
if (queueGroupId < 20 && mReflectionRenderActive)
{
mReflectionCamera->disableCustomNearClipPlane();
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
}
}
void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
{
if (queueGroupId < 20 && mReflectionRenderActive)
{
if (!mIsUnderwater)
mReflectionCamera->enableCustomNearClipPlane(mErrorPlane);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
}
}
void Water::update(float dt)
{
/*
Ogre::Vector3 pos = mCamera->getDerivedPosition ();
pos.y = -mWaterPlane.d;
mUnderwaterDome->setPosition (pos);
*/
mWaterTimer += dt / 30.0 * MWBase::Environment::get().getWorld()->getTimeScaleFactor();
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mWaterTimer))); sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mWaterTimer)));
mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater); mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater);
mPlayer = Ogre::Vector2(player.x, player.y);
}
void Water::frameStarted(float dt)
{
mSimulation->update(dt, mPlayer);
if (mReflection)
mReflection->update();
} }
void Water::applyRTT() void Water::applyRTT()
{ {
if (mReflectionTarget) delete mReflection;
{ mReflection = NULL;
TextureManager::getSingleton().remove("WaterReflection"); delete mRefraction;
mReflectionTarget = 0; mRefraction = NULL;
}
// Create rendertarget for reflection // Create rendertarget for reflection
int rttsize = Settings::Manager::getInt("rtt size", "Water"); //int rttsize = Settings::Manager::getInt("rtt size", "Water");
if (Settings::Manager::getBool("shader", "Water")) if (Settings::Manager::getBool("shader", "Water"))
{ {
mReflectionTexture = TextureManager::getSingleton().createManual("WaterReflection", mReflection = new PlaneReflection(mSceneMgr, mSky);
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_A8R8G8B8, TU_RENDERTARGET); mReflection->setParentCamera (mCamera);
mReflection->setHeight(mTop);
RenderTarget* rtt = mReflectionTexture->getBuffer()->getRenderTarget(); if (Settings::Manager::getBool("refraction", "Water"))
Viewport* vp = rtt->addViewport(mReflectionCamera); {
vp->setOverlaysEnabled(false); mRefraction = new Refraction(mCamera);
vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); mRefraction->setHeight(mTop);
vp->setShadowsEnabled(false); }
// use fallback techniques without shadows and without mrt (currently not implemented for sky and terrain)
vp->setMaterialScheme("water_reflection");
rtt->addListener(this);
rtt->setActive(true);
mReflectionTarget = rtt;
sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mReflectionTexture->getName());
} }
updateVisible();
} }
void Water::applyVisibilityMask() void Water::applyVisibilityMask()
@ -336,10 +418,8 @@ void Water::applyVisibilityMask()
+ RV_Misc * Settings::Manager::getBool("reflect misc", "Water") + RV_Misc * Settings::Manager::getBool("reflect misc", "Water")
+ RV_Sky; + RV_Sky;
if (mReflectionTarget) if (mReflection)
{ mReflection->setVisibilityMask(mVisibilityFlags);
mReflectionTexture->getBuffer()->getRenderTarget()->getViewport(0)->setVisibilityMask(mVisibilityFlags);
}
} }
void Water::processChangedSettings(const Settings::CategorySettingVector& settings) void Water::processChangedSettings(const Settings::CategorySettingVector& settings)
@ -350,7 +430,8 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin
it != settings.end(); ++it) it != settings.end(); ++it)
{ {
if ( it->first == "Water" && ( if ( it->first == "Water" && (
it->second == "shader" it->second == "shader"
|| it->second == "refraction"
|| it->second == "rtt size")) || it->second == "rtt size"))
applyRT = true; applyRT = true;
@ -368,7 +449,6 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin
applyRTT(); applyRTT();
applyVisibilityMask(); applyVisibilityMask();
mWater->setMaterial(mMaterial); mWater->setMaterial(mMaterial);
assignTextures();
} }
if (applyVisMask) if (applyVisMask)
applyVisibilityMask(); applyVisibilityMask();
@ -399,4 +479,19 @@ void Water::createdConfiguration (sh::MaterialInstance* m, const std::string& co
} }
} }
void Water::addEmitter (const MWWorld::Ptr& ptr, float scale, float force)
{
mSimulation->addEmitter (ptr, scale, force);
}
void Water::removeEmitter (const MWWorld::Ptr& ptr)
{
mSimulation->removeEmitter (ptr);
}
void Water::updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr)
{
mSimulation->updateEmitterPtr(old, ptr);
}
} // namespace } // namespace

View file

@ -7,13 +7,17 @@
#include <OgreRenderTargetListener.h> #include <OgreRenderTargetListener.h>
#include <OgreMaterial.h> #include <OgreMaterial.h>
#include <OgreTexture.h> #include <OgreTexture.h>
#include <OgreVector2.h>
#include <components/esm/loadcell.hpp> #include <components/esm/loadcell.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <extern/shiny/Main/MaterialInstance.hpp>
#include "renderconst.hpp" #include "renderconst.hpp"
#include <extern/shiny/Main/MaterialInstance.hpp> #include "../mwworld/ptr.hpp"
namespace Ogre namespace Ogre
{ {
@ -22,6 +26,7 @@ namespace Ogre
class SceneNode; class SceneNode;
class Entity; class Entity;
class Vector3; class Vector3;
class Rectangle2D;
struct RenderTargetEvent; struct RenderTargetEvent;
} }
@ -29,22 +34,82 @@ namespace MWRender {
class SkyManager; class SkyManager;
class RenderingManager; class RenderingManager;
class RippleSimulation;
class Refraction;
class Reflection
{
public:
Reflection(Ogre::SceneManager* sceneManager)
: mSceneMgr(sceneManager) {}
virtual ~Reflection() {}
virtual void setHeight (float height) {}
virtual void setParentCamera (Ogre::Camera* parent) { mParentCamera = parent; }
void setUnderwater(bool underwater) { mIsUnderwater = underwater; }
virtual void setActive (bool active) {}
virtual void setViewportBackground(Ogre::ColourValue colour) {}
virtual void update() {}
virtual void setVisibilityMask (int flags) {}
protected:
Ogre::Camera* mCamera;
Ogre::Camera* mParentCamera;
Ogre::TexturePtr mTexture;
Ogre::SceneManager* mSceneMgr;
bool mIsUnderwater;
};
class CubeReflection : public Reflection
{
public:
CubeReflection(Ogre::SceneManager* sceneManager);
virtual ~CubeReflection();
virtual void update();
protected:
Ogre::RenderTarget* mRenderTargets[6];
};
class PlaneReflection : public Reflection, public Ogre::RenderQueueListener, public Ogre::RenderTargetListener
{
public:
PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* sky);
virtual ~PlaneReflection();
virtual void setHeight (float height);
virtual void setActive (bool active);
virtual void setVisibilityMask (int flags);
void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation);
void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation);
virtual void setViewportBackground(Ogre::ColourValue colour);
protected:
Ogre::RenderTarget* mRenderTarget;
SkyManager* mSky;
Ogre::Plane mWaterPlane;
Ogre::Plane mErrorPlane;
Ogre::Plane mErrorPlaneUnderwater;
bool mRenderActive;
};
/// Water rendering /// Water rendering
class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener, public sh::MaterialInstanceListener class Water : public sh::MaterialInstanceListener
{ {
static const int CELL_SIZE = 8192; static const int CELL_SIZE = 8192;
Ogre::Camera *mCamera; Ogre::Camera *mCamera;
Ogre::SceneManager *mSceneManager; Ogre::SceneManager *mSceneMgr;
Ogre::Plane mWaterPlane; Ogre::Plane mWaterPlane;
Ogre::Plane mErrorPlane;
Ogre::SceneNode *mWaterNode; Ogre::SceneNode *mWaterNode;
Ogre::Entity *mWater; Ogre::Entity *mWater;
//Ogre::SceneNode* mUnderwaterDome;
bool mIsUnderwater; bool mIsUnderwater;
bool mActive; bool mActive;
bool mToggled; bool mToggled;
@ -52,17 +117,10 @@ namespace MWRender {
float mWaterTimer; float mWaterTimer;
bool mReflectionRenderActive;
Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY); Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY);
protected: protected:
void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation);
void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation);
void applyRTT(); void applyRTT();
void applyVisibilityMask(); void applyVisibilityMask();
@ -75,24 +133,29 @@ namespace MWRender {
Ogre::MaterialPtr mMaterial; Ogre::MaterialPtr mMaterial;
Ogre::Camera* mReflectionCamera;
Ogre::TexturePtr mReflectionTexture;
Ogre::RenderTarget* mReflectionTarget;
bool mUnderwaterEffect; bool mUnderwaterEffect;
int mVisibilityFlags; int mVisibilityFlags;
Reflection* mReflection;
Refraction* mRefraction;
RippleSimulation* mSimulation;
Ogre::Vector2 mPlayer;
public: public:
Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell); Water (Ogre::Camera *camera, RenderingManager* rend);
~Water(); ~Water();
void setActive(bool active); void setActive(bool active);
void toggle(); void toggle();
void update(float dt); void update(float dt, Ogre::Vector3 player);
void frameStarted(float dt);
void assignTextures(); /// adds an emitter, position will be tracked automatically using its scene node
void addEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f);
void removeEmitter (const MWWorld::Ptr& ptr);
void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
void setViewportBackground(const Ogre::ColourValue& bg); void setViewportBackground(const Ogre::ColourValue& bg);

View file

@ -119,15 +119,15 @@ namespace MWScript
if (axis == "x") if (axis == "x")
{ {
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees()); runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[0]).valueDegrees());
} }
else if (axis == "y") else if (axis == "y")
{ {
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees()); runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[1]).valueDegrees());
} }
else if (axis == "z") else if (axis == "z")
{ {
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees()); runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[2]).valueDegrees());
} }
else else
throw std::runtime_error ("invalid ration axis: " + axis); throw std::runtime_error ("invalid ration axis: " + axis);
@ -148,15 +148,15 @@ namespace MWScript
if (axis=="x") if (axis=="x")
{ {
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[0]).valueDegrees()); runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees());
} }
else if (axis=="y") else if (axis=="y")
{ {
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[1]).valueDegrees()); runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees());
} }
else if (axis=="z") else if (axis=="z")
{ {
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[2]).valueDegrees()); runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees());
} }
else else
throw std::runtime_error ("invalid ration axis: " + axis); throw std::runtime_error ("invalid ration axis: " + axis);
@ -241,15 +241,15 @@ namespace MWScript
if(axis == "x") if(axis == "x")
{ {
runtime.push(ptr.getCellRef().mPos.pos[0]); runtime.push(ptr.getRefData().getPosition().pos[0]);
} }
else if(axis == "y") else if(axis == "y")
{ {
runtime.push(ptr.getCellRef().mPos.pos[1]); runtime.push(ptr.getRefData().getPosition().pos[1]);
} }
else if(axis == "z") else if(axis == "z")
{ {
runtime.push(ptr.getCellRef().mPos.pos[2]); runtime.push(ptr.getRefData().getPosition().pos[2]);
} }
else else
throw std::runtime_error ("invalid axis: " + axis); throw std::runtime_error ("invalid axis: " + axis);

Some files were not shown because too many files have changed in this diff Show more