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();
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mOgre);
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mOgre);
Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mOgre);
#ifdef ENABLE_PLUGIN_GL

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -13,7 +13,7 @@
#include <openengine/bullet/physic.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/environment.hpp"

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

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

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

@ -15,15 +15,15 @@ add_component_dir (bsa
)
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
ogre_nif_loader
ogrenifloader
)
add_component_dir (nifbullet
bullet_nif_loader
bulletnifloader
)
add_component_dir (to_utf8

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

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

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

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

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

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

@ -21,7 +21,7 @@
*/
#include "nif_file.hpp"
#include "niffile.hpp"
#include "record.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)
: filename(name)
{
inp = Ogre::ResourceGroupManager::getSingleton().openResource(name);
parse();
// Make sure to close the file after it was loaded into memory
inp.setNull();
}
NIFFile::~NIFFile()
@ -188,6 +185,101 @@ NIFFile::~NIFFile()
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
where we stash all the functions we couldn't add as inline
definitions in the record types.
@ -195,18 +287,20 @@ NIFFile::~NIFFile()
void NIFFile::parse()
{
NIFStream nif (this, Ogre::ResourceGroupManager::getSingleton().openResource(filename));
// Check the header string
std::string head = getString(40);
std::string head = nif.getString(40);
if(head.compare(0, 22, "NetImmerse File Format") != 0)
fail("Invalid NIF header");
// Get BCD version
ver = getInt();
ver = nif.getInt();
if(ver != VER_MW)
fail("Unsupported NIF version");
// Number of records
size_t recNum = getInt();
size_t recNum = nif.getInt();
records.resize(recNum);
/* 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;
std::string rec = getString();
/* 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.
*/
// 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
std::string rec = nif.getString();
RecordFactoryEntry const * entry = lookupRecordFactory (rec.c_str ());
if (entry != NULL)
{
r = entry->mCreate ();
r->recType = entry->mType;
}
else
fail("Unknown record type " + rec);
fail("Unknown record type " + rec);
assert(r != NULL);
assert(r->recType != RC_MISSING);
r->recName = rec;
r->recIndex = i;
records[i] = r;
r->read(this);
r->read(&nif);
// Discard tranformations for the root node, otherwise some meshes
// occasionally get wrong orientation. Only for NiNode-s for now, but

@ -21,8 +21,8 @@
*/
#ifndef _NIF_FILE_H_
#define _NIF_FILE_H_
#ifndef OPENMW_COMPONENTS_NIF_NIFFILE_HPP
#define OPENMW_COMPONENTS_NIF_NIFFILE_HPP
#include <OgreResourceGroupManager.h>
#include <OgreDataStream.h>
@ -45,7 +45,8 @@
#include <libs/platform/stdint.h>
#include "record.hpp"
#include "nif_types.hpp"
#include "niftypes.hpp"
#include "nifstream.hpp"
namespace Nif
{
@ -59,9 +60,6 @@ class NIFFile
/// Nif file version
int ver;
/// Input stream
Ogre::DataStreamPtr inp;
/// File name, used for error messages
std::string filename;
@ -71,33 +69,6 @@ class NIFFile
/// Parse the file
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;
friend class LoadedCache;
@ -117,8 +88,8 @@ public:
void warn(const std::string &msg)
{
std::cerr<< "NIFFile Warning: "<<msg <<std::endl
<< "File: "<<filename <<std::endl;
std::cerr << "NIFFile Warning: " << msg <<std::endl
<< "File: " << filename <<std::endl;
}
typedef boost::shared_ptr <NIFFile> ptr;
@ -147,111 +118,6 @@ public:
/// Number of records
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::Quaternion> QuaternionKey;
template<typename T, T (NIFFile::*getValue)()>
template<typename T, T (NIFStream::*getValue)()>
struct KeyListT {
typedef std::vector< KeyT<T> > VecType;
@ -281,7 +147,7 @@ struct KeyListT {
int mInterpolationType;
VecType mKeys;
void read(NIFFile *nif, bool force=false)
void read(NIFStream *nif, bool force=false)
{
size_t count = nif->getInt();
if(count == 0 && !force)
@ -322,13 +188,13 @@ struct KeyListT {
}
}
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<Ogre::Vector3,&NIFFile::getVector3> Vector3KeyList;
typedef KeyListT<Ogre::Vector4,&NIFFile::getVector4> Vector4KeyList;
typedef KeyListT<Ogre::Quaternion,&NIFFile::getQuaternion> QuaternionKeyList;
typedef KeyListT<float,&NIFStream::getFloat> FloatKeyList;
typedef KeyListT<Ogre::Vector3,&NIFStream::getVector3> Vector3KeyList;
typedef KeyListT<Ogre::Vector4,&NIFStream::getVector4> Vector4KeyList;
typedef KeyListT<Ogre::Quaternion,&NIFStream::getQuaternion> QuaternionKeyList;
} // Namespace
#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_
#define _NIF_TYPES_H_
#ifndef OPENMW_COMPONENTS_NIF_NIFTYPES_HPP
#define OPENMW_COMPONENTS_NIF_NIFTYPES_HPP
#include <OgreVector3.h>
#include <OgreMatrix3.h>

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

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

@ -21,8 +21,8 @@
*/
#ifndef _NIF_RECORD_H_
#define _NIF_RECORD_H_
#ifndef OPENMW_COMPONENTS_NIF_RECORD_HPP
#define OPENMW_COMPONENTS_NIF_RECORD_HPP
#include <string>
@ -30,6 +30,7 @@ namespace Nif
{
class NIFFile;
class NIFStream;
enum RecordType
{
@ -97,7 +98,7 @@ struct Record
Record() : recType(RC_MISSING), recIndex(~(size_t)0) {}
/// 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
virtual void post(NIFFile *nif) {}

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

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

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

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

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

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

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

Loading…
Cancel
Save