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

actorid
Pieter van der Kloet 12 years ago
commit 9145fb210b

@ -112,14 +112,11 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
case '5': oper_str = ">="; break;
}
std::string value_str = "??";
if (ss.mType == ESM::VT_Int)
value_str = str(boost::format("%d") % ss.mI);
else if (ss.mType == ESM::VT_Float)
value_str = str(boost::format("%f") % ss.mF);
std::ostringstream stream;
stream << ss.mValue;
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;
}
@ -713,31 +710,13 @@ void Record<ESM::Faction>::print()
template<>
void Record<ESM::Global>::print()
{
// nothing to print (well, nothing that's correct anyway)
std::cout << " Type: " << mData.mType << std::endl;
std::cout << " Value: " << mData.mValue << std::endl;
std::cout << " " << mData.mValue << std::endl;
}
template<>
void Record<ESM::GameSetting>::print()
{
std::cout << " Value: ";
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";
}
std::cout << " " << mData.mValue << std::endl;
}
template<>

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

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

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

@ -12,13 +12,13 @@ namespace CSMWorld
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)
{
ESXRecordT record2 = record.get();
record2.mValue = data.toFloat();
record2.mValue.setFloat (data.toFloat());
record.setModified (record2);
}
@ -96,17 +96,17 @@ namespace CSMWorld
template<typename 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
{
return static_cast<int> (record.get().mType);
return static_cast<int> (record.get().mValue.getType());
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mType = static_cast<ESM::VarType> (data.toInt());
record2.mValue.setType (static_cast<ESM::VarType> (data.toInt()));
record.setModified (record2);
}
@ -123,11 +123,21 @@ namespace CSMWorld
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_Int: return record.get().mI; break;
case ESM::VT_Float: return record.get().mF; break;
case ESM::VT_String:
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();
}
@ -137,11 +147,24 @@ namespace CSMWorld
{
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_Int: record2.mI = data.toInt(); break;
case ESM::VT_Float: record2.mF = data.toFloat(); break;
case ESM::VT_String:
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;
}

@ -6,6 +6,7 @@
#include <QAbstractTableModel>
#include <components/esm/esmreader.hpp>
#include <components/esm/defs.hpp>
#include <components/esm/loadglob.hpp>
#include "idtable.hpp"
@ -26,12 +27,13 @@ CSMWorld::Data::Data()
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
mGlobals.addColumn (new RecordStateColumn<ESM::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 RecordStateColumn<ESM::GameSetting>);
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>);
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);

@ -35,8 +35,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
{
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));
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType,
new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float));
}
CSVDoc::ViewManager::~ViewManager()

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

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

@ -16,7 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender
renderingmanager debugging sky player animation npcanimation creatureanimation activatoranimation
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
@ -30,7 +30,7 @@ add_openmw_dir (mwgui
formatting inventorywindow container hud countdialog tradewindow settingswindow
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
)
add_openmw_dir (mwdialogue

@ -9,11 +9,11 @@
#include <components/bsa/bsa_archive.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/translation/translation.hpp>
#include <components/nif/nif_file.hpp>
#include <components/nif/niffile.hpp>
#include <components/nifoverrides/nifoverrides.hpp>
#include <components/nifbullet/bullet_nif_loader.hpp>
#include <components/nifogre/ogre_nif_loader.hpp>
#include <components/nifbullet/bulletnifloader.hpp>
#include <components/nifogre/ogrenifloader.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)
{
try
@ -316,7 +323,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
addResourcesDirectory(mResDir / "mygui");
addResourcesDirectory(mResDir / "water");
addResourcesDirectory(mResDir / "gbuffer");
addResourcesDirectory(mResDir / "shadows");
addZipResource(mResDir / "mygui" / "Obliviontt.zip");
@ -444,7 +450,7 @@ void OMW::Engine::go()
// Save user settings
settings.saveUser(settingspath);
std::cout << "Quitting peacefully.\n";
std::cout << "Quitting peacefully." << std::endl;
}
void OMW::Engine::activate()

@ -105,6 +105,7 @@ namespace OMW
void executeLocalScripts();
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
std::string loadSettings (Settings::Manager & settings);

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

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

@ -20,6 +20,8 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwmechanics/npcstats.hpp"
namespace MWClass
{
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}");
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;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {

@ -31,14 +31,13 @@ namespace
template<typename T>
bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1)
{
if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int ||
select.mType==ESM::VT_Long)
if (select.mValue.getType()==ESM::VT_Int)
{
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
throw std::runtime_error (

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

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

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

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

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

@ -216,7 +216,7 @@ namespace MWGui
}
}
void Console::keyPress(MyGUI::WidgetPtr _sender,
void Console::keyPress(MyGUI::Widget* _sender,
MyGUI::KeyCode key,
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();
if(cm.empty()) return;

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

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

@ -151,7 +151,7 @@ DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager)
getWidget(mTopicsList, "TopicsList");
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
MyGUI::ButtonPtr byeButton;
MyGUI::Button* byeButton;
getWidget(byeButton, "ByeButton");
byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
@ -164,7 +164,7 @@ DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager)
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
{
MyGUI::ISubWidgetText* t = mHistory->getClient()->getSubWidgetText();
if(t == nullptr)
if(t == NULL)
return;
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);
size_t historySize = 0;
if(mHistory->getClient()->getSubWidgetText() != nullptr)
if(mHistory->getClient()->getSubWidgetText() != NULL)
{
historySize = mHistory->getOnlyText().size();
}

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

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

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

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

@ -8,12 +8,13 @@
namespace MWGui
{
class DragAndDrop;
class SpellIcons;
class HUD : public OEngine::GUI::Layout, public LocalMapBase
{
public:
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 setFPS(float fps);
void setTriangleCount(unsigned int count);
@ -43,6 +44,10 @@ namespace MWGui
bool getWorldMouseOver() { return mWorldMouseOver; }
MyGUI::Widget* getEffectBox() { return mEffectBox; }
void update();
private:
MyGUI::ProgressPtr mHealth, mMagicka, mStamina;
MyGUI::Widget* mHealthFrame;
@ -51,7 +56,6 @@ namespace MWGui
MyGUI::ProgressPtr mWeapStatus, mSpellStatus;
MyGUI::Widget *mEffectBox, *mMinimapBox;
MyGUI::Button* mMinimapButton;
MyGUI::ImageBox* mEffect1;
MyGUI::ScrollView* mMinimap;
MyGUI::ImageBox* mCompass;
MyGUI::ImageBox* mCrosshair;
@ -60,7 +64,7 @@ namespace MWGui
MyGUI::Widget* mDummy;
MyGUI::WidgetPtr mFpsBox;
MyGUI::Widget* mFpsBox;
MyGUI::TextBox* mFpsCounter;
MyGUI::TextBox* mTriangleCounter;
MyGUI::TextBox* mBatchCounter;
@ -85,6 +89,8 @@ namespace MWGui
bool mWorldMouseOver;
SpellIcons* mSpellIcons;
void onWorldClicked(MyGUI::Widget* _sender);
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new);

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

@ -160,11 +160,8 @@ namespace MWGui
// the "Take" button should not be visible.
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
// 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;
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);

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

@ -1,6 +1,9 @@
#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::Widgets;

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

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

@ -247,7 +247,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
std::vector<std::string>::const_iterator 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,
std::string("MW_Button"),
dummyCoord,
@ -301,7 +301,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
MyGUI::IntSize buttonSize(0, buttonHeight);
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)
{
buttonCord.left = left;
@ -349,7 +349,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
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)
{
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::vector<MyGUI::ButtonPtr>::const_iterator button;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
@ -393,7 +393,7 @@ void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
{
mMarkedToDelete = true;
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)
{
if(*button == pressed)

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

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

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

@ -86,11 +86,11 @@ ReviewDialog::ReviewDialog(MWBase::WindowManager& parWindowManager)
mSkillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0)));
}
MyGUI::ButtonPtr backButton;
MyGUI::Button* backButton;
getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked);
MyGUI::ButtonPtr okButton;
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
}
@ -309,7 +309,7 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId
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);
}

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

