Merge remote-tracking branch 'zini/master' into material-fix

Conflicts:
	components/nifogre/ogrenifloader.cpp
actorid
Chris Robinson 12 years ago
commit 4e1e0eaf62

@ -121,6 +121,7 @@ bool GraphicsPage::setupOgre()
pluginDir = absPluginPath.string(); pluginDir = absPluginPath.string();
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mOgre); Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mOgre);
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mOgre);
Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mOgre); Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mOgre);
#ifdef ENABLE_PLUGIN_GL #ifdef ENABLE_PLUGIN_GL

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -3,7 +3,7 @@
#include <cassert> #include <cassert>
#include <iterator> #include <iterator>
#include "MyGUI_UString.h" #include <MyGUI_UString.h>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include <openengine/gui/manager.hpp> #include <openengine/gui/manager.hpp>
@ -54,14 +54,16 @@
#include "imagebutton.hpp" #include "imagebutton.hpp"
#include "exposedwindow.hpp" #include "exposedwindow.hpp"
#include "cursor.hpp" #include "cursor.hpp"
#include "spellicons.hpp"
using namespace MWGui; using namespace MWGui;
WindowManager::WindowManager( WindowManager::WindowManager(
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *ogre,
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
Translation::Storage& translationDataStorage) Translation::Storage& translationDataStorage)
: mGuiManager(NULL) : mGuiManager(NULL)
, mRendering(ogre)
, mHud(NULL) , mHud(NULL)
, mMap(NULL) , mMap(NULL)
, mMenu(NULL) , mMenu(NULL)
@ -112,7 +114,7 @@ WindowManager::WindowManager(
, mTranslationDataStorage (translationDataStorage) , mTranslationDataStorage (translationDataStorage)
{ {
// Set up the GUI system // Set up the GUI system
mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath); mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath);
mGui = mGuiManager->getGui(); mGui = mGuiManager->getGui();
//Register own widgets with MyGUI //Register own widgets with MyGUI
@ -177,15 +179,14 @@ WindowManager::WindowManager(
mEnchantingDialog = new EnchantingDialog(*this); mEnchantingDialog = new EnchantingDialog(*this);
mTrainingWindow = new TrainingWindow(*this); mTrainingWindow = new TrainingWindow(*this);
mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this);
mLoadingScreen->onResChange (w,h); mLoadingScreen->onResChange (w,h);
mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows",""); mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows","");
mCursor = new Cursor(); mCursor = new Cursor();
// The HUD is always on mHud->setVisible(mHudEnabled);
mHud->setVisible(true);
mCharGen = new CharacterCreation(this); mCharGen = new CharacterCreation(this);
@ -270,6 +271,8 @@ void WindowManager::update()
mHud->setTriangleCount(mTriangleCount); mHud->setTriangleCount(mTriangleCount);
mHud->setBatchCount(mBatchCount); mHud->setBatchCount(mBatchCount);
mHud->update();
mCursor->update(); mCursor->update();
} }
@ -299,7 +302,7 @@ void WindowManager::updateVisible()
mEnchantingDialog->setVisible(false); mEnchantingDialog->setVisible(false);
mTrainingWindow->setVisible(false); mTrainingWindow->setVisible(false);
mHud->setVisible(true); mHud->setVisible(mHudEnabled);
// Mouse is visible whenever we're not in game mode // Mouse is visible whenever we're not in game mode
mCursor->setVisible(isGuiMode()); mCursor->setVisible(isGuiMode());
@ -802,6 +805,7 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI")); mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI"));
bool changeRes = false; bool changeRes = false;
bool windowRecreated = false;
for (Settings::CategorySettingVector::const_iterator it = changed.begin(); for (Settings::CategorySettingVector::const_iterator it = changed.begin();
it != changed.end(); ++it) it != changed.end(); ++it)
{ {
@ -811,6 +815,8 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
{ {
changeRes = true; changeRes = true;
} }
else if (it->first == "Video" && it->second == "vsync")
windowRecreated = true;
else if (it->first == "HUD" && it->second == "crosshair") else if (it->first == "HUD" && it->second == "crosshair")
mCrosshairEnabled = Settings::Manager::getBool ("crosshair", "HUD"); mCrosshairEnabled = Settings::Manager::getBool ("crosshair", "HUD");
else if (it->first == "GUI" && it->second == "subtitles") else if (it->first == "GUI" && it->second == "subtitles")
@ -834,6 +840,11 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y)); mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y));
mInputBlocker->setSize(MyGUI::IntSize(x,y)); mInputBlocker->setSize(MyGUI::IntSize(x,y));
} }
if (windowRecreated)
{
mGuiManager->updateWindow (mRendering->getWindow ());
mLoadingScreen->updateWindow (mRendering->getWindow ());
}
} }
void WindowManager::pushGuiMode(GuiMode mode) void WindowManager::pushGuiMode(GuiMode mode)
@ -1050,7 +1061,6 @@ void WindowManager::notifyInputActionBound ()
allowMouse(); allowMouse();
} }
void WindowManager::showCrosshair (bool show) void WindowManager::showCrosshair (bool show)
{ {
mHud->setCrosshairVisible (show && mCrosshairEnabled); mHud->setCrosshairVisible (show && mCrosshairEnabled);

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

@ -42,9 +42,11 @@ namespace MWInput
, mMouseX(ogre.getWindow()->getWidth ()/2.f) , mMouseX(ogre.getWindow()->getWidth ()/2.f)
, mMouseY(ogre.getWindow()->getHeight ()/2.f) , mMouseY(ogre.getWindow()->getHeight ()/2.f)
, mMouseWheel(0) , mMouseWheel(0)
, mUserFile(userFile)
, mDragDrop(false) , mDragDrop(false)
, mGuiCursorEnabled(false) , mGuiCursorEnabled(false)
, mDebug(debug)
, mUserFile(userFile)
, mUserFileExists(userFileExists)
, mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mInvertY (Settings::Manager::getBool("invert y axis", "Input"))
, mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input"))
, mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input")) , mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input"))
@ -54,7 +56,7 @@ namespace MWInput
, mTimeIdle(0.f) , mTimeIdle(0.f)
, mOverencumberedMessageDelay(0.f) , mOverencumberedMessageDelay(0.f)
{ {
Ogre::RenderWindow* window = ogre.getWindow (); Ogre::RenderWindow* window = mOgre.getWindow ();
size_t windowHnd; size_t windowHnd;
resetIdleTime(); resetIdleTime();
@ -69,7 +71,7 @@ namespace MWInput
// Set non-exclusive mouse and keyboard input if the user requested // Set non-exclusive mouse and keyboard input if the user requested
// it. // it.
if (debug) if (mDebug)
{ {
#if defined OIS_WIN32_PLATFORM #if defined OIS_WIN32_PLATFORM
pl.insert(std::make_pair(std::string("w32_mouse"), pl.insert(std::make_pair(std::string("w32_mouse"),
@ -116,7 +118,7 @@ namespace MWInput
MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs); MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs);
std::string file = userFileExists ? userFile : ""; std::string file = mUserFileExists ? mUserFile : "";
mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
loadKeyDefaults(); loadKeyDefaults();
@ -242,7 +244,7 @@ namespace MWInput
case A_ToggleHUD: case A_ToggleHUD:
mWindows.toggleHud(); mWindows.toggleHud();
break; break;
} }
} }
} }

@ -150,6 +150,8 @@ namespace MWInput
float mMouseX; float mMouseX;
float mMouseY; float mMouseY;
int mMouseWheel; int mMouseWheel;
bool mDebug;
bool mUserFileExists;
std::map<std::string, bool> mControlSwitch; std::map<std::string, bool> mControlSwitch;

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

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

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

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

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

@ -40,6 +40,15 @@ namespace MWRender
void CharacterPreview::setup () void CharacterPreview::setup ()
{ {
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC); mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
/// \todo Read the fallback values from INIImporter (Inventory:Directional*)
Ogre::Light* l = mSceneMgr->createLight();
l->setType (Ogre::Light::LT_DIRECTIONAL);
l->setDirection (Ogre::Vector3(0.3, -0.7, 0.3));
l->setDiffuseColour (Ogre::ColourValue(1,1,1));
mSceneMgr->setAmbientLight (Ogre::ColourValue(0.5, 0.5, 0.5));
mCamera = mSceneMgr->createCamera (mName); mCamera = mSceneMgr->createCamera (mName);
mCamera->setAspectRatio (float(mSizeX) / float(mSizeY)); mCamera->setAspectRatio (float(mSizeX) / float(mSizeY));
@ -51,7 +60,7 @@ namespace MWRender
mNode = renderRoot->createChildSceneNode(); mNode = renderRoot->createChildSceneNode();
mAnimation = new NpcAnimation(mCharacter, mNode, mAnimation = new NpcAnimation(mCharacter, mNode,
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), RV_PlayerPreview); MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0);
mNode->setVisible (false); mNode->setVisible (false);
@ -73,8 +82,6 @@ namespace MWRender
mViewport->setOverlaysEnabled(false); mViewport->setOverlaysEnabled(false);
mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0)); mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0));
mViewport->setShadowsEnabled(false); mViewport->setShadowsEnabled(false);
mViewport->setMaterialScheme("local_map");
mViewport->setVisibilityMask (RV_PlayerPreview);
mRenderTarget->setActive(true); mRenderTarget->setActive(true);
mRenderTarget->setAutoUpdated (false); mRenderTarget->setAutoUpdated (false);
@ -95,7 +102,7 @@ namespace MWRender
delete mAnimation; delete mAnimation;
mAnimation = new NpcAnimation(mCharacter, mNode, mAnimation = new NpcAnimation(mCharacter, mNode,
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), RV_PlayerPreview); MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0);
mNode->setVisible (false); mNode->setVisible (false);
@ -111,6 +118,7 @@ namespace MWRender
InventoryPreview::InventoryPreview(MWWorld::Ptr character) InventoryPreview::InventoryPreview(MWWorld::Ptr character)
: CharacterPreview(character, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 65, -180), Ogre::Vector3(0,65,0)) : CharacterPreview(character, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 65, -180), Ogre::Vector3(0,65,0))
, mSelectionBuffer(NULL)
{ {
} }
@ -143,7 +151,8 @@ namespace MWRender
void InventoryPreview::onSetup () void InventoryPreview::onSetup ()
{ {
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview); if (!mSelectionBuffer)
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0);
mAnimation->play("inventoryhandtohand", "start", "stop", false); mAnimation->play("inventoryhandtohand", "start", "stop", false);
} }

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

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

