From 4f3eb3c34a1aae95d48c2aee0596d6778e29e60c Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 13 Sep 2012 00:54:32 +0200 Subject: [PATCH 01/11] character preview WIP --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/world.hpp | 2 + apps/openmw/mwgui/inventorywindow.cpp | 21 +++++---- apps/openmw/mwgui/inventorywindow.hpp | 1 + apps/openmw/mwrender/characterpreview.cpp | 52 ++++++++++++++++++++++ apps/openmw/mwrender/characterpreview.hpp | 29 ++++++++++++ apps/openmw/mwrender/npcanimation.cpp | 9 ++-- apps/openmw/mwrender/npcanimation.hpp | 4 +- apps/openmw/mwrender/renderconst.hpp | 4 +- apps/openmw/mwrender/renderingmanager.cpp | 11 ++++- apps/openmw/mwrender/renderingmanager.hpp | 5 +++ apps/openmw/mwrender/shadows.cpp | 2 +- apps/openmw/mwrender/water.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 5 +++ apps/openmw/mwworld/worldimp.hpp | 2 + files/mygui/openmw_inventory_window.layout | 8 +++- 16 files changed, 139 insertions(+), 20 deletions(-) create mode 100644 apps/openmw/mwrender/characterpreview.cpp create mode 100644 apps/openmw/mwrender/characterpreview.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index cffbc60c7..047cea760 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -16,7 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows - compositors + compositors characterpreview ) add_openmw_dir (mwinput diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 19405fb7a..5ecd1b1b9 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -271,6 +271,8 @@ namespace MWBase virtual void togglePlayerLooking(bool enable) = 0; virtual void renderPlayer() = 0; + + virtual void updateCharacterPreview(int sizeX, int sizeY) = 0; }; } diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 6dc19944f..cf23ecd8f 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -48,6 +48,7 @@ namespace MWGui static_cast(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); getWidget(mAvatar, "Avatar"); + getWidget(mAvatarImage, "AvatarImage"); getWidget(mEncumbranceBar, "EncumbranceBar"); getWidget(mEncumbranceText, "EncumbranceBarT"); getWidget(mFilterAll, "AllButton"); @@ -100,6 +101,13 @@ namespace MWGui _sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15, _sender->getSize().height-44 ); drawItems(); + + MyGUI::IntSize size = mAvatarImage->getSize(); + + std::cout << "dims " << size.width << " " << size.height << std::endl; + MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); + + mAvatarImage->setImageCoord (MyGUI::IntCoord(0,0,size.width, size.height)); } void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender) @@ -171,14 +179,7 @@ namespace MWGui drawItems(); - // update selected weapon icon - MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); - MWWorld::ContainerStoreIterator weaponSlot = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if (weaponSlot == invStore.end()) - mWindowManager.unsetSelectedWeapon(); - else - mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability - + notifyContentChanged(); } } @@ -265,6 +266,10 @@ namespace MWGui mWindowManager.unsetSelectedWeapon(); else mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability + + MyGUI::IntSize size = mAvatarImage->getSize(); + mAvatarImage->setImageCoord (MyGUI::IntCoord(0,0,size.width, size.height)); + MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); } void InventoryWindow::pickUpObject (MWWorld::Ptr object) diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index fbdb79977..4a385dd71 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -24,6 +24,7 @@ namespace MWGui protected: MyGUI::Widget* mAvatar; + MyGUI::ImageBox* mAvatarImage; MyGUI::TextBox* mArmorRating; MyGUI::ProgressBar* mEncumbranceBar; MyGUI::TextBox* mEncumbranceText; diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp new file mode 100644 index 000000000..3d3f0a58d --- /dev/null +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -0,0 +1,52 @@ +#include "characterpreview.hpp" + + +#include +#include + + +#include "renderconst.hpp" + +namespace MWRender +{ + + CharacterPreview::CharacterPreview(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *node) + : mSceneMgr(sceneMgr) + { + mCamera = mSceneMgr->createCamera ("CharacterPreviewCamera"); + mCamera->setAspectRatio (0.5); + + mNode = node->createChildSceneNode (); + mNode->attachObject (mCamera); + + mNode->setPosition(0, 185, 70); + mNode->roll(Ogre::Degree(180)); + + mNode->pitch(Ogre::Degree(90)); + + mTexture = Ogre::TextureManager::getSingleton().createManual("CharacterPreview", + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 1024, 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_Player); + mRenderTarget->setActive(true); + mRenderTarget->setAutoUpdated (false); + } + + void CharacterPreview::update(int sizeX, int sizeY) + { + bool wasVisible = mNode->getParentSceneNode()->getAttachedObject(0)->getVisible (); + mNode->getParentSceneNode()->setVisible(true, false); + //mViewport->setDimensions (0, 0, float(sizeX) / float(512), float(sizeY) / float(1024)); + + mRenderTarget->update(); + + mNode->getParentSceneNode()->setVisible(wasVisible, false); + } + +} diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp new file mode 100644 index 000000000..e15d6c359 --- /dev/null +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -0,0 +1,29 @@ +#ifndef MWRENDER_CHARACTERPREVIEW_H +#define MWRENDER_CHARACTERPREVIEW_H + +#include + +namespace MWRender +{ + + class CharacterPreview + { + public: + CharacterPreview(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* node); + + void update(int sizeX, int sizeY); + + private: + Ogre::TexturePtr mTexture; + Ogre::RenderTarget* mRenderTarget; + Ogre::Viewport* mViewport; + + Ogre::Camera* mCamera; + + Ogre::SceneManager* mSceneMgr; + Ogre::SceneNode* mNode; + }; + +} + +#endif diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 4f98aebc4..392a79c96 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -45,7 +45,7 @@ NpcAnimation::~NpcAnimation() } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv) +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv, bool player) : Animation(_rend), mStateID(-1), mInv(_inv), timeToChange(0), robe(mInv.end()), helmet(mInv.end()), shirt(mInv.end()), cuirass(mInv.end()), greaves(mInv.end()), @@ -53,6 +53,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere boots(mInv.end()), leftglove(mInv.end()), rightglove(mInv.end()), skirtiter(mInv.end()), pants(mInv.end()) + , mIsPlayer(player) { MWWorld::LiveCellRef *ref = ptr.get(); @@ -94,7 +95,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere { Ogre::Entity *base = mEntityList.mEntities[i]; - base->setVisibilityFlags(RV_Actors); + base->setVisibilityFlags(mIsPlayer ? RV_Player : RV_Actors); bool transparent = false; for(unsigned int j=0;j < base->getNumSubEntities();++j) { @@ -357,13 +358,13 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, con mInsert, mesh); std::vector &parts = entities.mEntities; for(size_t i = 0;i < parts.size();i++) - parts[i]->setVisibilityFlags(RV_Actors); + parts[i]->setVisibilityFlags(mIsPlayer ? RV_Player : RV_Actors); return entities; } void NpcAnimation::runAnimation(float timepassed) { - if(timeToChange > .2) + //if(timeToChange > .2) { timeToChange = 0; updateParts(); diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index d4b2a5b9e..945dd210e 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -18,6 +18,8 @@ private: int mPartslots[27]; //Each part slot is taken by clothing, armor, or is empty int mPartPriorities[27]; + bool mIsPlayer; + //Bounded Parts NifOgre::EntityList lclavicle; NifOgre::EntityList rclavicle; @@ -66,7 +68,7 @@ private: MWWorld::ContainerStoreIterator skirtiter; public: - NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); + NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv, bool player=false); virtual ~NpcAnimation(); NifOgre::EntityList insertBoundedPart(const std::string &mesh, const std::string &bonename); virtual void runAnimation(float timepassed); diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index 9f57833bb..194ca9da6 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -41,7 +41,7 @@ enum VisibilityFlags // Water RV_Water = 8, - // Actors (player, npcs, creatures) + // Actors (npcs, creatures) RV_Actors = 16, // Misc objects (containers, dynamic objects) @@ -54,6 +54,8 @@ enum VisibilityFlags RV_OcclusionQuery = 256, + RV_Player = 512, + RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water /// \todo markers (normally hidden) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 70d7de552..acb587d03 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -34,6 +34,7 @@ #include "water.hpp" #include "compositors.hpp" #include "npcanimation.hpp" +#include "characterpreview.hpp" using namespace MWRender; using namespace Ogre; @@ -159,6 +160,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mDebugging = new Debugging(mMwRoot, engine); mLocalMap = new MWRender::LocalMap(&mRendering, this); + mCharacterPreview = new CharacterPreview(mRendering.getScene (), playerNode); + setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); } @@ -175,6 +178,7 @@ RenderingManager::~RenderingManager () delete mOcclusionQuery; delete mCompositors; delete mWater; + delete mCharacterPreview; } MWRender::SkyManager* RenderingManager::getSkyManager() @@ -860,7 +864,7 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) new MWRender::NpcAnimation( ptr, mRendering, - MWWorld::Class::get(ptr).getInventoryStore(ptr) + MWWorld::Class::get(ptr).getInventoryStore(ptr), true ); mPlayer->setAnimation(anim); } @@ -882,4 +886,9 @@ bool RenderingManager::isPositionExplored (float nX, float nY, int x, int y, boo return mLocalMap->isPositionExplored(nX, nY, x, y, interior); } +void RenderingManager::updateCharacterPreview (int sizeX, int sizeY) +{ + mCharacterPreview->update(sizeX, sizeY); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index e5be238bd..fe79c9400 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -43,6 +43,7 @@ namespace MWRender class LocalMap; class Water; class Compositors; + class CharacterPreview; class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { @@ -191,6 +192,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList virtual bool isPositionExplored (float nX, float nY, int x, int y, bool interior); ///< see MWRender::LocalMap::isPositionExplored + void updateCharacterPreview(int sizeX, int sizeY); + protected: virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowClosed(Ogre::RenderWindow* rw); @@ -213,6 +216,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList TerrainManager* mTerrainManager; + CharacterPreview* mCharacterPreview; + MWRender::Water *mWater; OEngine::Render::OgreRenderer &mRendering; diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index 3d9f13243..fc28f1cb9 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -111,7 +111,7 @@ void Shadows::recreate() sh::Factory::getInstance ().setSharedParameter ("shadowFar_fadeStart", sh::makeProperty(shadowFar_fadeStart)); // Set visibility mask for the shadow render textures - int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows") + int visibilityMask = (RV_Actors + RV_Player) * Settings::Manager::getBool("actor shadows", "Shadows") + (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows") + RV_Misc * Settings::Manager::getBool("misc shadows", "Shadows"); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 7100540fc..6a3eeb509 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -332,7 +332,7 @@ void Water::applyVisibilityMask() mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") + RV_Statics * Settings::Manager::getBool("reflect statics", "Water") + RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water") - + RV_Actors * Settings::Manager::getBool("reflect actors", "Water") + + (RV_Actors + RV_Player) * Settings::Manager::getBool("reflect actors", "Water") + RV_Misc * Settings::Manager::getBool("reflect misc", "Water") + RV_Sky; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 869ce94d1..f88f5c320 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1222,4 +1222,9 @@ namespace MWWorld { mRendering->renderPlayer(mPlayer->getPlayer()); } + + void World::updateCharacterPreview (int sizeX, int sizeY) + { + mRendering->updateCharacterPreview(sizeX, sizeY); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 6279343d4..5e8bc697e 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -307,6 +307,8 @@ namespace MWWorld } virtual void renderPlayer(); + + virtual void updateCharacterPreview(int sizeX, int sizeY); }; } diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 1ffabe3b6..b9e14fffa 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -12,8 +12,12 @@ - - + + + + + + From 5155339cb65619ec69be8151f021e4de8054cc17 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 13 Sep 2012 14:56:50 +0200 Subject: [PATCH 02/11] character preview working --- apps/openmw/mwgui/inventorywindow.cpp | 12 ++++++------ apps/openmw/mwrender/characterpreview.cpp | 2 +- files/mygui/openmw_inventory_window.layout | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index cf23ecd8f..9ccf5cfe1 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -102,12 +102,10 @@ namespace MWGui _sender->getSize().height-44 ); drawItems(); - MyGUI::IntSize size = mAvatarImage->getSize(); + MyGUI::IntSize size = mAvatar->getSize(); - std::cout << "dims " << size.width << " " << size.height << std::endl; MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); - - mAvatarImage->setImageCoord (MyGUI::IntCoord(0,0,size.width, size.height)); + mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024))); } void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender) @@ -267,9 +265,11 @@ namespace MWGui else mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability - MyGUI::IntSize size = mAvatarImage->getSize(); - mAvatarImage->setImageCoord (MyGUI::IntCoord(0,0,size.width, size.height)); + MyGUI::IntSize size = mAvatar->getSize(); + MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); + + mAvatarImage->setSize(MyGUI::IntSize(512, 1024)); } void InventoryWindow::pickUpObject (MWWorld::Ptr object) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 3d3f0a58d..fd25aab08 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -42,7 +42,7 @@ namespace MWRender { bool wasVisible = mNode->getParentSceneNode()->getAttachedObject(0)->getVisible (); mNode->getParentSceneNode()->setVisible(true, false); - //mViewport->setDimensions (0, 0, float(sizeX) / float(512), float(sizeY) / float(1024)); + mViewport->setDimensions (0, 0, std::min(1.f, float(sizeX) / float(512)), std::min(1.f, float(sizeY) / float(1024))); mRenderTarget->update(); diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index b9e14fffa..31bf58c34 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -15,9 +15,9 @@ - - - + + + From eef750e6b05b9c8ea8059274d50d650679f0edd5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 13 Sep 2012 19:03:31 +0200 Subject: [PATCH 03/11] race selection preview --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwgui/inventorywindow.cpp | 2 + apps/openmw/mwgui/race.cpp | 15 +++-- apps/openmw/mwgui/race.hpp | 4 +- apps/openmw/mwrender/actors.cpp | 4 +- apps/openmw/mwrender/characterpreview.cpp | 72 +++++++++++++++++----- apps/openmw/mwrender/characterpreview.hpp | 33 ++++++++-- apps/openmw/mwrender/npcanimation.cpp | 16 +++-- apps/openmw/mwrender/npcanimation.hpp | 7 ++- apps/openmw/mwrender/player.cpp | 5 ++ apps/openmw/mwrender/player.hpp | 1 + apps/openmw/mwrender/renderconst.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 26 ++++++-- apps/openmw/mwrender/renderingmanager.hpp | 9 ++- apps/openmw/mwrender/shadows.cpp | 2 +- apps/openmw/mwrender/water.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 5 ++ apps/openmw/mwworld/worldimp.hpp | 1 + files/mygui/openmw_chargen_race.layout | 4 +- files/mygui/openmw_inventory_window.layout | 1 - libs/openengine/ogre/renderer.cpp | 4 +- 21 files changed, 167 insertions(+), 49 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 5ecd1b1b9..f56313ba3 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -273,6 +273,7 @@ namespace MWBase virtual void renderPlayer() = 0; virtual void updateCharacterPreview(int sizeX, int sizeY) = 0; + virtual void updateRaceSelectionPreview(float angle) = 0; }; } diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 9ccf5cfe1..9df6d893d 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -106,6 +106,7 @@ namespace MWGui MWBase::Environment::get().getWorld()->updateCharacterPreview (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::onFilterChanged(MyGUI::Widget* _sender) @@ -270,6 +271,7 @@ namespace MWGui MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); mAvatarImage->setSize(MyGUI::IntSize(512, 1024)); + mAvatarImage->setImageTexture("CharacterPreview"); } void InventoryWindow::pickUpObject (MWWorld::Ptr object) diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 370b30733..e1dc4af1a 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -25,15 +25,17 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager) , mHairIndex(0) , mFaceCount(10) , mHairCount(14) + , mCurrentAngle(0) { // Centre dialog center(); - // These are just demo values, you should replace these with - // real calls from outside the class later. - setText("AppearanceT", mWindowManager.getGameSettingString("sRaceMenu1", "Appearance")); - getWidget(mAppearanceBox, "AppearanceBox"); + getWidget(mPreviewImage, "PreviewImage"); + + MWBase::Environment::get().getWorld ()->updateRaceSelectionPreview (0); + + mPreviewImage->setImageTexture ("CharacterHeadPreview"); getWidget(mHeadRotate, "HeadRotate"); mHeadRotate->setScrollRange(50); @@ -149,7 +151,10 @@ void RaceDialog::onBackClicked(MyGUI::Widget* _sender) 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; + MWBase::Environment::get().getWorld ()->updateRaceSelectionPreview (diff); + mCurrentAngle += diff; } void RaceDialog::onSelectPreviousGender(MyGUI::Widget*) diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index 4aded28c3..c1517eb76 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -73,7 +73,7 @@ namespace MWGui void updateSkills(); void updateSpellPowers(); - MyGUI::CanvasPtr mAppearanceBox; + MyGUI::ImageBox* mPreviewImage; MyGUI::ListBox* mRaceList; MyGUI::ScrollBar* mHeadRotate; @@ -87,6 +87,8 @@ namespace MWGui int mFaceCount, mHairCount; std::string mCurrentRaceId; + + float mCurrentAngle; }; } #endif diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp index 415d17241..15c89d7f5 100644 --- a/apps/openmw/mwrender/actors.cpp +++ b/apps/openmw/mwrender/actors.cpp @@ -3,6 +3,8 @@ #include #include +#include "renderconst.hpp" + using namespace Ogre; using namespace MWRender; @@ -23,7 +25,7 @@ void Actors::setMwRoot(Ogre::SceneNode* root){ void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv){ insertBegin(ptr, true, true); - NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mRend, inv); + NpcAnimation* anim = new MWRender::NpcAnimation(ptr, ptr.getRefData ().getBaseNode (), mRend, inv, RV_Actors); mAllActors[ptr] = anim; } diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index fd25aab08..21442782f 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -6,26 +6,31 @@ #include "renderconst.hpp" +#include "npcanimation.hpp" namespace MWRender { - CharacterPreview::CharacterPreview(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *node) + CharacterPreview::CharacterPreview(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *node, int sizeX, int sizeY, const std::string& name, + Ogre::Vector3 position, Ogre::Vector3 lookAt) : mSceneMgr(sceneMgr) + , mSizeX(sizeX) + , mSizeY(sizeY) { - mCamera = mSceneMgr->createCamera ("CharacterPreviewCamera"); - mCamera->setAspectRatio (0.5); + mCamera = mSceneMgr->createCamera (name); + mCamera->setAspectRatio (float(sizeX) / float(sizeY)); - mNode = node->createChildSceneNode (); - mNode->attachObject (mCamera); + mNode = node; + mNode->setVisible (false); - mNode->setPosition(0, 185, 70); - mNode->roll(Ogre::Degree(180)); + mCamera->setPosition(position); + mCamera->lookAt(lookAt); - mNode->pitch(Ogre::Degree(90)); + mCamera->setNearClipDistance (0.01); + mCamera->setFarClipDistance (1000); - mTexture = Ogre::TextureManager::getSingleton().createManual("CharacterPreview", - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 1024, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET); + mTexture = Ogre::TextureManager::getSingleton().createManual(name, + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, sizeX, sizeY, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET); mRenderTarget = mTexture->getBuffer()->getRenderTarget(); mViewport = mRenderTarget->addViewport(mCamera); @@ -33,20 +38,55 @@ namespace MWRender mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0)); mViewport->setShadowsEnabled(false); mViewport->setMaterialScheme("local_map"); - mViewport->setVisibilityMask (RV_Player); + mViewport->setVisibilityMask (RV_PlayerPreview); mRenderTarget->setActive(true); mRenderTarget->setAutoUpdated (false); } - void CharacterPreview::update(int sizeX, int sizeY) + // -------------------------------------------------------------------------------------------------- + + + InventoryPreview::InventoryPreview(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *node) + : CharacterPreview(sceneMgr, node, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 65, -180), Ogre::Vector3(0,65,0)) + , mAnimation(NULL) { - bool wasVisible = mNode->getParentSceneNode()->getAttachedObject(0)->getVisible (); - mNode->getParentSceneNode()->setVisible(true, false); + + } + + void InventoryPreview::update(int sizeX, int sizeY) + { + if (mAnimation) + mAnimation->forceUpdate (); + mViewport->setDimensions (0, 0, std::min(1.f, float(sizeX) / float(512)), std::min(1.f, float(sizeY) / float(1024))); - mRenderTarget->update(); + mNode->setOrientation (Ogre::Quaternion::IDENTITY); - mNode->getParentSceneNode()->setVisible(wasVisible, false); + mNode->setVisible (true); + mRenderTarget->update(); + mNode->setVisible (false); + } + + void InventoryPreview::setNpcAnimation (NpcAnimation *anim) + { + mAnimation = anim; + } + + // -------------------------------------------------------------------------------------------------- + + RaceSelectionPreview::RaceSelectionPreview(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *node) + : CharacterPreview(sceneMgr, node, 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); } } diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index e15d6c359..ba48ea17d 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -6,14 +6,15 @@ namespace MWRender { + class NpcAnimation; + class CharacterPreview { public: - CharacterPreview(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* node); + CharacterPreview(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* node, int sizeX, int sizeY, const std::string& name, + Ogre::Vector3 position, Ogre::Vector3 lookAt); - void update(int sizeX, int sizeY); - - private: + protected: Ogre::TexturePtr mTexture; Ogre::RenderTarget* mRenderTarget; Ogre::Viewport* mViewport; @@ -22,6 +23,30 @@ namespace MWRender Ogre::SceneManager* mSceneMgr; Ogre::SceneNode* mNode; + + int mSizeX; + int mSizeY; + }; + + class InventoryPreview : public CharacterPreview + { + public: + InventoryPreview(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* node); + + void update(int sizeX, int sizeY); + + void setNpcAnimation (NpcAnimation* anim); + + private: + NpcAnimation* mAnimation; + }; + + class RaceSelectionPreview : public CharacterPreview + { + public: + RaceSelectionPreview(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* node); + + void update(float angle); }; } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 392a79c96..00b877ba0 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -45,15 +45,14 @@ NpcAnimation::~NpcAnimation() } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv, bool player) - : Animation(_rend), mStateID(-1), mInv(_inv), timeToChange(0), +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv, int visibilityFlags) + : Animation(_rend), mStateID(-1), mInv(_inv), timeToChange(0), mVisibilityFlags(visibilityFlags), robe(mInv.end()), helmet(mInv.end()), shirt(mInv.end()), cuirass(mInv.end()), greaves(mInv.end()), leftpauldron(mInv.end()), rightpauldron(mInv.end()), boots(mInv.end()), leftglove(mInv.end()), rightglove(mInv.end()), skirtiter(mInv.end()), pants(mInv.end()) - , mIsPlayer(player) { MWWorld::LiveCellRef *ref = ptr.get(); @@ -85,7 +84,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere std::cout << " Sex: Male" << " Height: " << race->data.height.male << "\n"; */ - mInsert = ptr.getRefData().getBaseNode(); + mInsert = node; assert(mInsert); std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif"); @@ -95,7 +94,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere { Ogre::Entity *base = mEntityList.mEntities[i]; - base->setVisibilityFlags(mIsPlayer ? RV_Player : RV_Actors); + base->setVisibilityFlags(mVisibilityFlags); bool transparent = false; for(unsigned int j=0;j < base->getNumSubEntities();++j) { @@ -358,7 +357,7 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, con mInsert, mesh); std::vector &parts = entities.mEntities; for(size_t i = 0;i < parts.size();i++) - parts[i]->setVisibilityFlags(mIsPlayer ? RV_Player : RV_Actors); + parts[i]->setVisibilityFlags(mVisibilityFlags); return entities; } @@ -582,4 +581,9 @@ void NpcAnimation::addPartGroup(int group, int priority, std::vector& parts); + + void forceUpdate(); }; } diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 3ccc08022..297cb8d7a 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -35,6 +35,11 @@ namespace MWRender mPreviewCam.yaw = 0.f; mPreviewCam.offset = 400.f; } + + Player::~Player() + { + delete mAnimation; + } bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) { diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 8dd313b7f..b4d8983e4 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -63,6 +63,7 @@ namespace MWRender public: Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); + ~Player(); /// Set where the player is looking at. Uses Morrowind (euler) angles /// \param rot Rotation angles in radians diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index 194ca9da6..e6ecb5150 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -54,7 +54,7 @@ enum VisibilityFlags RV_OcclusionQuery = 256, - RV_Player = 512, + RV_PlayerPreview = 512, RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index acb587d03..d2a51f5f1 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -160,8 +160,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mDebugging = new Debugging(mMwRoot, engine); mLocalMap = new MWRender::LocalMap(&mRendering, this); - mCharacterPreview = new CharacterPreview(mRendering.getScene (), playerNode); - setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); } @@ -178,7 +176,9 @@ RenderingManager::~RenderingManager () delete mOcclusionQuery; delete mCompositors; delete mWater; - delete mCharacterPreview; + delete mInventoryPreview; + delete mRaceSelectionPreview; + delete mPreviewAnimation; } MWRender::SkyManager* RenderingManager::getSkyManager() @@ -862,11 +862,20 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) { MWRender::NpcAnimation *anim = new MWRender::NpcAnimation( - ptr, + ptr, ptr.getRefData ().getBaseNode (), mRendering, - MWWorld::Class::get(ptr).getInventoryStore(ptr), true + MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors ); mPlayer->setAnimation(anim); + + MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr); + + Ogre::SceneNode* previewNode = mMwRoot->createChildSceneNode (); + mPreviewAnimation = new NpcAnimation(ptr, previewNode, mRendering, invStore, RV_PlayerPreview); + + mInventoryPreview = new InventoryPreview(mRendering.getScene (), previewNode); + mInventoryPreview->setNpcAnimation (mPreviewAnimation); + mRaceSelectionPreview = new RaceSelectionPreview(mRendering.getScene (), previewNode); } void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) @@ -888,7 +897,12 @@ bool RenderingManager::isPositionExplored (float nX, float nY, int x, int y, boo void RenderingManager::updateCharacterPreview (int sizeX, int sizeY) { - mCharacterPreview->update(sizeX, sizeY); + mInventoryPreview->update(sizeX, sizeY); +} + +void RenderingManager::updateRaceSelectionPreview (float angle) +{ + mRaceSelectionPreview->update(angle); } } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index fe79c9400..cbad67472 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -43,7 +43,8 @@ namespace MWRender class LocalMap; class Water; class Compositors; - class CharacterPreview; + class InventoryPreview; + class RaceSelectionPreview; class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { @@ -193,6 +194,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList ///< see MWRender::LocalMap::isPositionExplored void updateCharacterPreview(int sizeX, int sizeY); + void updateRaceSelectionPreview(float angle); protected: virtual void windowResized(Ogre::RenderWindow* rw); @@ -216,7 +218,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList TerrainManager* mTerrainManager; - CharacterPreview* mCharacterPreview; + InventoryPreview* mInventoryPreview; + RaceSelectionPreview* mRaceSelectionPreview; MWRender::Water *mWater; @@ -247,6 +250,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList MWRender::Shadows* mShadows; MWRender::Compositors* mCompositors; + + MWRender::NpcAnimation* mPreviewAnimation; }; } diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index fc28f1cb9..3d9f13243 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -111,7 +111,7 @@ void Shadows::recreate() sh::Factory::getInstance ().setSharedParameter ("shadowFar_fadeStart", sh::makeProperty(shadowFar_fadeStart)); // Set visibility mask for the shadow render textures - int visibilityMask = (RV_Actors + RV_Player) * Settings::Manager::getBool("actor shadows", "Shadows") + int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows") + (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows") + RV_Misc * Settings::Manager::getBool("misc shadows", "Shadows"); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 6a3eeb509..7100540fc 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -332,7 +332,7 @@ void Water::applyVisibilityMask() mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") + RV_Statics * Settings::Manager::getBool("reflect statics", "Water") + RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water") - + (RV_Actors + RV_Player) * Settings::Manager::getBool("reflect actors", "Water") + + RV_Actors * Settings::Manager::getBool("reflect actors", "Water") + RV_Misc * Settings::Manager::getBool("reflect misc", "Water") + RV_Sky; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f88f5c320..005b94ffa 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1227,4 +1227,9 @@ namespace MWWorld { mRendering->updateCharacterPreview(sizeX, sizeY); } + + void World::updateRaceSelectionPreview (float angle) + { + mRendering->updateRaceSelectionPreview(angle); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 5e8bc697e..20da6f729 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -309,6 +309,7 @@ namespace MWWorld virtual void renderPlayer(); virtual void updateCharacterPreview(int sizeX, int sizeY); + virtual void updateRaceSelectionPreview(float angle); }; } diff --git a/files/mygui/openmw_chargen_race.layout b/files/mygui/openmw_chargen_race.layout index 3d32ffd9a..6891f5d93 100644 --- a/files/mygui/openmw_chargen_race.layout +++ b/files/mygui/openmw_chargen_race.layout @@ -8,7 +8,9 @@ - + + + diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 31bf58c34..4f295212b 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -13,7 +13,6 @@ - diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index e342f4c5f..2764410ad 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -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, ¶ms); // 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. Ogre::TextureManager::getSingleton().createManual( "transparent.png", @@ -197,7 +197,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& 1, 1, 0, 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) From 6ac2a12296f92a3e55b3d2c1b6771aed5ab72270 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 14 Sep 2012 14:34:18 +0200 Subject: [PATCH 04/11] item selection working on the preview --- CMakeLists.txt | 1 + apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwgui/inventorywindow.cpp | 30 +++++ apps/openmw/mwgui/inventorywindow.hpp | 6 + apps/openmw/mwgui/tooltips.cpp | 13 ++- apps/openmw/mwrender/characterpreview.cpp | 16 +++ apps/openmw/mwrender/characterpreview.hpp | 15 +++ apps/openmw/mwrender/npcanimation.cpp | 59 +++++----- apps/openmw/mwrender/npcanimation.hpp | 4 +- apps/openmw/mwrender/renderingmanager.cpp | 6 + apps/openmw/mwrender/renderingmanager.hpp | 1 + apps/openmw/mwworld/worldimp.cpp | 15 +++ apps/openmw/mwworld/worldimp.hpp | 1 + extern/shiny | 2 +- files/CMakeLists.txt | 4 +- files/materials/selection.mat | 8 ++ files/materials/selection.shader | 24 ++++ files/materials/selection.shaderset | 15 +++ files/mygui/openmw_chargen_race.layout | 2 +- files/mygui/openmw_inventory_window.layout | 1 + libs/openengine/ogre/selectionbuffer.cpp | 123 +++++++++++++++++++++ libs/openengine/ogre/selectionbuffer.hpp | 54 +++++++++ 22 files changed, 367 insertions(+), 34 deletions(-) create mode 100644 files/materials/selection.mat create mode 100644 files/materials/selection.shader create mode 100644 files/materials/selection.shaderset create mode 100644 libs/openengine/ogre/selectionbuffer.cpp create mode 100644 libs/openengine/ogre/selectionbuffer.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b5b0884e4..e01b3d26b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,6 +103,7 @@ set(OENGINE_OGRE ${LIBDIR}/openengine/ogre/fader.cpp ${LIBDIR}/openengine/ogre/imagerotate.cpp ${LIBDIR}/openengine/ogre/atlas.cpp + ${LIBDIR}/openengine/ogre/selectionbuffer.cpp ) set(OENGINE_GUI ${LIBDIR}/openengine/gui/manager.cpp diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f56313ba3..0865f6383 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -274,6 +274,7 @@ namespace MWBase virtual void updateCharacterPreview(int sizeX, int sizeY) = 0; virtual void updateRaceSelectionPreview(float angle) = 0; + virtual MWWorld::Ptr getCharacterPreviewItemSelected(int posX, int posY) = 0; }; } diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 9df6d893d..7e46aeb03 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -44,6 +44,8 @@ namespace MWGui : ContainerBase(dragAndDrop) , WindowPinnableBase("openmw_inventory_window.layout", parWindowManager) , mTrading(false) + , mAvatarClickedPosX(0) + , mAvatarClickedPosY(0) { static_cast(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); @@ -107,6 +109,7 @@ namespace MWGui MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024))); mAvatarImage->setImageTexture("CharacterPreview"); + mAvatarImage->setImageTexture("SelectionBuffer"); } void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender) @@ -180,6 +183,28 @@ namespace MWGui notifyContentChanged(); } + else + { + MyGUI::IntPoint mousePos = MyGUI::InputManager::getInstance ().getLastPressedPosition (MyGUI::MouseButton::Left); + MyGUI::IntPoint relPos = mousePos - mAvatar->getAbsolutePosition (); + 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 = MWBase::Environment::get().getWorld ()->getCharacterPreviewItemSelected (realX, realY); + if (itemSelected.isEmpty ()) + return; + + + for (unsigned int i=0; i < mContainerWidget->getChildCount (); ++i) + { + MyGUI::Widget* w = mContainerWidget->getChildAt (i); + + if (*w->getUserData() == itemSelected) + { + onSelectedItem(w); + return; + } + } + } } std::vector InventoryWindow::getEquippedItems() @@ -336,4 +361,9 @@ namespace MWGui text->setCaption(getCountString(count)); mDragAndDrop->mDraggedFrom = this; } + + MyGUI::IntCoord InventoryWindow::getAvatarScreenCoord () + { + return mAvatar->getAbsoluteCoord (); + } } diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index 4a385dd71..288f32704 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -22,6 +22,8 @@ namespace MWGui int getPlayerGold(); + MyGUI::IntCoord getAvatarScreenCoord(); + protected: MyGUI::Widget* mAvatar; MyGUI::ImageBox* mAvatarImage; @@ -38,6 +40,10 @@ namespace MWGui MyGUI::Button* mFilterMagic; MyGUI::Button* mFilterMisc; + int mAvatarClickedPosX; + int mAvatarClickedPosY; + + bool mTrading; void onWindowResize(MyGUI::Window* _sender); diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 7aee26bcc..3306ea5c2 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -14,6 +14,7 @@ #include "map_window.hpp" #include "widgets.hpp" +#include "inventorywindow.hpp" using namespace MWGui; using namespace MyGUI; @@ -162,12 +163,22 @@ void ToolTips::onFrame(float frameDuration) return; } - if (type == "ItemPtr") { mFocusObject = *focus->getUserData(); 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 = MWBase::Environment::get().getWorld ()->getCharacterPreviewItemSelected (realX, realY); + + mFocusObject = item; + tooltipSize = getToolTipViaPtr(false); + } else if (type == "Spell") { ToolTipInfo info; diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 21442782f..4a450fad9 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include "renderconst.hpp" #include "npcanimation.hpp" @@ -50,7 +52,12 @@ namespace MWRender : CharacterPreview(sceneMgr, node, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 65, -180), Ogre::Vector3(0,65,0)) , mAnimation(NULL) { + mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview); + } + InventoryPreview::~InventoryPreview() + { + delete mSelectionBuffer; } void InventoryPreview::update(int sizeX, int sizeY) @@ -63,7 +70,10 @@ namespace MWRender mNode->setOrientation (Ogre::Quaternion::IDENTITY); mNode->setVisible (true); + mRenderTarget->update(); + mSelectionBuffer->update(); + mNode->setVisible (false); } @@ -72,6 +82,12 @@ namespace MWRender mAnimation = anim; } + int InventoryPreview::getSlotSelected (int posX, int posY) + { + std::cout << posX << " " << posY << std::endl; + return mSelectionBuffer->getSelected (posX, posY); + } + // -------------------------------------------------------------------------------------------------- RaceSelectionPreview::RaceSelectionPreview(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *node) diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index ba48ea17d..fd406ceb5 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -2,6 +2,16 @@ #define MWRENDER_CHARACTERPREVIEW_H #include +#include + + +namespace OEngine +{ +namespace Render +{ +class SelectionBuffer; +} +} namespace MWRender { @@ -32,13 +42,18 @@ namespace MWRender { public: InventoryPreview(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* node); + virtual ~InventoryPreview(); void update(int sizeX, int sizeY); + int getSlotSelected(int posX, int posY); + void setNpcAnimation (NpcAnimation* anim); private: NpcAnimation* mAnimation; + + OEngine::Render::SelectionBuffer* mSelectionBuffer; }; class RaceSelectionPreview : public CharacterPreview diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 00b877ba0..c039b8d44 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -94,6 +94,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, OEngi { Ogre::Entity *base = mEntityList.mEntities[i]; + base->getUserObjectBindings ().setUserAny (Ogre::Any(-1)); + base->setVisibilityFlags(mVisibilityFlags); bool transparent = false; 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, mInsert, mesh); std::vector &parts = entities.mEntities; for(size_t i = 0;i < parts.size();i++) + { parts[i]->setVisibilityFlags(mVisibilityFlags); + parts[i]->getUserObjectBindings ().setUserAny (Ogre::Any(group)); + } return entities; } @@ -480,83 +485,83 @@ bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority, switch(type) { case ESM::PRT_Head: //0 - head = insertBoundedPart(mesh, "Head"); + head = insertBoundedPart(mesh, group, "Head"); break; case ESM::PRT_Hair: //1 - hair = insertBoundedPart(mesh, "Head"); + hair = insertBoundedPart(mesh, group, "Head"); break; case ESM::PRT_Neck: //2 - neck = insertBoundedPart(mesh, "Neck"); + neck = insertBoundedPart(mesh, group, "Neck"); break; case ESM::PRT_Cuirass: //3 - chest = insertBoundedPart(mesh, "Chest"); + chest = insertBoundedPart(mesh, group, "Chest"); break; case ESM::PRT_Groin: //4 - groin = insertBoundedPart(mesh, "Groin"); + groin = insertBoundedPart(mesh, group, "Groin"); break; case ESM::PRT_Skirt: //5 - skirt = insertBoundedPart(mesh, "Groin"); + skirt = insertBoundedPart(mesh, group, "Groin"); break; case ESM::PRT_RHand: //6 - rHand = insertBoundedPart(mesh, "Right Hand"); + rHand = insertBoundedPart(mesh, group, "Right Hand"); break; case ESM::PRT_LHand: //7 - lHand = insertBoundedPart(mesh, "Left Hand"); + lHand = insertBoundedPart(mesh, group, "Left Hand"); break; case ESM::PRT_RWrist: //8 - rWrist = insertBoundedPart(mesh, "Right Wrist"); + rWrist = insertBoundedPart(mesh, group, "Right Wrist"); break; case ESM::PRT_LWrist: //9 - lWrist = insertBoundedPart(mesh, "Left Wrist"); + lWrist = insertBoundedPart(mesh, group, "Left Wrist"); break; case ESM::PRT_Shield: //10 break; case ESM::PRT_RForearm: //11 - rForearm = insertBoundedPart(mesh, "Right Forearm"); + rForearm = insertBoundedPart(mesh, group, "Right Forearm"); break; case ESM::PRT_LForearm: //12 - lForearm = insertBoundedPart(mesh, "Left Forearm"); + lForearm = insertBoundedPart(mesh, group, "Left Forearm"); break; case ESM::PRT_RUpperarm: //13 - rupperArm = insertBoundedPart(mesh, "Right Upper Arm"); + rupperArm = insertBoundedPart(mesh, group, "Right Upper Arm"); break; case ESM::PRT_LUpperarm: //14 - lupperArm = insertBoundedPart(mesh, "Left Upper Arm"); + lupperArm = insertBoundedPart(mesh, group, "Left Upper Arm"); break; case ESM::PRT_RFoot: //15 - rfoot = insertBoundedPart(mesh, "Right Foot"); + rfoot = insertBoundedPart(mesh, group, "Right Foot"); break; case ESM::PRT_LFoot: //16 - lfoot = insertBoundedPart(mesh, "Left Foot"); + lfoot = insertBoundedPart(mesh, group, "Left Foot"); break; case ESM::PRT_RAnkle: //17 - rAnkle = insertBoundedPart(mesh, "Right Ankle"); + rAnkle = insertBoundedPart(mesh, group, "Right Ankle"); break; case ESM::PRT_LAnkle: //18 - lAnkle = insertBoundedPart(mesh, "Left Ankle"); + lAnkle = insertBoundedPart(mesh, group, "Left Ankle"); break; case ESM::PRT_RKnee: //19 - rKnee = insertBoundedPart(mesh, "Right Knee"); + rKnee = insertBoundedPart(mesh, group, "Right Knee"); break; case ESM::PRT_LKnee: //20 - lKnee = insertBoundedPart(mesh, "Left Knee"); + lKnee = insertBoundedPart(mesh, group, "Left Knee"); break; case ESM::PRT_RLeg: //21 - rUpperLeg = insertBoundedPart(mesh, "Right Upper Leg"); + rUpperLeg = insertBoundedPart(mesh, group, "Right Upper Leg"); break; case ESM::PRT_LLeg: //22 - lUpperLeg = insertBoundedPart(mesh, "Left Upper Leg"); + lUpperLeg = insertBoundedPart(mesh, group, "Left Upper Leg"); break; case ESM::PRT_RPauldron: //23 - rclavicle = insertBoundedPart(mesh , "Right Clavicle"); + rclavicle = insertBoundedPart(mesh , group, "Right Clavicle"); break; case ESM::PRT_LPauldron: //24 - lclavicle = insertBoundedPart(mesh, "Left Clavicle"); + lclavicle = insertBoundedPart(mesh, group, "Left Clavicle"); break; case ESM::PRT_Weapon: //25 break; case ESM::PRT_Tail: //26 - tail = insertBoundedPart(mesh, "Tail"); + tail = insertBoundedPart(mesh, group, "Tail"); break; } return true; @@ -575,7 +580,7 @@ void NpcAnimation::addPartGroup(int group, int priority, std::vectorgetStore().bodyParts.search(part.male); if(bodypart) - addOrReplaceIndividualPart(part.part, group,priority,"meshes\\" + bodypart->model); + addOrReplaceIndividualPart(part.part, group, priority,"meshes\\" + bodypart->model); else reserveIndividualPart(part.part, group, priority); } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index fe66d733a..699c6648d 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -18,8 +18,6 @@ private: int mPartslots[27]; //Each part slot is taken by clothing, armor, or is empty int mPartPriorities[27]; - bool mIsPlayer; - //Bounded Parts NifOgre::EntityList lclavicle; NifOgre::EntityList rclavicle; @@ -73,7 +71,7 @@ public: NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv, int visibilityFlags); 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); void updateParts(); void removeEntities(NifOgre::EntityList &entities); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index d2a51f5f1..a1ad77caf 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -905,4 +905,10 @@ void RenderingManager::updateRaceSelectionPreview (float angle) mRaceSelectionPreview->update(angle); } +int RenderingManager::getCharacterPreviewSlotSelected(int posX, int posY) +{ + std::cout << "SLOT IS " << mInventoryPreview->getSlotSelected(posX, posY) << std::endl; + return mInventoryPreview->getSlotSelected(posX, posY); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index cbad67472..42fcb1502 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -195,6 +195,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void updateCharacterPreview(int sizeX, int sizeY); void updateRaceSelectionPreview(float angle); + int getCharacterPreviewSlotSelected(int posX, int posY); protected: virtual void windowResized(Ogre::RenderWindow* rw); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 005b94ffa..a38cdd5ff 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1232,4 +1232,19 @@ namespace MWWorld { mRendering->updateRaceSelectionPreview(angle); } + + MWWorld::Ptr World::getCharacterPreviewItemSelected(int posX, int posY) + { + int slot = mRendering->getCharacterPreviewSlotSelected(posX, posY); + + if (slot == -1) + return MWWorld::Ptr(); + + MWWorld::Ptr player = getPlayer().getPlayer (); + MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player); + if (invStore.getSlot(slot) != invStore.end()) + return *invStore.getSlot (slot); + else + return MWWorld::Ptr(); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 20da6f729..cd7286861 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -310,6 +310,7 @@ namespace MWWorld virtual void updateCharacterPreview(int sizeX, int sizeY); virtual void updateRaceSelectionPreview(float angle); + virtual MWWorld::Ptr getCharacterPreviewItemSelected(int posX, int posY); }; } diff --git a/extern/shiny b/extern/shiny index 716841523..4750676ac 160000 --- a/extern/shiny +++ b/extern/shiny @@ -1 +1 @@ -Subproject commit 7168415233905de2864eec71ed4312cb8f83059b +Subproject commit 4750676ac46a7aaa86bca53dc68c5a1ba11f3bc1 diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index 3e99f5745..e8426afb7 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -40,7 +40,9 @@ set(MATERIAL_FILES water.mat water.shader water.shaderset - + selection.mat + selection.shader + selection.shaderset ) copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/water "${OpenMW_BINARY_DIR}/resources/water/" "${WATER_FILES}") diff --git a/files/materials/selection.mat b/files/materials/selection.mat new file mode 100644 index 000000000..a76dd7179 --- /dev/null +++ b/files/materials/selection.mat @@ -0,0 +1,8 @@ +material SelectionColour +{ + pass + { + vertex_program selection_vertex + fragment_program selection_fragment + } +} diff --git a/files/materials/selection.shader b/files/materials/selection.shader new file mode 100644 index 000000000..095a31259 --- /dev/null +++ b/files/materials/selection.shader @@ -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 diff --git a/files/materials/selection.shaderset b/files/materials/selection.shaderset new file mode 100644 index 000000000..c90826282 --- /dev/null +++ b/files/materials/selection.shaderset @@ -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 +} diff --git a/files/mygui/openmw_chargen_race.layout b/files/mygui/openmw_chargen_race.layout index 6891f5d93..b69073899 100644 --- a/files/mygui/openmw_chargen_race.layout +++ b/files/mygui/openmw_chargen_race.layout @@ -14,7 +14,7 @@ - + diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 4f295212b..86dee558f 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -12,6 +12,7 @@ + diff --git a/libs/openengine/ogre/selectionbuffer.cpp b/libs/openengine/ogre/selectionbuffer.cpp new file mode 100644 index 000000000..99489f008 --- /dev/null +++ b/libs/openengine/ogre/selectionbuffer.cpp @@ -0,0 +1,123 @@ +#include "selectionbuffer.hpp" + +#include +#include +#include +#include + +#include + +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(rend); + int id = subEntity->getParent ()->getUserObjectBindings().getUserAny().get(); + std::cout << "found ID:" << id << " entity name is " << subEntity->getParent()->getName() << std::endl; + bool found = false; + Ogre::ColourValue colour; + for (std::map::iterator it = mColourMap.begin(); it != mColourMap.end(); ++it) + { + if (it->second == id) + { + found = true; + colour = it->first; + } + } + + + if (!found) + { + getNextColour(); + const_cast(subEntity)->setCustomParameter(1, Ogre::Vector4(mCurrentColour.r, mCurrentColour.g, mCurrentColour.b, 1.0)); + mColourMap[mCurrentColour] = id; + } + else + { + const_cast(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::max(); + + if (mCurrentColour.getAsARGB () == color) + { + getNextColour(); + return; + } + + mCurrentColour.setAsARGB(color); + mCurrentColour.a = 1; + } + + +} +} diff --git a/libs/openengine/ogre/selectionbuffer.hpp b/libs/openengine/ogre/selectionbuffer.hpp new file mode 100644 index 000000000..c487b24b0 --- /dev/null +++ b/libs/openengine/ogre/selectionbuffer.hpp @@ -0,0 +1,54 @@ +#ifndef OENGINE_SELECTIONBUFFER_H +#define OENGINE_SELECTIONBUFFER_H + + +#include +#include +#include + +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 mColourMap; + + Ogre::ColourValue mCurrentColour; + + void getNextColour(); + }; + +} +} + +#endif From 1f7e044fadd45b0658f08595d113b56d59f4d5f8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 14 Sep 2012 14:41:19 +0200 Subject: [PATCH 05/11] removed some debug stuff --- apps/openmw/mwgui/inventorywindow.cpp | 2 -- apps/openmw/mwrender/characterpreview.cpp | 1 - apps/openmw/mwrender/renderingmanager.cpp | 1 - libs/openengine/ogre/selectionbuffer.cpp | 1 - 4 files changed, 5 deletions(-) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 7e46aeb03..f5091eea6 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -109,7 +109,6 @@ namespace MWGui MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024))); mAvatarImage->setImageTexture("CharacterPreview"); - mAvatarImage->setImageTexture("SelectionBuffer"); } void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender) @@ -294,7 +293,6 @@ namespace MWGui MyGUI::IntSize size = mAvatar->getSize(); MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); - mAvatarImage->setSize(MyGUI::IntSize(512, 1024)); mAvatarImage->setImageTexture("CharacterPreview"); } diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 4a450fad9..1be78a0f7 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -84,7 +84,6 @@ namespace MWRender int InventoryPreview::getSlotSelected (int posX, int posY) { - std::cout << posX << " " << posY << std::endl; return mSelectionBuffer->getSelected (posX, posY); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a1ad77caf..4b77da5e1 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -907,7 +907,6 @@ void RenderingManager::updateRaceSelectionPreview (float angle) int RenderingManager::getCharacterPreviewSlotSelected(int posX, int posY) { - std::cout << "SLOT IS " << mInventoryPreview->getSlotSelected(posX, posY) << std::endl; return mInventoryPreview->getSlotSelected(posX, posY); } diff --git a/libs/openengine/ogre/selectionbuffer.cpp b/libs/openengine/ogre/selectionbuffer.cpp index 99489f008..7b9e6f984 100644 --- a/libs/openengine/ogre/selectionbuffer.cpp +++ b/libs/openengine/ogre/selectionbuffer.cpp @@ -71,7 +71,6 @@ namespace Render { const Ogre::SubEntity *subEntity = static_cast(rend); int id = subEntity->getParent ()->getUserObjectBindings().getUserAny().get(); - std::cout << "found ID:" << id << " entity name is " << subEntity->getParent()->getName() << std::endl; bool found = false; Ogre::ColourValue colour; for (std::map::iterator it = mColourMap.begin(); it != mColourMap.end(); ++it) From 565aad378333f9a07152694ad2c462365f850d46 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 14 Sep 2012 14:49:56 +0200 Subject: [PATCH 06/11] changed a method for ogre 1.8.0 --- libs/openengine/ogre/selectionbuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/openengine/ogre/selectionbuffer.cpp b/libs/openengine/ogre/selectionbuffer.cpp index 7b9e6f984..3ecb99f3b 100644 --- a/libs/openengine/ogre/selectionbuffer.cpp +++ b/libs/openengine/ogre/selectionbuffer.cpp @@ -70,7 +70,7 @@ namespace Render if(typeid(*rend) == typeid(Ogre::SubEntity)) { const Ogre::SubEntity *subEntity = static_cast(rend); - int id = subEntity->getParent ()->getUserObjectBindings().getUserAny().get(); + int id = Ogre::any_cast(subEntity->getParent ()->getUserObjectBindings().getUserAny()); bool found = false; Ogre::ColourValue colour; for (std::map::iterator it = mColourMap.begin(); it != mColourMap.end(); ++it) From a308d2e38a35db50d173408750086915fd6e2884 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 14 Sep 2012 15:33:24 +0200 Subject: [PATCH 07/11] fixed exception, fixed armor label obscuring the items --- apps/openmw/mwgui/tooltips.cpp | 3 ++- files/mygui/openmw_inventory_window.layout | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 3306ea5c2..039df2269 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -177,7 +177,8 @@ void ToolTips::onFrame(float frameDuration) MWWorld::Ptr item = MWBase::Environment::get().getWorld ()->getCharacterPreviewItemSelected (realX, realY); mFocusObject = item; - tooltipSize = getToolTipViaPtr(false); + if (!mFocusObject.isEmpty ()) + tooltipSize = getToolTipViaPtr(false); } else if (type == "Spell") { diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 86dee558f..3a60916f7 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -18,6 +18,7 @@ + From 7c59b83419809721f03a107d74be13434cf12597 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 14 Sep 2012 17:10:10 +0200 Subject: [PATCH 08/11] performance optimization --- apps/openmw/mwgui/inventorywindow.cpp | 16 ++++++++-------- apps/openmw/mwgui/inventorywindow.hpp | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index f5091eea6..dffd14d17 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -44,8 +44,8 @@ namespace MWGui : ContainerBase(dragAndDrop) , WindowPinnableBase("openmw_inventory_window.layout", parWindowManager) , mTrading(false) - , mAvatarClickedPosX(0) - , mAvatarClickedPosY(0) + , mLastXSize(0) + , mLastYSize(0) { static_cast(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); @@ -102,13 +102,13 @@ namespace MWGui mRightPane->getPosition().top, _sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15, _sender->getSize().height-44 ); - drawItems(); - MyGUI::IntSize size = mAvatar->getSize(); - - MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); - mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024))); - mAvatarImage->setImageTexture("CharacterPreview"); + if (mMainWidget->getSize().width != mLastXSize || mMainWidget->getSize().height != mLastYSize) + { + drawItems(); + mLastXSize = mMainWidget->getSize().width; + mLastYSize = mMainWidget->getSize().height; + } } void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender) diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index 288f32704..f17431597 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -40,8 +40,8 @@ namespace MWGui MyGUI::Button* mFilterMagic; MyGUI::Button* mFilterMisc; - int mAvatarClickedPosX; - int mAvatarClickedPosY; + int mLastXSize; + int mLastYSize; bool mTrading; From 35f7216f2f52b4b21e89ecdf974f731ca18add84 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 14 Sep 2012 17:25:32 +0200 Subject: [PATCH 09/11] fixed some things --- apps/openmw/mwgui/inventorywindow.cpp | 3 ++- apps/openmw/mwrender/npcanimation.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index dffd14d17..66a8efe5d 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -92,6 +92,7 @@ namespace MWGui mBoughtItems.clear(); onWindowResize(static_cast(mMainWidget)); + drawItems(); } void InventoryWindow::onWindowResize(MyGUI::Window* _sender) @@ -293,7 +294,7 @@ namespace MWGui MyGUI::IntSize size = mAvatar->getSize(); MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); - mAvatarImage->setSize(MyGUI::IntSize(512, 1024)); + mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024))); mAvatarImage->setImageTexture("CharacterPreview"); } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index c039b8d44..c386193c8 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -368,7 +368,7 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int void NpcAnimation::runAnimation(float timepassed) { - //if(timeToChange > .2) + if(timeToChange > .2) { timeToChange = 0; updateParts(); From b7c9285b24b1d9bd205ee36a5bf6676fd10d35be Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 14 Sep 2012 21:12:16 +0200 Subject: [PATCH 10/11] added support for out of world rendering --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/world.hpp | 7 +++++++ apps/openmw/mwrender/externalrendering.hpp | 23 ++++++++++++++++++++++ apps/openmw/mwrender/renderingmanager.cpp | 6 ++++++ apps/openmw/mwrender/renderingmanager.hpp | 7 +++++-- apps/openmw/mwworld/worldimp.cpp | 5 +++++ apps/openmw/mwworld/worldimp.hpp | 2 ++ 7 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 apps/openmw/mwrender/externalrendering.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index b9ea8041d..79d7f7af9 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -16,7 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows - compositors + compositors externalrendering ) add_openmw_dir (mwinput diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 19405fb7a..a83d6906f 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -35,6 +35,11 @@ namespace ESMS struct ESMStore; } +namespace MWRender +{ + class ExternalRendering; +} + namespace MWWorld { class CellStore; @@ -271,6 +276,8 @@ namespace MWBase virtual void togglePlayerLooking(bool enable) = 0; virtual void renderPlayer() = 0; + + virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; }; } diff --git a/apps/openmw/mwrender/externalrendering.hpp b/apps/openmw/mwrender/externalrendering.hpp new file mode 100644 index 000000000..33c9afd87 --- /dev/null +++ b/apps/openmw/mwrender/externalrendering.hpp @@ -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 + diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 70d7de552..da49442f6 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -34,6 +34,7 @@ #include "water.hpp" #include "compositors.hpp" #include "npcanimation.hpp" +#include "externalrendering.hpp" using namespace MWRender; using namespace Ogre; @@ -882,4 +883,9 @@ bool RenderingManager::isPositionExplored (float nX, float nY, int x, int y, boo return mLocalMap->isPositionExplored(nX, nY, x, y, interior); } +void RenderingManager::setupExternalRendering (MWRender::ExternalRendering& rendering) +{ + rendering.setup (mRendering.getScene()); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index e5be238bd..e994e4909 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -43,6 +43,7 @@ namespace MWRender class LocalMap; class Water; class Compositors; + class ExternalRendering; class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { @@ -185,12 +186,14 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList 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 - 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 + void setupExternalRendering (MWRender::ExternalRendering& rendering); + protected: virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowClosed(Ogre::RenderWindow* rw); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 869ce94d1..27c354aef 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1222,4 +1222,9 @@ namespace MWWorld { mRendering->renderPlayer(mPlayer->getPlayer()); } + + void World::setupExternalRendering (MWRender::ExternalRendering& rendering) + { + mRendering->setupExternalRendering (rendering); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 6279343d4..96e6ae3f8 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -307,6 +307,8 @@ namespace MWWorld } virtual void renderPlayer(); + + virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); }; } From 3e794a6087bfb708c151170dab8a0e508c66affa Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 15 Sep 2012 01:02:07 +0200 Subject: [PATCH 11/11] remove useless member and removed a warning --- apps/openmw/mwrender/renderingmanager.cpp | 5 ++--- apps/openmw/mwrender/renderingmanager.hpp | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index fea08f108..308a01688 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -95,7 +95,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const if (filter == "anisotropic") tfo = TFO_ANISOTROPIC; else if (filter == "trilinear") tfo = TFO_TRILINEAR; 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().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 ); @@ -176,7 +176,6 @@ RenderingManager::~RenderingManager () delete mOcclusionQuery; delete mCompositors; delete mWater; - delete mPreviewAnimation; } MWRender::SkyManager* RenderingManager::getSkyManager() @@ -725,7 +724,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec if (filter == "anisotropic") tfo = TFO_ANISOTROPIC; else if (filter == "trilinear") tfo = TFO_TRILINEAR; 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().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 ); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index b7944c9b9..e994e4909 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -245,8 +245,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList MWRender::Shadows* mShadows; MWRender::Compositors* mCompositors; - - MWRender::NpcAnimation* mPreviewAnimation; }; }