Merge branch 'master' into levelup

actorid
scrawl 12 years ago
commit 95f3a20e2c

@ -103,6 +103,7 @@ set(OENGINE_OGRE
${LIBDIR}/openengine/ogre/fader.cpp ${LIBDIR}/openengine/ogre/fader.cpp
${LIBDIR}/openengine/ogre/imagerotate.cpp ${LIBDIR}/openengine/ogre/imagerotate.cpp
${LIBDIR}/openengine/ogre/atlas.cpp ${LIBDIR}/openengine/ogre/atlas.cpp
${LIBDIR}/openengine/ogre/selectionbuffer.cpp
) )
set(OENGINE_GUI set(OENGINE_GUI
${LIBDIR}/openengine/gui/manager.cpp ${LIBDIR}/openengine/gui/manager.cpp

@ -16,7 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender add_openmw_dir (mwrender
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
compositors compositors characterpreview externalrendering
) )
add_openmw_dir (mwinput add_openmw_dir (mwinput

@ -35,6 +35,11 @@ namespace ESMS
struct ESMStore; struct ESMStore;
} }
namespace MWRender
{
class ExternalRendering;
}
namespace MWWorld namespace MWWorld
{ {
class CellStore; class CellStore;
@ -271,6 +276,8 @@ namespace MWBase
virtual void togglePlayerLooking(bool enable) = 0; virtual void togglePlayerLooking(bool enable) = 0;
virtual void renderPlayer() = 0; virtual void renderPlayer() = 0;
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
}; };
} }

@ -44,10 +44,14 @@ namespace MWGui
: ContainerBase(dragAndDrop) : ContainerBase(dragAndDrop)
, WindowPinnableBase("openmw_inventory_window.layout", parWindowManager) , WindowPinnableBase("openmw_inventory_window.layout", parWindowManager)
, mTrading(false) , mTrading(false)
, mLastXSize(0)
, mLastYSize(0)
, mPreview(MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ())
{ {
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
getWidget(mAvatar, "Avatar"); getWidget(mAvatar, "Avatar");
getWidget(mAvatarImage, "AvatarImage");
getWidget(mEncumbranceBar, "EncumbranceBar"); getWidget(mEncumbranceBar, "EncumbranceBar");
getWidget(mEncumbranceText, "EncumbranceBarT"); getWidget(mEncumbranceText, "EncumbranceBarT");
getWidget(mFilterAll, "AllButton"); getWidget(mFilterAll, "AllButton");
@ -76,6 +80,8 @@ namespace MWGui
setCoord(0, 342, 498, 258); setCoord(0, 342, 498, 258);
MWBase::Environment::get().getWorld ()->setupExternalRendering (mPreview);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
openContainer(player); openContainer(player);
} }
@ -89,6 +95,7 @@ namespace MWGui
mBoughtItems.clear(); mBoughtItems.clear();
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget)); onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
drawItems();
} }
void InventoryWindow::onWindowResize(MyGUI::Window* _sender) void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
@ -99,7 +106,13 @@ namespace MWGui
mRightPane->getPosition().top, mRightPane->getPosition().top,
_sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15, _sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15,
_sender->getSize().height-44 ); _sender->getSize().height-44 );
drawItems();
if (mMainWidget->getSize().width != mLastXSize || mMainWidget->getSize().height != mLastYSize)
{
drawItems();
mLastXSize = mMainWidget->getSize().width;
mLastYSize = mMainWidget->getSize().height;
}
} }
void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender) void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender)
@ -171,17 +184,47 @@ namespace MWGui
drawItems(); drawItems();
// update selected weapon icon notifyContentChanged();
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); }
MWWorld::ContainerStoreIterator weaponSlot = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); else
if (weaponSlot == invStore.end()) {
mWindowManager.unsetSelectedWeapon(); MyGUI::IntPoint mousePos = MyGUI::InputManager::getInstance ().getLastPressedPosition (MyGUI::MouseButton::Left);
else MyGUI::IntPoint relPos = mousePos - mAvatar->getAbsolutePosition ();
mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability int realX = int(float(relPos.left) / float(mAvatar->getSize().width) * 512.f );
int realY = int(float(relPos.top) / float(mAvatar->getSize().height) * 1024.f );
MWWorld::Ptr itemSelected = getAvatarSelectedItem (realX, realY);
if (itemSelected.isEmpty ())
return;
for (unsigned int i=0; i < mContainerWidget->getChildCount (); ++i)
{
MyGUI::Widget* w = mContainerWidget->getChildAt (i);
if (*w->getUserData<MWWorld::Ptr>() == itemSelected)
{
onSelectedItem(w);
return;
}
}
} }
} }
MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y)
{
int slot = mPreview.getSlotSelected (x, y);
if (slot == -1)
return MWWorld::Ptr();
MWWorld::Ptr player = mPtr;
MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player);
if (invStore.getSlot(slot) != invStore.end())
return *invStore.getSlot (slot);
else
return MWWorld::Ptr();
}
std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems() std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems()
{ {
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
@ -265,6 +308,12 @@ namespace MWGui
mWindowManager.unsetSelectedWeapon(); mWindowManager.unsetSelectedWeapon();
else else
mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability
MyGUI::IntSize size = mAvatar->getSize();
mPreview.update (size.width, size.height);
mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024)));
mAvatarImage->setImageTexture("CharacterPreview");
} }
void InventoryWindow::pickUpObject (MWWorld::Ptr object) void InventoryWindow::pickUpObject (MWWorld::Ptr object)
@ -329,4 +378,9 @@ namespace MWGui
text->setCaption(getCountString(count)); text->setCaption(getCountString(count));
mDragAndDrop->mDraggedFrom = this; mDragAndDrop->mDraggedFrom = this;
} }
MyGUI::IntCoord InventoryWindow::getAvatarScreenCoord ()
{
return mAvatar->getAbsoluteCoord ();
}
} }