@ -104,7 +104,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
Ogre::Entity *base = mEntityList.mEntities[i]; Ogre::Entity *base = mEntityList.mEntities[i];
base->getUserObjectBindings().setUserAny(Ogre::Any(-1)); base->getUserObjectBindings().setUserAny(Ogre::Any(-1));
base->setVisibilityFlags(mVisibilityFlags); if (mVisibilityFlags != 0)
base->setVisibilityFlags(mVisibilityFlags);
bool transparent = false; bool transparent = false;
for(unsigned int j=0;!transparent && j < base->getNumSubEntities();++j) for(unsigned int j=0;!transparent && j < base->getNumSubEntities();++j)
@ -322,7 +323,8 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int
for(size_t i = 0;i < parts.size();i++) for(size_t i = 0;i < parts.size();i++)
{ {
parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group)); parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
parts[i]->setVisibilityFlags(mVisibilityFlags); if (mVisibilityFlags != 0)
parts[i]->setVisibilityFlags(mVisibilityFlags);
bool transparent = false; bool transparent = false;
for(unsigned int j=0;!transparent && j < parts[i]->getNumSubEntities();++j) for(unsigned int j=0;!transparent && j < parts[i]->getNumSubEntities();++j)

@ -7,7 +7,7 @@
#include <OgreSubEntity.h> #include <OgreSubEntity.h>
#include <OgreStaticGeometry.h> #include <OgreStaticGeometry.h>
#include <components/nifogre/ogre_nif_loader.hpp> #include <components/nifogre/ogrenifloader.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
@ -264,17 +264,16 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, Ogre::Entity* skelBase, Ogre
info.time = Ogre::Math::RangeRandom(-500, +500); info.time = Ogre::Math::RangeRandom(-500, +500);
info.phase = Ogre::Math::RangeRandom(-500, +500); info.phase = Ogre::Math::RangeRandom(-500, +500);
// adjust the lights depending if we're in an interior or exterior cell // changed to linear to look like morrowind
// quadratic means the light intensity falls off quite fast, resulting in a
// dark, atmospheric environment (perfect for exteriors)
// for interiors, we want more "warm" lights, so use linear attenuation.
bool quadratic = false; bool quadratic = false;
/*
if (!lightOutQuadInLin) if (!lightOutQuadInLin)
quadratic = lightQuadratic; quadratic = lightQuadratic;
else else
{ {
quadratic = !info.interior; quadratic = !info.interior;
} }
*/
if (!quadratic) if (!quadratic)
{ {

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

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

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

@ -49,7 +49,12 @@ namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine)
: mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine) : mRendering(_rend)
, mObjects(mRendering)
, mActors(mRendering, this)
, mAmbientMode(0)
, mSunEnabled(0)
, mPhysicsEngine(engine)
{ {
// select best shader mode // select best shader mode
bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos);
@ -65,6 +70,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
mRendering.setWindowEventListener(this); mRendering.setWindowEventListener(this);
mRendering.getWindow()->addListener(this);
mCompositors = new Compositors(mRendering.getViewport()); mCompositors = new Compositors(mRendering.getViewport());
mWater = 0; mWater = 0;
@ -114,30 +121,26 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
//mRendering.getScene()->setCameraRelativeRendering(true); //mRendering.getScene()->setCameraRelativeRendering(true);
// disable unsupported effects // disable unsupported effects
//const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
if (!waterShaderSupported())
Settings::Manager::setBool("shader", "Water", false);
if (!Settings::Manager::getBool("shaders", "Objects")) if (!Settings::Manager::getBool("shaders", "Objects"))
Settings::Manager::setBool("enabled", "Shadows", false); Settings::Manager::setBool("enabled", "Shadows", false);
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));
sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false");
sh::Factory::getInstance ().setGlobalSetting ("fog", "true"); sh::Factory::getInstance ().setGlobalSetting ("fog", "true");
sh::Factory::getInstance ().setGlobalSetting ("lighting", "true"); sh::Factory::getInstance ().setGlobalSetting ("lighting", "true");
sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects")); sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects"));
sh::Factory::getInstance ().setGlobalSetting ("terrain_num_lights", Settings::Manager::getString ("num lights", "Terrain")); sh::Factory::getInstance ().setGlobalSetting ("terrain_num_lights", Settings::Manager::getString ("num lights", "Terrain"));
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water"));
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");
sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false");
sh::Factory::getInstance ().setSharedParameter ("viewportBackground", sh::makeProperty<sh::Vector3> (new sh::Vector3(0,0,0)));
sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(0.0))); sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(0.0)));
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2))); sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2)));
sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6))); sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6)));
sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty<sh::FloatValue>(new sh::FloatValue( sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false");
Settings::Manager::getFloat ("gamma", "Video")))); sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false");
sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty<sh::Vector4> (new sh::Vector4(0,0,0,0)));
applyCompositors(); applyCompositors();
@ -166,11 +169,14 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mDebugging = new Debugging(mRootNode, engine); mDebugging = new Debugging(mRootNode, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this); mLocalMap = new MWRender::LocalMap(&mRendering, this);
mWater = new MWRender::Water(mRendering.getCamera(), this);
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
} }
RenderingManager::~RenderingManager () RenderingManager::~RenderingManager ()
{ {
mRendering.getWindow()->removeListener(this);
mRendering.removeWindowEventListener(this); mRendering.removeWindowEventListener(this);
delete mPlayer; delete mPlayer;
@ -214,15 +220,12 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store)
void RenderingManager::removeWater () void RenderingManager::removeWater ()
{ {
if(mWater){ mWater->setActive(false);
mWater->setActive(false);
}
} }
void RenderingManager::toggleWater() void RenderingManager::toggleWater()
{ {
if (mWater) mWater->toggle();
mWater->toggle();
} }
void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store) void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
@ -313,6 +316,20 @@ RenderingManager::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &
void RenderingManager::update (float duration, bool paused) void RenderingManager::update (float duration, bool paused)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld();
// player position
MWWorld::RefData &data =
MWBase::Environment::get()
.getWorld()
->getPlayer()
.getPlayer()
.getRefData();
float *_playerPos = data.getPosition().pos;
Ogre::Vector3 playerPos(_playerPos[0], _playerPos[1], _playerPos[2]);
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();
Ogre::Vector3 orig, dest; Ogre::Vector3 orig, dest;
mPlayer->setCameraDistance(); mPlayer->setCameraDistance();
if (!mPlayer->getPosition(orig, dest)) { if (!mPlayer->getPosition(orig, dest)) {
@ -326,19 +343,21 @@ void RenderingManager::update (float duration, bool paused)
mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false); mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false);
} }
} }
mOcclusionQuery->update(duration); mOcclusionQuery->update(duration);
mVideoPlayer->update (); mVideoPlayer->update ();
mRendering.update(duration); mRendering.update(duration);
Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f);
applyFog(world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam));
if(paused) if(paused)
{ {
Ogre::ControllerManager::getSingleton().setTimeFactor(0.f);
return; return;
} }
Ogre::ControllerManager::getSingleton().setTimeFactor(
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);
mPlayer->update(duration); mPlayer->update(duration);
@ -350,38 +369,33 @@ void RenderingManager::update (float duration, bool paused)
mSkyManager->setGlare(mOcclusionQuery->getSunVisibility()); mSkyManager->setGlare(mOcclusionQuery->getSunVisibility());
MWWorld::RefData &data =
MWBase::Environment::get()
.getWorld()
->getPlayer()
.getPlayer()
.getRefData();
float *fpos = data.getPosition().pos;
// only for LocalMap::updatePlayer()
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
Ogre::SceneNode *node = data.getBaseNode(); Ogre::SceneNode *node = data.getBaseNode();
//Ogre::Quaternion orient = //Ogre::Quaternion orient =
//node->convertLocalToWorldOrientation(node->_getDerivedOrientation()); //node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
Ogre::Quaternion orient = Ogre::Quaternion orient =
node->_getDerivedOrientation(); node->_getDerivedOrientation();
mLocalMap->updatePlayer(pos, orient); mLocalMap->updatePlayer(playerPos, orient);
if (mWater) { mWater->updateUnderwater(
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); world->isUnderwater(
world->getPlayer().getPlayer().getCell(),
cam)
);
MWBase::World *world = MWBase::Environment::get().getWorld(); mWater->update(duration, playerPos);
}
mWater->updateUnderwater( void RenderingManager::preRenderTargetUpdate(const RenderTargetEvent &evt)
world->isUnderwater( {
world->getPlayer().getPlayer().getCell(), mOcclusionQuery->setActive(true);
cam) }
);
mWater->update(duration); void RenderingManager::postRenderTargetUpdate(const RenderTargetEvent &evt)
} {
// deactivate queries to make sure we aren't getting false results from several misc render targets
// (will be reactivated at the bottom of this method)
mOcclusionQuery->setActive(false);
} }
void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store) void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
@ -393,10 +407,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
|| ((store->mCell->isExterior()) || ((store->mCell->isExterior())
&& !lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land. && !lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land.
{ {
if(mWater == 0) mWater->changeCell(store->mCell);
mWater = new MWRender::Water(mRendering.getCamera(), this, store->mCell);
else
mWater->changeCell(store->mCell);
mWater->setActive(true); mWater->setActive(true);
} }
else else
@ -405,8 +416,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
void RenderingManager::setWaterHeight(const float height) void RenderingManager::setWaterHeight(const float height)
{ {
if (mWater) mWater->setHeight(height);
mWater->setHeight(height);
} }
void RenderingManager::skyEnable () void RenderingManager::skyEnable ()
@ -491,31 +501,34 @@ void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell)
color.setAsABGR (mCell.mCell->mAmbi.mFog); color.setAsABGR (mCell.mCell->mAmbi.mFog);
configureFog(mCell.mCell->mAmbi.mFogDensity, color); configureFog(mCell.mCell->mAmbi.mFogDensity, color);
if (mWater)
mWater->setViewportBackground (Ogre::ColourValue(0.8f, 0.9f, 1.0f));
} }
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
{ {
mFogColour = colour;
float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance"); float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance"); mFogStart = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance"); mFogEnd = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
mRendering.getCamera()->setFarClipDistance ( max / density );
mRendering.getViewport()->setBackgroundColour (colour);
if (mWater)
mWater->setViewportBackground (colour);
sh::Factory::getInstance ().setSharedParameter ("viewportBackground",
sh::makeProperty<sh::Vector3> (new sh::Vector3(colour.r, colour.g, colour.b)));
mRendering.getCamera()->setFarClipDistance ( Settings::Manager::getFloat("max viewing distance", "Viewing distance") / density );
} }
void RenderingManager::applyFog (bool underwater)
{
if (!underwater)
{
mRendering.getScene()->setFog (FOG_LINEAR, mFogColour, 0, mFogStart, mFogEnd);
mRendering.getViewport()->setBackgroundColour (mFogColour);
mWater->setViewportBackground (mFogColour);
}
else
{
mRendering.getScene()->setFog (FOG_LINEAR, Ogre::ColourValue(0.18039, 0.23137, 0.25490), 0, 0, 1000);
mRendering.getViewport()->setBackgroundColour (Ogre::ColourValue(0.18039, 0.23137, 0.25490));
mWater->setViewportBackground (Ogre::ColourValue(0.18039, 0.23137, 0.25490));
}
}
void RenderingManager::setAmbientMode() void RenderingManager::setAmbientMode()
{ {
@ -588,22 +601,28 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour)
mTerrainManager->setAmbient(colour); mTerrainManager->setAmbient(colour);
} }
void RenderingManager::sunEnable() void RenderingManager::sunEnable(bool real)
{ {
// Don't disable the light, as the shaders assume the first light to be directional. if (real && mSun) mSun->setVisible(true);
//if (mSun) mSun->setVisible(true); else
mSunEnabled = true; {
// Don't disable the light, as the shaders assume the first light to be directional.
mSunEnabled = true;
}
} }
void RenderingManager::sunDisable() void RenderingManager::sunDisable(bool real)
{ {
// Don't disable the light, as the shaders assume the first light to be directional. if (real && mSun) mSun->setVisible(false);
//if (mSun) mSun->setVisible(false); else
mSunEnabled = false;
if (mSun)
{ {
mSun->setDiffuseColour(ColourValue(0,0,0)); // Don't disable the light, as the shaders assume the first light to be directional.
mSun->setSpecularColour(ColourValue(0,0,0)); mSunEnabled = false;
if (mSun)
{
mSun->setDiffuseColour(ColourValue(0,0,0));
mSun->setSpecularColour(ColourValue(0,0,0));
}
} }
} }
@ -633,21 +652,16 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell)
mLocalMap->saveFogOfWar(cell); mLocalMap->saveFogOfWar(cell);
} }
void RenderingManager::disableLights() void RenderingManager::disableLights(bool sun)
{ {
mObjects.disableLights(); mObjects.disableLights();
sunDisable(); sunDisable(sun);
} }
void RenderingManager::enableLights() void RenderingManager::enableLights(bool sun)
{ {
mObjects.enableLights(); mObjects.enableLights();
sunEnable(); sunEnable(sun);
}
const bool RenderingManager::useMRT()
{
return Settings::Manager::getBool("shader", "Water");
} }
Shadows* RenderingManager::getShadows() Shadows* RenderingManager::getShadows()
@ -714,6 +728,7 @@ Compositors* RenderingManager::getCompositors()
void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings)
{ {
bool changeRes = false; bool changeRes = false;
bool rebuild = false; // rebuild static geometry (necessary after any material changes)
for (Settings::CategorySettingVector::const_iterator it=settings.begin(); for (Settings::CategorySettingVector::const_iterator it=settings.begin();
it != settings.end(); ++it) it != settings.end(); ++it)
{ {
@ -749,25 +764,19 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
else if (it->second == "shader" && it->first == "Water") else if (it->second == "shader" && it->first == "Water")
{ {
applyCompositors(); applyCompositors();
sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false");
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");
mObjects.rebuildStaticGeometry (); rebuild = true;
mRendering.getViewport ()->setClearEveryFrame (true); mRendering.getViewport ()->setClearEveryFrame (true);
} }
else if (it->second == "underwater effect" && it->first == "Water") else if (it->second == "refraction" && it->first == "Water")
{ {
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water")); sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false");
mObjects.rebuildStaticGeometry (); rebuild = true;
} }
else if (it->second == "shaders" && it->first == "Objects") else if (it->second == "shaders" && it->first == "Objects")
{ {
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));
mObjects.rebuildStaticGeometry (); rebuild = true;
}
else if (it->second == "gamma" && it->first == "Video")
{
sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(
Settings::Manager::getFloat ("gamma", "Video"))));
} }
else if (it->second == "shader mode" && it->first == "General") else if (it->second == "shader mode" && it->first == "General")
{ {
@ -780,13 +789,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
else else
lang = sh::Language_CG; lang = sh::Language_CG;
sh::Factory::getInstance ().setCurrentLanguage (lang); sh::Factory::getInstance ().setCurrentLanguage (lang);
mObjects.rebuildStaticGeometry (); rebuild = true;
} }
else if (it->first == "Shadows") else if (it->first == "Shadows")
{ {
mShadows->recreate (); mShadows->recreate ();
mObjects.rebuildStaticGeometry (); rebuild = true;
} }
} }
@ -802,8 +811,10 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y);
} }
if (mWater) mWater->processChangedSettings(settings);
mWater->processChangedSettings(settings);
if (rebuild)
mObjects.rebuildStaticGeometry();
} }
void RenderingManager::setMenuTransparency(float val) void RenderingManager::setMenuTransparency(float val)
@ -824,13 +835,12 @@ void RenderingManager::windowResized(Ogre::RenderWindow* rw)
mRendering.adjustViewport(); mRendering.adjustViewport();
mCompositors->recreate(); mCompositors->recreate();
mWater->assignTextures();
mVideoPlayer->setResolution (rw->getWidth(), rw->getHeight()); mVideoPlayer->setResolution (rw->getWidth(), rw->getHeight());
const Settings::CategorySettingVector& changed = Settings::Manager::apply(); const Settings::CategorySettingVector& changed = Settings::Manager::apply();
MWBase::Environment::get().getInputManager()->processChangedSettings(changed); //FIXME MWBase::Environment::get().getInputManager()->processChangedSettings(changed);
MWBase::Environment::get().getWindowManager()->processChangedSettings(changed); // FIXME MWBase::Environment::get().getWindowManager()->processChangedSettings(changed);
} }
void RenderingManager::windowClosed(Ogre::RenderWindow* rw) void RenderingManager::windowClosed(Ogre::RenderWindow* rw)
@ -838,27 +848,8 @@ void RenderingManager::windowClosed(Ogre::RenderWindow* rw)
Ogre::Root::getSingleton ().queueEndRendering (); Ogre::Root::getSingleton ().queueEndRendering ();
} }
bool RenderingManager::waterShaderSupported()
{
const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects"))
return false;
return true;
}
void RenderingManager::applyCompositors() void RenderingManager::applyCompositors()
{ {
mCompositors->removeAll();
if (useMRT())
{
mCompositors->addCompositor("gbuffer", 0);
mCompositors->setCompositorEnabled("gbuffer", true);
mCompositors->addCompositor("gbufferFinalizer", 2);
mCompositors->setCompositorEnabled("gbufferFinalizer", true);
}
if (mWater)
mWater->assignTextures();
} }
void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned int &batches) void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned int &batches)
@ -887,6 +878,8 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors
); );
mPlayer->setAnimation(anim); mPlayer->setAnimation(anim);
mWater->removeEmitter (ptr);
mWater->addEmitter (ptr);
} }
void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw)
@ -930,4 +923,19 @@ void RenderingManager::stopVideo()
mVideoPlayer->stopVideo (); mVideoPlayer->stopVideo ();
} }
void RenderingManager::addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale, float force)
{
mWater->addEmitter (ptr, scale, force);
}
void RenderingManager::removeWaterRippleEmitter (const MWWorld::Ptr& ptr)
{
mWater->removeEmitter (ptr);
}
void RenderingManager::updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr)
{
mWater->updateEmitterPtr(old, ptr);
}
} // namespace } // namespace

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

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

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

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

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

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

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

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

@ -4,17 +4,12 @@
#include <OgreEntity.h> #include <OgreEntity.h>
#include <OgreMeshManager.h> #include <OgreMeshManager.h>
#include <OgreHardwarePixelBuffer.h> #include <OgreHardwarePixelBuffer.h>
#include <OgreCompositorManager.h>
#include <OgreCompositorInstance.h>
#include <OgreCompositorChain.h>
#include <OgreRoot.h> #include <OgreRoot.h>
#include <OgreOverlayManager.h>
#include <OgreOverlayContainer.h>
#include <OgreOverlayElement.h>
#include "sky.hpp" #include "sky.hpp"
#include "renderingmanager.hpp" #include "renderingmanager.hpp"
#include "compositors.hpp" #include "ripplesimulation.hpp"
#include "refraction.hpp"
#include <extern/shiny/Main/Factory.hpp> #include <extern/shiny/Main/Factory.hpp>
#include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp> #include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp>
@ -27,18 +22,184 @@ using namespace Ogre;
namespace MWRender namespace MWRender
{ {
Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) : CubeReflection::CubeReflection(Ogre::SceneManager* sceneManager)
mCamera (camera), mSceneManager (camera->getSceneManager()), : Reflection(sceneManager)
{
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), mIsUnderwater(false), mVisibilityFlags(0),
mReflectionTarget(0), mActive(1), mToggled(1), mActive(1), mToggled(1),
mReflectionRenderActive(false), mRendering(rend), mRendering(rend),
mWaterTimer(0.f) mWaterTimer(0.f),
mReflection(NULL),
mRefraction(NULL),
mSimulation(NULL)
{ {
mSimulation = new RippleSimulation(mSceneMgr);
mSky = rend->getSkyManager(); mSky = rend->getSkyManager();
mMaterial = MaterialManager::getSingleton().getByName("Water"); mMaterial = MaterialManager::getSingleton().getByName("Water");
mTop = cell->mWater; mTop = 0;
mIsUnderwater = false; mIsUnderwater = false;
@ -46,19 +207,13 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Y); MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Y);
mWater = mSceneManager->createEntity("water"); mWater = mSceneMgr->createEntity("water");
mWater->setVisibilityFlags(RV_Water); mWater->setVisibilityFlags(RV_Water);
mWater->setRenderQueueGroup(RQG_Water);
mWater->setCastShadows(false); mWater->setCastShadows(false);
mWater->setRenderQueueGroup(RQG_Alpha);
mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); mWaterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mReflectionCamera = mSceneManager->createCamera("ReflectionCamera");
if(!(cell->mData.mFlags & cell->Interior))
{
mWaterNode->setPosition(getSceneNodeCoordinates(cell->mData.mX, cell->mData.mY));
}
mWaterNode->attachObject(mWater); mWaterNode->attachObject(mWater);
applyRTT(); applyRTT();
@ -66,26 +221,11 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
mWater->setMaterial(mMaterial); mWater->setMaterial(mMaterial);
/*
Ogre::Entity* underwaterDome = mSceneManager->createEntity ("underwater_dome.mesh");
underwaterDome->setRenderQueueGroup (RQG_UnderWater);
mUnderwaterDome = mSceneManager->getRootSceneNode ()->createChildSceneNode ();
mUnderwaterDome->attachObject (underwaterDome);
mUnderwaterDome->setScale(10000,10000,10000);
mUnderwaterDome->setVisible(false);
underwaterDome->setMaterialName("Underwater_Dome");
*/
mSceneManager->addRenderQueueListener(this);
assignTextures();
setHeight(mTop); setHeight(mTop);
sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water"); sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water");
m->setListener (this); m->setListener (this);
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
// ---------------------------------- reflection debug overlay ---------------------------------- // ---------------------------------- reflection debug overlay ----------------------------------
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
@ -146,12 +286,12 @@ Water::~Water()
{ {
MeshManager::getSingleton().remove("water"); MeshManager::getSingleton().remove("water");
if (mReflectionTarget)
mReflectionTexture->getBuffer()->getRenderTarget()->removeListener(this);
mWaterNode->detachObject(mWater); mWaterNode->detachObject(mWater);
mSceneManager->destroyEntity(mWater); mSceneMgr->destroyEntity(mWater);
mSceneManager->destroySceneNode(mWaterNode); mSceneMgr->destroySceneNode(mWaterNode);
delete mReflection;
delete mRefraction;
} }
void Water::changeCell(const ESM::Cell* cell) void Water::changeCell(const ESM::Cell* cell)
@ -168,10 +308,12 @@ void Water::setHeight(const float height)
{ {
mTop = height; mTop = height;
mWaterPlane = Plane(Vector3::UNIT_Z, height); mWaterPlane = Plane(Vector3::UNIT_Z, -height);
// small error due to reflection texture size & reflection distortion if (mReflection)
mErrorPlane = Plane(Vector3::UNIT_Z, height - 5); mReflection->setHeight(height);
if (mRefraction)
mRefraction->setHeight(height);
mWaterNode->setPosition(0, 0, height); mWaterNode->setPosition(0, 0, height);
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height))); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height)));
@ -194,6 +336,11 @@ Water::updateUnderwater(bool underwater)
mWater->isVisible() && mWater->isVisible() &&
mCamera->getPolygonMode() == Ogre::PM_SOLID; mCamera->getPolygonMode() == Ogre::PM_SOLID;
if (mReflection)
mReflection->setUnderwater (mIsUnderwater);
if (mRefraction)
mRefraction->setUnderwater (mIsUnderwater);
updateVisible(); updateVisible();
} }
@ -202,129 +349,58 @@ Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY)
return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), gridY * CELL_SIZE + (CELL_SIZE / 2), mTop); return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), gridY * CELL_SIZE + (CELL_SIZE / 2), mTop);
} }
void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
{
if (evt.source == mReflectionTarget)
{
mCamera->getParentSceneNode ()->needUpdate ();
mReflectionCamera->setOrientation(mCamera->getDerivedOrientation());
mReflectionCamera->setPosition(mCamera->getDerivedPosition());
mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance());
mReflectionCamera->setFarClipDistance(mCamera->getFarClipDistance());
mReflectionCamera->setAspectRatio(mCamera->getAspectRatio());
mReflectionCamera->setFOVy(mCamera->getFOVy());
mReflectionRenderActive = true;
Vector3 pos = mCamera->getRealPosition();
pos.z = mTop*2 - pos.z;
mSky->setSkyPosition(pos);
mReflectionCamera->enableReflection(mWaterPlane);
}
}
void Water::postRenderTargetUpdate(const RenderTargetEvent& evt)
{
if (evt.source == mReflectionTarget)
{
mSky->resetSkyPosition();
mReflectionCamera->disableReflection();
mReflectionCamera->disableCustomNearClipPlane();
mReflectionRenderActive = false;
}
}
void Water::assignTextures()
{
if (Settings::Manager::getBool("shader", "Water"))
{
CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mRendering->getViewport())->getCompositor("gbuffer");
TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0);
sh::Factory::getInstance ().setTextureAlias ("WaterRefraction", colorTexture->getName());
TexturePtr depthTexture = compositor->getTextureInstance("mrt_output", 1);
sh::Factory::getInstance ().setTextureAlias ("SceneDepth", depthTexture->getName());
}
}
void Water::setViewportBackground(const ColourValue& bg) void Water::setViewportBackground(const ColourValue& bg)
{ {
if (mReflectionTarget) if (mReflection)
mReflectionTarget->getViewport(0)->setBackgroundColour(bg); mReflection->setViewportBackground(bg);
} }
void Water::updateVisible() void Water::updateVisible()
{ {
mWater->setVisible(mToggled && mActive); mWater->setVisible(mToggled && mActive);
if (mReflectionTarget) if (mReflection)
mReflectionTarget->setActive(mToggled && mActive); mReflection->setActive(mToggled && mActive);
if (mRefraction)
mRefraction->setActive(mToggled && mActive);
} }
void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) void Water::update(float dt, Ogre::Vector3 player)
{ {
// We don't want the sky to get clipped by custom near clip plane (the water plane) mWaterTimer += dt;
if (queueGroupId < 20 && mReflectionRenderActive)
{
mReflectionCamera->disableCustomNearClipPlane();
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
}
}
void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
{
if (queueGroupId < 20 && mReflectionRenderActive)
{
if (!mIsUnderwater)
mReflectionCamera->enableCustomNearClipPlane(mErrorPlane);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
}
}
void Water::update(float dt)
{
/*
Ogre::Vector3 pos = mCamera->getDerivedPosition ();
pos.y = -mWaterPlane.d;
mUnderwaterDome->setPosition (pos);
*/
mWaterTimer += dt / 30.0 * MWBase::Environment::get().getWorld()->getTimeScaleFactor();
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mWaterTimer))); sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mWaterTimer)));
mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater); mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater);
mSimulation->update(dt, Ogre::Vector2(player.x, player.y));
if (mReflection)
mReflection->update();
} }
void Water::applyRTT() void Water::applyRTT()
{ {
if (mReflectionTarget) delete mReflection;
{ mReflection = NULL;
TextureManager::getSingleton().remove("WaterReflection"); delete mRefraction;
mReflectionTarget = 0; mRefraction = NULL;
}
// Create rendertarget for reflection // Create rendertarget for reflection
int rttsize = Settings::Manager::getInt("rtt size", "Water"); //int rttsize = Settings::Manager::getInt("rtt size", "Water");
if (Settings::Manager::getBool("shader", "Water")) if (Settings::Manager::getBool("shader", "Water"))
{ {
mReflectionTexture = TextureManager::getSingleton().createManual("WaterReflection", mReflection = new PlaneReflection(mSceneMgr, mSky);
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_A8R8G8B8, TU_RENDERTARGET); mReflection->setParentCamera (mCamera);
mReflection->setHeight(mTop);
RenderTarget* rtt = mReflectionTexture->getBuffer()->getRenderTarget();
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;
sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mReflectionTexture->getName()); if (Settings::Manager::getBool("refraction", "Water"))
{
mRefraction = new Refraction(mCamera);
mRefraction->setHeight(mTop);
}
} }
updateVisible();
} }
void Water::applyVisibilityMask() void Water::applyVisibilityMask()
@ -336,10 +412,8 @@ void Water::applyVisibilityMask()
+ RV_Misc * Settings::Manager::getBool("reflect misc", "Water") + RV_Misc * Settings::Manager::getBool("reflect misc", "Water")
+ RV_Sky; + RV_Sky;
if (mReflectionTarget) if (mReflection)
{ mReflection->setVisibilityMask(mVisibilityFlags);
mReflectionTexture->getBuffer()->getRenderTarget()->getViewport(0)->setVisibilityMask(mVisibilityFlags);
}
} }
void Water::processChangedSettings(const Settings::CategorySettingVector& settings) void Water::processChangedSettings(const Settings::CategorySettingVector& settings)
@ -350,7 +424,8 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin
it != settings.end(); ++it) it != settings.end(); ++it)
{ {
if ( it->first == "Water" && ( if ( it->first == "Water" && (
it->second == "shader" it->second == "shader"
|| it->second == "refraction"
|| it->second == "rtt size")) || it->second == "rtt size"))
applyRT = true; applyRT = true;
@ -368,7 +443,6 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin
applyRTT(); applyRTT();
applyVisibilityMask(); applyVisibilityMask();
mWater->setMaterial(mMaterial); mWater->setMaterial(mMaterial);
assignTextures();
} }
if (applyVisMask) if (applyVisMask)
applyVisibilityMask(); applyVisibilityMask();
@ -399,4 +473,19 @@ void Water::createdConfiguration (sh::MaterialInstance* m, const std::string& co
} }
} }
void Water::addEmitter (const MWWorld::Ptr& ptr, float scale, float force)
{
mSimulation->addEmitter (ptr, scale, force);
}
void Water::removeEmitter (const MWWorld::Ptr& ptr)
{
mSimulation->removeEmitter (ptr);
}
void Water::updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr)
{
mSimulation->updateEmitterPtr(old, ptr);
}
} // namespace } // namespace

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