@ -2,6 +2,7 @@
#include <OgreRoot.h>
#include <OgreRenderSystem.h>
#include <OgrePlugin.h>
#include <OgreString.h>
#include <boost/lexical_cast.hpp>
@ -77,6 +78,17 @@ namespace
{
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
@ -109,6 +121,7 @@ namespace MWGui
getWidget(mReflectActorsButton, "ReflectActorsButton");
getWidget(mReflectTerrainButton, "ReflectTerrainButton");
getWidget(mShadersButton, "ShadersButton");
getWidget(mShaderModeButton, "ShaderModeButton");
getWidget(mShadowsEnabledButton, "ShadowsEnabledButton");
getWidget(mShadowsLargeDistance, "ShadowsLargeDistance");
getWidget(mShadowsTextureSize, "ShadowsTextureSize");
@ -116,22 +129,22 @@ namespace MWGui
getWidget(mStaticsShadows, "StaticsShadows");
getWidget(mMiscShadows, "MiscShadows");
getWidget(mShadowsDebug, "ShadowsDebug");
getWidget(mUnderwaterButton, "UnderwaterButton");
getWidget(mControlsBox, "ControlsBox");
getWidget(mResetControlsButton, "ResetControlsButton");
getWidget(mInvertYButton, "InvertYButton");
getWidget(mUISensitivitySlider, "UISensitivitySlider");
getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider");
getWidget(mGammaSlider, "GammaSlider");
getWidget(mRefractionButton, "RefractionButton");
mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mInvertYButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked);
mUnderwaterButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled);
mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled);
mFullscreenButton->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);
mReflectTerrainButton->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);
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
mGammaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
@ -202,14 +214,6 @@ namespace MWGui
getWidget(fovText, "FovText");
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;
mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1));
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}");
mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "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"));
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}");
mActorShadows->setCaptionWithReplacing(Settings::Manager::getBool("actor 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}");
std::string shaders;
if (!Settings::Manager::getBool("shaders", "Objects"))
shaders = "off";
else
{
shaders = Settings::Manager::getString("shader mode", "General");
}
mShadersButton->setCaption (shaders);
mShadersButton->setCaptionWithReplacing (Settings::Manager::getBool("shaders", "Objects") ? "#{sOn}" : "#{sOff}");
mShaderModeButton->setCaption (Settings::Manager::getString("shader mode", "General"));
if (!MWRender::RenderingManager::waterShaderSupported())
{
mWaterShaderButton->setEnabled(false);
mReflectObjectsButton->setEnabled(false);
mReflectActorsButton->setEnabled(false);
mReflectTerrainButton->setEnabled(false);
}
mRefractionButton->setCaptionWithReplacing (Settings::Manager::getBool("refraction", "Water") ? "#{sOn}" : "#{sOff}");
if (shaders == "off")
if (!Settings::Manager::getBool("shaders", "Objects"))
{
mUnderwaterButton->setEnabled (false);
mRefractionButton->setEnabled(false);
mShadowsEnabledButton->setEnabled(false);
}
@ -385,12 +379,12 @@ namespace MWGui
}
else
{
if (_sender == mVSyncButton)
Settings::Manager::setBool("vsync", "Video", newState);
if (_sender == mWaterShaderButton)
Settings::Manager::setBool("shader", "Water", newState);
else if (_sender == mUnderwaterButton)
{
Settings::Manager::setBool("underwater effect", "Water", newState);
}
else if (_sender == mRefractionButton)
Settings::Manager::setBool("refraction", "Water", newState);
else if (_sender == mReflectObjectsButton)
{
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();
if (val == "off")
if (val == "cg")
{
val = hlslGlsl();
}
else if (val == hlslGlsl())
else if (cgAvailable ())
val = "cg";
else
val = "off";
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);
// water shader not supported with object shaders off
mWaterShaderButton->setCaptionWithReplacing("#{sOff}");
mUnderwaterButton->setCaptionWithReplacing("#{sOff}");
mWaterShaderButton->setEnabled(false);
mReflectObjectsButton->setEnabled(false);
mReflectActorsButton->setEnabled(false);
mReflectTerrainButton->setEnabled(false);
mUnderwaterButton->setEnabled(false);
Settings::Manager::setBool("shader", "Water", false);
// refraction needs shaders to display underwater fog
mRefractionButton->setCaptionWithReplacing("#{sOff}");
mRefractionButton->setEnabled(false);
Settings::Manager::setBool("refraction", "Water", false);
Settings::Manager::setBool("underwater effect", "Water", false);
// shadows not supported
@ -461,17 +466,13 @@ namespace MWGui
else
{
Settings::Manager::setBool("shaders", "Objects", true);
Settings::Manager::setString("shader mode", "General", val);
// re-enable
if (MWRender::RenderingManager::waterShaderSupported())
{
mWaterShaderButton->setEnabled(true);
mReflectObjectsButton->setEnabled(true);
mReflectActorsButton->setEnabled(true);
mReflectTerrainButton->setEnabled(true);
}
mUnderwaterButton->setEnabled(true);
mReflectObjectsButton->setEnabled(true);
mReflectActorsButton->setEnabled(true);
mReflectTerrainButton->setEnabled(true);
mRefractionButton->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)) + ")");
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)
{
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")");

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

@ -94,9 +94,6 @@ namespace MWGui
mPtr = actor;
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();
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)
continue; // don't try to sell diseases, curses or powers
if (std::find (playerSpells.begin(), playerSpells.end(), *iter)!=playerSpells.end())
continue; // we have that spell already
if (playerHasSpell(iter->first))
continue;
addSpell (iter->first);
}
@ -118,6 +115,18 @@ namespace MWGui
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)
{
int price = *_sender->getUserData<int>();

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

@ -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");
}
}

@ -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

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

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

@ -67,7 +67,7 @@ StatsWindow::StatsWindow (MWBase::WindowManager& parWindowManager)
for (int i = 0; i < ESM::Skill::Length; ++i)
{
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);
@ -419,7 +419,7 @@ void StatsWindow::updateSkillArea()
{
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);
}

@ -67,11 +67,11 @@ namespace MWGui
SkillList mMajorSkills, mMinorSkills, mMiscSkills;
std::map<int, MWMechanics::Stat<float> > mSkillValues;
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
std::string mBirthSignId;
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;
bool mChanged;

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

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