@ -1,6 +1,8 @@
#ifndef MGUI_Inventory_H #ifndef MGUI_Inventory_H
#define MGUI_Inventory_H #define MGUI_Inventory_H
#include "../mwrender/characterpreview.hpp"
#include "container.hpp" #include "container.hpp"
#include "window_pinnable_base.hpp" #include "window_pinnable_base.hpp"
@ -22,8 +24,13 @@ namespace MWGui
int getPlayerGold(); int getPlayerGold();
MyGUI::IntCoord getAvatarScreenCoord();
MWWorld::Ptr getAvatarSelectedItem(int x, int y);
protected: protected:
MyGUI::Widget* mAvatar; MyGUI::Widget* mAvatar;
MyGUI::ImageBox* mAvatarImage;
MyGUI::TextBox* mArmorRating; MyGUI::TextBox* mArmorRating;
MyGUI::ProgressBar* mEncumbranceBar; MyGUI::ProgressBar* mEncumbranceBar;
MyGUI::TextBox* mEncumbranceText; MyGUI::TextBox* mEncumbranceText;
@ -37,6 +44,11 @@ namespace MWGui
MyGUI::Button* mFilterMagic; MyGUI::Button* mFilterMagic;
MyGUI::Button* mFilterMisc; MyGUI::Button* mFilterMisc;
int mLastXSize;
int mLastYSize;
MWRender::InventoryPreview mPreview;
bool mTrading; bool mTrading;
void onWindowResize(MyGUI::Window* _sender); void onWindowResize(MyGUI::Window* _sender);

@ -25,15 +25,18 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
, mHairIndex(0) , mHairIndex(0)
, mFaceCount(10) , mFaceCount(10)
, mHairCount(14) , mHairCount(14)
, mCurrentAngle(0)
{ {
// Centre dialog // Centre dialog
center(); center();
// These are just demo values, you should replace these with
// real calls from outside the class later.
setText("AppearanceT", mWindowManager.getGameSettingString("sRaceMenu1", "Appearance")); setText("AppearanceT", mWindowManager.getGameSettingString("sRaceMenu1", "Appearance"));
getWidget(mAppearanceBox, "AppearanceBox"); getWidget(mPreviewImage, "PreviewImage");
MWBase::Environment::get().getWorld ()->setupExternalRendering (mPreview);
mPreview.update (0);
mPreviewImage->setImageTexture ("CharacterHeadPreview");
getWidget(mHeadRotate, "HeadRotate"); getWidget(mHeadRotate, "HeadRotate");
mHeadRotate->setScrollRange(50); mHeadRotate->setScrollRange(50);
@ -149,7 +152,10 @@ void RaceDialog::onBackClicked(MyGUI::Widget* _sender)
void RaceDialog::onHeadRotate(MyGUI::ScrollBar*, size_t _position) void RaceDialog::onHeadRotate(MyGUI::ScrollBar*, size_t _position)
{ {
// TODO: Rotate head float angle = (float(_position) / 49.f - 0.5) * 3.14 * 2;
float diff = angle - mCurrentAngle;
mPreview.update (diff);
mCurrentAngle += diff;
} }
void RaceDialog::onSelectPreviousGender(MyGUI::Widget*) void RaceDialog::onSelectPreviousGender(MyGUI::Widget*)

@ -1,11 +1,15 @@
#ifndef MWGUI_RACE_H #ifndef MWGUI_RACE_H
#define MWGUI_RACE_H #define MWGUI_RACE_H
#include <boost/array.hpp>
#include <components/esm_store/store.hpp> #include <components/esm_store/store.hpp>
#include "../mwrender/characterpreview.hpp"
#include "window_base.hpp" #include "window_base.hpp"
#include <boost/array.hpp>
namespace MWGui namespace MWGui
{ {
@ -73,7 +77,7 @@ namespace MWGui
void updateSkills(); void updateSkills();
void updateSpellPowers(); void updateSpellPowers();
MyGUI::CanvasPtr mAppearanceBox; MyGUI::ImageBox* mPreviewImage;
MyGUI::ListBox* mRaceList; MyGUI::ListBox* mRaceList;
MyGUI::ScrollBar* mHeadRotate; MyGUI::ScrollBar* mHeadRotate;
@ -87,6 +91,10 @@ namespace MWGui
int mFaceCount, mHairCount; int mFaceCount, mHairCount;
std::string mCurrentRaceId; std::string mCurrentRaceId;
float mCurrentAngle;
MWRender::RaceSelectionPreview mPreview;
}; };
} }
#endif #endif