@ -548,7 +548,8 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStoreIterator::operator++ (int
bool MWWorld::ContainerStoreIterator::isEqual (const ContainerStoreIterator& iter) const bool MWWorld::ContainerStoreIterator::isEqual (const ContainerStoreIterator& iter) const
{ {
assert (mContainer==iter.mContainer); if (mContainer!=iter.mContainer)
return false;
if (mType!=iter.mType) if (mType!=iter.mType)
return false; return false;

@ -13,7 +13,7 @@
#include <openengine/bullet/physic.hpp> #include <openengine/bullet/physic.hpp>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bulletnifloader.hpp>
//#include "../mwbase/world.hpp" // FIXME //#include "../mwbase/world.hpp" // FIXME
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"

@ -1,6 +1,6 @@
#include "scene.hpp" #include "scene.hpp"
#include <components/nif/nif_file.hpp> #include <components/nif/niffile.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" /// FIXME #include "../mwbase/world.hpp" /// FIXME

@ -718,14 +718,14 @@ void WeatherManager::update(float duration)
mRendering->getSkyManager()->setLightningStrength(0.f); mRendering->getSkyManager()->setLightningStrength(0.f);
mRendering->setAmbientColour(result.mAmbientColor); mRendering->setAmbientColour(result.mAmbientColor);
mRendering->sunEnable(); mRendering->sunEnable(false);
mRendering->setSunColour(result.mSunColor); mRendering->setSunColour(result.mSunColor);
mRendering->getSkyManager()->setWeather(result); mRendering->getSkyManager()->setWeather(result);
} }
else else
{ {
mRendering->sunDisable(); mRendering->sunDisable(false);
mRendering->skyDisable(); mRendering->skyDisable();
mRendering->getSkyManager()->setLightningStrength(0.f); mRendering->getSkyManager()->setLightningStrength(0.f);
} }

@ -974,6 +974,8 @@ namespace MWWorld
void World::update (float duration, bool paused) void World::update (float duration, bool paused)
{ {
mWeatherManager->update (duration);
mWorldScene->update (duration, paused); mWorldScene->update (duration, paused);
float pitch, yaw; float pitch, yaw;
@ -981,8 +983,6 @@ namespace MWWorld
mRendering->getPlayerData(eyepos, pitch, yaw); mRendering->getPlayerData(eyepos, pitch, yaw);
mPhysics->updatePlayerData(eyepos, pitch, yaw); mPhysics->updatePlayerData(eyepos, pitch, yaw);
mWeatherManager->update (duration);
performUpdateSceneQueries (); performUpdateSceneQueries ();
updateWindowManager (); updateWindowManager ();

@ -15,15 +15,15 @@ add_component_dir (bsa
) )
add_component_dir (nif add_component_dir (nif
controlled effect nif_types record controller extra node record_ptr data nif_file property controlled effect niftypes record controller extra node record_ptr data niffile property
) )
add_component_dir (nifogre add_component_dir (nifogre
ogre_nif_loader ogrenifloader
) )
add_component_dir (nifbullet add_component_dir (nifbullet
bullet_nif_loader bulletnifloader
) )
add_component_dir (to_utf8 add_component_dir (to_utf8

@ -305,6 +305,11 @@ public:
return new BSAArchive(name); return new BSAArchive(name);
} }
virtual Archive* createInstance(const String& name, bool readOnly)
{
return new BSAArchive(name);
}
void destroyInstance( Archive* arch) { delete arch; } void destroyInstance( Archive* arch) { delete arch; }
}; };