@ -127,9 +127,7 @@ void ToolTips::onFrame(float frameDuration)
Widget* focus = InputManager::getInstance().getMouseFocusWidget();
if (focus == 0)
{
return;
}
IntSize tooltipSize;
@ -168,6 +166,10 @@ void ToolTips::onFrame(float frameDuration)
mFocusObject = *focus->getUserData<MWWorld::Ptr>();
tooltipSize = getToolTipViaPtr(false);
}
else if (type == "ToolTipInfo")
{
tooltipSize = createToolTip(*focus->getUserData<MWGui::ToolTipInfo>());
}
else if (type == "AvatarItemSelection")
{
MyGUI::IntCoord avatarPos = mWindowManager->getInventoryWindow ()->getAvatarScreenCoord ();
@ -363,7 +365,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
std::string caption = info.caption;
std::string image = info.icon;
int imageSize = (image != "") ? 32 : 0;
int imageSize = (image != "") ? info.imageSize : 0;
std::string text = info.text;
// 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");
captionWidget->setProperty("Static", "true");
captionWidget->setCaption(caption);
captionWidget->setCaptionWithReplacing(caption);
IntSize captionSize = captionWidget->getTextSize();
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");
textWidget->setProperty("Static", "true");
textWidget->setProperty("MultiLine", "true");
textWidget->setProperty("WordWrap", "true");
textWidget->setProperty("WordWrap", info.wordWrap ? "true" : "false");
textWidget->setCaptionWithReplacing(text);
textWidget->setTextAlign(Align::HCenter | Align::Top);
IntSize textSize = textWidget->getTextSize();
@ -439,7 +441,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
effectsWidget->setWindowManager(mWindowManager);
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);
totalSize.height += coord.top-6;
totalSize.width = std::max(totalSize.width, coord.width);
@ -459,7 +461,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
enchantWidget->setWindowManager(mWindowManager);
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;
enchantWidget->createEffectWidgets(enchantEffectItems, enchantArea, coord, true, flag);
totalSize.height += coord.top-6;

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

@ -64,6 +64,7 @@ namespace MWGui
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onCancelButtonClicked);
mOfferButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onOfferButtonClicked);
mMaxSaleButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onMaxSaleButtonClicked);
mIncreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onIncreaseButtonPressed);
mIncreaseButton->eventMouseButtonReleased += MyGUI::newDelegate(this, &TradeWindow::onBalanceButtonReleased);
mDecreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onDecreaseButtonPressed);
@ -191,21 +192,7 @@ namespace MWGui
}
// check if the merchant can afford this
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;
}
if (mCurrentBalance > 0 && merchantgold < mCurrentBalance)
if (mCurrentBalance > 0 && getMerchantGold() < mCurrentBalance)
{
// user notification
MWBase::Environment::get().getWindowManager()->
@ -293,6 +280,12 @@ namespace MWGui
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)
{
mBalanceButtonsState = BBS_Increase;
@ -341,22 +334,7 @@ namespace MWGui
mTotalBalance->setCaption(boost::lexical_cast<std::string>(-mCurrentBalance));
}
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;
}
mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast<std::string>(merchantgold));
mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast<std::string>(getMerchantGold()));
}
std::vector<MWWorld::Ptr> TradeWindow::getEquippedItems()
@ -468,4 +446,25 @@ namespace MWGui
mWindowManager.removeGuiMode(GM_Barter);
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;
}
}

@ -74,6 +74,7 @@ namespace MWGui
void onFilterChanged(MyGUI::Widget* _sender);
void onOfferButtonClicked(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 onDecreaseButtonPressed(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();
virtual void onReferenceUnavailable();
private:
int getMerchantGold();
};
}

@ -2,6 +2,9 @@
#include <boost/lexical_cast.hpp>
#include <MyGUI_ProgressBar.h>
#include <MyGUI_ImageBox.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
@ -31,10 +34,10 @@ void MWGui::Widgets::fixTexturePath(std::string &path)
/* MWSkill */
MWSkill::MWSkill()
: mManager(nullptr)
: mManager(NULL)
, mSkillId(ESM::Skill::Length)
, mSkillNameWidget(nullptr)
, mSkillValueWidget(nullptr)
, mSkillNameWidget(NULL)
, mSkillValueWidget(NULL)
{
}
@ -103,7 +106,7 @@ void MWSkill::initialiseOverride()
assignWidget(mSkillNameWidget, "StatName");
assignWidget(mSkillValueWidget, "StatValue");
MyGUI::ButtonPtr button;
MyGUI::Button* button;
assignWidget(button, "StatNameButton");
if (button)
{
@ -123,10 +126,10 @@ void MWSkill::initialiseOverride()
/* MWAttribute */
MWAttribute::MWAttribute()
: mManager(nullptr)
: mManager(NULL)
, mId(-1)
, mAttributeNameWidget(nullptr)
, mAttributeValueWidget(nullptr)
, mAttributeNameWidget(NULL)
, mAttributeValueWidget(NULL)
{
}
@ -195,7 +198,7 @@ void MWAttribute::initialiseOverride()
assignWidget(mAttributeNameWidget, "StatName");
assignWidget(mAttributeValueWidget, "StatValue");
MyGUI::ButtonPtr button;
MyGUI::Button* button;
assignWidget(button, "StatNameButton");
if (button)
{
@ -215,8 +218,8 @@ void MWAttribute::initialiseOverride()
/* MWSpell */
MWSpell::MWSpell()
: mWindowManager(nullptr)
, mSpellNameWidget(nullptr)
: mWindowManager(NULL)
, mSpellNameWidget(NULL)
{
}
@ -226,7 +229,7 @@ void MWSpell::setSpellId(const std::string &spellId)
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 =
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);
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();
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != end; ++it)
{
@ -286,7 +289,7 @@ MWSpell::~MWSpell()
/* MWEffectList */
MWEffectList::MWEffectList()
: mWindowManager(nullptr)
: mWindowManager(NULL)
, mEffectList(0)
{
}
@ -297,11 +300,11 @@ void MWEffectList::setEffectList(const SpellEffectList& list)
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
// 2 steps: first, create all widgets and check their width....
MWSpellEffectPtr effect = nullptr;
MWSpellEffectPtr effect = NULL;
int maxwidth = coord.width;
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
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);
bool needcenter = center && (maxwidth > effect->getRequestedWidth());
@ -375,9 +378,9 @@ SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects)
/* MWSpellEffect */
MWSpellEffect::MWSpellEffect()
: mWindowManager(nullptr)
, mImageWidget(nullptr)
, mTextWidget(nullptr)
: mWindowManager(NULL)
, mImageWidget(NULL)
, mTextWidget(NULL)
, mRequestedWidth(0)
{
}
@ -421,17 +424,7 @@ void MWSpellEffect::updateWidgets()
}
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
{
static const char *attributes[8] = {
"sAttributeStrength",
"sAttributeIntelligence",
"sAttributeWillpower",
"sAttributeAgility",
"sAttributeSpeed",
"sAttributeEndurance",
"sAttributePersonality",
"sAttributeLuck"
};
spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], "");
spellLine += " " + mWindowManager->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], "");
}
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
@ -495,9 +488,9 @@ void MWSpellEffect::initialiseOverride()
MWDynamicStat::MWDynamicStat()
: mValue(0)
, mMax(1)
, mTextWidget(nullptr)
, mBarWidget(nullptr)
, mBarTextWidget(nullptr)
, mTextWidget(NULL)
, mBarWidget(NULL)
, mBarTextWidget(NULL)
{
}