@ -14,6 +14,7 @@
#include "map_window.hpp" #include "map_window.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "inventorywindow.hpp"
using namespace MWGui; using namespace MWGui;
using namespace MyGUI; using namespace MyGUI;
@ -162,12 +163,23 @@ void ToolTips::onFrame(float frameDuration)
return; return;
} }
if (type == "ItemPtr") if (type == "ItemPtr")
{ {
mFocusObject = *focus->getUserData<MWWorld::Ptr>(); mFocusObject = *focus->getUserData<MWWorld::Ptr>();
tooltipSize = getToolTipViaPtr(false); tooltipSize = getToolTipViaPtr(false);
} }
else if (type == "AvatarItemSelection")
{
MyGUI::IntCoord avatarPos = mWindowManager->getInventoryWindow ()->getAvatarScreenCoord ();
MyGUI::IntPoint relMousePos = MyGUI::InputManager::getInstance ().getMousePosition () - MyGUI::IntPoint(avatarPos.left, avatarPos.top);
int realX = int(float(relMousePos.left) / float(avatarPos.width) * 512.f );
int realY = int(float(relMousePos.top) / float(avatarPos.height) * 1024.f );
MWWorld::Ptr item = mWindowManager->getInventoryWindow ()->getAvatarSelectedItem (realX, realY);
mFocusObject = item;
if (!mFocusObject.isEmpty ())
tooltipSize = getToolTipViaPtr(false);
}
else if (type == "Spell") else if (type == "Spell")
{ {
ToolTipInfo info; ToolTipInfo info;

@ -3,6 +3,8 @@
#include <OgreSceneNode.h> #include <OgreSceneNode.h>
#include <OgreSceneManager.h> #include <OgreSceneManager.h>
#include "renderconst.hpp"
using namespace Ogre; using namespace Ogre;
using namespace MWRender; using namespace MWRender;
@ -23,7 +25,7 @@ void Actors::setMwRoot(Ogre::SceneNode* root){
void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv){ void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv){
insertBegin(ptr, true, true); insertBegin(ptr, true, true);
NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mRend, inv); NpcAnimation* anim = new MWRender::NpcAnimation(ptr, ptr.getRefData ().getBaseNode (), inv, RV_Actors);
mAllActors[ptr] = anim; mAllActors[ptr] = anim;
} }
@ -68,7 +70,7 @@ void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){
void Actors::insertCreature (const MWWorld::Ptr& ptr){ void Actors::insertCreature (const MWWorld::Ptr& ptr){
insertBegin(ptr, true, true); insertBegin(ptr, true, true);
CreatureAnimation* anim = new MWRender::CreatureAnimation(ptr, mRend); CreatureAnimation* anim = new MWRender::CreatureAnimation(ptr);
//mAllActors.insert(std::pair<MWWorld::Ptr, Animation*>(ptr,anim)); //mAllActors.insert(std::pair<MWWorld::Ptr, Animation*>(ptr,anim));
delete mAllActors[ptr]; delete mAllActors[ptr];
mAllActors[ptr] = anim; mAllActors[ptr] = anim;

@ -11,9 +11,8 @@
namespace MWRender namespace MWRender
{ {
Animation::Animation(OEngine::Render::OgreRenderer& _rend) Animation::Animation()
: mInsert(NULL) : mInsert(NULL)
, mRend(_rend)
, mTime(0.0f) , mTime(0.0f)
, mSkipFrame(false) , mSkipFrame(false)
{ {

@ -31,7 +31,6 @@ class Animation {
protected: protected:
Ogre::SceneNode* mInsert; Ogre::SceneNode* mInsert;
OEngine::Render::OgreRenderer &mRend;
float mTime; float mTime;
GroupTimes mCurGroup; GroupTimes mCurGroup;
@ -45,7 +44,7 @@ protected:
bool findGroupTimes(const std::string &groupname, GroupTimes *times); bool findGroupTimes(const std::string &groupname, GroupTimes *times);
public: public:
Animation(OEngine::Render::OgreRenderer& _rend); Animation();
virtual ~Animation(); virtual ~Animation();
void playGroup(std::string groupname, int mode, int loops); void playGroup(std::string groupname, int mode, int loops);

@ -0,0 +1,135 @@
#include "characterpreview.hpp"
#include <OgreSceneManager.h>
#include <OgreHardwarePixelBuffer.h>
#include <libs/openengine/ogre/selectionbuffer.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
#include "renderconst.hpp"
#include "npcanimation.hpp"
namespace MWRender
{
CharacterPreview::CharacterPreview(MWWorld::Ptr character, int sizeX, int sizeY, const std::string& name,
Ogre::Vector3 position, Ogre::Vector3 lookAt)
: mSizeX(sizeX)
, mSizeY(sizeY)
, mName(name)
, mPosition(position)
, mLookAt(lookAt)
, mCharacter(character)
{
}
void CharacterPreview::onSetup()
{
}
void CharacterPreview::setup (Ogre::SceneManager *sceneManager)
{
mSceneMgr = sceneManager;
mCamera = mSceneMgr->createCamera (mName);
mCamera->setAspectRatio (float(mSizeX) / float(mSizeY));
mNode = static_cast<Ogre::SceneNode*>(mSceneMgr->getRootSceneNode()->getChild("mwRoot"))->createChildSceneNode ();
mAnimation = new NpcAnimation(mCharacter, mNode,
MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), RV_PlayerPreview);
mNode->setVisible (false);
mCamera->setPosition(mPosition);
mCamera->lookAt(mLookAt);
mCamera->setNearClipDistance (0.01);
mCamera->setFarClipDistance (1000);
mTexture = Ogre::TextureManager::getSingleton().createManual(mName,
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mSizeX, mSizeY, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET);
mRenderTarget = mTexture->getBuffer()->getRenderTarget();
mViewport = mRenderTarget->addViewport(mCamera);
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);
onSetup ();
}
CharacterPreview::~CharacterPreview ()
{
Ogre::TextureManager::getSingleton().remove(mName);
}
// --------------------------------------------------------------------------------------------------
InventoryPreview::InventoryPreview(MWWorld::Ptr character)
: CharacterPreview(character, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 65, -180), Ogre::Vector3(0,65,0))
{
}
InventoryPreview::~InventoryPreview()
{
delete mSelectionBuffer;
}
void InventoryPreview::update(int sizeX, int sizeY)
{
mAnimation->forceUpdate ();
mViewport->setDimensions (0, 0, std::min(1.f, float(sizeX) / float(512)), std::min(1.f, float(sizeY) / float(1024)));
mNode->setOrientation (Ogre::Quaternion::IDENTITY);
mNode->setVisible (true);
mRenderTarget->update();
mSelectionBuffer->update();
mNode->setVisible (false);
}
int InventoryPreview::getSlotSelected (int posX, int posY)
{
return mSelectionBuffer->getSelected (posX, posY);
}
void InventoryPreview::onSetup ()
{
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview);
}
// --------------------------------------------------------------------------------------------------
RaceSelectionPreview::RaceSelectionPreview()
: CharacterPreview(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(),
512, 512, "CharacterHeadPreview", Ogre::Vector3(0, 120, -35), Ogre::Vector3(0,125,0))
{
}
void RaceSelectionPreview::update(float angle)
{
mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL);
mNode->setVisible (true);
mRenderTarget->update();
mNode->setVisible (false);
}
}

@ -0,0 +1,88 @@
#ifndef MWRENDER_CHARACTERPREVIEW_H
#define MWRENDER_CHARACTERPREVIEW_H
#include <OgreRenderTarget.h>
#include <OgreMaterialManager.h>
#include "externalrendering.hpp"
#include "../mwworld/ptr.hpp"
namespace OEngine
{
namespace Render
{
class SelectionBuffer;
}
}
namespace MWRender
{
class NpcAnimation;
class CharacterPreview : public ExternalRendering
{
public:
CharacterPreview(MWWorld::Ptr character, int sizeX, int sizeY, const std::string& name,
Ogre::Vector3 position, Ogre::Vector3 lookAt);
virtual ~CharacterPreview();
virtual void setup (Ogre::SceneManager *sceneManager);
virtual void onSetup();
protected:
Ogre::TexturePtr mTexture;
Ogre::RenderTarget* mRenderTarget;
Ogre::Viewport* mViewport;
Ogre::Camera* mCamera;
Ogre::SceneManager* mSceneMgr;
Ogre::SceneNode* mNode;
Ogre::Vector3 mPosition;
Ogre::Vector3 mLookAt;
MWWorld::Ptr mCharacter;
MWRender::NpcAnimation* mAnimation;
std::string mName;
int mSizeX;
int mSizeY;
};
class InventoryPreview : public CharacterPreview
{
public:
InventoryPreview(MWWorld::Ptr character);
virtual ~InventoryPreview();
virtual void onSetup();
void update(int sizeX, int sizeY);
int getSlotSelected(int posX, int posY);
void setNpcAnimation (NpcAnimation* anim);
private:
OEngine::Render::SelectionBuffer* mSelectionBuffer;
};
class RaceSelectionPreview : public CharacterPreview
{
public:
RaceSelectionPreview();
void update(float angle);
};
}
#endif

@ -16,7 +16,7 @@ CreatureAnimation::~CreatureAnimation()
{ {
} }
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend): Animation(_rend) CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr): Animation()
{ {
mInsert = ptr.getRefData().getBaseNode(); mInsert = ptr.getRefData().getBaseNode();
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>(); MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();

@ -8,13 +8,13 @@
namespace MWRender{ namespace MWRender{
class CreatureAnimation: public Animation{ class CreatureAnimation: public Animation
{
public: public:
virtual ~CreatureAnimation(); virtual ~CreatureAnimation();
CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend); CreatureAnimation(const MWWorld::Ptr& ptr);
virtual void runAnimation(float timepassed); virtual void runAnimation(float timepassed);
}; };
} }
#endif #endif

@ -0,0 +1,23 @@
#ifndef GAME_RENDERING_EXTERNALRENDERING_H
#define GAME_RENDERING_EXTERNALRENDERING_H
namespace Ogre
{
class SceneManager;
}
namespace MWRender
{
/// \brief Base class for out of world rendering
class ExternalRendering
{
public:
virtual void setup (Ogre::SceneManager *sceneManager) = 0;
virtual ~ExternalRendering() {}
};
}
#endif

@ -45,8 +45,8 @@ NpcAnimation::~NpcAnimation()
} }
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv) NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& _inv, int visibilityFlags)
: Animation(_rend), mStateID(-1), mInv(_inv), timeToChange(0), : Animation(), mStateID(-1), mInv(_inv), timeToChange(0), mVisibilityFlags(visibilityFlags),
robe(mInv.end()), helmet(mInv.end()), shirt(mInv.end()), robe(mInv.end()), helmet(mInv.end()), shirt(mInv.end()),
cuirass(mInv.end()), greaves(mInv.end()), cuirass(mInv.end()), greaves(mInv.end()),
leftpauldron(mInv.end()), rightpauldron(mInv.end()), leftpauldron(mInv.end()), rightpauldron(mInv.end()),
@ -84,7 +84,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere
std::cout << " Sex: Male" << " Height: " << race->data.height.male << "\n"; std::cout << " Sex: Male" << " Height: " << race->data.height.male << "\n";
*/ */
mInsert = ptr.getRefData().getBaseNode(); mInsert = node;
assert(mInsert); assert(mInsert);
std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif"); std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif");
@ -94,7 +94,9 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere
{ {
Ogre::Entity *base = mEntityList.mEntities[i]; Ogre::Entity *base = mEntityList.mEntities[i];
base->setVisibilityFlags(RV_Actors); base->getUserObjectBindings ().setUserAny (Ogre::Any(-1));
base->setVisibilityFlags(mVisibilityFlags);
bool transparent = false; bool transparent = false;
for(unsigned int j=0;j < base->getNumSubEntities();++j) for(unsigned int j=0;j < base->getNumSubEntities();++j)
{ {
@ -351,13 +353,16 @@ void NpcAnimation::updateParts()
} }
} }
NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, const std::string &bonename) NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int group, const std::string &bonename)
{ {
NifOgre::EntityList entities = NIFLoader::createEntities(mEntityList.mSkelBase, bonename, NifOgre::EntityList entities = NIFLoader::createEntities(mEntityList.mSkelBase, bonename,
mInsert, mesh); mInsert, mesh);
std::vector<Ogre::Entity*> &parts = entities.mEntities; std::vector<Ogre::Entity*> &parts = entities.mEntities;
for(size_t i = 0;i < parts.size();i++) for(size_t i = 0;i < parts.size();i++)
parts[i]->setVisibilityFlags(RV_Actors); {
parts[i]->setVisibilityFlags(mVisibilityFlags);
parts[i]->getUserObjectBindings ().setUserAny (Ogre::Any(group));
}
return entities; return entities;
} }
@ -480,83 +485,83 @@ bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority,
switch(type) switch(type)
{ {
case ESM::PRT_Head: //0 case ESM::PRT_Head: //0
head = insertBoundedPart(mesh, "Head"); head = insertBoundedPart(mesh, group, "Head");
break; break;
case ESM::PRT_Hair: //1 case ESM::PRT_Hair: //1
hair = insertBoundedPart(mesh, "Head"); hair = insertBoundedPart(mesh, group, "Head");
break; break;
case ESM::PRT_Neck: //2 case ESM::PRT_Neck: //2
neck = insertBoundedPart(mesh, "Neck"); neck = insertBoundedPart(mesh, group, "Neck");
break; break;
case ESM::PRT_Cuirass: //3 case ESM::PRT_Cuirass: //3
chest = insertBoundedPart(mesh, "Chest"); chest = insertBoundedPart(mesh, group, "Chest");
break; break;
case ESM::PRT_Groin: //4 case ESM::PRT_Groin: //4
groin = insertBoundedPart(mesh, "Groin"); groin = insertBoundedPart(mesh, group, "Groin");
break; break;
case ESM::PRT_Skirt: //5 case ESM::PRT_Skirt: //5
skirt = insertBoundedPart(mesh, "Groin"); skirt = insertBoundedPart(mesh, group, "Groin");
break; break;
case ESM::PRT_RHand: //6 case ESM::PRT_RHand: //6
rHand = insertBoundedPart(mesh, "Right Hand"); rHand = insertBoundedPart(mesh, group, "Right Hand");
break; break;
case ESM::PRT_LHand: //7 case ESM::PRT_LHand: //7
lHand = insertBoundedPart(mesh, "Left Hand"); lHand = insertBoundedPart(mesh, group, "Left Hand");
break; break;
case ESM::PRT_RWrist: //8 case ESM::PRT_RWrist: //8
rWrist = insertBoundedPart(mesh, "Right Wrist"); rWrist = insertBoundedPart(mesh, group, "Right Wrist");
break; break;
case ESM::PRT_LWrist: //9 case ESM::PRT_LWrist: //9
lWrist = insertBoundedPart(mesh, "Left Wrist"); lWrist = insertBoundedPart(mesh, group, "Left Wrist");
break; break;
case ESM::PRT_Shield: //10 case ESM::PRT_Shield: //10
break; break;
case ESM::PRT_RForearm: //11 case ESM::PRT_RForearm: //11
rForearm = insertBoundedPart(mesh, "Right Forearm"); rForearm = insertBoundedPart(mesh, group, "Right Forearm");
break; break;
case ESM::PRT_LForearm: //12 case ESM::PRT_LForearm: //12
lForearm = insertBoundedPart(mesh, "Left Forearm"); lForearm = insertBoundedPart(mesh, group, "Left Forearm");
break; break;
case ESM::PRT_RUpperarm: //13 case ESM::PRT_RUpperarm: //13
rupperArm = insertBoundedPart(mesh, "Right Upper Arm"); rupperArm = insertBoundedPart(mesh, group, "Right Upper Arm");
break; break;
case ESM::PRT_LUpperarm: //14 case ESM::PRT_LUpperarm: //14
lupperArm = insertBoundedPart(mesh, "Left Upper Arm"); lupperArm = insertBoundedPart(mesh, group, "Left Upper Arm");
break; break;
case ESM::PRT_RFoot: //15 case ESM::PRT_RFoot: //15
rfoot = insertBoundedPart(mesh, "Right Foot"); rfoot = insertBoundedPart(mesh, group, "Right Foot");
break; break;
case ESM::PRT_LFoot: //16 case ESM::PRT_LFoot: //16
lfoot = insertBoundedPart(mesh, "Left Foot"); lfoot = insertBoundedPart(mesh, group, "Left Foot");
break; break;
case ESM::PRT_RAnkle: //17 case ESM::PRT_RAnkle: //17
rAnkle = insertBoundedPart(mesh, "Right Ankle"); rAnkle = insertBoundedPart(mesh, group, "Right Ankle");
break; break;
case ESM::PRT_LAnkle: //18 case ESM::PRT_LAnkle: //18
lAnkle = insertBoundedPart(mesh, "Left Ankle"); lAnkle = insertBoundedPart(mesh, group, "Left Ankle");
break; break;
case ESM::PRT_RKnee: //19 case ESM::PRT_RKnee: //19
rKnee = insertBoundedPart(mesh, "Right Knee"); rKnee = insertBoundedPart(mesh, group, "Right Knee");
break; break;
case ESM::PRT_LKnee: //20 case ESM::PRT_LKnee: //20
lKnee = insertBoundedPart(mesh, "Left Knee"); lKnee = insertBoundedPart(mesh, group, "Left Knee");
break; break;
case ESM::PRT_RLeg: //21 case ESM::PRT_RLeg: //21
rUpperLeg = insertBoundedPart(mesh, "Right Upper Leg"); rUpperLeg = insertBoundedPart(mesh, group, "Right Upper Leg");
break; break;
case ESM::PRT_LLeg: //22 case ESM::PRT_LLeg: //22
lUpperLeg = insertBoundedPart(mesh, "Left Upper Leg"); lUpperLeg = insertBoundedPart(mesh, group, "Left Upper Leg");
break; break;
case ESM::PRT_RPauldron: //23 case ESM::PRT_RPauldron: //23
rclavicle = insertBoundedPart(mesh , "Right Clavicle"); rclavicle = insertBoundedPart(mesh , group, "Right Clavicle");
break; break;
case ESM::PRT_LPauldron: //24 case ESM::PRT_LPauldron: //24
lclavicle = insertBoundedPart(mesh, "Left Clavicle"); lclavicle = insertBoundedPart(mesh, group, "Left Clavicle");
break; break;
case ESM::PRT_Weapon: //25 case ESM::PRT_Weapon: //25
break; break;
case ESM::PRT_Tail: //26 case ESM::PRT_Tail: //26
tail = insertBoundedPart(mesh, "Tail"); tail = insertBoundedPart(mesh, group, "Tail");
break; break;
} }
return true; return true;
@ -575,10 +580,15 @@ void NpcAnimation::addPartGroup(int group, int priority, std::vector<ESM::PartRe
bodypart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search(part.male); bodypart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search(part.male);
if(bodypart) if(bodypart)
addOrReplaceIndividualPart(part.part, group,priority,"meshes\\" + bodypart->model); addOrReplaceIndividualPart(part.part, group, priority,"meshes\\" + bodypart->model);
else else
reserveIndividualPart(part.part, group, priority); reserveIndividualPart(part.part, group, priority);
} }
} }
void NpcAnimation::forceUpdate ()
{
updateParts();
}
} }