@ -21,8 +21,8 @@
*/ */
#ifndef _NIF_CONTROLLED_H_ #ifndef OPENMW_COMPONENTS_NIF_CONTROLLED_HPP
#define _NIF_CONTROLLED_H_ #define OPENMW_COMPONENTS_NIF_CONTROLLED_HPP
#include "extra.hpp" #include "extra.hpp"
#include "controller.hpp" #include "controller.hpp"
@ -36,7 +36,7 @@ class Controlled : public Extra
public: public:
ControllerPtr controller; ControllerPtr controller;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Extra::read(nif); Extra::read(nif);
controller.read(nif); controller.read(nif);
@ -55,7 +55,7 @@ class Named : public Controlled
public: public:
std::string name; std::string name;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
name = nif->getString(); name = nif->getString();
Controlled::read(nif); Controlled::read(nif);
@ -66,7 +66,7 @@ typedef Named NiSequenceStreamHelper;
class NiParticleGrowFade : public Controlled class NiParticleGrowFade : public Controlled
{ {
public: public:
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
@ -80,7 +80,7 @@ class NiParticleColorModifier : public Controlled
public: public:
NiColorDataPtr data; NiColorDataPtr data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
data.read(nif); data.read(nif);
@ -96,7 +96,7 @@ public:
class NiGravity : public Controlled class NiGravity : public Controlled
{ {
public: public:
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
@ -109,7 +109,7 @@ public:
class NiPlanarCollider : public Controlled class NiPlanarCollider : public Controlled
{ {
public: public:
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controlled::read(nif); Controlled::read(nif);
@ -121,7 +121,7 @@ public:
class NiParticleRotation : public Controlled class NiParticleRotation : public Controlled
{ {
public: public:
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controlled::read(nif); Controlled::read(nif);

@ -21,12 +21,12 @@
*/ */
#ifndef _NIF_CONTROLLER_H_ #ifndef OPENMW_COMPONENTS_NIF_CONTROLLER_HPP
#define _NIF_CONTROLLER_H_ #define OPENMW_COMPONENTS_NIF_CONTROLLER_HPP
#include "record.hpp" #include "record.hpp"
#include "nif_file.hpp" #include "niffile.hpp"
#include "record_ptr.hpp" #include "recordptr.hpp"
namespace Nif namespace Nif
{ {
@ -40,7 +40,7 @@ public:
float timeStart, timeStop; float timeStart, timeStop;
ControlledPtr target; ControlledPtr target;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
next.read(nif); next.read(nif);
@ -65,7 +65,7 @@ public:
class NiBSPArrayController : public Controller class NiBSPArrayController : public Controller
{ {
public: public:
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controller::read(nif); Controller::read(nif);
@ -82,7 +82,7 @@ class NiMaterialColorController : public Controller
public: public:
NiPosDataPtr data; NiPosDataPtr data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
@ -101,7 +101,7 @@ public:
NiPosDataPtr posData; NiPosDataPtr posData;
NiFloatDataPtr floatData; NiFloatDataPtr floatData;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controller::read(nif); Controller::read(nif);
@ -129,7 +129,7 @@ class NiUVController : public Controller
public: public:
NiUVDataPtr data; NiUVDataPtr data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controller::read(nif); Controller::read(nif);
@ -149,7 +149,7 @@ class NiKeyframeController : public Controller
public: public:
NiKeyframeDataPtr data; NiKeyframeDataPtr data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
@ -167,7 +167,7 @@ class NiAlphaController : public Controller
public: public:
NiFloatDataPtr data; NiFloatDataPtr data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
@ -185,7 +185,7 @@ class NiGeomMorpherController : public Controller
public: public:
NiMorphDataPtr data; NiMorphDataPtr data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
@ -204,7 +204,7 @@ class NiVisController : public Controller
public: public:
NiVisDataPtr data; NiVisDataPtr data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);

@ -21,8 +21,8 @@
*/ */
#ifndef _NIF_DATA_H_ #ifndef OPENMW_COMPONENTS_NIF_DATA_HPP
#define _NIF_DATA_H_ #define OPENMW_COMPONENTS_NIF_DATA_HPP
#include "controlled.hpp" #include "controlled.hpp"
@ -65,7 +65,7 @@ public:
*/ */
int alpha; int alpha;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Named::read(nif); Named::read(nif);
@ -102,7 +102,7 @@ public:
Ogre::Vector3 center; Ogre::Vector3 center;
float radius; float radius;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
int verts = nif->getUShort(); int verts = nif->getUShort();
@ -138,7 +138,7 @@ public:
// Triangles, three vertex indices per triangle // Triangles, three vertex indices per triangle
std::vector<short> triangles; std::vector<short> triangles;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
ShapeData::read(nif); ShapeData::read(nif);
@ -167,7 +167,7 @@ class NiAutoNormalParticlesData : public ShapeData
public: public:
int activeCount; int activeCount;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
ShapeData::read(nif); ShapeData::read(nif);
@ -189,7 +189,7 @@ public:
class NiRotatingParticlesData : public NiAutoNormalParticlesData class NiRotatingParticlesData : public NiAutoNormalParticlesData
{ {
public: public:
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
NiAutoNormalParticlesData::read(nif); NiAutoNormalParticlesData::read(nif);
@ -208,7 +208,7 @@ class NiPosData : public Record
public: public:
Vector3KeyList mKeyList; Vector3KeyList mKeyList;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
mKeyList.read(nif); mKeyList.read(nif);
} }
@ -219,7 +219,7 @@ class NiUVData : public Record
public: public:
FloatKeyList mKeyList[4]; FloatKeyList mKeyList[4];
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
for(int i = 0;i < 4;i++) for(int i = 0;i < 4;i++)
mKeyList[i].read(nif); mKeyList[i].read(nif);
@ -231,7 +231,7 @@ class NiFloatData : public Record
public: public:
FloatKeyList mKeyList; FloatKeyList mKeyList;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
mKeyList.read(nif); mKeyList.read(nif);
} }
@ -243,7 +243,7 @@ public:
unsigned int rmask, gmask, bmask, amask; unsigned int rmask, gmask, bmask, amask;
int bpp, mips; int bpp, mips;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
nif->getInt(); // always 0 or 1 nif->getInt(); // always 0 or 1
@ -281,7 +281,7 @@ class NiColorData : public Record
public: public:
Vector4KeyList mKeyList; Vector4KeyList mKeyList;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
mKeyList.read(nif); mKeyList.read(nif);
} }
@ -295,7 +295,7 @@ public:
char isSet; char isSet;
}; };
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
int count = nif->getInt(); int count = nif->getInt();
@ -311,7 +311,7 @@ public:
NodePtr root; NodePtr root;
NodeList bones; NodeList bones;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
data.read(nif); data.read(nif);
root.read(nif); root.read(nif);
@ -347,7 +347,7 @@ public:
BoneTrafo trafo; BoneTrafo trafo;
std::vector<BoneInfo> bones; std::vector<BoneInfo> bones;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
trafo.rotation = nif->getMatrix3(); trafo.rotation = nif->getMatrix3();
trafo.trans = nif->getVector3(); trafo.trans = nif->getVector3();
@ -385,7 +385,7 @@ struct NiMorphData : public Record
}; };
std::vector<MorphData> mMorphs; std::vector<MorphData> mMorphs;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
int morphCount = nif->getInt(); int morphCount = nif->getInt();
int vertCount = nif->getInt(); int vertCount = nif->getInt();
@ -410,7 +410,7 @@ struct NiKeyframeData : public Record
Vector3KeyList mTranslations; Vector3KeyList mTranslations;
FloatKeyList mScales; FloatKeyList mScales;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
mRotations.read(nif); mRotations.read(nif);
mTranslations.read(nif); mTranslations.read(nif);

@ -21,8 +21,8 @@
*/ */
#ifndef _NIF_EFFECT_H_ #ifndef OPENMW_COMPONENTS_NIF_EFFECT_HPP
#define _NIF_EFFECT_H_ #define OPENMW_COMPONENTS_NIF_EFFECT_HPP
#include "node.hpp" #include "node.hpp"
@ -42,7 +42,7 @@ struct NiLight : Effect
Ogre::Vector3 diffuse; Ogre::Vector3 diffuse;
Ogre::Vector3 specular; Ogre::Vector3 specular;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
dimmer = nif->getFloat(); dimmer = nif->getFloat();
ambient = nif->getVector3(); ambient = nif->getVector3();
@ -52,7 +52,7 @@ struct NiLight : Effect
}; };
SLight light; SLight light;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Effect::read(nif); Effect::read(nif);
@ -66,7 +66,7 @@ struct NiTextureEffect : Effect
{ {
NiSourceTexturePtr texture; NiSourceTexturePtr texture;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Effect::read(nif); Effect::read(nif);

@ -21,12 +21,12 @@
*/ */
#ifndef _NIF_EXTRA_H_ #ifndef OPENMW_COMPONENTS_NIF_EXTRA_HPP
#define _NIF_EXTRA_H_ #define OPENMW_COMPONENTS_NIF_EXTRA_HPP
#include "record.hpp" #include "record.hpp"
#include "nif_file.hpp" #include "niffile.hpp"
#include "record_ptr.hpp" #include "recordptr.hpp"
namespace Nif namespace Nif
{ {
@ -40,14 +40,14 @@ class Extra : public Record
public: public:
ExtraPtr extra; ExtraPtr extra;
void read(NIFFile *nif) { extra.read(nif); } void read(NIFStream *nif) { extra.read(nif); }
void post(NIFFile *nif) { extra.post(nif); } void post(NIFFile *nif) { extra.post(nif); }
}; };
class NiVertWeightsExtraData : public Extra class NiVertWeightsExtraData : public Extra
{ {
public: public:
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Extra::read(nif); Extra::read(nif);
@ -70,7 +70,7 @@ public:
}; };
std::vector<TextKey> list; std::vector<TextKey> list;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Extra::read(nif); Extra::read(nif);
@ -95,7 +95,7 @@ public:
*/ */
std::string string; std::string string;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Extra::read(nif); Extra::read(nif);

@ -21,7 +21,7 @@
*/ */
#include "nif_file.hpp" #include "niffile.hpp"
#include "record.hpp" #include "record.hpp"
#include "components/misc/stringops.hpp" #include "components/misc/stringops.hpp"
@ -174,10 +174,7 @@ NIFFile::ptr NIFFile::create (const std::string &name) { return LoadedCache::cre
NIFFile::NIFFile(const std::string &name, psudo_private_modifier) NIFFile::NIFFile(const std::string &name, psudo_private_modifier)
: filename(name) : filename(name)
{ {
inp = Ogre::ResourceGroupManager::getSingleton().openResource(name);
parse(); parse();
// Make sure to close the file after it was loaded into memory
inp.setNull();
} }
NIFFile::~NIFFile() NIFFile::~NIFFile()
@ -188,6 +185,101 @@ NIFFile::~NIFFile()
delete records[i]; delete records[i];
} }
template <typename NodeType> static Record* construct() { return new NodeType; }
struct RecordFactoryEntry {
typedef Record* (*create_t) ();
char const * mName;
create_t mCreate;
RecordType mType;
};
/* These are all the record types we know how to read.
This can be heavily optimized later if needed. For example, a
hash table or a FSM-based parser could be used to look up
node names.
*/
static const RecordFactoryEntry recordFactories [] = {
{ "NiNode", &construct <NiNode >, RC_NiNode },
{ "AvoidNode", &construct <NiNode >, RC_NiNode },
{ "NiBSParticleNode", &construct <NiNode >, RC_NiNode },
{ "NiBSAnimationNode", &construct <NiNode >, RC_NiNode },
{ "NiBillboardNode", &construct <NiNode >, RC_NiNode },
{ "NiTriShape", &construct <NiTriShape >, RC_NiTriShape },
{ "NiRotatingParticles", &construct <NiRotatingParticles >, RC_NiRotatingParticles },
{ "NiAutoNormalParticles", &construct <NiAutoNormalParticles >, RC_NiAutoNormalParticles },
{ "NiCamera", &construct <NiCamera >, RC_NiCamera },
{ "RootCollisionNode", &construct <NiNode >, RC_RootCollisionNode },
{ "NiTexturingProperty", &construct <NiTexturingProperty >, RC_NiTexturingProperty },
{ "NiMaterialProperty", &construct <NiMaterialProperty >, RC_NiMaterialProperty },
{ "NiZBufferProperty", &construct <NiZBufferProperty >, RC_NiZBufferProperty },
{ "NiAlphaProperty", &construct <NiAlphaProperty >, RC_NiAlphaProperty },
{ "NiVertexColorProperty", &construct <NiVertexColorProperty >, RC_NiVertexColorProperty },
{ "NiShadeProperty", &construct <NiShadeProperty >, RC_NiShadeProperty },
{ "NiDitherProperty", &construct <NiDitherProperty >, RC_NiDitherProperty },
{ "NiWireframeProperty", &construct <NiWireframeProperty >, RC_NiWireframeProperty },
{ "NiSpecularProperty", &construct <NiSpecularProperty >, RC_NiSpecularProperty },
{ "NiStencilProperty", &construct <NiStencilProperty >, RC_NiStencilProperty },
{ "NiVisController", &construct <NiVisController >, RC_NiVisController },
{ "NiGeomMorpherController", &construct <NiGeomMorpherController >, RC_NiGeomMorpherController },
{ "NiKeyframeController", &construct <NiKeyframeController >, RC_NiKeyframeController },
{ "NiAlphaController", &construct <NiAlphaController >, RC_NiAlphaController },
{ "NiUVController", &construct <NiUVController >, RC_NiUVController },
{ "NiPathController", &construct <NiPathController >, RC_NiPathController },
{ "NiMaterialColorController", &construct <NiMaterialColorController >, RC_NiMaterialColorController },
{ "NiBSPArrayController", &construct <NiBSPArrayController >, RC_NiBSPArrayController },
{ "NiParticleSystemController", &construct <NiParticleSystemController >, RC_NiParticleSystemController },
{ "NiAmbientLight", &construct <NiLight >, RC_NiLight },
{ "NiDirectionalLight", &construct <NiLight >, RC_NiLight },
{ "NiTextureEffect", &construct <NiTextureEffect >, RC_NiTextureEffect },
{ "NiVertWeightsExtraData", &construct <NiVertWeightsExtraData >, RC_NiVertWeightsExtraData },
{ "NiTextKeyExtraData", &construct <NiTextKeyExtraData >, RC_NiTextKeyExtraData },
{ "NiStringExtraData", &construct <NiStringExtraData >, RC_NiStringExtraData },
{ "NiGravity", &construct <NiGravity >, RC_NiGravity },
{ "NiPlanarCollider", &construct <NiPlanarCollider >, RC_NiPlanarCollider },
{ "NiParticleGrowFade", &construct <NiParticleGrowFade >, RC_NiParticleGrowFade },
{ "NiParticleColorModifier", &construct <NiParticleColorModifier >, RC_NiParticleColorModifier },
{ "NiParticleRotation", &construct <NiParticleRotation >, RC_NiParticleRotation },
{ "NiFloatData", &construct <NiFloatData >, RC_NiFloatData },
{ "NiTriShapeData", &construct <NiTriShapeData >, RC_NiTriShapeData },
{ "NiVisData", &construct <NiVisData >, RC_NiVisData },
{ "NiColorData", &construct <NiColorData >, RC_NiColorData },
{ "NiPixelData", &construct <NiPixelData >, RC_NiPixelData },
{ "NiMorphData", &construct <NiMorphData >, RC_NiMorphData },
{ "NiKeyframeData", &construct <NiKeyframeData >, RC_NiKeyframeData },
{ "NiSkinData", &construct <NiSkinData >, RC_NiSkinData },
{ "NiUVData", &construct <NiUVData >, RC_NiUVData },
{ "NiPosData", &construct <NiPosData >, RC_NiPosData },
{ "NiRotatingParticlesData", &construct <NiRotatingParticlesData >, RC_NiRotatingParticlesData },
{ "NiAutoNormalParticlesData", &construct <NiAutoNormalParticlesData >, RC_NiAutoNormalParticlesData },
{ "NiSequenceStreamHelper", &construct <NiSequenceStreamHelper >, RC_NiSequenceStreamHelper },
{ "NiSourceTexture", &construct <NiSourceTexture >, RC_NiSourceTexture },
{ "NiSkinInstance", &construct <NiSkinInstance >, RC_NiSkinInstance },
};
static RecordFactoryEntry const * recordFactories_begin = &recordFactories [0];
static RecordFactoryEntry const * recordFactories_end = &recordFactories [sizeof (recordFactories) / sizeof (recordFactories[0])];
RecordFactoryEntry const * lookupRecordFactory (char const * name)
{
RecordFactoryEntry const * i;
for (i = recordFactories_begin; i != recordFactories_end; ++i)
if (strcmp (name, i->mName) == 0)
break;
if (i == recordFactories_end)
return NULL;
return i;
}
/* This file implements functions from the NIFFile class. It is also /* This file implements functions from the NIFFile class. It is also
where we stash all the functions we couldn't add as inline where we stash all the functions we couldn't add as inline
definitions in the record types. definitions in the record types.
@ -195,18 +287,20 @@ NIFFile::~NIFFile()
void NIFFile::parse() void NIFFile::parse()
{ {
NIFStream nif (this, Ogre::ResourceGroupManager::getSingleton().openResource(filename));
// Check the header string // Check the header string
std::string head = getString(40); std::string head = nif.getString(40);
if(head.compare(0, 22, "NetImmerse File Format") != 0) if(head.compare(0, 22, "NetImmerse File Format") != 0)
fail("Invalid NIF header"); fail("Invalid NIF header");
// Get BCD version // Get BCD version
ver = getInt(); ver = nif.getInt();
if(ver != VER_MW) if(ver != VER_MW)
fail("Unsupported NIF version"); fail("Unsupported NIF version");
// Number of records // Number of records
size_t recNum = getInt(); size_t recNum = nif.getInt();
records.resize(recNum); records.resize(recNum);
/* The format for 10.0.1.0 seems to be a bit different. After the /* The format for 10.0.1.0 seems to be a bit different. After the
@ -222,97 +316,24 @@ void NIFFile::parse()
{ {
Record *r = NULL; Record *r = NULL;
std::string rec = getString(); std::string rec = nif.getString();
/* These are all the record types we know how to read. RecordFactoryEntry const * entry = lookupRecordFactory (rec.c_str ());
This can be heavily optimized later if needed. For example, a if (entry != NULL)
hash table or a FSM-based parser could be used to look up {
node names. r = entry->mCreate ();
*/ r->recType = entry->mType;
}
// NiNodes
if(rec == "NiNode" || rec == "AvoidNode" ||
rec == "NiBSParticleNode" ||
rec == "NiBSAnimationNode" ||
rec == "NiBillboardNode") { r = new NiNode; r->recType = RC_NiNode; }
// Other nodes
else if(rec == "NiTriShape") { r = new NiTriShape; r->recType = RC_NiTriShape; }
else if(rec == "NiRotatingParticles") { r = new NiRotatingParticles; r->recType = RC_NiRotatingParticles; }
else if(rec == "NiAutoNormalParticles") { r = new NiAutoNormalParticles; r->recType = RC_NiAutoNormalParticles; }
else if(rec == "NiCamera") { r = new NiCamera; r->recType = RC_NiCamera; }
else if(rec == "RootCollisionNode"){ r = new NiNode; r->recType = RC_RootCollisionNode; }// a root collision node is exactly like a node
//that's why there is no need to create a new type
// Properties
else if(rec == "NiTexturingProperty") { r = new NiTexturingProperty; r->recType = RC_NiTexturingProperty; }
else if(rec == "NiMaterialProperty") { r = new NiMaterialProperty; r->recType = RC_NiMaterialProperty; }
else if(rec == "NiZBufferProperty") { r = new NiZBufferProperty; r->recType = RC_NiZBufferProperty; }
else if(rec == "NiAlphaProperty") { r = new NiAlphaProperty; r->recType = RC_NiAlphaProperty; }
else if(rec == "NiVertexColorProperty") { r = new NiVertexColorProperty; r->recType = RC_NiVertexColorProperty; }
else if(rec == "NiShadeProperty") { r = new NiShadeProperty; r->recType = RC_NiShadeProperty; }
else if(rec == "NiDitherProperty") { r = new NiDitherProperty; r->recType = RC_NiDitherProperty; }
else if(rec == "NiWireframeProperty") { r = new NiWireframeProperty; r->recType = RC_NiWireframeProperty; }
else if(rec == "NiSpecularProperty") { r = new NiSpecularProperty; r->recType = RC_NiSpecularProperty; }
else if(rec == "NiStencilProperty") { r = new NiStencilProperty; r->recType = RC_NiStencilProperty; }
// Controllers
else if(rec == "NiVisController") { r = new NiVisController; r->recType = RC_NiVisController; }
else if(rec == "NiGeomMorpherController") { r = new NiGeomMorpherController; r->recType = RC_NiGeomMorpherController; }
else if(rec == "NiKeyframeController") { r = new NiKeyframeController; r->recType = RC_NiKeyframeController; }
else if(rec == "NiAlphaController") { r = new NiAlphaController; r->recType = RC_NiAlphaController; }
else if(rec == "NiUVController") { r = new NiUVController; r->recType = RC_NiUVController; }
else if(rec == "NiPathController") { r = new NiPathController; r->recType = RC_NiPathController; }
else if(rec == "NiMaterialColorController") { r = new NiMaterialColorController; r->recType = RC_NiMaterialColorController; }
else if(rec == "NiBSPArrayController") { r = new NiBSPArrayController; r->recType = RC_NiBSPArrayController; }
else if(rec == "NiParticleSystemController") { r = new NiParticleSystemController; r->recType = RC_NiParticleSystemController; }
// Effects
else if(rec == "NiAmbientLight" ||
rec == "NiDirectionalLight") { r = new NiLight; r->recType = RC_NiLight; }
else if(rec == "NiTextureEffect") { r = new NiTextureEffect; r->recType = RC_NiTextureEffect; }
// Extra Data
else if(rec == "NiVertWeightsExtraData") { r = new NiVertWeightsExtraData; r->recType = RC_NiVertWeightsExtraData; }
else if(rec == "NiTextKeyExtraData") { r = new NiTextKeyExtraData; r->recType = RC_NiTextKeyExtraData; }
else if(rec == "NiStringExtraData") { r = new NiStringExtraData; r->recType = RC_NiStringExtraData; }
else if(rec == "NiGravity") { r = new NiGravity; r->recType = RC_NiGravity; }
else if(rec == "NiPlanarCollider") { r = new NiPlanarCollider; r->recType = RC_NiPlanarCollider; }
else if(rec == "NiParticleGrowFade") { r = new NiParticleGrowFade; r->recType = RC_NiParticleGrowFade; }
else if(rec == "NiParticleColorModifier") { r = new NiParticleColorModifier; r->recType = RC_NiParticleColorModifier; }
else if(rec == "NiParticleRotation") { r = new NiParticleRotation; r->recType = RC_NiParticleRotation; }
// Data
else if(rec == "NiFloatData") { r = new NiFloatData; r->recType = RC_NiFloatData; }
else if(rec == "NiTriShapeData") { r = new NiTriShapeData; r->recType = RC_NiTriShapeData; }
else if(rec == "NiVisData") { r = new NiVisData; r->recType = RC_NiVisData; }
else if(rec == "NiColorData") { r = new NiColorData; r->recType = RC_NiColorData; }
else if(rec == "NiPixelData") { r = new NiPixelData; r->recType = RC_NiPixelData; }
else if(rec == "NiMorphData") { r = new NiMorphData; r->recType = RC_NiMorphData; }
else if(rec == "NiKeyframeData") { r = new NiKeyframeData; r->recType = RC_NiKeyframeData; }
else if(rec == "NiSkinData") { r = new NiSkinData; r->recType = RC_NiSkinData; }
else if(rec == "NiUVData") { r = new NiUVData; r->recType = RC_NiUVData; }
else if(rec == "NiPosData") { r = new NiPosData; r->recType = RC_NiPosData; }
else if(rec == "NiRotatingParticlesData") { r = new NiRotatingParticlesData; r->recType = RC_NiRotatingParticlesData; }
else if(rec == "NiAutoNormalParticlesData") { r = new NiAutoNormalParticlesData; r->recType = RC_NiAutoNormalParticlesData; }
// Other
else if(rec == "NiSequenceStreamHelper") { r = new NiSequenceStreamHelper; r->recType = RC_NiSequenceStreamHelper; }
else if(rec == "NiSourceTexture") { r = new NiSourceTexture; r->recType = RC_NiSourceTexture; }
else if(rec == "NiSkinInstance") { r = new NiSkinInstance; r->recType = RC_NiSkinInstance; }
// Failure
else else
fail("Unknown record type " + rec); fail("Unknown record type " + rec);
assert(r != NULL); assert(r != NULL);
assert(r->recType != RC_MISSING); assert(r->recType != RC_MISSING);
r->recName = rec; r->recName = rec;
r->recIndex = i; r->recIndex = i;
records[i] = r; records[i] = r;
r->read(this); r->read(&nif);
// Discard tranformations for the root node, otherwise some meshes // Discard tranformations for the root node, otherwise some meshes
// occasionally get wrong orientation. Only for NiNode-s for now, but // occasionally get wrong orientation. Only for NiNode-s for now, but

@ -21,8 +21,8 @@
*/ */
#ifndef _NIF_FILE_H_ #ifndef OPENMW_COMPONENTS_NIF_NIFFILE_HPP
#define _NIF_FILE_H_ #define OPENMW_COMPONENTS_NIF_NIFFILE_HPP
#include <OgreResourceGroupManager.h> #include <OgreResourceGroupManager.h>
#include <OgreDataStream.h> #include <OgreDataStream.h>
@ -45,7 +45,8 @@
#include <libs/platform/stdint.h> #include <libs/platform/stdint.h>
#include "record.hpp" #include "record.hpp"
#include "nif_types.hpp" #include "niftypes.hpp"
#include "nifstream.hpp"
namespace Nif namespace Nif
{ {
@ -59,9 +60,6 @@ class NIFFile
/// Nif file version /// Nif file version
int ver; int ver;
/// Input stream
Ogre::DataStreamPtr inp;
/// File name, used for error messages /// File name, used for error messages
std::string filename; std::string filename;
@ -71,33 +69,6 @@ class NIFFile
/// Parse the file /// Parse the file
void parse(); void parse();
uint8_t read_byte()
{
uint8_t byte;
if(inp->read(&byte, 1) != 1) return 0;
return byte;
}
uint16_t read_le16()
{
uint8_t buffer[2];
if(inp->read(buffer, 2) != 2) return 0;
return buffer[0] | (buffer[1]<<8);
}
uint32_t read_le32()
{
uint8_t buffer[4];
if(inp->read(buffer, 4) != 4) return 0;
return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24);
}
float read_le32f()
{
union {
uint32_t i;
float f;
} u = { read_le32() };
return u.f;
}
class LoadedCache; class LoadedCache;
friend class LoadedCache; friend class LoadedCache;
@ -117,8 +88,8 @@ public:
void warn(const std::string &msg) void warn(const std::string &msg)
{ {
std::cerr<< "NIFFile Warning: "<<msg <<std::endl std::cerr << "NIFFile Warning: " << msg <<std::endl
<< "File: "<<filename <<std::endl; << "File: " << filename <<std::endl;
} }
typedef boost::shared_ptr <NIFFile> ptr; typedef boost::shared_ptr <NIFFile> ptr;
@ -147,111 +118,6 @@ public:
/// Number of records /// Number of records
size_t numRecords() { return records.size(); } size_t numRecords() { return records.size(); }
/*************************************************
Parser functions
****************************************************/
void skip(size_t size) { inp->skip(size); }
char getChar() { return read_byte(); }
short getShort() { return read_le16(); }
unsigned short getUShort() { return read_le16(); }
int getInt() { return read_le32(); }
unsigned int getUInt() { return read_le32(); }
float getFloat() { return read_le32f(); }
Ogre::Vector2 getVector2()
{
float a[2];
for(size_t i = 0;i < 2;i++)
a[i] = getFloat();
return Ogre::Vector2(a);
}
Ogre::Vector3 getVector3()
{
float a[3];
for(size_t i = 0;i < 3;i++)
a[i] = getFloat();
return Ogre::Vector3(a);
}
Ogre::Vector4 getVector4()
{
float a[4];
for(size_t i = 0;i < 4;i++)
a[i] = getFloat();
return Ogre::Vector4(a);
}
Ogre::Matrix3 getMatrix3()
{
Ogre::Real a[3][3];
for(size_t i = 0;i < 3;i++)
{
for(size_t j = 0;j < 3;j++)
a[i][j] = Ogre::Real(getFloat());
}
return Ogre::Matrix3(a);
}
Ogre::Quaternion getQuaternion()
{
float a[4];
for(size_t i = 0;i < 4;i++)
a[i] = getFloat();
return Ogre::Quaternion(a);
}
Transformation getTrafo()
{
Transformation t;
t.pos = getVector3();
t.rotation = getMatrix3();
t.scale = getFloat();
return t;
}
std::string getString(size_t length)
{
std::vector<char> str (length+1, 0);
if(inp->read(&str[0], length) != length)
throw std::runtime_error ("string length in NIF file does not match");
return &str[0];
}
std::string getString()
{
size_t size = read_le32();
return getString(size);
}
void getShorts(std::vector<short> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getShort();
}
void getFloats(std::vector<float> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getFloat();
}
void getVector2s(std::vector<Ogre::Vector2> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getVector2();
}
void getVector3s(std::vector<Ogre::Vector3> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getVector3();
}
void getVector4s(std::vector<Ogre::Vector4> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getVector4();
}
}; };
@ -270,7 +136,7 @@ typedef KeyT<Ogre::Vector3> Vector3Key;
typedef KeyT<Ogre::Vector4> Vector4Key; typedef KeyT<Ogre::Vector4> Vector4Key;
typedef KeyT<Ogre::Quaternion> QuaternionKey; typedef KeyT<Ogre::Quaternion> QuaternionKey;
template<typename T, T (NIFFile::*getValue)()> template<typename T, T (NIFStream::*getValue)()>
struct KeyListT { struct KeyListT {
typedef std::vector< KeyT<T> > VecType; typedef std::vector< KeyT<T> > VecType;
@ -281,7 +147,7 @@ struct KeyListT {
int mInterpolationType; int mInterpolationType;
VecType mKeys; VecType mKeys;
void read(NIFFile *nif, bool force=false) void read(NIFStream *nif, bool force=false)
{ {
size_t count = nif->getInt(); size_t count = nif->getInt();
if(count == 0 && !force) if(count == 0 && !force)
@ -322,13 +188,13 @@ struct KeyListT {
} }
} }
else else
nif->warn("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType)); nif->file->warn("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType));
} }
}; };
typedef KeyListT<float,&NIFFile::getFloat> FloatKeyList; typedef KeyListT<float,&NIFStream::getFloat> FloatKeyList;
typedef KeyListT<Ogre::Vector3,&NIFFile::getVector3> Vector3KeyList; typedef KeyListT<Ogre::Vector3,&NIFStream::getVector3> Vector3KeyList;
typedef KeyListT<Ogre::Vector4,&NIFFile::getVector4> Vector4KeyList; typedef KeyListT<Ogre::Vector4,&NIFStream::getVector4> Vector4KeyList;
typedef KeyListT<Ogre::Quaternion,&NIFFile::getQuaternion> QuaternionKeyList; typedef KeyListT<Ogre::Quaternion,&NIFStream::getQuaternion> QuaternionKeyList;
} // Namespace } // Namespace
#endif #endif