@ -2,10 +2,16 @@
#define MWGUI_WIDGETS_H
#include "../mwworld/esmstore.hpp"
#include "../mwmechanics/stat.hpp"
#include <MyGUI.h>
#include <MyGUI_Widget.h>
#include <MyGUI_TextBox.h>
#include <MyGUI_Button.h>
#include "../mwmechanics/stat.hpp"
namespace MyGUI
{
class ImageBox;
}
namespace MWBase
{
@ -118,7 +124,8 @@ namespace MWGui
MWBase::WindowManager *mManager;
ESM::Skill::SkillEnum mSkillId;
SkillValue mValue;
MyGUI::WidgetPtr mSkillNameWidget, mSkillValueWidget;
MyGUI::Widget* mSkillNameWidget;
MyGUI::Widget* mSkillValueWidget;
};
typedef MWSkill* MWSkillPtr;
@ -160,7 +167,8 @@ namespace MWGui
MWBase::WindowManager *mManager;
int mId;
AttributeValue mValue;
MyGUI::WidgetPtr mAttributeNameWidget, mAttributeValueWidget;
MyGUI::Widget* mAttributeNameWidget;
MyGUI::Widget* mAttributeValueWidget;
};
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 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; }
@ -230,7 +238,7 @@ namespace MWGui
* @param center the effect widgets horizontally
* @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:
virtual ~MWEffectList();

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

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

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

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

@ -62,7 +62,7 @@ namespace MWMechanics
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;
float magnitude = iter->second.second;
@ -74,7 +74,7 @@ namespace MWMechanics
{
int duration = iter->mDuration;
if (effects.second)
if (effects.second.first)
duration *= magnitude;
MWWorld::TimeStamp end = start;
@ -85,7 +85,7 @@ namespace MWMechanics
{
EffectParam param;
if (effects.second)
if (effects.second.first)
{
const ESM::MagicEffect *magicEffect =
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 =
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 =
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 =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Ingredient>().search (id))
@ -140,11 +140,12 @@ namespace MWMechanics
effect.mMagnMin = 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.second = true;
return result;
}
@ -157,7 +158,8 @@ namespace MWMechanics
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;
@ -178,7 +180,7 @@ namespace MWMechanics
float random = static_cast<float> (std::rand()) / RAND_MAX;
if (effects.second)
if (effects.second.first)
{
// ingredient -> special treatment required.
const CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
@ -194,7 +196,7 @@ namespace MWMechanics
random *= 0.25 * x;
}
if (iter==mSpells.end())
if (iter==mSpells.end() || stacks)
mSpells.insert (std::make_pair (id,
std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random)));
else
@ -236,7 +238,7 @@ namespace MWMechanics
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;
@ -247,7 +249,7 @@ namespace MWMechanics
duration = iter->mDuration;
}
if (effects.second)
if (effects.second.first)
duration *= iterator->second.second;
double scaledDuration = duration *
@ -274,4 +276,9 @@ namespace MWMechanics
}
return false;
}
const ActiveSpells::TContainer& ActiveSpells::getActiveSpells() const
{
return mSpells;
}
}

@ -30,7 +30,7 @@ namespace MWMechanics
{
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;
private:
@ -44,7 +44,8 @@ namespace MWMechanics
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:
@ -63,6 +64,8 @@ namespace MWMechanics
const MagicEffects& getMagicEffects() const;
const TContainer& getActiveSpells() const;
TIterator begin() const;
TIterator end() const;

@ -46,6 +46,7 @@ static const struct {
{ CharState_Idle8, "idle8" },
{ CharState_Idle9, "idle9" },
{ CharState_IdleSwim, "idleswim" },
{ CharState_IdleSneak, "idlesneak" },
{ CharState_WalkForward, "walkforward" },
{ CharState_WalkBack, "walkback" },
@ -67,6 +68,11 @@ static const struct {
{ CharState_SwimRunLeft, "swimrunleft" },
{ CharState_SwimRunRight, "swimrunright" },
{ CharState_SneakForward, "sneakforward" },
{ CharState_SneakBack, "sneakback" },
{ CharState_SneakLeft, "sneakleft" },
{ CharState_SneakRight, "sneakright" },
{ CharState_Jump, "jump" },
{ CharState_Death1, "death1" },
@ -176,6 +182,7 @@ Ogre::Vector3 CharacterController::update(float duration)
bool onground = world->isOnGround(mPtr);
bool inwater = world->isSwimming(mPtr);
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak);
speed = cls.getSpeed(mPtr);
/* 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(vec.x > 0.0f)
setState(isrunning ?
(inwater ? CharState_SwimRunRight : CharState_RunRight) :
(inwater ? CharState_SwimWalkRight : CharState_WalkRight), true);
setState(inwater ? (isrunning ? CharState_SwimRunRight : CharState_SwimWalkRight)
: (sneak ? CharState_SneakRight : (isrunning ? CharState_RunRight : CharState_WalkRight)), true);
else if(vec.x < 0.0f)
setState(isrunning ?
(inwater ? CharState_SwimRunLeft: CharState_RunLeft) :
(inwater ? CharState_SwimWalkLeft : CharState_WalkLeft), true);
setState(inwater ? (isrunning ? CharState_SwimRunLeft : CharState_SwimWalkLeft)
: (sneak ? CharState_SneakLeft : (isrunning ? CharState_RunLeft : CharState_WalkLeft)), true);
// Apply any forward/backward movement manually
movement.y += vec.y * (speed*duration);
}
else if(vec.y != 0.0f && speed > 0.0f)
{
if(vec.y > 0.0f)
setState(isrunning ?
(inwater ? CharState_SwimRunForward : CharState_RunForward) :
(inwater ? CharState_SwimWalkForward : CharState_WalkForward), true);
setState(inwater ? (isrunning ? CharState_SwimRunForward : CharState_SwimWalkForward)
: (sneak ? CharState_SneakForward : (isrunning ? CharState_RunForward : CharState_WalkForward)), true);
else if(vec.y < 0.0f)
setState(isrunning ?
(inwater ? CharState_SwimRunBack : CharState_RunBack) :
(inwater ? CharState_SwimWalkBack : CharState_WalkBack), true);
setState(inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack)
: (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack)), true);
// Apply any sideways movement manually
movement.x += vec.x * (speed*duration);
}
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)

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

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

@ -30,24 +30,13 @@ ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
{
Ogre::Entity *ent = mEntityList.mEntities[i];
bool transparent = false;
for(unsigned int j=0;!transparent && j < ent->getNumSubEntities(); ++j)
for(unsigned int j=0; j < ent->getNumSubEntities(); ++j)
{
Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
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();
}
}
Ogre::SubEntity* subEnt = ent->getSubEntity(j);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
ent->setVisibilityFlags(RV_Misc);
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
setAnimationSource(mesh);
}

@ -6,6 +6,8 @@
#include "../mwworld/ptr.hpp"
#include "../mwworld/class.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "animation.hpp"
#include "activatoranimation.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);
delete mAllActors[ptr];
mAllActors[ptr] = anim;
mRendering->addWaterRippleEmitter (ptr);
}
void Actors::insertCreature (const MWWorld::Ptr& ptr)
{
@ -79,6 +82,7 @@ void Actors::insertCreature (const MWWorld::Ptr& ptr)
CreatureAnimation* anim = new CreatureAnimation(ptr);
delete mAllActors[ptr];
mAllActors[ptr] = anim;
mRendering->addWaterRippleEmitter (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)
{
mRendering->removeWaterRippleEmitter (ptr);
delete mAllActors[ptr];
mAllActors.erase(ptr);
@ -120,6 +126,7 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store)
{
if(iter->first.getCell() == store)
{
mRendering->removeWaterRippleEmitter (iter->first);
delete iter->second;
mAllActors.erase(iter++);
}
@ -172,6 +179,8 @@ void Actors::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
anim->updatePtr(cur);
mAllActors[cur] = anim;
}
mRendering->updateWaterRippleEmitterPtr (old, cur);
}
}

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

@ -1,7 +1,7 @@
#ifndef _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"

@ -40,6 +40,15 @@ namespace MWRender
void CharacterPreview::setup ()
{
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->setAspectRatio (float(mSizeX) / float(mSizeY));
@ -51,7 +60,7 @@ namespace MWRender
mNode = renderRoot->createChildSceneNode();
mAnimation = new NpcAnimation(mCharacter, mNode,
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), RV_PlayerPreview);
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0, renderHeadOnly());
mNode->setVisible (false);
@ -73,8 +82,6 @@ namespace MWRender
mViewport->setOverlaysEnabled(false);
mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0));
mViewport->setShadowsEnabled(false);
mViewport->setMaterialScheme("local_map");
mViewport->setVisibilityMask (RV_PlayerPreview);
mRenderTarget->setActive(true);
mRenderTarget->setAutoUpdated (false);
@ -95,7 +102,7 @@ namespace MWRender
delete mAnimation;
mAnimation = new NpcAnimation(mCharacter, mNode,
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), RV_PlayerPreview);
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0, renderHeadOnly());
mNode->setVisible (false);
@ -111,6 +118,7 @@ namespace MWRender
InventoryPreview::InventoryPreview(MWWorld::Ptr character)
: 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 ()
{
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);
}
@ -152,7 +161,7 @@ namespace MWRender
RaceSelectionPreview::RaceSelectionPreview()
: 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)
{
mBase = *mCharacter.get<ESM::NPC>()->mBase;
@ -164,6 +173,8 @@ namespace MWRender
mAnimation->runAnimation(0.0f);
mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL);
updateCamera();
mNode->setVisible (true);
mRenderTarget->update();
mNode->setVisible (false);
@ -180,5 +191,17 @@ namespace MWRender
void RaceSelectionPreview::onSetup ()
{
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);
}
}

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

@ -31,23 +31,11 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
Ogre::Entity *ent = mEntityList.mEntities[i];
ent->setVisibilityFlags(RV_Actors);
bool transparent = false;
for(unsigned int j=0;!transparent && j < ent->getNumSubEntities(); ++j)
for(unsigned int j=0; j < ent->getNumSubEntities(); ++j)
{
Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
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();
}
}
Ogre::SubEntity* subEnt = ent->getSubEntity(j);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
std::vector<std::string> names;

@ -1,6 +1,5 @@
#include "localmap.hpp"
#include <OgreOverlayManager.h>
#include <OgreMaterialManager.h>
#include <OgreHardwarePixelBuffer.h>
@ -30,6 +29,12 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag
mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
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()
@ -191,22 +196,24 @@ void LocalMap::render(const float x, const float y,
const float zlow, const float zhigh,
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(0); // infinite
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;
// try loading from memory
@ -231,14 +238,13 @@ void LocalMap::render(const float x, const float y,
TU_RENDERTARGET);
RenderTarget* rtt = tex->getBuffer()->getRenderTarget();
rtt->setAutoUpdated(false);
Viewport* vp = rtt->addViewport(mCellCamera);
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setBackgroundColour(ColourValue(0, 0, 0));
vp->setVisibilityMask(RV_Map);
// use fallback techniques without shadows and without mrt
vp->setMaterialScheme("local_map");
rtt->update();
@ -272,11 +278,12 @@ void LocalMap::render(const float x, const float y,
//rtt->writeContentsToFile("./" + texture + ".jpg");
}
}
mRenderingManager->enableLights();
mRenderingManager->enableLights(true);
mLight->setVisible(false);
// 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)

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

@ -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),
mStateID(-1),
mTimeToChange(0),
@ -70,7 +70,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
mPants(inv.end()),
mGloveL(inv.end()),
mGloveR(inv.end()),
mSkirtIter(inv.end())
mSkirtIter(inv.end()),
mHeadOnly(headOnly)
{
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];
base->getUserObjectBindings().setUserAny(Ogre::Any(-1));
base->setVisibilityFlags(mVisibilityFlags);
if (mVisibilityFlags != 0)
base->setVisibilityFlags(mVisibilityFlags);
bool transparent = false;
for(unsigned int j=0;!transparent && j < base->getNumSubEntities();++j)
for(unsigned int j=0; j < base->getNumSubEntities(); ++j)
{
Ogre::MaterialPtr mat = base->getSubEntity(j)->getMaterial();
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();
}
}
Ogre::SubEntity* subEnt = base->getSubEntity(j);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
std::vector<std::string> skelnames(1, smodel);
@ -226,7 +216,7 @@ void NpcAnimation::updateParts(bool forceupdate)
if(!forceupdate)
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);
@ -263,6 +253,9 @@ void NpcAnimation::updateParts(bool forceupdate)
if(mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1)
addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1, mHairModel);
if (mHeadOnly)
return;
static const struct {
ESM::PartReferenceType type;
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++)
{
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;!transparent && j < parts[i]->getNumSubEntities();++j)
for(unsigned int j=0; j < parts[i]->getNumSubEntities(); ++j)
{
Ogre::MaterialPtr mat = parts[i]->getSubEntity(j)->getMaterial();
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();
}
}
Ogre::SubEntity* subEnt = parts[i]->getSubEntity(j);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
parts[i]->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
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");
}
}

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

@ -7,7 +7,7 @@
#include <OgreSubEntity.h>
#include <OgreStaticGeometry.h>
#include <components/nifogre/ogre_nif_loader.hpp>
#include <components/nifogre/ogrenifloader.hpp>
#include <components/settings/settings.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()].merge(bounds);
bool transparent = false;
for(size_t i = 0;!transparent && i < entities.mEntities.size();i++)
bool anyTransparency = false;
for(size_t i = 0;!anyTransparency && i < entities.mEntities.size();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();
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();
}
}
anyTransparency = ent->getSubEntity(i)->getMaterial()->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++)
{
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->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
}
else
@ -203,7 +195,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool
sg->setCastShadows(true);
sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
sg->setRenderQueueGroup(RQG_Main);
std::vector<Ogre::Entity*>::reverse_iterator iter = entities.mEntities.rbegin();
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.phase = Ogre::Math::RangeRandom(-500, +500);
// adjust the lights depending if we're in an interior or exterior cell
// 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.
// changed to linear to look like morrowind
bool quadratic = false;
/*
if (!lightOutQuadInLin)
quadratic = lightQuadratic;
else
{
quadratic = !info.interior;
}
*/
if (!quadratic)
{

@ -15,8 +15,8 @@ using namespace Ogre;
OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) :
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0),
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false),
mBBNode(0)
mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false),
mBBNode(0), mActive(false)
{
mRendering = renderer;
mSunNode = sunNode;
@ -94,6 +94,9 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
OcclusionQuery::~OcclusionQuery()
{
mRendering->getScene()->removeRenderObjectListener (this);
mRendering->getScene()->removeRenderQueueListener(this);
RenderSystem* renderSystem = Root::getSingleton().getRenderSystem();
if (mSunTotalAreaQuery) renderSystem->destroyHardwareOcclusionQuery(mSunTotalAreaQuery);
if (mSunVisibleAreaQuery) renderSystem->destroyHardwareOcclusionQuery(mSunVisibleAreaQuery);
@ -108,8 +111,10 @@ bool OcclusionQuery::supported()
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
const LightList* pLightList, bool suppressRenderStateChanges)
{
if (!mActive) return;
// 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
// 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)
{
if (!mActive) return;
if (mActiveQuery != NULL)
{
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() );
mQuerySingleObjectRequested = true;
mDoQuery = true;
}
bool OcclusionQuery::occlusionTestPending()

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

@ -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);
}
}