@ -65,10 +65,13 @@ private:
MWWorld::ContainerStoreIterator rightglove; MWWorld::ContainerStoreIterator rightglove;
MWWorld::ContainerStoreIterator skirtiter; MWWorld::ContainerStoreIterator skirtiter;
int mVisibilityFlags;
public: public:
NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node,
MWWorld::InventoryStore& _inv, int visibilityFlags);
virtual ~NpcAnimation(); virtual ~NpcAnimation();
NifOgre::EntityList insertBoundedPart(const std::string &mesh, const std::string &bonename); NifOgre::EntityList insertBoundedPart(const std::string &mesh, int group, const std::string &bonename);
virtual void runAnimation(float timepassed); virtual void runAnimation(float timepassed);
void updateParts(); void updateParts();
void removeEntities(NifOgre::EntityList &entities); void removeEntities(NifOgre::EntityList &entities);
@ -78,6 +81,8 @@ public:
bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh);
void removePartGroup(int group); void removePartGroup(int group);
void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts); void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts);
void forceUpdate();
}; };
} }

@ -35,6 +35,11 @@ namespace MWRender
mPreviewCam.yaw = 0.f; mPreviewCam.yaw = 0.f;
mPreviewCam.offset = 400.f; mPreviewCam.offset = 400.f;
} }
Player::~Player()
{
delete mAnimation;
}
bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
{ {

@ -63,6 +63,7 @@ namespace MWRender
public: public:
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); Player (Ogre::Camera *camera, Ogre::SceneNode* mNode);
~Player();
/// Set where the player is looking at. Uses Morrowind (euler) angles /// Set where the player is looking at. Uses Morrowind (euler) angles
/// \param rot Rotation angles in radians /// \param rot Rotation angles in radians

@ -41,7 +41,7 @@ enum VisibilityFlags
// Water // Water
RV_Water = 8, RV_Water = 8,
// Actors (player, npcs, creatures) // Actors (npcs, creatures)
RV_Actors = 16, RV_Actors = 16,
// Misc objects (containers, dynamic objects) // Misc objects (containers, dynamic objects)
@ -54,6 +54,8 @@ enum VisibilityFlags
RV_OcclusionQuery = 256, RV_OcclusionQuery = 256,
RV_PlayerPreview = 512,
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water
/// \todo markers (normally hidden) /// \todo markers (normally hidden)

@ -34,6 +34,7 @@
#include "water.hpp" #include "water.hpp"
#include "compositors.hpp" #include "compositors.hpp"
#include "npcanimation.hpp" #include "npcanimation.hpp"
#include "externalrendering.hpp"
using namespace MWRender; using namespace MWRender;
using namespace Ogre; using namespace Ogre;
@ -94,7 +95,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
if (filter == "anisotropic") tfo = TFO_ANISOTROPIC; if (filter == "anisotropic") tfo = TFO_ANISOTROPIC;
else if (filter == "trilinear") tfo = TFO_TRILINEAR; else if (filter == "trilinear") tfo = TFO_TRILINEAR;
else if (filter == "bilinear") tfo = TFO_BILINEAR; else if (filter == "bilinear") tfo = TFO_BILINEAR;
else if (filter == "none") tfo = TFO_NONE; else /*if (filter == "none")*/ tfo = TFO_NONE;
MaterialManager::getSingleton().setDefaultTextureFiltering(tfo); MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 ); MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
@ -137,7 +138,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
// Morrowind uses, and it automagically makes everything work as it // Morrowind uses, and it automagically makes everything work as it
// should. // should.
SceneNode *rt = mRendering.getScene()->getRootSceneNode(); SceneNode *rt = mRendering.getScene()->getRootSceneNode();
mMwRoot = rt->createChildSceneNode(); mMwRoot = rt->createChildSceneNode("mwRoot");
mMwRoot->pitch(Degree(-90)); mMwRoot->pitch(Degree(-90));
mObjects.setMwRoot(mMwRoot); mObjects.setMwRoot(mMwRoot);
@ -723,7 +724,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
if (filter == "anisotropic") tfo = TFO_ANISOTROPIC; if (filter == "anisotropic") tfo = TFO_ANISOTROPIC;
else if (filter == "trilinear") tfo = TFO_TRILINEAR; else if (filter == "trilinear") tfo = TFO_TRILINEAR;
else if (filter == "bilinear") tfo = TFO_BILINEAR; else if (filter == "bilinear") tfo = TFO_BILINEAR;
else if (filter == "none") tfo = TFO_NONE; else /*if (filter == "none")*/ tfo = TFO_NONE;
MaterialManager::getSingleton().setDefaultTextureFiltering(tfo); MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 ); MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
@ -858,9 +859,8 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
{ {
MWRender::NpcAnimation *anim = MWRender::NpcAnimation *anim =
new MWRender::NpcAnimation( new MWRender::NpcAnimation(
ptr, ptr, ptr.getRefData ().getBaseNode (),
mRendering, MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors
MWWorld::Class::get(ptr).getInventoryStore(ptr)
); );
mPlayer->setAnimation(anim); mPlayer->setAnimation(anim);
} }
@ -882,4 +882,9 @@ bool RenderingManager::isPositionExplored (float nX, float nY, int x, int y, boo
return mLocalMap->isPositionExplored(nX, nY, x, y, interior); return mLocalMap->isPositionExplored(nX, nY, x, y, interior);
} }
void RenderingManager::setupExternalRendering (MWRender::ExternalRendering& rendering)
{
rendering.setup (mRendering.getScene());
}
} // namespace } // namespace

@ -43,6 +43,7 @@ namespace MWRender
class LocalMap; class LocalMap;
class Water; class Water;
class Compositors; class Compositors;
class ExternalRendering;
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener {
@ -185,12 +186,14 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
static bool waterShaderSupported(); static bool waterShaderSupported();
virtual void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y); void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y);
///< see MWRender::LocalMap::getInteriorMapPosition ///< see MWRender::LocalMap::getInteriorMapPosition
virtual bool isPositionExplored (float nX, float nY, int x, int y, bool interior); bool isPositionExplored (float nX, float nY, int x, int y, bool interior);
///< see MWRender::LocalMap::isPositionExplored ///< see MWRender::LocalMap::isPositionExplored
void setupExternalRendering (MWRender::ExternalRendering& rendering);
protected: protected:
virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowResized(Ogre::RenderWindow* rw);
virtual void windowClosed(Ogre::RenderWindow* rw); virtual void windowClosed(Ogre::RenderWindow* rw);

@ -1222,4 +1222,9 @@ namespace MWWorld
{ {
mRendering->renderPlayer(mPlayer->getPlayer()); mRendering->renderPlayer(mPlayer->getPlayer());
} }
void World::setupExternalRendering (MWRender::ExternalRendering& rendering)
{
mRendering->setupExternalRendering (rendering);
}
} }

@ -307,6 +307,8 @@ namespace MWWorld
} }
virtual void renderPlayer(); virtual void renderPlayer();
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
}; };
} }

2
extern/shiny vendored

@ -1 +1 @@
Subproject commit 7168415233905de2864eec71ed4312cb8f83059b Subproject commit 4750676ac46a7aaa86bca53dc68c5a1ba11f3bc1

@ -40,7 +40,9 @@ set(MATERIAL_FILES
water.mat water.mat
water.shader water.shader
water.shaderset water.shaderset
selection.mat
selection.shader
selection.shaderset
) )
copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/water "${OpenMW_BINARY_DIR}/resources/water/" "${WATER_FILES}") copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/water "${OpenMW_BINARY_DIR}/resources/water/" "${WATER_FILES}")

@ -0,0 +1,8 @@
material SelectionColour
{
pass
{
vertex_program selection_vertex
fragment_program selection_fragment
}
}

@ -0,0 +1,24 @@
#include "core.h"
#ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
SH_START_PROGRAM
{
shOutputPosition = shMatrixMult(wvp, shInputPosition);
}
#else
SH_BEGIN_PROGRAM
shUniform(float4, colour) @shAutoConstant(colour, custom, 1)
SH_START_PROGRAM
{
shOutputColour(0) = colour;
//shOutputColour(0) = float4(1,0,0,1);
}
#endif