@ -0,0 +1,175 @@
#ifndef OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP
#define OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP
namespace Nif
{
class NIFFile;
class NIFStream {
/// Input stream
Ogre::DataStreamPtr inp;
uint8_t read_byte()
{
uint8_t byte;
if(inp->read(&byte, 1) != 1) return 0;
return byte;
}
uint16_t read_le16()
{
uint8_t buffer[2];
if(inp->read(buffer, 2) != 2) return 0;
return buffer[0] | (buffer[1]<<8);
}
uint32_t read_le32()
{
uint8_t buffer[4];
if(inp->read(buffer, 4) != 4) return 0;
return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24);
}
float read_le32f()
{
union {
uint32_t i;
float f;
} u = { read_le32() };
return u.f;
}
public:
NIFFile * const file;
NIFStream (NIFFile * file, Ogre::DataStreamPtr inp): file (file), inp (inp) {}
/*************************************************
Parser functions
****************************************************/
template <typename T>
struct GetHandler
{
typedef T (NIFStream::*fn_t)();
static const fn_t sValue; // this is specialized per supported type in the .cpp file
static T read (NIFStream* nif)
{
return (nif->*sValue) ();
}
};
template <typename T>
void read (NIFStream* nif, T & Value)
{
Value = GetHandler <T>::read (nif);
}
void skip(size_t size) { inp->skip(size); }
void read (void * data, size_t size) { inp->read (data, size); }
char getChar() { return read_byte(); }
short getShort() { return read_le16(); }
unsigned short getUShort() { return read_le16(); }
int getInt() { return read_le32(); }
int getUInt() { return read_le32(); }
float getFloat() { return read_le32f(); }
Ogre::Vector2 getVector2()
{
float a[2];
for(size_t i = 0;i < 2;i++)
a[i] = getFloat();
return Ogre::Vector2(a);
}
Ogre::Vector3 getVector3()
{
float a[3];
for(size_t i = 0;i < 3;i++)
a[i] = getFloat();
return Ogre::Vector3(a);
}
Ogre::Vector4 getVector4()
{
float a[4];
for(size_t i = 0;i < 4;i++)
a[i] = getFloat();
return Ogre::Vector4(a);
}
Ogre::Matrix3 getMatrix3()
{
Ogre::Real a[3][3];
for(size_t i = 0;i < 3;i++)
{
for(size_t j = 0;j < 3;j++)
a[i][j] = Ogre::Real(getFloat());
}
return Ogre::Matrix3(a);
}
Ogre::Quaternion getQuaternion()
{
float a[4];
for(size_t i = 0;i < 4;i++)
a[i] = getFloat();
return Ogre::Quaternion(a);
}
Transformation getTrafo()
{
Transformation t;
t.pos = getVector3();
t.rotation = getMatrix3();
t.scale = getFloat();
return t;
}
std::string getString(size_t length)
{
std::vector<char> str (length+1, 0);
if(inp->read(&str[0], length) != length)
throw std::runtime_error ("string length in NIF file does not match");
return &str[0];
}
std::string getString()
{
size_t size = read_le32();
return getString(size);
}
void getShorts(std::vector<short> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getShort();
}
void getFloats(std::vector<float> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getFloat();
}
void getVector2s(std::vector<Ogre::Vector2> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getVector2();
}
void getVector3s(std::vector<Ogre::Vector3> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getVector3();
}
void getVector4s(std::vector<Ogre::Vector4> &vec, size_t size)
{
vec.resize(size);
for(size_t i = 0;i < vec.size();i++)
vec[i] = getVector4();
}
};
}
#endif