@ -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

@ -20,7 +20,7 @@ enum RenderQueueGroups
RQG_UnderWater = Ogre::RENDER_QUEUE_4,
RQG_Water = Ogre::RENDER_QUEUE_7+1,
RQG_Water = RQG_Alpha,
// Sky late (sun & sun flare)
RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE
@ -54,9 +54,10 @@ enum VisibilityFlags
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
};

@ -49,7 +49,12 @@ namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
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
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.setWindowEventListener(this);
mRendering.getWindow()->addListener(this);
mCompositors = new Compositors(mRendering.getViewport());
mWater = 0;
@ -93,7 +100,9 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mFactory->loadAllFiles();
// 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
TextureFilterOptions tfo;
@ -114,30 +123,25 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
//mRendering.getScene()->setCameraRelativeRendering(true);
// disable unsupported effects
//const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
if (!waterShaderSupported())
Settings::Manager::setBool("shader", "Water", false);
if (!Settings::Manager::getBool("shaders", "Objects"))
Settings::Manager::setBool("enabled", "Shadows", false);
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 ("lighting", "true");
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 ("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 ("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 ("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 ("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 ("gammaCorrection", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(
Settings::Manager::getFloat ("gamma", "Video"))));
sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false");
sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false");
sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty<sh::Vector4> (new sh::Vector4(0,0,0,0)));
applyCompositors();
@ -166,11 +170,14 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mDebugging = new Debugging(mRootNode, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this);
mWater = new MWRender::Water(mRendering.getCamera(), this);
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
}
RenderingManager::~RenderingManager ()
{
mRendering.getWindow()->removeListener(this);
mRendering.removeWindowEventListener(this);
delete mPlayer;
@ -214,15 +221,12 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store)
void RenderingManager::removeWater ()
{
if(mWater){
mWater->setActive(false);
}
mWater->setActive(false);
}
void RenderingManager::toggleWater()
{
if (mWater)
mWater->toggle();
mWater->toggle();
}
void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
@ -270,28 +274,31 @@ bool RenderingManager::rotateObject( const MWWorld::Ptr &ptr, Ogre::Vector3 &rot
if (!isPlayer && isActive)
{
Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yr(Ogre::Radian(rot.y), Ogre::Vector3::UNIT_Y);
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;
rot.y = newo.y;
rot.z = newo.z;
Ogre::Quaternion xr(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yr(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y);
Ogre::Quaternion zr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
Ogre::Quaternion xref(Ogre::Radian(-ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yref(Ogre::Radian(-ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::UNIT_Y);
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);
}
else if(isPlayer)
{
rot.x = mPlayer->getPitch();
rot.x = -mPlayer->getPitch();
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;
}
@ -313,6 +320,18 @@ RenderingManager::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &
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;
mPlayer->setCameraDistance();
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);
}
}
mOcclusionQuery->update(duration);
mVideoPlayer->update ();
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)
{
Ogre::ControllerManager::getSingleton().setTimeFactor(0.f);
return;
}
Ogre::ControllerManager::getSingleton().setTimeFactor(
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);
mPlayer->update(duration);
@ -350,38 +373,33 @@ void RenderingManager::update (float duration, bool paused)
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::Quaternion orient =
//node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
Ogre::Quaternion orient =
node->_getDerivedOrientation();
mLocalMap->updatePlayer(pos, orient);
mLocalMap->updatePlayer(playerPos, orient);
if (mWater) {
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();
mWater->updateUnderwater(
world->isUnderwater(
world->getPlayer().getPlayer().getCell(),
cam)
);
MWBase::World *world = MWBase::Environment::get().getWorld();
mWater->update(duration, playerPos);
}
mWater->updateUnderwater(
world->isUnderwater(
world->getPlayer().getPlayer().getCell(),
cam)
);
mWater->update(duration);
}
void RenderingManager::preRenderTargetUpdate(const RenderTargetEvent &evt)
{
mOcclusionQuery->setActive(true);
}
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)
@ -393,10 +411,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
|| ((store->mCell->isExterior())
&& !lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land.
{
if(mWater == 0)
mWater = new MWRender::Water(mRendering.getCamera(), this, store->mCell);
else
mWater->changeCell(store->mCell);
mWater->changeCell(store->mCell);
mWater->setActive(true);
}
else
@ -405,8 +420,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
void RenderingManager::setWaterHeight(const float height)
{
if (mWater)
mWater->setHeight(height);
mWater->setHeight(height);
}
void RenderingManager::skyEnable ()
@ -491,31 +505,34 @@ void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell)
color.setAsABGR (mCell.mCell->mAmbi.mFog);
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)
{
mFogColour = colour;
float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
mRendering.getCamera()->setFarClipDistance ( 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)));
mFogStart = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
mFogEnd = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
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()
{
@ -588,22 +605,28 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& 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 (mSun) mSun->setVisible(true);
mSunEnabled = true;
if (real && mSun) mSun->setVisible(true);
else
{
// 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 (mSun) mSun->setVisible(false);
mSunEnabled = false;
if (mSun)
if (real && mSun) mSun->setVisible(false);
else
{
mSun->setDiffuseColour(ColourValue(0,0,0));
mSun->setSpecularColour(ColourValue(0,0,0));
// Don't disable the light, as the shaders assume the first light to be directional.
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);
}
void RenderingManager::disableLights()
void RenderingManager::disableLights(bool sun)
{
mObjects.disableLights();
sunDisable();
sunDisable(sun);
}
void RenderingManager::enableLights()
void RenderingManager::enableLights(bool sun)
{
mObjects.enableLights();
sunEnable();
}
const bool RenderingManager::useMRT()
{
return Settings::Manager::getBool("shader", "Water");
sunEnable(sun);
}
Shadows* RenderingManager::getShadows()
@ -714,6 +732,7 @@ Compositors* RenderingManager::getCompositors()
void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings)
{
bool changeRes = false;
bool rebuild = false; // rebuild static geometry (necessary after any material changes)
for (Settings::CategorySettingVector::const_iterator it=settings.begin();
it != settings.end(); ++it)
{
@ -749,25 +768,19 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
else if (it->second == "shader" && it->first == "Water")
{
applyCompositors();
sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false");
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");
mObjects.rebuildStaticGeometry ();
rebuild = 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"));
mObjects.rebuildStaticGeometry ();
sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false");
rebuild = true;
}
else if (it->second == "shaders" && it->first == "Objects")
{
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));
mObjects.rebuildStaticGeometry ();
}
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"))));
rebuild = true;
}
else if (it->second == "shader mode" && it->first == "General")
{
@ -780,13 +793,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
else
lang = sh::Language_CG;
sh::Factory::getInstance ().setCurrentLanguage (lang);
mObjects.rebuildStaticGeometry ();
rebuild = true;
}
else if (it->first == "Shadows")
{
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);
}
if (mWater)
mWater->processChangedSettings(settings);
mWater->processChangedSettings(settings);
if (rebuild)
mObjects.rebuildStaticGeometry();
}
void RenderingManager::setMenuTransparency(float val)
@ -824,13 +839,12 @@ void RenderingManager::windowResized(Ogre::RenderWindow* rw)
mRendering.adjustViewport();
mCompositors->recreate();
mWater->assignTextures();
mVideoPlayer->setResolution (rw->getWidth(), rw->getHeight());
const Settings::CategorySettingVector& changed = Settings::Manager::apply();
MWBase::Environment::get().getInputManager()->processChangedSettings(changed); //FIXME
MWBase::Environment::get().getWindowManager()->processChangedSettings(changed); // FIXME
MWBase::Environment::get().getInputManager()->processChangedSettings(changed);
MWBase::Environment::get().getWindowManager()->processChangedSettings(changed);
}
void RenderingManager::windowClosed(Ogre::RenderWindow* rw)
@ -838,27 +852,8 @@ void RenderingManager::windowClosed(Ogre::RenderWindow* rw)
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()
{
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)
@ -887,6 +882,8 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors
);
mPlayer->setAnimation(anim);
mWater->removeEmitter (ptr);
mWater->addEmitter (ptr);
}
void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw)
@ -930,4 +927,24 @@ void RenderingManager::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

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