@ -0,0 +1,15 @@
shader_set selection_vertex
{
source selection.shader
type vertex
profiles_cg vs_2_0 arbvp1
profiles_hlsl vs_2_0
}
shader_set selection_fragment
{
source selection.shader
type fragment
profiles_cg ps_2_x ps_2_0 ps arbfp1
profiles_hlsl ps_2_0
}

@ -8,11 +8,13 @@
<Property key="Caption" value="Appearance"/> <Property key="Caption" value="Appearance"/>
<Property key="TextAlign" value="ALIGN_LEFT ALIGN_TOP"/> <Property key="TextAlign" value="ALIGN_LEFT ALIGN_TOP"/>
</Widget> </Widget>
<Widget type="Canvas" skin="MW_Box" position="8 39 241 230" name="AppearanceBox"/> <Widget type="Widget" skin="MW_Box" position="8 39 241 230">
<Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Stretch" name="PreviewImage"/>
</Widget>
<!-- Sliders --> <!-- Sliders -->
<!-- Rotation of head --> <!-- Rotation of head -->
<Widget type="HScroll" skin="MW_HScroll" position="8 276 241 14" name="HeadRotate"/> <Widget type="ScrollBar" skin="MW_HScroll" position="8 276 241 14" name="HeadRotate"/>
<!-- Gender choice --> <!-- Gender choice -->
<Widget type="Button" skin="MW_ScrollLeft" position="8 298 14 14" name="PrevGenderButton"/> <Widget type="Button" skin="MW_ScrollLeft" position="8 298 14 14" name="PrevGenderButton"/>

@ -12,8 +12,13 @@
<!-- Avatar --> <!-- Avatar -->
<Widget type="Widget" skin="MW_Box" position="8 38 212 185" name="Avatar" align="Left Top Stretch"> <Widget type="Widget" skin="MW_Box" position="8 38 212 185" name="Avatar" align="Left Top Stretch">
<UserString key="ToolTipType" value="AvatarItemSelection"/>
<Widget type="ImageBox" skin="ImageBox" position="0 0 212 185" align="Stretch" name="AvatarImage">
<Property key="NeedMouse" value="false"/>
</Widget>
<Widget type="TextBox" skin="ProgressText" position="0 150 212 24" align="HCenter Bottom" name="ArmorRating"> <Widget type="TextBox" skin="ProgressText" position="0 150 212 24" align="HCenter Bottom" name="ArmorRating">
<Property key="Caption" value="Armor Rating"/> <Property key="Caption" value="Armor Rating"/>
<Property key="NeedMouse" value="false"/>
</Widget> </Widget>
</Widget> </Widget>

@ -188,7 +188,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings&
mWindow = mRoot->createRenderWindow(title, settings.window_x, settings.window_y, settings.fullscreen, &params); mWindow = mRoot->createRenderWindow(title, settings.window_x, settings.window_y, settings.fullscreen, &params);
// create the semi-transparent black background texture used by the GUI. // create the semi-transparent black background texture used by the GUI.
// has to be created in code with TU_DYNAMIC_WRITE_ONLY_DISCARDABLE param // has to be created in code with TU_DYNAMIC_WRITE_ONLY param
// so that it can be modified at runtime. // so that it can be modified at runtime.
Ogre::TextureManager::getSingleton().createManual( Ogre::TextureManager::getSingleton().createManual(
"transparent.png", "transparent.png",
@ -197,7 +197,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings&
1, 1, 1, 1,
0, 0,
Ogre::PF_A8R8G8B8, Ogre::PF_A8R8G8B8,
Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); Ogre::TU_DYNAMIC_WRITE_ONLY);
} }
void OgreRenderer::createScene(const std::string& camName, float fov, float nearClip) void OgreRenderer::createScene(const std::string& camName, float fov, float nearClip)

@ -0,0 +1,122 @@
#include "selectionbuffer.hpp"
#include <OgreHardwarePixelBuffer.h>
#include <OgreRenderTexture.h>
#include <OgreSubEntity.h>
#include <OgreEntity.h>
#include <extern/shiny/Main/Factory.hpp>
namespace OEngine
{
namespace Render
{
SelectionBuffer::SelectionBuffer(Ogre::Camera *camera, int sizeX, int sizeY, int visibilityFlags)
{
mTexture = Ogre::TextureManager::getSingleton().createManual("SelectionBuffer",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, sizeX, sizeY, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
mRenderTarget = mTexture->getBuffer()->getRenderTarget();
Ogre::Viewport* vp = mRenderTarget->addViewport(camera);
vp->setOverlaysEnabled(false);
vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0));
vp->setShadowsEnabled(false);
vp->setMaterialScheme("selectionbuffer");
vp->setVisibilityMask (visibilityFlags);
mRenderTarget->setActive(true);
mRenderTarget->setAutoUpdated (false);
mCurrentColour = Ogre::ColourValue(0.3, 0.3, 0.3);
}
SelectionBuffer::~SelectionBuffer()
{
Ogre::TextureManager::getSingleton ().remove("SelectionBuffer");
}
void SelectionBuffer::update ()
{
Ogre::MaterialManager::getSingleton ().addListener (this);
mRenderTarget->update();
Ogre::MaterialManager::getSingleton ().removeListener (this);
mTexture->convertToImage(mBuffer);
}
int SelectionBuffer::getSelected(int xPos, int yPos)
{
Ogre::ColourValue clr = mBuffer.getColourAt (xPos, yPos, 0);
clr.a = 1;
if (mColourMap.find(clr) != mColourMap.end())
return mColourMap[clr];
else
return -1; // nothing selected
}
Ogre::Technique* SelectionBuffer::handleSchemeNotFound (
unsigned short schemeIndex, const Ogre::String &schemeName, Ogre::Material *originalMaterial,
unsigned short lodIndex, const Ogre::Renderable *rend)
{
if (schemeName == "selectionbuffer")
{
sh::Factory::getInstance ()._ensureMaterial ("SelectionColour", "Default");
Ogre::MaterialPtr m = Ogre::MaterialManager::getSingleton ().getByName("SelectionColour");
if(typeid(*rend) == typeid(Ogre::SubEntity))
{
const Ogre::SubEntity *subEntity = static_cast<const Ogre::SubEntity *>(rend);
int id = Ogre::any_cast<int>(subEntity->getParent ()->getUserObjectBindings().getUserAny());
bool found = false;
Ogre::ColourValue colour;
for (std::map<Ogre::ColourValue, int>::iterator it = mColourMap.begin(); it != mColourMap.end(); ++it)
{
if (it->second == id)
{
found = true;
colour = it->first;
}
}
if (!found)
{
getNextColour();
const_cast<Ogre::SubEntity *>(subEntity)->setCustomParameter(1, Ogre::Vector4(mCurrentColour.r, mCurrentColour.g, mCurrentColour.b, 1.0));
mColourMap[mCurrentColour] = id;
}
else
{
const_cast<Ogre::SubEntity *>(subEntity)->setCustomParameter(1, Ogre::Vector4(colour.r, colour.g, colour.b, 1.0));
}
assert(m->getTechnique(1));
return m->getTechnique(1);
}
else
throw std::runtime_error("selectionbuffer only works with entities");
}
return NULL;
}
void SelectionBuffer::getNextColour ()
{
Ogre::ARGB color = (float(rand()) / float(RAND_MAX)) * std::numeric_limits<Ogre::uint32>::max();
if (mCurrentColour.getAsARGB () == color)
{
getNextColour();
return;
}
mCurrentColour.setAsARGB(color);
mCurrentColour.a = 1;
}
}
}

@ -0,0 +1,54 @@
#ifndef OENGINE_SELECTIONBUFFER_H
#define OENGINE_SELECTIONBUFFER_H
#include <OgreTexture.h>
#include <OgreRenderTarget.h>
#include <OgreMaterialManager.h>
namespace OEngine
{
namespace Render
{
struct cmp_ColourValue
{
bool operator()(const Ogre::ColourValue &a, const Ogre::ColourValue &b) const
{
return a.getAsBGRA() < b.getAsBGRA();
}
};
class SelectionBuffer : public Ogre::MaterialManager::Listener
{
public:
SelectionBuffer(Ogre::Camera* camera, int sizeX, int sizeY, int visibilityFlags);
virtual ~SelectionBuffer();
int getSelected(int xPos, int yPos);
///< @return ID of the selected object
void update();
virtual Ogre::Technique* handleSchemeNotFound (
unsigned short schemeIndex, const Ogre::String &schemeName, Ogre::Material *originalMaterial,
unsigned short lodIndex, const Ogre::Renderable *rend);
private:
Ogre::TexturePtr mTexture;
Ogre::RenderTexture* mRenderTarget;
Ogre::Image mBuffer;
std::map<Ogre::ColourValue, int, cmp_ColourValue> mColourMap;
Ogre::ColourValue mCurrentColour;
void getNextColour();
};
}
}
#endif
Loading…
Cancel
Save