@ -21,8 +21,8 @@
*/ */
#ifndef _NIF_TYPES_H_ #ifndef OPENMW_COMPONENTS_NIF_NIFTYPES_HPP
#define _NIF_TYPES_H_ #define OPENMW_COMPONENTS_NIF_NIFTYPES_HPP
#include <OgreVector3.h> #include <OgreVector3.h>
#include <OgreMatrix3.h> #include <OgreMatrix3.h>

@ -21,8 +21,8 @@
*/ */
#ifndef _NIF_NODE_H_ #ifndef OPENMW_COMPONENTS_NIF_NODE_HPP
#define _NIF_NODE_H_ #define OPENMW_COMPONENTS_NIF_NODE_HPP
#include <OgreMatrix4.h> #include <OgreMatrix4.h>
@ -54,7 +54,7 @@ public:
Ogre::Matrix3 boundRot; Ogre::Matrix3 boundRot;
Ogre::Vector3 boundXYZ; // Box size Ogre::Vector3 boundXYZ; // Box size
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Named::read(nif); Named::read(nif);
@ -128,7 +128,7 @@ struct NiNode : Node
0x20, 0x40, 0x80 unknown 0x20, 0x40, 0x80 unknown
*/ */
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Node::read(nif); Node::read(nif);
children.read(nif); children.read(nif);
@ -162,7 +162,7 @@ struct NiTriShape : Node
NiTriShapeDataPtr data; NiTriShapeDataPtr data;
NiSkinInstancePtr skin; NiSkinInstancePtr skin;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Node::read(nif); Node::read(nif);
data.read(nif); data.read(nif);
@ -190,7 +190,7 @@ struct NiCamera : Node
// Level of detail modifier // Level of detail modifier
float LOD; float LOD;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
left = nif->getFloat(); left = nif->getFloat();
right = nif->getFloat(); right = nif->getFloat();
@ -209,7 +209,7 @@ struct NiCamera : Node
}; };
Camera cam; Camera cam;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Node::read(nif); Node::read(nif);
@ -224,7 +224,7 @@ struct NiAutoNormalParticles : Node
{ {
NiAutoNormalParticlesDataPtr data; NiAutoNormalParticlesDataPtr data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Node::read(nif); Node::read(nif);
data.read(nif); data.read(nif);
@ -242,7 +242,7 @@ struct NiRotatingParticles : Node
{ {
NiRotatingParticlesDataPtr data; NiRotatingParticlesDataPtr data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Node::read(nif); Node::read(nif);
data.read(nif); data.read(nif);

@ -21,8 +21,8 @@
*/ */
#ifndef _NIF_PROPERTY_H_ #ifndef OPENMW_COMPONENTS_NIF_PROPERTY_HPP
#define _NIF_PROPERTY_H_ #define OPENMW_COMPONENTS_NIF_PROPERTY_HPP
#include "controlled.hpp" #include "controlled.hpp"
@ -35,7 +35,7 @@ public:
// The meaning of these depends on the actual property type. // The meaning of these depends on the actual property type.
int flags; int flags;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Named::read(nif); Named::read(nif);
flags = nif->getUShort(); flags = nif->getUShort();
@ -67,7 +67,7 @@ public:
int clamp, set, filter; int clamp, set, filter;
short unknown2; short unknown2;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
inUse = !!nif->getInt(); inUse = !!nif->getInt();
if(!inUse) return; if(!inUse) return;
@ -111,7 +111,7 @@ public:
*/ */
Texture textures[7]; Texture textures[7];
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Property::read(nif); Property::read(nif);
apply = nif->getInt(); apply = nif->getInt();
@ -157,7 +157,7 @@ struct StructPropT : Property
{ {
T data; T data;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
Property::read(nif); Property::read(nif);
data.read(nif); data.read(nif);
@ -170,7 +170,7 @@ struct S_MaterialProperty
Ogre::Vector3 ambient, diffuse, specular, emissive; Ogre::Vector3 ambient, diffuse, specular, emissive;
float glossiness, alpha; float glossiness, alpha;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
ambient = nif->getVector3(); ambient = nif->getVector3();
diffuse = nif->getVector3(); diffuse = nif->getVector3();
@ -194,7 +194,7 @@ struct S_VertexColorProperty
*/ */
int vertmode, lightmode; int vertmode, lightmode;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
vertmode = nif->getInt(); vertmode = nif->getInt();
lightmode = nif->getInt(); lightmode = nif->getInt();
@ -251,7 +251,7 @@ struct S_AlphaProperty
// Tested against when certain flags are set (see above.) // Tested against when certain flags are set (see above.)
unsigned char threshold; unsigned char threshold;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
threshold = nif->getChar(); threshold = nif->getChar();
} }
@ -300,7 +300,7 @@ struct S_StencilProperty
*/ */
int drawMode; int drawMode;
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
enabled = nif->getChar(); enabled = nif->getChar();
compareFunc = nif->getInt(); compareFunc = nif->getInt();

@ -21,8 +21,8 @@
*/ */
#ifndef _NIF_RECORD_H_ #ifndef OPENMW_COMPONENTS_NIF_RECORD_HPP
#define _NIF_RECORD_H_ #define OPENMW_COMPONENTS_NIF_RECORD_HPP
#include <string> #include <string>
@ -30,6 +30,7 @@ namespace Nif
{ {
class NIFFile; class NIFFile;
class NIFStream;
enum RecordType enum RecordType
{ {
@ -97,7 +98,7 @@ struct Record
Record() : recType(RC_MISSING), recIndex(~(size_t)0) {} Record() : recType(RC_MISSING), recIndex(~(size_t)0) {}
/// Parses the record from file /// Parses the record from file
virtual void read(NIFFile *nif) = 0; virtual void read(NIFStream *nif) = 0;
/// Does post-processing, after the entire tree is loaded /// Does post-processing, after the entire tree is loaded
virtual void post(NIFFile *nif) {} virtual void post(NIFFile *nif) {}

@ -21,10 +21,10 @@
*/ */
#ifndef _NIF_RECORD_PTR_H_ #ifndef OPENMW_COMPONENTS_NIF_RECORDPTR_HPP
#define _NIF_RECORD_PTR_H_ #define OPENMW_COMPONENTS_NIF_RECORDPTR_HPP
#include "nif_file.hpp" #include "niffile.hpp"
#include <vector> #include <vector>
namespace Nif namespace Nif
@ -46,7 +46,7 @@ public:
RecordPtrT() : index(-2) {} RecordPtrT() : index(-2) {}
/// Read the index from the nif /// Read the index from the nif
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
// Can only read the index once // Can only read the index once
assert(index == -2); assert(index == -2);
@ -99,7 +99,7 @@ class RecordListT
std::vector<Ptr> list; std::vector<Ptr> list;
public: public:
void read(NIFFile *nif) void read(NIFStream *nif)
{ {
int len = nif->getInt(); int len = nif->getInt();
list.resize(len); list.resize(len);

@ -21,11 +21,11 @@ http://www.gnu.org/licenses/ .
*/ */
#include "bullet_nif_loader.hpp" #include "bulletnifloader.hpp"
#include <Ogre.h> #include <Ogre.h>
#include <cstdio> #include <cstdio>
#include "../nif/nif_file.hpp" #include "../nif/niffile.hpp"
#include "../nif/node.hpp" #include "../nif/node.hpp"
#include "../nif/data.hpp" #include "../nif/data.hpp"
#include "../nif/property.hpp" #include "../nif/property.hpp"

@ -21,8 +21,8 @@
*/ */
#ifndef _BULLET_NIF_LOADER_H_ #ifndef OPENMW_COMPONENTS_NIFBULLET_BULLETNIFLOADER_HPP
#define _BULLET_NIF_LOADER_H_ #define OPENMW_COMPONENTS_NIFBULLET_BULLETNIFLOADER_HPP
#include <OgreMesh.h> #include <OgreMesh.h>
#include <cassert> #include <cassert>

@ -21,7 +21,7 @@
*/ */
#include "ogre_nif_loader.hpp" #include "ogrenifloader.hpp"
#include <algorithm> #include <algorithm>

@ -21,8 +21,8 @@
*/ */
#ifndef _OGRE_NIF_LOADER_H_ #ifndef OPENMW_COMPONENTS_NIFOGRE_OGRENIFLOADER_HPP
#define _OGRE_NIF_LOADER_H_ #define OPENMW_COMPONENTS_NIFOGRE_OGRENIFLOADER_HPP
#include <OgreResource.h> #include <OgreResource.h>
#include <OgreMesh.h> #include <OgreMesh.h>

@ -1,5 +1,5 @@
#ifndef COMPONENTS_NIFOVERRIDES_H #ifndef OPENMW_COMPONENTS_NIFOVERRIDES_NIFOVERRIDES_HPP
#define COMPONENTS_NIFOVERRIDES_H #define OPENMW_COMPONENTS_NIFOVERRIDES_NIFOVERRIDES_HPP
#include <OgreConfigFile.h> #include <OgreConfigFile.h>

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

Loading…
Cancel
Save