@ -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;
}
}
}
}

@ -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

@ -9,9 +9,6 @@
#include <OgreShadowCameraSetupPSSM.h>
#include <OgreHardwarePixelBuffer.h>
#include <OgreOverlayContainer.h>
#include <OgreOverlayManager.h>
#include <extern/shiny/Main/Factory.hpp>
#include "renderconst.hpp"
@ -33,8 +30,8 @@ void Shadows::recreate()
// 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
bool split = Settings::Manager::getBool("split", "Shadows");
//const bool split = false;
//bool split = Settings::Manager::getBool("split", "Shadows");
const bool split = false;
sh::Factory::getInstance ().setGlobalSetting ("shadows", 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 -----------------------------------
// --------------------------------------------------------------------------------------------------------------------
/*
if (Settings::Manager::getBool("debug", "Shadows"))
{
OverlayManager& mgr = OverlayManager::getSingleton();
@ -181,6 +179,7 @@ void Shadows::recreate()
if ((overlay = mgr.getByName("DebugOverlay")))
mgr.destroy(overlay);
}
*/
}
PSSMShadowCameraSetup* Shadows::getPSSMSetup()

@ -14,7 +14,7 @@
#include <boost/lexical_cast.hpp>
#include <components/nifogre/ogre_nif_loader.hpp>
#include <components/nifogre/ogrenifloader.hpp>
#include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp>
@ -254,6 +254,7 @@ void SkyManager::create()
sh::Factory::getInstance().setSharedParameter ("nightFade",
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 ("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_2", "");
@ -279,6 +280,9 @@ void SkyManager::create()
mSunGlare->setRenderQueue(RQG_SkiesLate);
mSunGlare->setVisibilityFlags(RV_NoReflection);
Ogre::AxisAlignedBox aabInf;
aabInf.setInfinite ();
// Stars
mAtmosphereNight = mRootNode->createChildSceneNode();
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->setVisibilityFlags(RV_Sky);
night1_ent->setCastShadows(false);
night1_ent->getMesh()->_setBounds (aabInf);
for (unsigned int j=0; j<night1_ent->getNumSubEntities(); ++j)
{
@ -313,8 +318,12 @@ void SkyManager::create()
atmosphere_ent->setCastShadows(false);
atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
atmosphere_ent->setVisibilityFlags(RV_Sky);
for(unsigned int j = 0;j < atmosphere_ent->getNumSubEntities();j++)
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++)
clouds_ent->getSubEntity(j)->setMaterialName("openmw_clouds");
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;
@ -362,7 +373,7 @@ void SkyManager::update(float duration)
mRootNode->setPosition(mCamera->getDerivedPosition());
// UV Scroll the clouds
mCloudAnimationTimer += duration * mCloudSpeed * (MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);
mCloudAnimationTimer += duration * mCloudSpeed;
sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer",
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)));
}
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;
if (weather.mNight && mStarsOpacity != weather.mNightFade)
@ -583,6 +601,10 @@ void SkyManager::setLightningStrength(const float factor)
else
mLightning->setVisible(false);
}
void SkyManager::setLightningEnabled(bool enabled)
{
/// \todo
}
void SkyManager::setLightningDirection(const Ogre::Vector3& dir)
{

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

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

@ -119,10 +119,6 @@ namespace MWRender
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(
Ogre::StringConverter::toString(numBlendTextures + numLayers + 2))));
@ -153,9 +149,8 @@ namespace MWRender
--freeTextureUnits;
// colourmap
--freeTextureUnits;
freeTextureUnits -= 3; // shadow PSSM
--freeTextureUnits; // caustics
// shadow
--freeTextureUnits;
// each layer needs 1.25 units (1xdiffusespec, 0.25xblend)
return static_cast<Ogre::uint8>(freeTextureUnits / (1.25f));

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

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

@ -4,17 +4,12 @@
#include <OgreEntity.h>
#include <OgreMeshManager.h>
#include <OgreHardwarePixelBuffer.h>
#include <OgreCompositorManager.h>
#include <OgreCompositorInstance.h>
#include <OgreCompositorChain.h>
#include <OgreRoot.h>
#include <OgreOverlayManager.h>
#include <OgreOverlayContainer.h>
#include <OgreOverlayElement.h>
#include "sky.hpp"
#include "renderingmanager.hpp"
#include "compositors.hpp"
#include "ripplesimulation.hpp"
#include "refraction.hpp"
#include <extern/shiny/Main/Factory.hpp>
#include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp>
@ -27,18 +22,185 @@ using namespace Ogre;
namespace MWRender
{
Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) :
mCamera (camera), mSceneManager (camera->getSceneManager()),
CubeReflection::CubeReflection(Ogre::SceneManager* sceneManager)
: Reflection(sceneManager)
{
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),
mReflectionTarget(0), mActive(1), mToggled(1),
mReflectionRenderActive(false), mRendering(rend),
mWaterTimer(0.f)
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();
mMaterial = MaterialManager::getSingleton().getByName("Water");
mTop = cell->mWater;
mTop = 0;
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);
mWater = mSceneManager->createEntity("water");
mWater = mSceneMgr->createEntity("water");
mWater->setVisibilityFlags(RV_Water);
mWater->setRenderQueueGroup(RQG_Water);
mWater->setCastShadows(false);
mWater->setRenderQueueGroup(RQG_Alpha);
mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
mReflectionCamera = mSceneManager->createCamera("ReflectionCamera");
mWaterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
if(!(cell->mData.mFlags & cell->Interior))
{
mWaterNode->setPosition(getSceneNodeCoordinates(cell->mData.mX, cell->mData.mY));
}
mWaterNode->attachObject(mWater);
applyRTT();
@ -66,26 +222,11 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
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);
sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water");
m->setListener (this);
// ----------------------------------------------------------------------------------------------
// ---------------------------------- reflection debug overlay ----------------------------------
// ----------------------------------------------------------------------------------------------
@ -146,12 +287,12 @@ Water::~Water()
{
MeshManager::getSingleton().remove("water");
if (mReflectionTarget)
mReflectionTexture->getBuffer()->getRenderTarget()->removeListener(this);
mWaterNode->detachObject(mWater);
mSceneManager->destroyEntity(mWater);
mSceneManager->destroySceneNode(mWaterNode);
mSceneMgr->destroyEntity(mWater);
mSceneMgr->destroySceneNode(mWaterNode);
delete mReflection;
delete mRefraction;
}
void Water::changeCell(const ESM::Cell* cell)
@ -168,10 +309,12 @@ void Water::setHeight(const float height)
{
mTop = height;
mWaterPlane = Plane(Vector3::UNIT_Z, height);
mWaterPlane = Plane(Vector3::UNIT_Z, -height);
// small error due to reflection texture size & reflection distortion
mErrorPlane = Plane(Vector3::UNIT_Z, height - 5);
if (mReflection)
mReflection->setHeight(height);
if (mRefraction)
mRefraction->setHeight(height);
mWaterNode->setPosition(0, 0, height);
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height)));
@ -194,6 +337,11 @@ Water::updateUnderwater(bool underwater)
mWater->isVisible() &&
mCamera->getPolygonMode() == Ogre::PM_SOLID;
if (mReflection)
mReflection->setUnderwater (mIsUnderwater);
if (mRefraction)
mRefraction->setUnderwater (mIsUnderwater);
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);
}
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)
{
if (mReflectionTarget)
mReflectionTarget->getViewport(0)->setBackgroundColour(bg);
if (mReflection)
mReflection->setViewportBackground(bg);
}
void Water::updateVisible()
{
mWater->setVisible(mToggled && mActive);
if (mReflectionTarget)
mReflectionTarget->setActive(mToggled && mActive);
if (mReflection)
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)
if (queueGroupId < 20 && mReflectionRenderActive)
{
mReflectionCamera->disableCustomNearClipPlane();
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
}
}
mWaterTimer += dt;
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mWaterTimer)));
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());
}
mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater);
mPlayer = Ogre::Vector2(player.x, player.y);
}
void Water::update(float dt)
void Water::frameStarted(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)));
mSimulation->update(dt, mPlayer);
mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater);
if (mReflection)
mReflection->update();
}
void Water::applyRTT()
{
if (mReflectionTarget)
{
TextureManager::getSingleton().remove("WaterReflection");
mReflectionTarget = 0;
}
delete mReflection;
mReflection = NULL;
delete mRefraction;
mRefraction = NULL;
// 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"))
{
mReflectionTexture = TextureManager::getSingleton().createManual("WaterReflection",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_A8R8G8B8, TU_RENDERTARGET);
RenderTarget* rtt = mReflectionTexture->getBuffer()->getRenderTarget();
Viewport* vp = rtt->addViewport(mReflectionCamera);
vp->setOverlaysEnabled(false);
vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f));
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;
mReflection = new PlaneReflection(mSceneMgr, mSky);
mReflection->setParentCamera (mCamera);
mReflection->setHeight(mTop);
sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mReflectionTexture->getName());
if (Settings::Manager::getBool("refraction", "Water"))
{
mRefraction = new Refraction(mCamera);
mRefraction->setHeight(mTop);
}
}
updateVisible();
}
void Water::applyVisibilityMask()
@ -336,10 +418,8 @@ void Water::applyVisibilityMask()
+ RV_Misc * Settings::Manager::getBool("reflect misc", "Water")
+ RV_Sky;
if (mReflectionTarget)
{
mReflectionTexture->getBuffer()->getRenderTarget()->getViewport(0)->setVisibilityMask(mVisibilityFlags);
}
if (mReflection)
mReflection->setVisibilityMask(mVisibilityFlags);
}
void Water::processChangedSettings(const Settings::CategorySettingVector& settings)
@ -350,7 +430,8 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin
it != settings.end(); ++it)
{
if ( it->first == "Water" && (
it->second == "shader"
it->second == "shader"
|| it->second == "refraction"
|| it->second == "rtt size"))
applyRT = true;
@ -368,7 +449,6 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin
applyRTT();
applyVisibilityMask();
mWater->setMaterial(mMaterial);
assignTextures();
}
if (applyVisMask)
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

@ -7,13 +7,17 @@
#include <OgreRenderTargetListener.h>
#include <OgreMaterial.h>
#include <OgreTexture.h>
#include <OgreVector2.h>
#include <components/esm/loadcell.hpp>
#include <components/settings/settings.hpp>
#include <extern/shiny/Main/MaterialInstance.hpp>
#include "renderconst.hpp"
#include <extern/shiny/Main/MaterialInstance.hpp>
#include "../mwworld/ptr.hpp"
namespace Ogre
{
@ -22,6 +26,7 @@ namespace Ogre
class SceneNode;
class Entity;
class Vector3;
class Rectangle2D;
struct RenderTargetEvent;
}
@ -29,22 +34,82 @@ namespace MWRender {
class SkyManager;
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
class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener, public sh::MaterialInstanceListener
class Water : public sh::MaterialInstanceListener
{
static const int CELL_SIZE = 8192;
Ogre::Camera *mCamera;
Ogre::SceneManager *mSceneManager;
Ogre::SceneManager *mSceneMgr;
Ogre::Plane mWaterPlane;
Ogre::Plane mErrorPlane;
Ogre::SceneNode *mWaterNode;
Ogre::Entity *mWater;
//Ogre::SceneNode* mUnderwaterDome;
bool mIsUnderwater;
bool mActive;
bool mToggled;
@ -52,17 +117,10 @@ namespace MWRender {
float mWaterTimer;
bool mReflectionRenderActive;
Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY);
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 applyVisibilityMask();
@ -75,24 +133,29 @@ namespace MWRender {
Ogre::MaterialPtr mMaterial;
Ogre::Camera* mReflectionCamera;
Ogre::TexturePtr mReflectionTexture;
Ogre::RenderTarget* mReflectionTarget;
bool mUnderwaterEffect;
int mVisibilityFlags;
Reflection* mReflection;
Refraction* mRefraction;
RippleSimulation* mSimulation;
Ogre::Vector2 mPlayer;
public:
Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell);
Water (Ogre::Camera *camera, RenderingManager* rend);
~Water();
void setActive(bool active);
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);

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

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

Loading…
Cancel
Save