mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 07:23:54 +00:00
Merge remote-tracking branch 'zini/master' into nifogre
This commit is contained in:
commit
3768e04a0c
30 changed files with 1075 additions and 17 deletions
|
@ -1182,7 +1182,7 @@ void Record<ESM::Script>::print()
|
|||
std::cout << " Variable: " << *vit << std::endl;
|
||||
|
||||
std::cout << " ByteCode: ";
|
||||
std::vector<char>::iterator cit;
|
||||
std::vector<unsigned char>::iterator cit;
|
||||
for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); cit++)
|
||||
std::cout << boost::format("%02X") % (int)(*cit);
|
||||
std::cout << std::endl;
|
||||
|
|
|
@ -35,7 +35,7 @@ opencs_units (model/tools
|
|||
)
|
||||
|
||||
opencs_units_noqt (model/tools
|
||||
stage verifier mandatoryid skillcheck classcheck factioncheck racecheck
|
||||
stage verifier mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
||||
)
|
||||
|
||||
|
||||
|
|
33
apps/opencs/model/tools/regioncheck.cpp
Normal file
33
apps/opencs/model/tools/regioncheck.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
|
||||
#include "regioncheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include <components/esm/loadregn.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::RegionCheckStage::RegionCheckStage (const CSMWorld::IdCollection<ESM::Region>& regions)
|
||||
: mRegions (regions)
|
||||
{}
|
||||
|
||||
int CSMTools::RegionCheckStage::setup()
|
||||
{
|
||||
return mRegions.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::RegionCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Region& region = mRegions.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Region, region.mId);
|
||||
|
||||
// test for empty name
|
||||
if (region.mName.empty())
|
||||
messages.push_back (id.toString() + "|" + region.mId + " has an empty name");
|
||||
|
||||
/// \todo test that the ID in mSleeplist exists
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
29
apps/opencs/model/tools/regioncheck.hpp
Normal file
29
apps/opencs/model/tools/regioncheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_REGIONCHECK_H
|
||||
#define CSM_TOOLS_REGIONCHECK_H
|
||||
|
||||
#include <components/esm/loadregn.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that region records are internally consistent
|
||||
class RegionCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Region>& mRegions;
|
||||
|
||||
public:
|
||||
|
||||
RegionCheckStage (const CSMWorld::IdCollection<ESM::Region>& regions);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
29
apps/opencs/model/tools/soundcheck.cpp
Normal file
29
apps/opencs/model/tools/soundcheck.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
#include "soundcheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::SoundCheckStage::SoundCheckStage (const CSMWorld::IdCollection<ESM::Sound>& sounds)
|
||||
: mSounds (sounds)
|
||||
{}
|
||||
|
||||
int CSMTools::SoundCheckStage::setup()
|
||||
{
|
||||
return mSounds.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::SoundCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Sound& sound = mSounds.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId);
|
||||
|
||||
if (sound.mData.mMinRange>sound.mData.mMaxRange)
|
||||
messages.push_back (id.toString() + "|Maximum range larger than minimum range");
|
||||
|
||||
/// \todo check, if the sound file exists
|
||||
}
|
29
apps/opencs/model/tools/soundcheck.hpp
Normal file
29
apps/opencs/model/tools/soundcheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_SOUNDCHECK_H
|
||||
#define CSM_TOOLS_SOUNDCHECK_H
|
||||
|
||||
#include <components/esm/loadsoun.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that sound records are internally consistent
|
||||
class SoundCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Sound>& mSounds;
|
||||
|
||||
public:
|
||||
|
||||
SoundCheckStage (const CSMWorld::IdCollection<ESM::Sound>& sounds);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -16,6 +16,8 @@
|
|||
#include "classcheck.hpp"
|
||||
#include "factioncheck.hpp"
|
||||
#include "racecheck.hpp"
|
||||
#include "soundcheck.hpp"
|
||||
#include "regioncheck.hpp"
|
||||
|
||||
CSMTools::Operation *CSMTools::Tools::get (int type)
|
||||
{
|
||||
|
@ -63,6 +65,10 @@ CSMTools::Verifier *CSMTools::Tools::getVerifier()
|
|||
mVerifier->appendStage (new FactionCheckStage (mData.getFactions()));
|
||||
|
||||
mVerifier->appendStage (new RaceCheckStage (mData.getRaces()));
|
||||
|
||||
mVerifier->appendStage (new SoundCheckStage (mData.getSounds()));
|
||||
|
||||
mVerifier->appendStage (new RegionCheckStage (mData.getRegions()));
|
||||
}
|
||||
|
||||
return mVerifier;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <QColor>
|
||||
|
||||
#include "columnbase.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
|
@ -506,6 +508,148 @@ namespace CSMWorld
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SoundParamColumn : public Column<ESXRecordT>
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Type_Volume,
|
||||
Type_MinRange,
|
||||
Type_MaxRange
|
||||
};
|
||||
|
||||
Type mType;
|
||||
|
||||
SoundParamColumn (Type type)
|
||||
: Column<ESXRecordT> (
|
||||
type==Type_Volume ? "Volume" : (type==Type_MinRange ? "Min Range" : "Max Range"),
|
||||
ColumnBase::Display_Integer),
|
||||
mType (type)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
switch (mType)
|
||||
{
|
||||
case Type_Volume: value = record.get().mData.mVolume; break;
|
||||
case Type_MinRange: value = record.get().mData.mMinRange; break;
|
||||
case Type_MaxRange: value = record.get().mData.mMaxRange; break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
int value = data.toInt();
|
||||
|
||||
if (value<0)
|
||||
value = 0;
|
||||
else if (value>255)
|
||||
value = 255;
|
||||
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
switch (mType)
|
||||
{
|
||||
case Type_Volume: record2.mData.mVolume = static_cast<unsigned char> (value); break;
|
||||
case Type_MinRange: record2.mData.mMinRange = static_cast<unsigned char> (value); break;
|
||||
case Type_MaxRange: record2.mData.mMaxRange = static_cast<unsigned char> (value); break;
|
||||
}
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SoundFileColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SoundFileColumn() : Column<ESXRecordT> ("Sound File", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mSound.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mSound = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// \todo QColor is a GUI class and should not be in model. Need to think of an alternative
|
||||
/// solution.
|
||||
template<typename ESXRecordT>
|
||||
struct MapColourColumn : public Column<ESXRecordT>
|
||||
{
|
||||
/// \todo Replace Display_Integer with something that displays the colour value more directly.
|
||||
MapColourColumn() : Column<ESXRecordT> ("Map Colour", ColumnBase::Display_Integer) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
int colour = record.get().mMapColor;
|
||||
|
||||
return QColor (colour & 0xff, (colour>>8) & 0xff, (colour>>16) & 0xff);
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
QColor colour = data.value<QColor>();
|
||||
|
||||
record2.mMapColor = colour.rgb() & 0xffffff;
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SleepListColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SleepListColumn() : Column<ESXRecordT> ("Sleep Encounter", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mSleepList.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mSleepList = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -77,12 +77,31 @@ CSMWorld::Data::Data()
|
|||
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (false, true));
|
||||
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (false, false));
|
||||
|
||||
mSounds.addColumn (new StringIdColumn<ESM::Sound>);
|
||||
mSounds.addColumn (new RecordStateColumn<ESM::Sound>);
|
||||
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_Volume));
|
||||
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MinRange));
|
||||
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MaxRange));
|
||||
mSounds.addColumn (new SoundFileColumn<ESM::Sound>);
|
||||
|
||||
mScripts.addColumn (new StringIdColumn<ESM::Script>);
|
||||
mScripts.addColumn (new RecordStateColumn<ESM::Script>);
|
||||
|
||||
mRegions.addColumn (new StringIdColumn<ESM::Region>);
|
||||
mRegions.addColumn (new RecordStateColumn<ESM::Region>);
|
||||
mRegions.addColumn (new NameColumn<ESM::Region>);
|
||||
mRegions.addColumn (new MapColourColumn<ESM::Region>);
|
||||
mRegions.addColumn (new SleepListColumn<ESM::Region>);
|
||||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
|
||||
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
|
||||
addModel (new IdTable (&mFactions), UniversalId::Type_Factions, UniversalId::Type_Faction);
|
||||
addModel (new IdTable (&mRaces), UniversalId::Type_Races, UniversalId::Type_Race);
|
||||
addModel (new IdTable (&mSounds), UniversalId::Type_Sounds, UniversalId::Type_Sound);
|
||||
addModel (new IdTable (&mScripts), UniversalId::Type_Scripts, UniversalId::Type_Script);
|
||||
addModel (new IdTable (&mRegions), UniversalId::Type_Regions, UniversalId::Type_Region);
|
||||
}
|
||||
|
||||
CSMWorld::Data::~Data()
|
||||
|
@ -151,6 +170,36 @@ CSMWorld::IdCollection<ESM::Race>& CSMWorld::Data::getRaces()
|
|||
return mRaces;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Sound>& CSMWorld::Data::getSounds() const
|
||||
{
|
||||
return mSounds;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Sound>& CSMWorld::Data::getSounds()
|
||||
{
|
||||
return mSounds;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Script>& CSMWorld::Data::getScripts() const
|
||||
{
|
||||
return mScripts;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Script>& CSMWorld::Data::getScripts()
|
||||
{
|
||||
return mScripts;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Region>& CSMWorld::Data::getRegions() const
|
||||
{
|
||||
return mRegions;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Region>& CSMWorld::Data::getRegions()
|
||||
{
|
||||
return mRegions;
|
||||
}
|
||||
|
||||
QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
||||
{
|
||||
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
|
||||
|
@ -191,6 +240,9 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base)
|
|||
case ESM::REC_CLAS: mClasses.load (reader, base); break;
|
||||
case ESM::REC_FACT: mFactions.load (reader, base); break;
|
||||
case ESM::REC_RACE: mRaces.load (reader, base); break;
|
||||
case ESM::REC_SOUN: mSounds.load (reader, base); break;
|
||||
case ESM::REC_SCPT: mScripts.load (reader, base); break;
|
||||
case ESM::REC_REGN: mRegions.load (reader, base); break;
|
||||
|
||||
default:
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include <components/esm/loadclas.hpp>
|
||||
#include <components/esm/loadfact.hpp>
|
||||
#include <components/esm/loadrace.hpp>
|
||||
#include <components/esm/loadsoun.hpp>
|
||||
#include <components/esm/loadscpt.hpp>
|
||||
#include <components/esm/loadregn.hpp>
|
||||
|
||||
#include "idcollection.hpp"
|
||||
#include "universalid.hpp"
|
||||
|
@ -28,6 +31,9 @@ namespace CSMWorld
|
|||
IdCollection<ESM::Class> mClasses;
|
||||
IdCollection<ESM::Faction> mFactions;
|
||||
IdCollection<ESM::Race> mRaces;
|
||||
IdCollection<ESM::Sound> mSounds;
|
||||
IdCollection<ESM::Script> mScripts;
|
||||
IdCollection<ESM::Region> mRegions;
|
||||
std::vector<QAbstractItemModel *> mModels;
|
||||
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
||||
|
||||
|
@ -68,6 +74,18 @@ namespace CSMWorld
|
|||
|
||||
IdCollection<ESM::Race>& getRaces();
|
||||
|
||||
const IdCollection<ESM::Sound>& getSounds() const;
|
||||
|
||||
IdCollection<ESM::Sound>& getSounds();
|
||||
|
||||
const IdCollection<ESM::Script>& getScripts() const;
|
||||
|
||||
IdCollection<ESM::Script>& getScripts();
|
||||
|
||||
const IdCollection<ESM::Region>& getRegions() const;
|
||||
|
||||
IdCollection<ESM::Region>& getRegions();
|
||||
|
||||
QAbstractItemModel *getTableModel (const UniversalId& id);
|
||||
///< If no table model is available for \a id, an exception is thrown.
|
||||
///
|
||||
|
|
|
@ -23,6 +23,9 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Classes, "Classes" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Factions, "Factions" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Races, "Races" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Sounds, "Sounds" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Scripts, "Scripts" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Regions, "Regions" },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
|
@ -35,6 +38,9 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region" },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
|
|
|
@ -45,7 +45,13 @@ namespace CSMWorld
|
|||
Type_Factions,
|
||||
Type_Faction,
|
||||
Type_Races,
|
||||
Type_Race
|
||||
Type_Race,
|
||||
Type_Sounds,
|
||||
Type_Sound,
|
||||
Type_Scripts,
|
||||
Type_Script,
|
||||
Type_Regions,
|
||||
Type_Region
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -105,6 +105,18 @@ void CSVDoc::View::setupWorldMenu()
|
|||
QAction *races = new QAction (tr ("Races"), this);
|
||||
connect (races, SIGNAL (triggered()), this, SLOT (addRacesSubView()));
|
||||
world->addAction (races);
|
||||
|
||||
QAction *sounds = new QAction (tr ("Sounds"), this);
|
||||
connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView()));
|
||||
world->addAction (sounds);
|
||||
|
||||
QAction *scripts = new QAction (tr ("Scripts"), this);
|
||||
connect (scripts, SIGNAL (triggered()), this, SLOT (addScriptsSubView()));
|
||||
world->addAction (scripts);
|
||||
|
||||
QAction *regions = new QAction (tr ("Regions"), this);
|
||||
connect (regions, SIGNAL (triggered()), this, SLOT (addRegionsSubView()));
|
||||
world->addAction (regions);
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupUi()
|
||||
|
@ -280,6 +292,21 @@ void CSVDoc::View::addRacesSubView()
|
|||
addSubView (CSMWorld::UniversalId::Type_Races);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addSoundsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Sounds);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addScriptsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Scripts);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addRegionsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Regions);
|
||||
}
|
||||
|
||||
void CSVDoc::View::abortOperation (int type)
|
||||
{
|
||||
mDocument->abortOperation (type);
|
||||
|
|
|
@ -123,6 +123,12 @@ namespace CSVDoc
|
|||
void addFactionsSubView();
|
||||
|
||||
void addRacesSubView();
|
||||
|
||||
void addSoundsSubView();
|
||||
|
||||
void addScriptsSubView();
|
||||
|
||||
void addRegionsSubView();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
CSMWorld::UniversalId::Type_Classes,
|
||||
CSMWorld::UniversalId::Type_Factions,
|
||||
CSMWorld::UniversalId::Type_Races,
|
||||
CSMWorld::UniversalId::Type_Sounds,
|
||||
CSMWorld::UniversalId::Type_Scripts,
|
||||
CSMWorld::UniversalId::Type_Regions,
|
||||
|
||||
CSMWorld::UniversalId::Type_None // end marker
|
||||
};
|
||||
|
|
|
@ -301,6 +301,12 @@ namespace MWInput
|
|||
mPlayer.setForwardBackward (-1);
|
||||
}
|
||||
|
||||
else if(mPlayer.getAutoMove())
|
||||
{
|
||||
triedToMove = true;
|
||||
mPlayer.setForwardBackward (1);
|
||||
}
|
||||
|
||||
mPlayer.setSneak(actionIsActive(A_Sneak));
|
||||
|
||||
if (actionIsActive(A_Jump) && mControlSwitch["playerjumping"])
|
||||
|
@ -321,6 +327,7 @@ namespace MWInput
|
|||
mOverencumberedMessageDelay -= dt;
|
||||
if (MWWorld::Class::get(player).getEncumbrance(player) >= MWWorld::Class::get(player).getCapacity(player))
|
||||
{
|
||||
mPlayer.setAutoMove (false);
|
||||
if (mOverencumberedMessageDelay <= 0)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage59}");
|
||||
|
|
|
@ -149,7 +149,7 @@ namespace MWMechanics
|
|||
// forced update and current value adjustments
|
||||
mActors.updateActor (ptr, 0);
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
DynamicStat<float> stat = creatureStats.getDynamic (i);
|
||||
stat.setCurrent (stat.getModified());
|
||||
|
|
|
@ -242,14 +242,15 @@ namespace MWRender
|
|||
|
||||
void Player::setPitch(float angle)
|
||||
{
|
||||
float limit = Ogre::Math::HALF_PI;
|
||||
const float epsilon = 0.000001;
|
||||
float limit = Ogre::Math::HALF_PI - epsilon;
|
||||
if (mVanity.forced || mPreviewMode) {
|
||||
limit /= 2;
|
||||
}
|
||||
if (angle > limit) {
|
||||
angle = limit - 0.01;
|
||||
angle = limit;
|
||||
} else if (angle < -limit) {
|
||||
angle = -limit + 0.01;
|
||||
angle = -limit;
|
||||
}
|
||||
if (mVanity.enabled || mPreviewMode) {
|
||||
mPreviewCam.pitch = angle;
|
||||
|
|
|
@ -46,4 +46,17 @@ void Region::save(ESMWriter &esm)
|
|||
}
|
||||
}
|
||||
|
||||
void Region::blank()
|
||||
{
|
||||
mName.clear();
|
||||
|
||||
mData.mClear = mData.mCloudy = mData.mFoggy = mData.mOvercast = mData.mRain =
|
||||
mData.mThunder = mData.mAsh, mData.mBlight = mData.mA = mData.mB = 0;
|
||||
|
||||
mMapColor = 0;
|
||||
|
||||
mName.clear();
|
||||
mSleepList.clear();
|
||||
mSoundList.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ struct Region
|
|||
|
||||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm);
|
||||
|
||||
void blank();
|
||||
///< Set record to default state (does not touch the ID/index).
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -76,10 +76,21 @@ void Script::save(ESMWriter &esm)
|
|||
}
|
||||
|
||||
esm.startSubRecord("SCDT");
|
||||
esm.write(&mScriptData[0], mData.mScriptDataSize);
|
||||
esm.write(reinterpret_cast<const char * >(&mScriptData[0]), mData.mScriptDataSize);
|
||||
esm.endRecord("SCDT");
|
||||
|
||||
esm.writeHNOString("SCTX", mScriptText);
|
||||
}
|
||||
|
||||
void Script::blank()
|
||||
{
|
||||
mData.mNumShorts = mData.mNumLongs = mData.mNumFloats = 0;
|
||||
mData.mScriptDataSize = 0;
|
||||
mData.mStringTableSize = 0;
|
||||
|
||||
mVarNames.clear();
|
||||
mScriptData.clear();
|
||||
mScriptText = "Begin " + mId + "\n\nEnd " + mId + "\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,11 +52,14 @@ public:
|
|||
SCHDstruct mData;
|
||||
|
||||
std::vector<std::string> mVarNames; // Variable names
|
||||
std::vector<char> mScriptData; // Compiled bytecode
|
||||
std::vector<unsigned char> mScriptData; // Compiled bytecode
|
||||
std::string mScriptText; // Uncompiled script
|
||||
|
||||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm);
|
||||
|
||||
void blank();
|
||||
///< Set record to default state (does not touch the ID/index).
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -23,4 +23,12 @@ void Sound::save(ESMWriter &esm)
|
|||
esm.writeHNT("DATA", mData, 3);
|
||||
}
|
||||
|
||||
void Sound::blank()
|
||||
{
|
||||
mSound.clear();
|
||||
|
||||
mData.mVolume = 128;
|
||||
mData.mMinRange = 0;
|
||||
mData.mMaxRange = 255;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ struct Sound
|
|||
|
||||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm);
|
||||
|
||||
void blank();
|
||||
///< Set record to default state (does not touch the ID/index).
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -44,6 +44,9 @@ set(MATERIAL_FILES
|
|||
watersim_common.h
|
||||
watersim.mat
|
||||
watersim.shaderset
|
||||
mygui.mat
|
||||
mygui.shader
|
||||
mygui.shaderset
|
||||
)
|
||||
|
||||
copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/water "${OpenMW_BINARY_DIR}/resources/water/" "${WATER_FILES}")
|
||||
|
|
25
files/materials/mygui.mat
Normal file
25
files/materials/mygui.mat
Normal file
|
@ -0,0 +1,25 @@
|
|||
material MyGUI/NoTexture
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_program mygui_vertex
|
||||
fragment_program mygui_fragment
|
||||
shader_properties
|
||||
{
|
||||
has_texture false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material MyGUI/OneTexture
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_program mygui_vertex
|
||||
fragment_program mygui_fragment
|
||||
shader_properties
|
||||
{
|
||||
has_texture true
|
||||
}
|
||||
}
|
||||
}
|
45
files/materials/mygui.shader
Normal file
45
files/materials/mygui.shader
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "core.h"
|
||||
|
||||
#define TEXTURE @shPropertyBool(has_texture)
|
||||
|
||||
#ifdef SH_VERTEX_SHADER
|
||||
|
||||
SH_BEGIN_PROGRAM
|
||||
#if TEXTURE
|
||||
shVertexInput(float2, uv0)
|
||||
shOutput(float2, UV)
|
||||
#endif
|
||||
shColourInput(float4)
|
||||
shOutput(float4, colourPassthrough)
|
||||
|
||||
SH_START_PROGRAM
|
||||
{
|
||||
shOutputPosition = float4(shInputPosition.xyz, 1.f);
|
||||
#if TEXTURE
|
||||
UV.xy = uv0;
|
||||
#endif
|
||||
colourPassthrough = colour;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
SH_BEGIN_PROGRAM
|
||||
|
||||
#if TEXTURE
|
||||
shSampler2D(diffuseMap)
|
||||
shInput(float2, UV)
|
||||
#endif
|
||||
|
||||
shInput(float4, colourPassthrough)
|
||||
|
||||
SH_START_PROGRAM
|
||||
{
|
||||
#if TEXTURE
|
||||
shOutputColour(0) = shSample(diffuseMap, UV.xy) * colourPassthrough;
|
||||
#else
|
||||
shOutputColour(0) = colourPassthrough;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
15
files/materials/mygui.shaderset
Normal file
15
files/materials/mygui.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
|||
shader_set mygui_vertex
|
||||
{
|
||||
source mygui.shader
|
||||
type vertex
|
||||
profiles_cg vs_2_0 vp40 arbvp1
|
||||
profiles_hlsl vs_3_0 vs_2_0
|
||||
}
|
||||
|
||||
shader_set mygui_fragment
|
||||
{
|
||||
source mygui.shader
|
||||
type fragment
|
||||
profiles_cg ps_3_0 ps_2_x ps_2_0 fp40 arbfp1
|
||||
profiles_hlsl ps_3_0 ps_2_0
|
||||
}
|
|
@ -2,11 +2,18 @@
|
|||
|
||||
#include <MyGUI_Gui.h>
|
||||
#include <MyGUI_OgrePlatform.h>
|
||||
#include <MyGUI_Timer.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
#include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp>
|
||||
|
||||
using namespace OEngine::GUI;
|
||||
|
||||
namespace MyGUI
|
||||
{
|
||||
|
||||
/*
|
||||
* As of MyGUI 3.2.0, MyGUI::OgreDataManager::isDataExist is unnecessarily complex
|
||||
* this override fixes the resulting performance issue.
|
||||
|
@ -20,6 +27,532 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* As of MyGUI 3.2.0, rendering with shaders is not supported.
|
||||
* We definitely need this though to run in GL3 core / DX11 at all.
|
||||
* To make matters worse, subclassing OgreRenderManager doesn't seem to be possible here. :/
|
||||
*/
|
||||
class ShaderBasedRenderManager : public RenderManager,
|
||||
public IRenderTarget,
|
||||
public Ogre::WindowEventListener,
|
||||
public Ogre::RenderQueueListener,
|
||||
public Ogre::RenderSystem::Listener
|
||||
{
|
||||
// флаг для обновления всех и вся
|
||||
bool mUpdate;
|
||||
|
||||
IntSize mViewSize;
|
||||
|
||||
Ogre::SceneManager* mSceneManager;
|
||||
|
||||
VertexColourType mVertexFormat;
|
||||
|
||||
// окно, на которое мы подписываемся для изменения размеров
|
||||
Ogre::RenderWindow* mWindow;
|
||||
|
||||
// вьюпорт, с которым работает система
|
||||
unsigned short mActiveViewport;
|
||||
|
||||
Ogre::RenderSystem* mRenderSystem;
|
||||
Ogre::TextureUnitState::UVWAddressingMode mTextureAddressMode;
|
||||
Ogre::LayerBlendModeEx mColorBlendMode, mAlphaBlendMode;
|
||||
|
||||
RenderTargetInfo mInfo;
|
||||
|
||||
typedef std::map<std::string, ITexture*> MapTexture;
|
||||
MapTexture mTextures;
|
||||
|
||||
bool mIsInitialise;
|
||||
bool mManualRender;
|
||||
size_t mCountBatch;
|
||||
|
||||
// ADDED
|
||||
Ogre::GpuProgram* mVertexProgramNoTexture;
|
||||
Ogre::GpuProgram* mVertexProgramOneTexture;
|
||||
Ogre::GpuProgram* mFragmentProgramNoTexture;
|
||||
Ogre::GpuProgram* mFragmentProgramOneTexture;
|
||||
|
||||
public:
|
||||
ShaderBasedRenderManager& getInstance()
|
||||
{
|
||||
return *getInstancePtr();
|
||||
}
|
||||
ShaderBasedRenderManager* getInstancePtr()
|
||||
{
|
||||
return static_cast<ShaderBasedRenderManager*>(RenderManager::getInstancePtr());
|
||||
}
|
||||
|
||||
ShaderBasedRenderManager() :
|
||||
mUpdate(false),
|
||||
mSceneManager(nullptr),
|
||||
mWindow(nullptr),
|
||||
mActiveViewport(0),
|
||||
mRenderSystem(nullptr),
|
||||
mIsInitialise(false),
|
||||
mManualRender(false),
|
||||
mCountBatch(0)
|
||||
{
|
||||
}
|
||||
|
||||
void initialise(Ogre::RenderWindow* _window, Ogre::SceneManager* _scene)
|
||||
{
|
||||
MYGUI_PLATFORM_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
|
||||
MYGUI_PLATFORM_LOG(Info, "* Initialise: " << getClassTypeName());
|
||||
|
||||
mColorBlendMode.blendType = Ogre::LBT_COLOUR;
|
||||
mColorBlendMode.source1 = Ogre::LBS_TEXTURE;
|
||||
mColorBlendMode.source2 = Ogre::LBS_DIFFUSE;
|
||||
mColorBlendMode.operation = Ogre::LBX_MODULATE;
|
||||
|
||||
mAlphaBlendMode.blendType = Ogre::LBT_ALPHA;
|
||||
mAlphaBlendMode.source1 = Ogre::LBS_TEXTURE;
|
||||
mAlphaBlendMode.source2 = Ogre::LBS_DIFFUSE;
|
||||
mAlphaBlendMode.operation = Ogre::LBX_MODULATE;
|
||||
|
||||
mTextureAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP;
|
||||
mTextureAddressMode.v = Ogre::TextureUnitState::TAM_CLAMP;
|
||||
mTextureAddressMode.w = Ogre::TextureUnitState::TAM_CLAMP;
|
||||
|
||||
mSceneManager = nullptr;
|
||||
mWindow = nullptr;
|
||||
mUpdate = false;
|
||||
mRenderSystem = nullptr;
|
||||
mActiveViewport = 0;
|
||||
|
||||
Ogre::Root* root = Ogre::Root::getSingletonPtr();
|
||||
if (root != nullptr)
|
||||
setRenderSystem(root->getRenderSystem());
|
||||
setRenderWindow(_window);
|
||||
setSceneManager(_scene);
|
||||
|
||||
// ADDED
|
||||
sh::MaterialInstance* mat = sh::Factory::getInstance().getMaterialInstance("MyGUI/NoTexture");
|
||||
sh::Factory::getInstance()._ensureMaterial("MyGUI/NoTexture", "Default");
|
||||
mVertexProgramNoTexture = static_cast<sh::OgreMaterial*>(mat->getMaterial())->getOgreTechniqueForConfiguration("Default")->getPass(0)
|
||||
->getVertexProgram()->_getBindingDelegate();
|
||||
|
||||
mat = sh::Factory::getInstance().getMaterialInstance("MyGUI/OneTexture");
|
||||
sh::Factory::getInstance()._ensureMaterial("MyGUI/OneTexture", "Default");
|
||||
mVertexProgramOneTexture = static_cast<sh::OgreMaterial*>(mat->getMaterial())->getOgreTechniqueForConfiguration("Default")->getPass(0)
|
||||
->getVertexProgram()->_getBindingDelegate();
|
||||
|
||||
mat = sh::Factory::getInstance().getMaterialInstance("MyGUI/NoTexture");
|
||||
sh::Factory::getInstance()._ensureMaterial("MyGUI/NoTexture", "Default");
|
||||
mFragmentProgramNoTexture = static_cast<sh::OgreMaterial*>(mat->getMaterial())->getOgreTechniqueForConfiguration("Default")->getPass(0)
|
||||
->getFragmentProgram()->_getBindingDelegate();
|
||||
|
||||
mat = sh::Factory::getInstance().getMaterialInstance("MyGUI/OneTexture");
|
||||
sh::Factory::getInstance()._ensureMaterial("MyGUI/OneTexture", "Default");
|
||||
mFragmentProgramOneTexture = static_cast<sh::OgreMaterial*>(mat->getMaterial())->getOgreTechniqueForConfiguration("Default")->getPass(0)
|
||||
->getFragmentProgram()->_getBindingDelegate();
|
||||
|
||||
|
||||
|
||||
MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully initialized");
|
||||
mIsInitialise = true;
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
MYGUI_PLATFORM_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
|
||||
MYGUI_PLATFORM_LOG(Info, "* Shutdown: " << getClassTypeName());
|
||||
|
||||
destroyAllResources();
|
||||
|
||||
setSceneManager(nullptr);
|
||||
setRenderWindow(nullptr);
|
||||
setRenderSystem(nullptr);
|
||||
|
||||
MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully shutdown");
|
||||
mIsInitialise = false;
|
||||
}
|
||||
|
||||
void setRenderSystem(Ogre::RenderSystem* _render)
|
||||
{
|
||||
// отписываемся
|
||||
if (mRenderSystem != nullptr)
|
||||
{
|
||||
mRenderSystem->removeListener(this);
|
||||
mRenderSystem = nullptr;
|
||||
}
|
||||
|
||||
mRenderSystem = _render;
|
||||
|
||||
// подписываемся на рендер евент
|
||||
if (mRenderSystem != nullptr)
|
||||
{
|
||||
mRenderSystem->addListener(this);
|
||||
|
||||
// формат цвета в вершинах
|
||||
Ogre::VertexElementType vertex_type = mRenderSystem->getColourVertexElementType();
|
||||
if (vertex_type == Ogre::VET_COLOUR_ARGB)
|
||||
mVertexFormat = VertexColourType::ColourARGB;
|
||||
else if (vertex_type == Ogre::VET_COLOUR_ABGR)
|
||||
mVertexFormat = VertexColourType::ColourABGR;
|
||||
|
||||
updateRenderInfo();
|
||||
}
|
||||
}
|
||||
|
||||
Ogre::RenderSystem* getRenderSystem()
|
||||
{
|
||||
return mRenderSystem;
|
||||
}
|
||||
|
||||
void setRenderWindow(Ogre::RenderWindow* _window)
|
||||
{
|
||||
// отписываемся
|
||||
if (mWindow != nullptr)
|
||||
{
|
||||
Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
|
||||
mWindow = nullptr;
|
||||
}
|
||||
|
||||
mWindow = _window;
|
||||
|
||||
if (mWindow != nullptr)
|
||||
{
|
||||
Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
|
||||
windowResized(mWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void setSceneManager(Ogre::SceneManager* _scene)
|
||||
{
|
||||
if (nullptr != mSceneManager)
|
||||
{
|
||||
mSceneManager->removeRenderQueueListener(this);
|
||||
mSceneManager = nullptr;
|
||||
}
|
||||
|
||||
mSceneManager = _scene;
|
||||
|
||||
if (nullptr != mSceneManager)
|
||||
{
|
||||
mSceneManager->addRenderQueueListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
void setActiveViewport(unsigned short _num)
|
||||
{
|
||||
mActiveViewport = _num;
|
||||
|
||||
if (mWindow != nullptr)
|
||||
{
|
||||
Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
|
||||
Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
|
||||
|
||||
// рассылка обновлений
|
||||
windowResized(mWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation)
|
||||
{
|
||||
Gui* gui = Gui::getInstancePtr();
|
||||
if (gui == nullptr)
|
||||
return;
|
||||
|
||||
if (Ogre::RENDER_QUEUE_OVERLAY != queueGroupId)
|
||||
return;
|
||||
|
||||
Ogre::Viewport* viewport = mSceneManager->getCurrentViewport();
|
||||
if (nullptr == viewport
|
||||
|| !viewport->getOverlaysEnabled())
|
||||
return;
|
||||
|
||||
if (mWindow->getNumViewports() <= mActiveViewport
|
||||
|| viewport != mWindow->getViewport(mActiveViewport))
|
||||
return;
|
||||
|
||||
mCountBatch = 0;
|
||||
|
||||
static Timer timer;
|
||||
static unsigned long last_time = timer.getMilliseconds();
|
||||
unsigned long now_time = timer.getMilliseconds();
|
||||
unsigned long time = now_time - last_time;
|
||||
|
||||
onFrameEvent((float)((double)(time) / (double)1000));
|
||||
|
||||
last_time = now_time;
|
||||
|
||||
//begin();
|
||||
setManualRender(true);
|
||||
onRenderToTarget(this, mUpdate);
|
||||
//end();
|
||||
|
||||
// сбрасываем флаг
|
||||
mUpdate = false;
|
||||
}
|
||||
|
||||
void renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation)
|
||||
{
|
||||
}
|
||||
|
||||
void eventOccurred(const Ogre::String& eventName, const Ogre::NameValuePairList* parameters)
|
||||
{
|
||||
if (eventName == "DeviceLost")
|
||||
{
|
||||
}
|
||||
else if (eventName == "DeviceRestored")
|
||||
{
|
||||
// обновить всех
|
||||
mUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
IVertexBuffer* createVertexBuffer()
|
||||
{
|
||||
return new OgreVertexBuffer();
|
||||
}
|
||||
|
||||
void destroyVertexBuffer(IVertexBuffer* _buffer)
|
||||
{
|
||||
delete _buffer;
|
||||
}
|
||||
|
||||
// для оповещений об изменении окна рендера
|
||||
void windowResized(Ogre::RenderWindow* _window)
|
||||
{
|
||||
if (_window->getNumViewports() > mActiveViewport)
|
||||
{
|
||||
Ogre::Viewport* port = _window->getViewport(mActiveViewport);
|
||||
#if OGRE_VERSION >= MYGUI_DEFINE_VERSION(1, 7, 0) && OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0
|
||||
Ogre::OrientationMode orient = port->getOrientationMode();
|
||||
if (orient == Ogre::OR_DEGREE_90 || orient == Ogre::OR_DEGREE_270)
|
||||
mViewSize.set(port->getActualHeight(), port->getActualWidth());
|
||||
else
|
||||
mViewSize.set(port->getActualWidth(), port->getActualHeight());
|
||||
#else
|
||||
mViewSize.set(port->getActualWidth(), port->getActualHeight());
|
||||
#endif
|
||||
|
||||
// обновить всех
|
||||
mUpdate = true;
|
||||
|
||||
updateRenderInfo();
|
||||
|
||||
onResizeView(mViewSize);
|
||||
}
|
||||
}
|
||||
|
||||
void updateRenderInfo()
|
||||
{
|
||||
if (mRenderSystem != nullptr)
|
||||
{
|
||||
mInfo.maximumDepth = mRenderSystem->getMaximumDepthInputValue();
|
||||
mInfo.hOffset = mRenderSystem->getHorizontalTexelOffset() / float(mViewSize.width);
|
||||
mInfo.vOffset = mRenderSystem->getVerticalTexelOffset() / float(mViewSize.height);
|
||||
mInfo.aspectCoef = float(mViewSize.height) / float(mViewSize.width);
|
||||
mInfo.pixScaleX = 1.0f / float(mViewSize.width);
|
||||
mInfo.pixScaleY = 1.0f / float(mViewSize.height);
|
||||
}
|
||||
}
|
||||
|
||||
void doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count)
|
||||
{
|
||||
if (getManualRender())
|
||||
{
|
||||
begin();
|
||||
setManualRender(false);
|
||||
}
|
||||
|
||||
// ADDED
|
||||
|
||||
if (_texture)
|
||||
{
|
||||
Ogre::Root::getSingleton().getRenderSystem()->bindGpuProgram(mVertexProgramOneTexture);
|
||||
Ogre::Root::getSingleton().getRenderSystem()->bindGpuProgram(mFragmentProgramOneTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ogre::Root::getSingleton().getRenderSystem()->bindGpuProgram(mVertexProgramNoTexture);
|
||||
Ogre::Root::getSingleton().getRenderSystem()->bindGpuProgram(mFragmentProgramNoTexture);
|
||||
}
|
||||
|
||||
if (_texture)
|
||||
{
|
||||
OgreTexture* texture = static_cast<OgreTexture*>(_texture);
|
||||
Ogre::TexturePtr texture_ptr = texture->getOgreTexture();
|
||||
if (!texture_ptr.isNull())
|
||||
{
|
||||
mRenderSystem->_setTexture(0, true, texture_ptr);
|
||||
mRenderSystem->_setTextureUnitFiltering(0, Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
OgreVertexBuffer* buffer = static_cast<OgreVertexBuffer*>(_buffer);
|
||||
Ogre::RenderOperation* operation = buffer->getRenderOperation();
|
||||
operation->vertexData->vertexCount = _count;
|
||||
|
||||
mRenderSystem->_render(*operation);
|
||||
|
||||
++ mCountBatch;
|
||||
}
|
||||
|
||||
void begin()
|
||||
{
|
||||
// set-up matrices
|
||||
mRenderSystem->_setWorldMatrix(Ogre::Matrix4::IDENTITY);
|
||||
mRenderSystem->_setViewMatrix(Ogre::Matrix4::IDENTITY);
|
||||
|
||||
#if OGRE_VERSION >= MYGUI_DEFINE_VERSION(1, 7, 0) && OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0
|
||||
Ogre::OrientationMode orient = mWindow->getViewport(mActiveViewport)->getOrientationMode();
|
||||
mRenderSystem->_setProjectionMatrix(Ogre::Matrix4::IDENTITY * Ogre::Quaternion(Ogre::Degree(orient * 90.f), Ogre::Vector3::UNIT_Z));
|
||||
#else
|
||||
mRenderSystem->_setProjectionMatrix(Ogre::Matrix4::IDENTITY);
|
||||
#endif
|
||||
|
||||
// initialise render settings
|
||||
mRenderSystem->setLightingEnabled(false);
|
||||
mRenderSystem->_setDepthBufferParams(false, false);
|
||||
mRenderSystem->_setDepthBias(0, 0);
|
||||
mRenderSystem->_setCullingMode(Ogre::CULL_NONE);
|
||||
mRenderSystem->_setFog(Ogre::FOG_NONE);
|
||||
mRenderSystem->_setColourBufferWriteEnabled(true, true, true, true);
|
||||
mRenderSystem->unbindGpuProgram(Ogre::GPT_FRAGMENT_PROGRAM);
|
||||
mRenderSystem->unbindGpuProgram(Ogre::GPT_VERTEX_PROGRAM);
|
||||
mRenderSystem->setShadingType(Ogre::SO_GOURAUD);
|
||||
|
||||
// initialise texture settings
|
||||
mRenderSystem->_setTextureCoordCalculation(0, Ogre::TEXCALC_NONE);
|
||||
mRenderSystem->_setTextureCoordSet(0, 0);
|
||||
mRenderSystem->_setTextureUnitFiltering(0, Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE);
|
||||
mRenderSystem->_setTextureAddressingMode(0, mTextureAddressMode);
|
||||
mRenderSystem->_setTextureMatrix(0, Ogre::Matrix4::IDENTITY);
|
||||
#if OGRE_VERSION < MYGUI_DEFINE_VERSION(1, 6, 0)
|
||||
mRenderSystem->_setAlphaRejectSettings(Ogre::CMPF_ALWAYS_PASS, 0);
|
||||
#else
|
||||
mRenderSystem->_setAlphaRejectSettings(Ogre::CMPF_ALWAYS_PASS, 0, false);
|
||||
#endif
|
||||
mRenderSystem->_setTextureBlendMode(0, mColorBlendMode);
|
||||
mRenderSystem->_setTextureBlendMode(0, mAlphaBlendMode);
|
||||
mRenderSystem->_disableTextureUnitsFrom(1);
|
||||
|
||||
// enable alpha blending
|
||||
mRenderSystem->_setSceneBlending(Ogre::SBF_SOURCE_ALPHA, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA);
|
||||
|
||||
// always use wireframe
|
||||
// TODO: add option to enable wireframe mode in platform
|
||||
mRenderSystem->_setPolygonMode(Ogre::PM_SOLID);
|
||||
}
|
||||
|
||||
void end()
|
||||
{
|
||||
}
|
||||
|
||||
ITexture* createTexture(const std::string& _name)
|
||||
{
|
||||
MapTexture::const_iterator item = mTextures.find(_name);
|
||||
MYGUI_PLATFORM_ASSERT(item == mTextures.end(), "Texture '" << _name << "' already exist");
|
||||
|
||||
OgreTexture* texture = new OgreTexture(_name, OgreDataManager::getInstance().getGroup());
|
||||
mTextures[_name] = texture;
|
||||
return texture;
|
||||
}
|
||||
|
||||
void destroyTexture(ITexture* _texture)
|
||||
{
|
||||
if (_texture == nullptr) return;
|
||||
|
||||
MapTexture::iterator item = mTextures.find(_texture->getName());
|
||||
MYGUI_PLATFORM_ASSERT(item != mTextures.end(), "Texture '" << _texture->getName() << "' not found");
|
||||
|
||||
mTextures.erase(item);
|
||||
delete _texture;
|
||||
}
|
||||
|
||||
ITexture* getTexture(const std::string& _name)
|
||||
{
|
||||
MapTexture::const_iterator item = mTextures.find(_name);
|
||||
if (item == mTextures.end())
|
||||
{
|
||||
Ogre::TexturePtr texture = (Ogre::TexturePtr)Ogre::TextureManager::getSingleton().getByName(_name);
|
||||
if (!texture.isNull())
|
||||
{
|
||||
ITexture* result = createTexture(_name);
|
||||
static_cast<OgreTexture*>(result)->setOgreTexture(texture);
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return item->second;
|
||||
}
|
||||
|
||||
bool isFormatSupported(PixelFormat _format, TextureUsage _usage)
|
||||
{
|
||||
return Ogre::TextureManager::getSingleton().isFormatSupported(
|
||||
Ogre::TEX_TYPE_2D,
|
||||
OgreTexture::convertFormat(_format),
|
||||
OgreTexture::convertUsage(_usage));
|
||||
}
|
||||
|
||||
void destroyAllResources()
|
||||
{
|
||||
for (MapTexture::const_iterator item = mTextures.begin(); item != mTextures.end(); ++item)
|
||||
{
|
||||
delete item->second;
|
||||
}
|
||||
mTextures.clear();
|
||||
}
|
||||
|
||||
#if MYGUI_DEBUG_MODE == 1
|
||||
bool checkTexture(ITexture* _texture)
|
||||
{
|
||||
for (MapTexture::const_iterator item = mTextures.begin(); item != mTextures.end(); ++item)
|
||||
{
|
||||
if (item->second == _texture)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
const IntSize& getViewSize() const
|
||||
{
|
||||
return mViewSize;
|
||||
}
|
||||
|
||||
VertexColourType getVertexFormat()
|
||||
{
|
||||
return mVertexFormat;
|
||||
}
|
||||
|
||||
const RenderTargetInfo& getInfo()
|
||||
{
|
||||
return mInfo;
|
||||
}
|
||||
|
||||
size_t getActiveViewport()
|
||||
{
|
||||
return mActiveViewport;
|
||||
}
|
||||
|
||||
Ogre::RenderWindow* getRenderWindow()
|
||||
{
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
bool getManualRender()
|
||||
{
|
||||
return mManualRender;
|
||||
}
|
||||
|
||||
void setManualRender(bool _value)
|
||||
{
|
||||
mManualRender = _value;
|
||||
}
|
||||
|
||||
size_t getBatchCount() const
|
||||
{
|
||||
return mCountBatch;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging, const std::string& logDir)
|
||||
{
|
||||
assert(wnd);
|
||||
|
@ -41,8 +574,8 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool
|
|||
|
||||
// Set up OGRE platform (bypassing OgrePlatform). We might make this more generic later.
|
||||
mLogManager = new LogManager();
|
||||
mRenderManager = new OgreRenderManager();
|
||||
mDataManager = new FixedOgreDataManager();
|
||||
mRenderManager = new MyGUI::ShaderBasedRenderManager();
|
||||
mDataManager = new MyGUI::FixedOgreDataManager();
|
||||
|
||||
LogManager::getInstance().setSTDOutputEnabled(logging);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace MyGUI
|
|||
class Gui;
|
||||
class LogManager;
|
||||
class OgreDataManager;
|
||||
class OgreRenderManager;
|
||||
class ShaderBasedRenderManager;
|
||||
}
|
||||
|
||||
namespace Ogre
|
||||
|
@ -25,7 +25,7 @@ namespace GUI
|
|||
MyGUI::Gui *mGui;
|
||||
MyGUI::LogManager* mLogManager;
|
||||
MyGUI::OgreDataManager* mDataManager;
|
||||
MyGUI::OgreRenderManager* mRenderManager;
|
||||
MyGUI::ShaderBasedRenderManager* mRenderManager;
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue