From 5b38b17baf090976496825446dbe9bbd6a20252e Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 Mar 2012 15:28:18 +0100 Subject: [PATCH 01/20] local map rendering (nothing to see yet, as it is not displayed in GUI) --- apps/openmw/CMakeLists.txt | 3 +- apps/openmw/mwrender/localmap.cpp | 160 ++++++++++++++++++++++ apps/openmw/mwrender/localmap.hpp | 48 +++++++ apps/openmw/mwrender/objects.cpp | 12 ++ apps/openmw/mwrender/objects.hpp | 4 + apps/openmw/mwrender/renderingmanager.cpp | 11 ++ apps/openmw/mwrender/renderingmanager.hpp | 6 + apps/openmw/mwworld/scene.cpp | 3 +- 8 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 apps/openmw/mwrender/localmap.cpp create mode 100644 apps/openmw/mwrender/localmap.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 39cd99cf6..2af808e9a 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -14,7 +14,8 @@ set(GAME_HEADER source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender - renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface + renderingmanager debugging sky player animation npcanimation creatureanimation actors objects + renderinginterface localmap ) add_openmw_dir (mwinput diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp new file mode 100644 index 000000000..3e3ff77db --- /dev/null +++ b/apps/openmw/mwrender/localmap.cpp @@ -0,0 +1,160 @@ +#include "localmap.hpp" +#include "renderingmanager.hpp" + +#include +#include + +#include + +using namespace MWRender; +using namespace Ogre; + +#define CACHE_EXTENSION ".jpg" + +#define MAP_RESOLUTION 1024 // 1024*1024 pixels for a 8192*8192 area in world units + +LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) +{ + mRendering = rend; + + mCellCamera = mRendering->getScene()->createCamera("CellCamera"); + mCellCamera->setProjectionType(PT_ORTHOGRAPHIC); + // look down -y + const float sqrt0pt5 = 0.707106781; + mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0)); + + // Debug overlay to view the maps + /* + render(0, 0, 10000, 10000, 8192, 8192, "Cell_0_0"); + + MaterialPtr mat = MaterialManager::getSingleton().create("testMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + mat->getTechnique(0)->getPass(0)->createTextureUnitState("Cell_0_0"); + + OverlayManager& ovm = OverlayManager::getSingleton(); + + Overlay* mOverlay = ovm.create( "testOverlay" ); + + OverlayContainer* overlay_panel; + overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", "testPanel"); + + overlay_panel->_setPosition(0, 0); + overlay_panel->_setDimensions(0.5, 0.5); + + overlay_panel->setMaterialName( "testMaterial" ); + overlay_panel->show(); + mOverlay->add2D(overlay_panel); + mOverlay->show(); + */ +} + +void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell) +{ + std::string name = "Cell_" + StringConverter::toString(cell->cell->data.gridX) + + "_" + StringConverter::toString(cell->cell->data.gridY); + + const int x = cell->cell->data.gridX; + const int y = cell->cell->data.gridY; + + render((x+0.5)*8192, (-y-0.5)*8192, -10000, 10000, 8192, 8192, name); +} + +void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, + AxisAlignedBox bounds) +{ + Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y); + Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z); + Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z); + + /// \todo why is this workaround needed? + min *= 1.3; + max *= 1.3; + + Vector2 length = max-min; + Vector2 center(bounds.getCenter().x, bounds.getCenter().z); + + // divide into 8192*8192 segments + const int segsX = std::ceil( length.x / 8192 ); + const int segsY = std::ceil( length.y / 8192 ); + + for (int x=0; xcell->name + "_" + StringConverter::toString(x) + "_" + StringConverter::toString(y)); + } + } +} + +void LocalMap::render(const float x, const float y, + const float zlow, const float zhigh, + const float xw, const float yw, const std::string& texture) +{ + // disable fog + // changing FOG_MODE is not a solution when using shaders, thus we have to push linear start/end + const float fStart = mRendering->getScene()->getFogStart(); + const float fEnd = mRendering->getScene()->getFogEnd(); + const ColourValue& clr = mRendering->getScene()->getFogColour(); + mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, 1000000, 10000000); + + // make everything visible + mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); + + mCellCamera->setPosition(Vector3(x, zhigh, y)); + mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); + + mCellCamera->setOrthoWindow(xw, yw); + + TexturePtr tex; + // try loading from memory + tex = TextureManager::getSingleton().getByName(texture); + if (tex.isNull()) + { + // try loading from disk + //if (boost::filesystem::exists(texture+CACHE_EXTENSION)) + //{ + /// \todo + //} + //else + { + // render + tex = TextureManager::getSingleton().createManual( + texture, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, + xw*MAP_RESOLUTION/8192, yw*MAP_RESOLUTION/8192, + 0, + PF_R8G8B8, + TU_RENDERTARGET); + + RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); + rtt->setAutoUpdated(false); + Viewport* vp = rtt->addViewport(mCellCamera); + vp->setOverlaysEnabled(false); + vp->setShadowsEnabled(false); + vp->setBackgroundColour(ColourValue(0, 0, 0)); + //vp->setVisibilityMask( ... ); + + rtt->update(); + + /// \todo + // save to cache for next time + //rtt->writeContentsToFile("./" + texture + CACHE_EXTENSION); + } + } + + + /* + if (!MaterialManager::getSingleton().getByName("testMaterial").isNull()) + { + MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial"); + mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(texture); + } + */ + + // re-enable fog + mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); +} diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp new file mode 100644 index 000000000..ac62031f4 --- /dev/null +++ b/apps/openmw/mwrender/localmap.hpp @@ -0,0 +1,48 @@ +#ifndef _GAME_RENDER_LOCALMAP_H +#define _GAME_RENDER_LOCALMAP_H + +#include "../mwworld/ptr.hpp" + +#include + +namespace MWRender +{ + /// + /// \brief Local map rendering + /// + class LocalMap + { + public: + LocalMap(OEngine::Render::OgreRenderer*); + + /** + * Request the local map for an exterior cell. + * It will either be loaded from a disk cache, + * or rendered if it is not already cached. + * @param exterior cell + */ + void requestMap (MWWorld::Ptr::CellStore* cell); + + /** + * Request the local map for an interior cell. + * It will either be loaded from a disk cache, + * or rendered if it is not already cached. + * @param interior cell + * @param bounding box of the cell + */ + void requestMap (MWWorld::Ptr::CellStore* cell, + Ogre::AxisAlignedBox bounds); + + private: + OEngine::Render::OgreRenderer* mRendering; + + Ogre::Camera* mCellCamera; + + void render(const float x, const float y, + const float zlow, const float zhigh, + const float xw, const float yw, + const std::string& texture); + }; + +} +#endif diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 717064ada..e4e721227 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -109,6 +109,9 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) // If it is set too low: // - there will be too many batches. sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); + + mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; + mBounds[ptr.getCell()].merge(ent->getBoundingBox()); } else { @@ -116,6 +119,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) } sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale()); + mBounds[ptr.getCell()].merge(insert->_getDerivedPosition()); mRenderer.getScene()->destroyEntity(ent); } @@ -202,6 +206,9 @@ void Objects::removeCell(MWWorld::Ptr::CellStore* store) mRenderer.getScene()->destroyStaticGeometry (sg); sg = 0; } + + if(mBounds.find(store) != mBounds.end()) + mBounds.erase(store); } void Objects::buildStaticGeometry(ESMS::CellStore& cell) @@ -212,3 +219,8 @@ void Objects::buildStaticGeometry(ESMS::CellStore& cell) sg->build(); } } + +Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell) +{ + return mBounds[cell]; +} diff --git a/apps/openmw/mwrender/objects.hpp b/apps/openmw/mwrender/objects.hpp index d58455b9f..1ca81331d 100644 --- a/apps/openmw/mwrender/objects.hpp +++ b/apps/openmw/mwrender/objects.hpp @@ -14,6 +14,7 @@ class Objects{ OEngine::Render::OgreRenderer &mRenderer; std::map mCellSceneNodes; std::map mStaticGeometry; + std::map mBounds; Ogre::SceneNode* mMwRoot; bool mIsStatic; static int uniqueID; @@ -42,6 +43,9 @@ public: void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); void insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius); + Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*); + ///< get a bounding box that encloses all objects in the specified cell + bool deleteObject (const MWWorld::Ptr& ptr); ///< \return found? diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 7b58a80d7..41f4e72d6 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -55,6 +55,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mSun = 0; + + mLocalMap = new MWRender::LocalMap(&mRendering); } RenderingManager::~RenderingManager () @@ -62,6 +64,7 @@ RenderingManager::~RenderingManager () //TODO: destroy mSun? delete mPlayer; delete mSkyManager; + delete mLocalMap; } MWRender::SkyManager* RenderingManager::getSkyManager() @@ -322,4 +325,12 @@ void RenderingManager::setGlare(bool glare) mSkyManager->setGlare(glare); } +void RenderingManager::requestMap(MWWorld::Ptr::CellStore* cell) +{ + if (!(cell->cell->data.flags & ESM::Cell::Interior)) + mLocalMap->requestMap(cell); + else + mLocalMap->requestMap(cell, mObjects.getDimensions(cell)); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index d84ee43e0..65aa46b01 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -24,6 +24,7 @@ #include "objects.hpp" #include "actors.hpp" #include "player.hpp" +#include "localmap.hpp" namespace Ogre { @@ -102,6 +103,9 @@ class RenderingManager: private RenderingInterface { int skyGetSecundaPhase() const; void skySetMoonColour (bool red); void configureAmbient(ESMS::CellStore &mCell); + + void requestMap (MWWorld::Ptr::CellStore* cell); + ///< request the local map for a cell /// configure fog according to cell void configureFog(ESMS::CellStore &mCell); @@ -148,6 +152,8 @@ class RenderingManager: private RenderingInterface { MWRender::Player *mPlayer; MWRender::Debugging mDebugging; + + MWRender::LocalMap* mLocalMap; }; } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 47d5f1a2d..e7a3f2d5d 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -101,7 +101,8 @@ namespace MWWorld insertCell(*cell, mEnvironment); mRendering.cellAdded (cell); mRendering.configureAmbient(*cell); - + mRendering.requestMap(cell); + mRendering.configureAmbient(*cell); } From fa68be2b190919eb43d0219d849bbcbd1280ff7b Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 10 Mar 2012 16:05:12 +0100 Subject: [PATCH 02/20] set map window cell name --- apps/openmw/mwgui/window_manager.cpp | 5 +++++ apps/openmw/mwgui/window_manager.hpp | 2 ++ apps/openmw/mwworld/scene.cpp | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index aca9fbd9a..347db09e2 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -401,3 +401,8 @@ const ESMS::ESMStore& WindowManager::getStore() const { return environment.mWorld->getStore(); } + +void WindowManager::setCellName(const std::string& cellName) +{ + map->setCellName(cellName); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 89ff4b9bb..258ab7993 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -151,6 +151,8 @@ namespace MWGui void updateSkillArea(); ///< update display of skills, factions, birth sign, reputation and bounty + void setCellName(const std::string& cellName); ///< set the cell name to display in the map window + template void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr. void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted. diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index e7a3f2d5d..a63f6d150 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -6,6 +6,8 @@ #include "../mwsound/soundmanager.hpp" +#include "../mwgui/window_manager.hpp" + #include "ptr.hpp" #include "environment.hpp" #include "player.hpp" @@ -118,6 +120,17 @@ namespace MWWorld // TODO orientation mEnvironment.mMechanicsManager->addActor (mWorld->getPlayer().getPlayer()); mEnvironment.mMechanicsManager->watchActor (mWorld->getPlayer().getPlayer()); + + // set map window cell name + if (!(mCurrentCell->cell->data.flags & ESM::Cell::Interior)) + { + if (mCurrentCell->cell->name != "") + mEnvironment.mWindowManager->setCellName( mCurrentCell->cell->name ); + else + mEnvironment.mWindowManager->setCellName( mCurrentCell->cell->region ); + } + else + mEnvironment.mWindowManager->setCellName( mCurrentCell->cell->name ); } void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) From 583a25f63424f2da8da0f771cd7c751657cc4f28 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 14 Mar 2012 14:51:58 +0100 Subject: [PATCH 03/20] fog of war rendering (incomplete) --- apps/openmw/mwrender/localmap.cpp | 96 +++++++++++++++++++++-- apps/openmw/mwrender/localmap.hpp | 19 ++++- apps/openmw/mwrender/renderingmanager.cpp | 2 + 3 files changed, 110 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 3e3ff77db..8c56bb511 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -12,6 +12,7 @@ using namespace Ogre; #define CACHE_EXTENSION ".jpg" #define MAP_RESOLUTION 1024 // 1024*1024 pixels for a 8192*8192 area in world units +#define FOGOFWAR_RESOLUTION 1024 LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) { @@ -24,11 +25,14 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0)); // Debug overlay to view the maps - /* + render(0, 0, 10000, 10000, 8192, 8192, "Cell_0_0"); MaterialPtr mat = MaterialManager::getSingleton().create("testMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mat->getTechnique(0)->getPass(0)->createTextureUnitState("Cell_0_0"); + mat->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); + mat->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); + mat->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); OverlayManager& ovm = OverlayManager::getSingleton(); @@ -44,23 +48,27 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) overlay_panel->show(); mOverlay->add2D(overlay_panel); mOverlay->show(); - */ + } void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell) { + mInterior = false; + std::string name = "Cell_" + StringConverter::toString(cell->cell->data.gridX) + "_" + StringConverter::toString(cell->cell->data.gridY); const int x = cell->cell->data.gridX; const int y = cell->cell->data.gridY; - + render((x+0.5)*8192, (-y-0.5)*8192, -10000, 10000, 8192, 8192, name); } void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, AxisAlignedBox bounds) { + mInterior = true; + Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y); Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z); Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z); @@ -68,7 +76,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, /// \todo why is this workaround needed? min *= 1.3; max *= 1.3; - + Vector2 length = max-min; Vector2 center(bounds.getCenter().x, bounds.getCenter().z); @@ -102,7 +110,7 @@ void LocalMap::render(const float x, const float y, // make everything visible mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); - + mCellCamera->setPosition(Vector3(x, zhigh, y)); mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); @@ -140,6 +148,16 @@ void LocalMap::render(const float x, const float y, rtt->update(); + // create "fog of war" texture + TexturePtr tex2 = TextureManager::getSingleton().createManual( + texture + "_fog", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, + xw*FOGOFWAR_RESOLUTION/8192, yw*FOGOFWAR_RESOLUTION/8192, + 0, + PF_A8R8G8B8, + TU_DYNAMIC); + /// \todo // save to cache for next time //rtt->writeContentsToFile("./" + texture + CACHE_EXTENSION); @@ -158,3 +176,71 @@ void LocalMap::render(const float x, const float y, // re-enable fog mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); } + +void LocalMap::setPlayerPosition (const Ogre::Vector3& position) +{ + // retrieve the x,y grid coordinates the player is in + int x,y; + Vector2 pos(position.x, -position.z); + if (!mInterior) + { + x = std::ceil(pos.x / 8192.f); + y = std::ceil(pos.y / 8192.f); + } + else + { + /// \todo + } + + // convert from world coordinates to texture UV coordinates + float u,v; + std::string texName; + if (!mInterior) + { + u = std::abs((pos.x - (8192*x))/8192.f); + v = std::abs((pos.y - (8192*y))/8192.f); + texName = "Cell_" + StringConverter::toString(x) + "_" + + StringConverter::toString(y) + "_fog"; + } + else + { + /// \todo + } + + //std::cout << "u " << u<< " v " << v << std::endl; + + // explore radius (squared) + const float sqrExploreRadius = 0.001 * FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION; + + // get the appropriate fog of war texture + TexturePtr tex = TextureManager::getSingleton().getByName(texName); + HardwarePixelBufferSharedPtr buffer = tex->getBuffer(); + + /*void* data = buffer->lock(HardwareBuffer::HBL_NORMAL); + + for (int texU = 0; texU> 24); + uint8 r=0; + uint8 g=0; + uint8 b=0; + alpha = std::max( alpha, (uint8) (std::max(0.f, std::min(1.f, 1.f-(sqrDist/sqrExploreRadius)))*255) ); + *((uint32*)data) = (r) + (g<<8) + (b<<16) + (alpha << 24); + + // move to next texel + data = static_cast (data) + sizeof(uint32); + } + } + + buffer->unlock();*/ + + if (!MaterialManager::getSingleton().getByName("testMaterial").isNull()) + { + MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial"); + mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(tex->getName()); + } +} diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index ac62031f4..afce94c8d 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -17,7 +17,7 @@ namespace MWRender /** * Request the local map for an exterior cell. - * It will either be loaded from a disk cache, + * @remarks It will either be loaded from a disk cache, * or rendered if it is not already cached. * @param exterior cell */ @@ -25,7 +25,7 @@ namespace MWRender /** * Request the local map for an interior cell. - * It will either be loaded from a disk cache, + * @remarks It will either be loaded from a disk cache, * or rendered if it is not already cached. * @param interior cell * @param bounding box of the cell @@ -33,6 +33,14 @@ namespace MWRender void requestMap (MWWorld::Ptr::CellStore* cell, Ogre::AxisAlignedBox bounds); + /** + * Set the position of the player. + * @remarks This is used to draw a "fog of war" effect + * to hide areas on the map the player has not discovered yet. + * @param position (OGRE coordinates) + */ + void setPlayerPosition (const Ogre::Vector3& position); + private: OEngine::Render::OgreRenderer* mRendering; @@ -42,6 +50,13 @@ namespace MWRender const float zlow, const float zhigh, const float xw, const float yw, const std::string& texture); + + bool mInterior; + + // a buffer for the "fog of war" texture of the current cell. + // interior cells could be divided into multiple textures, + // so we store in a map. + std::map mBuffer; }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 41f4e72d6..bddf575d9 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -140,6 +140,8 @@ void RenderingManager::update (float duration){ mSkyManager->update(duration); mRendering.update(duration); + + mLocalMap->setPlayerPosition( mRendering.getCamera()->getRealPosition() ); } void RenderingManager::skyEnable () From 5a46d58da5912be269ef7a07cc027bee2f2cda57 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 14 Mar 2012 17:44:19 +0100 Subject: [PATCH 04/20] fully working fog of war --- apps/openmw/mwrender/localmap.cpp | 155 +++++++++++++++++++++++------- apps/openmw/mwrender/localmap.hpp | 11 ++- 2 files changed, 128 insertions(+), 38 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 8c56bb511..496a162dd 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -12,7 +12,13 @@ using namespace Ogre; #define CACHE_EXTENSION ".jpg" #define MAP_RESOLUTION 1024 // 1024*1024 pixels for a 8192*8192 area in world units -#define FOGOFWAR_RESOLUTION 1024 + +// warning: don't set this too high! dynamic textures are a bottleneck +#define FOGOFWAR_RESOLUTION 32 + +// how many frames to skip before rendering the fog of war. +// example: at 60 fps, a value of 2 would mean to render it at 20 fps. +#define FOGOFWAR_SKIP 2 LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) { @@ -25,7 +31,7 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0)); // Debug overlay to view the maps - + render(0, 0, 10000, 10000, 8192, 8192, "Cell_0_0"); MaterialPtr mat = MaterialManager::getSingleton().create("testMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); @@ -33,11 +39,17 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) mat->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); mat->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); mat->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); + + mat = MaterialManager::getSingleton().create("testMaterial2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + mat->getTechnique(0)->getPass(0)->createTextureUnitState("Cell_0_0"); + mat->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); + mat->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); + mat->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); OverlayManager& ovm = OverlayManager::getSingleton(); Overlay* mOverlay = ovm.create( "testOverlay" ); - + mOverlay->setZOrder(0); OverlayContainer* overlay_panel; overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", "testPanel"); @@ -48,11 +60,42 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) overlay_panel->show(); mOverlay->add2D(overlay_panel); mOverlay->show(); + + Overlay* mOverlay2 = ovm.create( "testOverlay2" ); + mOverlay2->setZOrder(1); + OverlayContainer* overlay_panel2; + overlay_panel2 = (OverlayContainer*)ovm.createOverlayElement("Panel", "testPanel2"); + overlay_panel2->_setPosition(0, 0); + overlay_panel2->_setDimensions(0.5, 0.5); + + overlay_panel2->setMaterialName( "testMaterial2" ); + overlay_panel2->show(); + mOverlay2->add2D(overlay_panel2); + + mOverlay2->show(); + +} + +LocalMap::~LocalMap() +{ + deleteBuffers(); +} + +void LocalMap::deleteBuffers() +{ + for (std::map::iterator it=mBuffers.begin(); + it != mBuffers.end(); ++it) + { + delete it->second; + } + mBuffers.clear(); } void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell) { + deleteBuffers(); + mInterior = false; std::string name = "Cell_" + StringConverter::toString(cell->cell->data.gridX) @@ -67,7 +110,10 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell) void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, AxisAlignedBox bounds) { + deleteBuffers(); + mInterior = true; + mBounds = bounds; Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y); Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z); @@ -81,9 +127,12 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, Vector2 center(bounds.getCenter().x, bounds.getCenter().z); // divide into 8192*8192 segments + /// \todo interiors with more than 1 segment are untested const int segsX = std::ceil( length.x / 8192 ); const int segsY = std::ceil( length.y / 8192 ); + mInteriorName = cell->cell->name; + for (int x=0; xgetBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION*4); + tex2->getBuffer()->unlock(); + + mBuffers[texture] = buffer; /// \todo // save to cache for next time @@ -165,13 +229,13 @@ void LocalMap::render(const float x, const float y, } - /* + if (!MaterialManager::getSingleton().getByName("testMaterial").isNull()) { MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial"); mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(texture); } - */ + // re-enable fog mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); @@ -179,17 +243,28 @@ void LocalMap::render(const float x, const float y, void LocalMap::setPlayerPosition (const Ogre::Vector3& position) { + #if FOGOFWAR_SKIP != 0 + static int count=0; + if (++count % FOGOFWAR_SKIP != 0) + return; + #endif + // retrieve the x,y grid coordinates the player is in int x,y; - Vector2 pos(position.x, -position.z); + Vector2 pos(position.x, position.z); if (!mInterior) { - x = std::ceil(pos.x / 8192.f); - y = std::ceil(pos.y / 8192.f); + x = (int) (pos.x / 8192.f); + y = (int) (pos.y / 8192.f); } else { - /// \todo + Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); + min *= 1.3; + + /// \todo interiors with more than 1 segment are untested + x = (int) ((pos.x - min.x)/8192.f); + y = (int) ((pos.y - min.y)/8192.f); } // convert from world coordinates to texture UV coordinates @@ -200,47 +275,57 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) u = std::abs((pos.x - (8192*x))/8192.f); v = std::abs((pos.y - (8192*y))/8192.f); texName = "Cell_" + StringConverter::toString(x) + "_" - + StringConverter::toString(y) + "_fog"; + + StringConverter::toString(y); } else { - /// \todo + Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); + min *= 1.3; + + u = (pos.x - min.x - 8192*x)/8192.f; + v = (pos.y - min.y - 8192*y)/8192.f; + + texName = mInteriorName + "_" + StringConverter::toString(x) + "_" + + StringConverter::toString(y); } //std::cout << "u " << u<< " v " << v << std::endl; // explore radius (squared) - const float sqrExploreRadius = 0.001 * FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION; + const float sqrExploreRadius = 0.01 * FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION; // get the appropriate fog of war texture - TexturePtr tex = TextureManager::getSingleton().getByName(texName); - HardwarePixelBufferSharedPtr buffer = tex->getBuffer(); - - /*void* data = buffer->lock(HardwareBuffer::HBL_NORMAL); - - for (int texU = 0; texU> 24); - uint8 r=0; - uint8 g=0; - uint8 b=0; - alpha = std::max( alpha, (uint8) (std::max(0.f, std::min(1.f, 1.f-(sqrDist/sqrExploreRadius)))*255) ); - *((uint32*)data) = (r) + (g<<8) + (b<<16) + (alpha << 24); + for (int texU = 0; texU> 24); + alpha = std::min( alpha, (uint8) (std::max(0.f, std::min(1.f, (sqrDist/sqrExploreRadius)))*255) ); + *((uint32*)pointer) = (alpha << 24); - // move to next texel - data = static_cast (data) + sizeof(uint32); + // move to next texel + ++pointer; + } } - } - buffer->unlock();*/ + // copy to the texture + memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION*4); + tex->getBuffer()->unlock(); - if (!MaterialManager::getSingleton().getByName("testMaterial").isNull()) - { - MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial"); - mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(tex->getName()); + if (!MaterialManager::getSingleton().getByName("testMaterial2").isNull()) + { + MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial2"); + mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(tex->getName()); + } + } } diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index afce94c8d..588e76633 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -14,6 +14,7 @@ namespace MWRender { public: LocalMap(OEngine::Render::OgreRenderer*); + ~LocalMap(); /** * Request the local map for an exterior cell. @@ -51,12 +52,16 @@ namespace MWRender const float xw, const float yw, const std::string& texture); - bool mInterior; - // a buffer for the "fog of war" texture of the current cell. // interior cells could be divided into multiple textures, // so we store in a map. - std::map mBuffer; + std::map mBuffers; + + void deleteBuffers(); + + bool mInterior; + Ogre::AxisAlignedBox mBounds; + std::string mInteriorName; }; } From 2edd7e59f407fa21f165fc44b698d3e8dc720837 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 14 Mar 2012 20:44:06 +0100 Subject: [PATCH 05/20] some fixes and facilities for saving the fog of war to disk --- apps/openmw/mwrender/localmap.cpp | 150 ++++++++++++++-------- apps/openmw/mwrender/localmap.hpp | 13 ++ apps/openmw/mwrender/renderingmanager.cpp | 5 + apps/openmw/mwrender/renderingmanager.hpp | 3 + apps/openmw/mwworld/scene.cpp | 2 + 5 files changed, 118 insertions(+), 55 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 496a162dd..fe9b3c191 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -4,14 +4,10 @@ #include #include -#include - using namespace MWRender; using namespace Ogre; -#define CACHE_EXTENSION ".jpg" - -#define MAP_RESOLUTION 1024 // 1024*1024 pixels for a 8192*8192 area in world units +#define MAP_RESOLUTION 1024 // 1024*1024 pixels for a SIZE*SIZE area in world units // warning: don't set this too high! dynamic textures are a bottleneck #define FOGOFWAR_RESOLUTION 32 @@ -20,6 +16,9 @@ using namespace Ogre; // example: at 60 fps, a value of 2 would mean to render it at 20 fps. #define FOGOFWAR_SKIP 2 +// size of a map segment (for exterior regions, this equals 1 cell) +#define SIZE 8192.f + LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) { mRendering = rend; @@ -32,16 +31,16 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) // Debug overlay to view the maps - render(0, 0, 10000, 10000, 8192, 8192, "Cell_0_0"); + render(0, 0, 10000, 10000, SIZE, SIZE, "Cell_0_0_"); MaterialPtr mat = MaterialManager::getSingleton().create("testMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - mat->getTechnique(0)->getPass(0)->createTextureUnitState("Cell_0_0"); + mat->getTechnique(0)->getPass(0)->createTextureUnitState("Cell_0_0_"); mat->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); mat->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); mat->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); mat = MaterialManager::getSingleton().create("testMaterial2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - mat->getTechnique(0)->getPass(0)->createTextureUnitState("Cell_0_0"); + mat->getTechnique(0)->getPass(0)->createTextureUnitState("Cell_0_0_"); mat->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); mat->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); mat->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); @@ -92,26 +91,75 @@ void LocalMap::deleteBuffers() mBuffers.clear(); } +void LocalMap::saveTexture(const std::string& texname, const std::string& filename) +{ + TexturePtr tex = TextureManager::getSingleton().getByName(texname); + if (tex.isNull()) return; + HardwarePixelBufferSharedPtr readbuffer = tex->getBuffer(); + readbuffer->lock(HardwareBuffer::HBL_NORMAL ); + const PixelBox &readrefpb = readbuffer->getCurrentLock(); + uchar *readrefdata = static_cast(readrefpb.data); + + Image img; + img = img.loadDynamicImage (readrefdata, tex->getWidth(), + tex->getHeight(), tex->getFormat()); + img.save("./" + filename); + + readbuffer->unlock(); +} + +std::string LocalMap::coordStr(const int x, const int y) +{ + return StringConverter::toString(x) + "_" + StringConverter::toString(y); +} + +void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell) +{ + if (!mInterior) + { + /*saveTexture("Cell_"+coordStr(mCellX, mCellY)+"_fog", + "Cell_"+coordStr(mCellX, mCellY)+"_fog.png");*/ + } + else + { + Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); + Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); + /// \todo why is this workaround needed? + min *= 1.3; + max *= 1.3; + Vector2 length = max-min; + + // divide into segments + const int segsX = std::ceil( length.x / SIZE ); + const int segsY = std::ceil( length.y / SIZE ); + + for (int x=0; xcell->data.gridX) - + "_" + StringConverter::toString(cell->cell->data.gridY); + std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY); - const int x = cell->cell->data.gridX; - const int y = cell->cell->data.gridY; + int x = cell->cell->data.gridX; + int y = cell->cell->data.gridY; - render((x+0.5)*8192, (-y-0.5)*8192, -10000, 10000, 8192, 8192, name); + render((x+0.5)*SIZE, (-y-0.5)*SIZE, -10000, 10000, SIZE, SIZE, name); } void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, AxisAlignedBox bounds) { - deleteBuffers(); - mInterior = true; mBounds = bounds; @@ -126,10 +174,9 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, Vector2 length = max-min; Vector2 center(bounds.getCenter().x, bounds.getCenter().z); - // divide into 8192*8192 segments - /// \todo interiors with more than 1 segment are untested - const int segsX = std::ceil( length.x / 8192 ); - const int segsY = std::ceil( length.y / 8192 ); + // divide into segments + const int segsX = std::ceil( length.x / SIZE ); + const int segsY = std::ceil( length.y / SIZE ); mInteriorName = cell->cell->name; @@ -137,11 +184,11 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, { for (int y=0; ycell->name + "_" + StringConverter::toString(x) + "_" + StringConverter::toString(y)); + render(newcenter.x, newcenter.y, z.y, z.x, SIZE, SIZE, + cell->cell->name + "_" + coordStr(x,y)); } } } @@ -171,7 +218,7 @@ void LocalMap::render(const float x, const float y, if (tex.isNull()) { // try loading from disk - //if (boost::filesystem::exists(texture+CACHE_EXTENSION)) + //if (boost::filesystem::exists(texture+".jpg")) //{ /// \todo //} @@ -182,7 +229,7 @@ void LocalMap::render(const float x, const float y, texture, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - xw*MAP_RESOLUTION/8192, yw*MAP_RESOLUTION/8192, + xw*MAP_RESOLUTION/SIZE, yw*MAP_RESOLUTION/SIZE, 0, PF_R8G8B8, TU_RENDERTARGET); @@ -202,7 +249,7 @@ void LocalMap::render(const float x, const float y, texture + "_fog", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - xw*FOGOFWAR_RESOLUTION/8192, yw*FOGOFWAR_RESOLUTION/8192, + xw*FOGOFWAR_RESOLUTION/SIZE, yw*FOGOFWAR_RESOLUTION/SIZE, 0, PF_A8R8G8B8, TU_DYNAMIC_WRITE_ONLY); @@ -221,20 +268,11 @@ void LocalMap::render(const float x, const float y, tex2->getBuffer()->unlock(); mBuffers[texture] = buffer; - - /// \todo + // save to cache for next time - //rtt->writeContentsToFile("./" + texture + CACHE_EXTENSION); + //rtt->writeContentsToFile("./" + texture + ".jpg"); } } - - - - if (!MaterialManager::getSingleton().getByName("testMaterial").isNull()) - { - MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial"); - mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(texture); - } // re-enable fog @@ -254,17 +292,18 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) Vector2 pos(position.x, position.z); if (!mInterior) { - x = (int) (pos.x / 8192.f); - y = (int) (pos.y / 8192.f); + x = std::ceil(pos.x / SIZE)-1; + y = std::ceil(-pos.y / SIZE)-1; + mCellX = x; + mCellY = y; } else { Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); min *= 1.3; - /// \todo interiors with more than 1 segment are untested - x = (int) ((pos.x - min.x)/8192.f); - y = (int) ((pos.y - min.y)/8192.f); + x = std::ceil((pos.x - min.x)/SIZE)-1; + y = std::ceil((pos.y - min.y)/SIZE)-1; } // convert from world coordinates to texture UV coordinates @@ -272,34 +311,30 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) std::string texName; if (!mInterior) { - u = std::abs((pos.x - (8192*x))/8192.f); - v = std::abs((pos.y - (8192*y))/8192.f); - texName = "Cell_" + StringConverter::toString(x) + "_" - + StringConverter::toString(y); + u = std::abs((pos.x - (SIZE*x))/SIZE); + v = 1-std::abs((pos.y + (SIZE*y))/SIZE); + texName = "Cell_"+coordStr(x,y); } else { Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); min *= 1.3; - u = (pos.x - min.x - 8192*x)/8192.f; - v = (pos.y - min.y - 8192*y)/8192.f; + u = (pos.x - min.x - SIZE*x)/SIZE; + v = (pos.y - min.y - SIZE*y)/SIZE; - texName = mInteriorName + "_" + StringConverter::toString(x) + "_" - + StringConverter::toString(y); + texName = mInteriorName + "_" + coordStr(x,y); } - //std::cout << "u " << u<< " v " << v << std::endl; - // explore radius (squared) const float sqrExploreRadius = 0.01 * FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION; // get the appropriate fog of war texture TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog"); - if (!tex.isNull()) { // get its buffer + if (mBuffers.find(texName) == mBuffers.end()) return; uint32* buffer = mBuffers[texName]; uint32* pointer = buffer; for (int texV = 0; texV> 24); alpha = std::min( alpha, (uint8) (std::max(0.f, std::min(1.f, (sqrDist/sqrExploreRadius)))*255) ); *((uint32*)pointer) = (alpha << 24); @@ -321,6 +356,11 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION*4); tex->getBuffer()->unlock(); + if (!MaterialManager::getSingleton().getByName("testMaterial").isNull()) + { + MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial"); + mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(texName); + } if (!MaterialManager::getSingleton().getByName("testMaterial2").isNull()) { MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial2"); diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 588e76633..9e06200c1 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -42,6 +42,14 @@ namespace MWRender */ void setPlayerPosition (const Ogre::Vector3& position); + /** + * Save the fog of war for the current cell to disk. + * @remarks This should be called before loading a + * new cell, as well as when the game is quit. + * @param current cell + */ + void saveFogOfWar(MWWorld::Ptr::CellStore* cell); + private: OEngine::Render::OgreRenderer* mRendering; @@ -52,6 +60,10 @@ namespace MWRender const float xw, const float yw, const std::string& texture); + void saveTexture(const std::string& texname, const std::string& filename); + + std::string coordStr(const int x, const int y); + // a buffer for the "fog of war" texture of the current cell. // interior cells could be divided into multiple textures, // so we store in a map. @@ -60,6 +72,7 @@ namespace MWRender void deleteBuffers(); bool mInterior; + int mCellX, mCellY; Ogre::AxisAlignedBox mBounds; std::string mInteriorName; }; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index bddf575d9..a8887e64f 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -335,4 +335,9 @@ void RenderingManager::requestMap(MWWorld::Ptr::CellStore* cell) mLocalMap->requestMap(cell, mObjects.getDimensions(cell)); } +void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell) +{ + mLocalMap->saveFogOfWar(cell); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 65aa46b01..78a1d2fdb 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -76,6 +76,9 @@ class RenderingManager: private RenderingInterface { /// when rebatching is needed and update automatically at the end of each frame. void cellAdded (MWWorld::Ptr::CellStore *store); + void preCellChange (MWWorld::Ptr::CellStore* store); + ///< this event is fired immediately before changing cell + void addObject (const MWWorld::Ptr& ptr); void removeObject (const MWWorld::Ptr& ptr); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index a63f6d150..84c10072a 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -135,6 +135,8 @@ namespace MWWorld void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) { + mRendering.preCellChange(mCurrentCell); + // remove active mEnvironment.mMechanicsManager->removeActor (mWorld->getPlayer().getPlayer()); From 91d2031eb7d54a6c0ffdf9c7a0cb666ef4999f33 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 16 Mar 2012 17:09:31 +0100 Subject: [PATCH 06/20] first attempt at map window --- apps/openmw/mwgui/layouts.hpp | 28 ++++++++++- apps/openmw/mwgui/window_manager.cpp | 18 ++++++- apps/openmw/mwgui/window_manager.hpp | 4 +- apps/openmw/mwrender/localmap.cpp | 6 +-- apps/openmw/mwworld/scene.cpp | 11 +---- .../openmw_map_window_layout.xml | 48 +++++++++++++++++-- 6 files changed, 94 insertions(+), 21 deletions(-) diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 9917dcdcc..7b7c84225 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -67,7 +67,7 @@ namespace MWGui { setCoord(500,0,320,300); setText("WorldButton", "World"); - setImage("Compass", "compass.dds"); + setImage("Compass", "textures\\compass.dds"); // Obviously you should override this later on setCellName("No Cell Loaded"); @@ -77,6 +77,32 @@ namespace MWGui { mMainWidget->setCaption(cellName); } + + // for interiors: cell name, for exteriors: "Cell" + void setCellPrefix(const std::string& prefix) + { + mPrefix = prefix; + } + + void setActiveCell(const int x, const int y) + { + for (int mx=0; mx<3; ++mx) + { + for (int my=0; my<3; ++my) + { + std::string name = "Map_" + boost::lexical_cast(mx) + "_" + + boost::lexical_cast(my); + + std::string image = mPrefix+"_"+ boost::lexical_cast(x + (mx-1)) + "_" + + boost::lexical_cast(y - (my-1)); + setImage(name, image); + setImage(name+"_fog", image+"_fog"); + } + } + } + + private: + std::string mPrefix; }; class MainMenu : public OEngine::GUI::Layout diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 347db09e2..014aa8108 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -402,7 +402,21 @@ const ESMS::ESMStore& WindowManager::getStore() const return environment.mWorld->getStore(); } -void WindowManager::setCellName(const std::string& cellName) +void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) { - map->setCellName(cellName); + if (!(cell->cell->data.flags & ESM::Cell::Interior)) + { + if (cell->cell->name != "") + map->setCellName( cell->cell->name ); + else + map->setCellName( cell->cell->region ); + map->setCellPrefix("Cell"); + map->setActiveCell( cell->cell->data.gridX, cell->cell->data.gridY ); + } + else + { + map->setCellName( cell->cell->name ); + map->setCellPrefix( cell->cell->name ); + } + } diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 258ab7993..c867fedbe 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -18,6 +18,7 @@ #include #include #include "../mwmechanics/stat.hpp" +#include "../mwworld/ptr.hpp" #include "mode.hpp" namespace MyGUI @@ -150,8 +151,7 @@ namespace MWGui void setBounty (int bounty); ///< set the current bounty value void updateSkillArea(); ///< update display of skills, factions, birth sign, reputation and bounty - - void setCellName(const std::string& cellName); ///< set the cell name to display in the map window + void changeCell(MWWorld::Ptr::CellStore* cell); ///< change the active cell template void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr. diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index fe9b3c191..ee5413cab 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -58,7 +58,7 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) overlay_panel->setMaterialName( "testMaterial" ); overlay_panel->show(); mOverlay->add2D(overlay_panel); - mOverlay->show(); + //mOverlay->show(); Overlay* mOverlay2 = ovm.create( "testOverlay2" ); mOverlay2->setZOrder(1); @@ -72,7 +72,7 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) overlay_panel2->show(); mOverlay2->add2D(overlay_panel2); - mOverlay2->show(); + //mOverlay2->show(); } @@ -252,7 +252,7 @@ void LocalMap::render(const float x, const float y, xw*FOGOFWAR_RESOLUTION/SIZE, yw*FOGOFWAR_RESOLUTION/SIZE, 0, PF_A8R8G8B8, - TU_DYNAMIC_WRITE_ONLY); + TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); // create a buffer to use for dynamic operations uint32* buffer = new uint32[FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION]; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 84c10072a..22955bf32 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -121,16 +121,7 @@ namespace MWWorld mEnvironment.mMechanicsManager->addActor (mWorld->getPlayer().getPlayer()); mEnvironment.mMechanicsManager->watchActor (mWorld->getPlayer().getPlayer()); - // set map window cell name - if (!(mCurrentCell->cell->data.flags & ESM::Cell::Interior)) - { - if (mCurrentCell->cell->name != "") - mEnvironment.mWindowManager->setCellName( mCurrentCell->cell->name ); - else - mEnvironment.mWindowManager->setCellName( mCurrentCell->cell->region ); - } - else - mEnvironment.mWindowManager->setCellName( mCurrentCell->cell->name ); + mEnvironment.mWindowManager->changeCell( mCurrentCell ); } void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_map_window_layout.xml b/extern/mygui_3.0.1/openmw_resources/openmw_map_window_layout.xml index f4ff50f72..d4b1b5b0a 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_map_window_layout.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_map_window_layout.xml @@ -2,8 +2,50 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5e939e4818b987f12ee27be8b4ab980446374070 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 17 Mar 2012 13:59:51 +0100 Subject: [PATCH 07/20] map window now works for interiors --- apps/openmw/mwgui/layouts.hpp | 4 +- apps/openmw/mwgui/window_manager.cpp | 5 ++ apps/openmw/mwgui/window_manager.hpp | 3 + apps/openmw/mwrender/localmap.cpp | 68 +++-------------------- apps/openmw/mwrender/localmap.hpp | 8 ++- apps/openmw/mwrender/renderingmanager.cpp | 2 +- 6 files changed, 26 insertions(+), 64 deletions(-) diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 7b7c84225..9cf22685a 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -84,7 +84,7 @@ namespace MWGui mPrefix = prefix; } - void setActiveCell(const int x, const int y) + void setActiveCell(const int x, const int y, bool interior=false) { for (int mx=0; mx<3; ++mx) { @@ -94,7 +94,7 @@ namespace MWGui + boost::lexical_cast(my); std::string image = mPrefix+"_"+ boost::lexical_cast(x + (mx-1)) + "_" - + boost::lexical_cast(y - (my-1)); + + boost::lexical_cast(y + (interior ? (my-1) : -1*(my-1))); setImage(name, image); setImage(name+"_fog", image+"_fog"); } diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 014aa8108..c8c518a93 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -420,3 +420,8 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) } } + +void WindowManager::setInteriorMapTexture(const int x, const int y) +{ + map->setActiveCell(x,y, true); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index c867fedbe..0345cb99d 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -152,6 +152,9 @@ namespace MWGui void updateSkillArea(); ///< update display of skills, factions, birth sign, reputation and bounty void changeCell(MWWorld::Ptr::CellStore* cell); ///< change the active cell + + void setInteriorMapTexture(const int x, const int y); + ///< set the index of the map texture that should be used (for interiors) template void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr. diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index ee5413cab..d4a25750f 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -1,6 +1,9 @@ #include "localmap.hpp" #include "renderingmanager.hpp" +#include "../mwworld/environment.hpp" +#include "../mwgui/window_manager.hpp" + #include #include @@ -19,61 +22,16 @@ using namespace Ogre; // size of a map segment (for exterior regions, this equals 1 cell) #define SIZE 8192.f -LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend) +LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env) { mRendering = rend; - + mEnvironment = env; + mCellCamera = mRendering->getScene()->createCamera("CellCamera"); mCellCamera->setProjectionType(PT_ORTHOGRAPHIC); // look down -y const float sqrt0pt5 = 0.707106781; mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0)); - - // Debug overlay to view the maps - - render(0, 0, 10000, 10000, SIZE, SIZE, "Cell_0_0_"); - - MaterialPtr mat = MaterialManager::getSingleton().create("testMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - mat->getTechnique(0)->getPass(0)->createTextureUnitState("Cell_0_0_"); - mat->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); - mat->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); - mat->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); - - mat = MaterialManager::getSingleton().create("testMaterial2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - mat->getTechnique(0)->getPass(0)->createTextureUnitState("Cell_0_0_"); - mat->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); - mat->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); - mat->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); - - OverlayManager& ovm = OverlayManager::getSingleton(); - - Overlay* mOverlay = ovm.create( "testOverlay" ); - mOverlay->setZOrder(0); - OverlayContainer* overlay_panel; - overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", "testPanel"); - - overlay_panel->_setPosition(0, 0); - overlay_panel->_setDimensions(0.5, 0.5); - - overlay_panel->setMaterialName( "testMaterial" ); - overlay_panel->show(); - mOverlay->add2D(overlay_panel); - //mOverlay->show(); - - Overlay* mOverlay2 = ovm.create( "testOverlay2" ); - mOverlay2->setZOrder(1); - OverlayContainer* overlay_panel2; - overlay_panel2 = (OverlayContainer*)ovm.createOverlayElement("Panel", "testPanel2"); - - overlay_panel2->_setPosition(0, 0); - overlay_panel2->_setDimensions(0.5, 0.5); - - overlay_panel2->setMaterialName( "testMaterial2" ); - overlay_panel2->show(); - mOverlay2->add2D(overlay_panel2); - - //mOverlay2->show(); - } LocalMap::~LocalMap() @@ -304,6 +262,8 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) x = std::ceil((pos.x - min.x)/SIZE)-1; y = std::ceil((pos.y - min.y)/SIZE)-1; + + mEnvironment->mWindowManager->setInteriorMapTexture(x,y); } // convert from world coordinates to texture UV coordinates @@ -355,17 +315,5 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) // copy to the texture memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION*4); tex->getBuffer()->unlock(); - - if (!MaterialManager::getSingleton().getByName("testMaterial").isNull()) - { - MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial"); - mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(texName); - } - if (!MaterialManager::getSingleton().getByName("testMaterial2").isNull()) - { - MaterialPtr mat = MaterialManager::getSingleton().getByName("testMaterial2"); - mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(tex->getName()); - } - } } diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 9e06200c1..fd5d4770b 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -5,6 +5,11 @@ #include +namespace MWWorld +{ + class Environment; +} + namespace MWRender { /// @@ -13,7 +18,7 @@ namespace MWRender class LocalMap { public: - LocalMap(OEngine::Render::OgreRenderer*); + LocalMap(OEngine::Render::OgreRenderer*, MWWorld::Environment* env); ~LocalMap(); /** @@ -52,6 +57,7 @@ namespace MWRender private: OEngine::Render::OgreRenderer* mRendering; + MWWorld::Environment* mEnvironment; Ogre::Camera* mCellCamera; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index f83e16717..e25a6a7a0 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -56,7 +56,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mSun = 0; - mLocalMap = new MWRender::LocalMap(&mRendering); + mLocalMap = new MWRender::LocalMap(&mRendering, &environment); } RenderingManager::~RenderingManager () From 1907e21207d82a9aa7f1fc8431dbf6a7542ccaf9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 18 Mar 2012 20:44:56 +0100 Subject: [PATCH 08/20] removed preprocessor constants --- apps/openmw/mwrender/localmap.cpp | 73 +++++++++++++------------------ apps/openmw/mwrender/localmap.hpp | 12 +++++ 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index d4a25750f..e08559d26 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -10,18 +10,6 @@ using namespace MWRender; using namespace Ogre; -#define MAP_RESOLUTION 1024 // 1024*1024 pixels for a SIZE*SIZE area in world units - -// warning: don't set this too high! dynamic textures are a bottleneck -#define FOGOFWAR_RESOLUTION 32 - -// how many frames to skip before rendering the fog of war. -// example: at 60 fps, a value of 2 would mean to render it at 20 fps. -#define FOGOFWAR_SKIP 2 - -// size of a map segment (for exterior regions, this equals 1 cell) -#define SIZE 8192.f - LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env) { mRendering = rend; @@ -88,8 +76,8 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell) Vector2 length = max-min; // divide into segments - const int segsX = std::ceil( length.x / SIZE ); - const int segsY = std::ceil( length.y / SIZE ); + const int segsX = std::ceil( length.x / sSize ); + const int segsY = std::ceil( length.y / sSize ); for (int x=0; xcell->data.gridX; int y = cell->cell->data.gridY; - render((x+0.5)*SIZE, (-y-0.5)*SIZE, -10000, 10000, SIZE, SIZE, name); + render((x+0.5)*sSize, (-y-0.5)*sSize, -10000, 10000, sSize, sSize, name); } void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, @@ -133,8 +121,8 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, Vector2 center(bounds.getCenter().x, bounds.getCenter().z); // divide into segments - const int segsX = std::ceil( length.x / SIZE ); - const int segsY = std::ceil( length.y / SIZE ); + const int segsX = std::ceil( length.x / sSize ); + const int segsY = std::ceil( length.y / sSize ); mInteriorName = cell->cell->name; @@ -142,10 +130,10 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, { for (int y=0; ycell->name + "_" + coordStr(x,y)); } } @@ -187,7 +175,7 @@ void LocalMap::render(const float x, const float y, texture, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - xw*MAP_RESOLUTION/SIZE, yw*MAP_RESOLUTION/SIZE, + xw*sMapResolution/sSize, yw*sMapResolution/sSize, 0, PF_R8G8B8, TU_RENDERTARGET); @@ -207,22 +195,22 @@ void LocalMap::render(const float x, const float y, texture + "_fog", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - xw*FOGOFWAR_RESOLUTION/SIZE, yw*FOGOFWAR_RESOLUTION/SIZE, + xw*sFogOfWarResolution/sSize, yw*sFogOfWarResolution/sSize, 0, PF_A8R8G8B8, TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); // create a buffer to use for dynamic operations - uint32* buffer = new uint32[FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION]; + uint32* buffer = new uint32[sFogOfWarResolution*sFogOfWarResolution]; // initialize to (0, 0, 0, 1) uint32* pointer = buffer; - for (int p=0; pgetBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION*4); + memcpy(tex2->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, sFogOfWarResolution*sFogOfWarResolution*4); tex2->getBuffer()->unlock(); mBuffers[texture] = buffer; @@ -239,19 +227,20 @@ void LocalMap::render(const float x, const float y, void LocalMap::setPlayerPosition (const Ogre::Vector3& position) { - #if FOGOFWAR_SKIP != 0 - static int count=0; - if (++count % FOGOFWAR_SKIP != 0) - return; - #endif + if (sFogOfWarSkip != 0) + { + static int count=0; + if (++count % sFogOfWarSkip != 0) + return; + } // retrieve the x,y grid coordinates the player is in int x,y; Vector2 pos(position.x, position.z); if (!mInterior) { - x = std::ceil(pos.x / SIZE)-1; - y = std::ceil(-pos.y / SIZE)-1; + x = std::ceil(pos.x / sSize)-1; + y = std::ceil(-pos.y / sSize)-1; mCellX = x; mCellY = y; } @@ -260,8 +249,8 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); min *= 1.3; - x = std::ceil((pos.x - min.x)/SIZE)-1; - y = std::ceil((pos.y - min.y)/SIZE)-1; + x = std::ceil((pos.x - min.x)/sSize)-1; + y = std::ceil((pos.y - min.y)/sSize)-1; mEnvironment->mWindowManager->setInteriorMapTexture(x,y); } @@ -271,8 +260,8 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) std::string texName; if (!mInterior) { - u = std::abs((pos.x - (SIZE*x))/SIZE); - v = 1-std::abs((pos.y + (SIZE*y))/SIZE); + u = std::abs((pos.x - (sSize*x))/sSize); + v = 1-std::abs((pos.y + (sSize*y))/sSize); texName = "Cell_"+coordStr(x,y); } else @@ -280,14 +269,14 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); min *= 1.3; - u = (pos.x - min.x - SIZE*x)/SIZE; - v = (pos.y - min.y - SIZE*y)/SIZE; + u = (pos.x - min.x - sSize*x)/sSize; + v = (pos.y - min.y - sSize*y)/sSize; texName = mInteriorName + "_" + coordStr(x,y); } // explore radius (squared) - const float sqrExploreRadius = 0.01 * FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION; + const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; // get the appropriate fog of war texture TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog"); @@ -297,11 +286,11 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) if (mBuffers.find(texName) == mBuffers.end()) return; uint32* buffer = mBuffers[texName]; uint32* pointer = buffer; - for (int texV = 0; texV> 24); alpha = std::min( alpha, (uint8) (std::max(0.f, std::min(1.f, (sqrDist/sqrExploreRadius)))*255) ); @@ -313,7 +302,7 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) } // copy to the texture - memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, FOGOFWAR_RESOLUTION*FOGOFWAR_RESOLUTION*4); + memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, sFogOfWarResolution*sFogOfWarResolution*4); tex->getBuffer()->unlock(); } } diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index fd5d4770b..13e01b7f4 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -59,6 +59,18 @@ namespace MWRender OEngine::Render::OgreRenderer* mRendering; MWWorld::Environment* mEnvironment; + // 1024*1024 pixels for a cell + static const int sMapResolution = 1024; + + // the dynamic texture is a bottleneck, so don't set this too high + static const int sFogOfWarResolution = 32; + + // frames to skip before rendering fog of war + static const int sFogOfWarSkip = 2; + + // size of a map segment (for exteriors, 1 cell) + static const int sSize = 8192; + Ogre::Camera* mCellCamera; void render(const float x, const float y, From cc9f20a04f69a8907161f4e75d828293caf53e61 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 22 Mar 2012 20:25:41 +0100 Subject: [PATCH 09/20] MW_MapView skin --- apps/openmw/mwgui/layouts.hpp | 3 +++ files/mygui/CMakeLists.txt | 1 + files/mygui/core.xml | 1 + files/mygui/openmw_map_window_layout.xml | 29 ++++++++++++------------ files/mygui/openmw_map_window_skin.xml | 11 +++++++++ 5 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 files/mygui/openmw_map_window_skin.xml diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 058aac6a5..13f80badc 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -71,6 +71,8 @@ namespace MWGui // Obviously you should override this later on setCellName("No Cell Loaded"); + + getWidget(mMap, "Map"); } void setCellName(const std::string& cellName) @@ -103,6 +105,7 @@ namespace MWGui private: std::string mPrefix; + MyGUI::ScrollView* mMap; }; class MainMenu : public OEngine::GUI::Layout diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index 9ea84747c..9a6cde7ba 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -42,6 +42,7 @@ configure_file("${SDIR}/openmw_layers.xml" "${DDIR}/openmw_layers.xml" COPYONLY) configure_file("${SDIR}/openmw_mainmenu_layout.xml" "${DDIR}/openmw_mainmenu_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_mainmenu_skin.xml" "${DDIR}/openmw_mainmenu_skin.xml" COPYONLY) configure_file("${SDIR}/openmw_map_window_layout.xml" "${DDIR}/openmw_map_window_layout.xml" COPYONLY) +configure_file("${SDIR}/openmw_map_window_skin.xml" "${DDIR}/openmw_map_window_skin.xml" COPYONLY) configure_file("${SDIR}/openmw.pointer.xml" "${DDIR}/openmw.pointer.xml" COPYONLY) configure_file("${SDIR}/openmw_progress.skin.xml" "${DDIR}/openmw_progress.skin.xml" COPYONLY) configure_file("${SDIR}/openmw_stats_window_layout.xml" "${DDIR}/openmw_stats_window_layout.xml" COPYONLY) diff --git a/files/mygui/core.xml b/files/mygui/core.xml index 30e01a8f3..5bec13aef 100644 --- a/files/mygui/core.xml +++ b/files/mygui/core.xml @@ -20,6 +20,7 @@ + diff --git a/files/mygui/openmw_map_window_layout.xml b/files/mygui/openmw_map_window_layout.xml index 2b0d4b2ac..1bb304455 100644 --- a/files/mygui/openmw_map_window_layout.xml +++ b/files/mygui/openmw_map_window_layout.xml @@ -2,50 +2,49 @@ - - - - - - + + - + - + - + - + - + - + - + - + - + + + + diff --git a/files/mygui/openmw_map_window_skin.xml b/files/mygui/openmw_map_window_skin.xml new file mode 100644 index 000000000..452177464 --- /dev/null +++ b/files/mygui/openmw_map_window_skin.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + From cf3515a8989bb3480e043c3ce6c668ca535c2331 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 22 Mar 2012 21:27:21 +0100 Subject: [PATCH 10/20] it is now possible to drag the minimap with the mouse --- apps/openmw/mwgui/layouts.hpp | 44 ++++++++++++++++++++++-- files/mygui/openmw_map_window_layout.xml | 4 ++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 13f80badc..6c66bb51f 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -73,6 +73,15 @@ namespace MWGui setCellName("No Cell Loaded"); getWidget(mMap, "Map"); + + MyGUI::Button* button; + getWidget(button, "WorldButton"); + button->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); + + MyGUI::Button* eventbox; + getWidget(eventbox, "EventBox"); + eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); + eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); } void setCellName(const std::string& cellName) @@ -88,6 +97,7 @@ namespace MWGui void setActiveCell(const int x, const int y, bool interior=false) { + if (x==mCurX && y==mCurY && mInterior==interior) return; // don't do anything if we're still in the same cell for (int mx=0; mx<3; ++mx) { for (int my=0; my<3; ++my) @@ -97,15 +107,45 @@ namespace MWGui std::string image = mPrefix+"_"+ boost::lexical_cast(x + (mx-1)) + "_" + boost::lexical_cast(y + (interior ? (my-1) : -1*(my-1))); - setImage(name, image); - setImage(name+"_fog", image+"_fog"); + + if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) + setImage(name, image); + if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) + setImage(name+"_fog", image+"_fog"); } } + mInterior = interior; + mCurX = x; + mCurY = y; + } + + void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) + { + if (_id!=MyGUI::MouseButton::Left) return; + mLastDragPos = MyGUI::IntPoint(_left, _top); + } + + void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) + { + if (_id!=MyGUI::MouseButton::Left) return; + + MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; + mMap->setViewOffset( mMap->getViewOffset() + diff ); + + mLastDragPos = MyGUI::IntPoint(_left, _top); + } + + void onWorldButtonClicked(MyGUI::Widget* _sender) + { + /// \todo } private: std::string mPrefix; MyGUI::ScrollView* mMap; + MyGUI::IntPoint mLastDragPos; + int mCurX, mCurY; + bool mInterior; }; class MainMenu : public OEngine::GUI::Layout diff --git a/files/mygui/openmw_map_window_layout.xml b/files/mygui/openmw_map_window_layout.xml index 1bb304455..90ad70edb 100644 --- a/files/mygui/openmw_map_window_layout.xml +++ b/files/mygui/openmw_map_window_layout.xml @@ -4,7 +4,7 @@ - + @@ -44,6 +44,8 @@ + + From 2dd329938a87ccf17b490288f73f31b1529cd57c Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 08:16:04 +0100 Subject: [PATCH 11/20] automatically zoom in on the player while moving --- apps/openmw/mwgui/layouts.hpp | 26 ++++++++++++++++++++++++++ apps/openmw/mwgui/window_manager.cpp | 5 +++++ apps/openmw/mwgui/window_manager.hpp | 1 + apps/openmw/mwrender/localmap.cpp | 2 ++ 4 files changed, 34 insertions(+) diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 6c66bb51f..e55feceb2 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -84,6 +84,15 @@ namespace MWGui eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); } + void setVisible(bool b) + { + mMainWidget->setVisible(b); + if (b) + mVisible = true; + else + mVisible = false; + } + void setCellName(const std::string& cellName) { static_cast(mMainWidget)->setCaption(cellName); @@ -110,8 +119,13 @@ namespace MWGui if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) setImage(name, image); + else + setImage(name, "black.png"); + if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) setImage(name+"_fog", image+"_fog"); + else + setImage(name+"_fog", "black.png"); } } mInterior = interior; @@ -119,6 +133,17 @@ namespace MWGui mCurY = y; } + void setPlayerPos(const float x, const float y) + { + if (mVisible) return; + MyGUI::IntSize size = mMap->getCanvasSize(); + MyGUI::IntPoint middle = MyGUI::IntPoint(x*size.width,y*size.height); + MyGUI::IntCoord viewsize = mMap->getCoord(); + MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); + std::cout << pos.left << " top " << pos.top << std::endl; + mMap->setViewOffset(pos); + } + void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { if (_id!=MyGUI::MouseButton::Left) return; @@ -146,6 +171,7 @@ namespace MWGui MyGUI::IntPoint mLastDragPos; int mCurX, mCurY; bool mInterior; + bool mVisible; }; class MainMenu : public OEngine::GUI::Layout diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index bb04543a0..c7ee1438e 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -424,3 +424,8 @@ void WindowManager::setInteriorMapTexture(const int x, const int y) { map->setActiveCell(x,y, true); } + +void WindowManager::setPlayerPos(const float x, const float y) +{ + map->setPlayerPos(x,y); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 2b141acf5..922009e4d 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -154,6 +154,7 @@ namespace MWGui void updateSkillArea(); ///< update display of skills, factions, birth sign, reputation and bounty void changeCell(MWWorld::Ptr::CellStore* cell); ///< change the active cell + void setPlayerPos(const float x, const float y); ///< set player position in map space void setInteriorMapTexture(const int x, const int y); ///< set the index of the map texture that should be used (for interiors) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index e08559d26..b7deb6f7f 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -263,6 +263,7 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) u = std::abs((pos.x - (sSize*x))/sSize); v = 1-std::abs((pos.y + (sSize*y))/sSize); texName = "Cell_"+coordStr(x,y); + } else { @@ -274,6 +275,7 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) texName = mInteriorName + "_" + coordStr(x,y); } + mEnvironment->mWindowManager->setPlayerPos(1/3.f + u/3.f, 1/3.f + v/3.f); // explore radius (squared) const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; From 8e299bd25b12c134f4abd36252c0c388363d73c6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 08:16:32 +0100 Subject: [PATCH 12/20] remove unuseful std::cout --- apps/openmw/mwgui/layouts.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index e55feceb2..20ee1a80c 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -140,7 +140,6 @@ namespace MWGui MyGUI::IntPoint middle = MyGUI::IntPoint(x*size.width,y*size.height); MyGUI::IntCoord viewsize = mMap->getCoord(); MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); - std::cout << pos.left << " top " << pos.top << std::endl; mMap->setViewOffset(pos); } From 9c3e1f48f06df360c00d6e15d1626a7044eeb336 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 09:00:00 +0100 Subject: [PATCH 13/20] player arrow --- apps/openmw/mwgui/layouts.hpp | 10 +++++++++- apps/openmw/mwrender/localmap.cpp | 2 +- files/mygui/core.skin | 3 +++ files/mygui/openmw_map_window_layout.xml | 12 ++++++------ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 20ee1a80c..1f0bdd0fa 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -73,6 +73,7 @@ namespace MWGui setCellName("No Cell Loaded"); getWidget(mMap, "Map"); + getWidget(mPlayerArrow, "Compass"); MyGUI::Button* button; getWidget(button, "WorldButton"); @@ -137,10 +138,16 @@ namespace MWGui { if (mVisible) return; MyGUI::IntSize size = mMap->getCanvasSize(); - MyGUI::IntPoint middle = MyGUI::IntPoint(x*size.width,y*size.height); + MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); MyGUI::IntCoord viewsize = mMap->getCoord(); MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); mMap->setViewOffset(pos); + + mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); + + MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); + MyGUI::RotatingSkin* rotatingSubskin = main->castType(); + rotatingSubskin->setAngle(3.141 * 0.5); } void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) @@ -167,6 +174,7 @@ namespace MWGui private: std::string mPrefix; MyGUI::ScrollView* mMap; + MyGUI::ImageBox* mPlayerArrow; MyGUI::IntPoint mLastDragPos; int mCurX, mCurY; bool mInterior; diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index b7deb6f7f..e7a7c9f05 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -275,7 +275,7 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) texName = mInteriorName + "_" + coordStr(x,y); } - mEnvironment->mWindowManager->setPlayerPos(1/3.f + u/3.f, 1/3.f + v/3.f); + mEnvironment->mWindowManager->setPlayerPos(u, v); // explore radius (squared) const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; diff --git a/files/mygui/core.skin b/files/mygui/core.skin index 83dcd4b9f..28838c234 100644 --- a/files/mygui/core.skin +++ b/files/mygui/core.skin @@ -14,4 +14,7 @@ + + + diff --git a/files/mygui/openmw_map_window_layout.xml b/files/mygui/openmw_map_window_layout.xml index 90ad70edb..0ec99f450 100644 --- a/files/mygui/openmw_map_window_layout.xml +++ b/files/mygui/openmw_map_window_layout.xml @@ -4,7 +4,7 @@ - + @@ -23,7 +23,10 @@ - + + + + @@ -42,11 +45,8 @@ - - - - + From 770b0f2106e36caa74f1e4bc52bf8c714ca0b548 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 10:25:55 +0100 Subject: [PATCH 14/20] gui changes --- apps/openmw/mwgui/layouts.hpp | 45 +++++++++++++++--------- files/mygui/openmw_list.skin.xml | 4 +-- files/mygui/openmw_map_window_layout.xml | 13 +++++-- files/mygui/openmw_map_window_skin.xml | 6 ++-- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 1f0bdd0fa..49b956f0a 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -63,7 +63,7 @@ namespace MWGui { public: MapWindow() - : Layout("openmw_map_window_layout.xml") + : Layout("openmw_map_window_layout.xml"), mGlobal(false) { setCoord(500,0,320,300); setText("WorldButton", "World"); @@ -72,12 +72,12 @@ namespace MWGui // Obviously you should override this later on setCellName("No Cell Loaded"); - getWidget(mMap, "Map"); + getWidget(mLocalMap, "LocalMap"); + getWidget(mGlobalMap, "GlobalMap"); getWidget(mPlayerArrow, "Compass"); - MyGUI::Button* button; - getWidget(button, "WorldButton"); - button->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); + getWidget(mButton, "WorldButton"); + mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); MyGUI::Button* eventbox; getWidget(eventbox, "EventBox"); @@ -136,49 +136,62 @@ namespace MWGui void setPlayerPos(const float x, const float y) { - if (mVisible) return; - MyGUI::IntSize size = mMap->getCanvasSize(); + if (mGlobal || mVisible) return; + MyGUI::IntSize size = mLocalMap->getCanvasSize(); MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); - MyGUI::IntCoord viewsize = mMap->getCoord(); + MyGUI::IntCoord viewsize = mLocalMap->getCoord(); MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); - mMap->setViewOffset(pos); + mLocalMap->setViewOffset(pos); mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); MyGUI::RotatingSkin* rotatingSubskin = main->castType(); - rotatingSubskin->setAngle(3.141 * 0.5); + rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); + rotatingSubskin->setAngle(3.141); } void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { if (_id!=MyGUI::MouseButton::Left) return; - mLastDragPos = MyGUI::IntPoint(_left, _top); + if (!mGlobal) + mLastDragPos = MyGUI::IntPoint(_left, _top); } void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { if (_id!=MyGUI::MouseButton::Left) return; - MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; - mMap->setViewOffset( mMap->getViewOffset() + diff ); + if (!mGlobal) + { + MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; + mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); - mLastDragPos = MyGUI::IntPoint(_left, _top); + mLastDragPos = MyGUI::IntPoint(_left, _top); + } } void onWorldButtonClicked(MyGUI::Widget* _sender) { - /// \todo + mGlobal = !mGlobal; + mGlobalMap->setVisible(mGlobal); + mLocalMap->setVisible(!mGlobal); + + mButton->setCaption( mGlobal ? "Local" : "World" ); } private: std::string mPrefix; - MyGUI::ScrollView* mMap; + MyGUI::ScrollView* mLocalMap; + MyGUI::ScrollView* mGlobalMap; MyGUI::ImageBox* mPlayerArrow; + MyGUI::Button* mButton; MyGUI::IntPoint mLastDragPos; int mCurX, mCurY; bool mInterior; bool mVisible; + + bool mGlobal; }; class MainMenu : public OEngine::GUI::Layout diff --git a/files/mygui/openmw_list.skin.xml b/files/mygui/openmw_list.skin.xml index c3b97c752..98390367c 100644 --- a/files/mygui/openmw_list.skin.xml +++ b/files/mygui/openmw_list.skin.xml @@ -197,7 +197,7 @@ - + @@ -233,7 +233,7 @@ - + diff --git a/files/mygui/openmw_map_window_layout.xml b/files/mygui/openmw_map_window_layout.xml index 0ec99f450..f5c2c9991 100644 --- a/files/mygui/openmw_map_window_layout.xml +++ b/files/mygui/openmw_map_window_layout.xml @@ -2,7 +2,13 @@ - + + + + + + + @@ -46,7 +52,10 @@ - + + + + diff --git a/files/mygui/openmw_map_window_skin.xml b/files/mygui/openmw_map_window_skin.xml index 452177464..fbb7af7ae 100644 --- a/files/mygui/openmw_map_window_skin.xml +++ b/files/mygui/openmw_map_window_skin.xml @@ -2,10 +2,10 @@ - + - - + + From 06fa310e292ebc7db3e270a804dc6b5b03630dd4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 15:00:48 +0100 Subject: [PATCH 15/20] player arrow rotated correctly --- apps/openmw/mwgui/layouts.hpp | 9 ++++++++- apps/openmw/mwgui/window_manager.cpp | 5 +++++ apps/openmw/mwgui/window_manager.hpp | 1 + apps/openmw/mwrender/localmap.cpp | 3 ++- apps/openmw/mwrender/localmap.hpp | 5 +++-- apps/openmw/mwrender/renderingmanager.cpp | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 49b956f0a..7ae28b4d8 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -14,6 +14,8 @@ #include "../mwmechanics/stat.hpp" #include "window_base.hpp" +#include + /* This file contains classes corresponding to window layouts defined in resources/mygui/ *.xml. @@ -144,11 +146,16 @@ namespace MWGui mLocalMap->setViewOffset(pos); mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); + } + void setPlayerDir(const float x, const float y) + { + if (!mVisible) return; MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); MyGUI::RotatingSkin* rotatingSubskin = main->castType(); rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); - rotatingSubskin->setAngle(3.141); + float angle = std::atan2(x,y); + rotatingSubskin->setAngle(angle); } void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index c7ee1438e..a263ee2a0 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -429,3 +429,8 @@ void WindowManager::setPlayerPos(const float x, const float y) { map->setPlayerPos(x,y); } + +void WindowManager::setPlayerDir(const float x, const float y) +{ + map->setPlayerDir(x,y); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 922009e4d..582f438e8 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -155,6 +155,7 @@ namespace MWGui void changeCell(MWWorld::Ptr::CellStore* cell); ///< change the active cell void setPlayerPos(const float x, const float y); ///< set player position in map space + void setPlayerDir(const float x, const float y); ///< set player view direction in map space void setInteriorMapTexture(const int x, const int y); ///< set the index of the map texture that should be used (for interiors) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index e7a7c9f05..83fe40166 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -225,7 +225,7 @@ void LocalMap::render(const float x, const float y, mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); } -void LocalMap::setPlayerPosition (const Ogre::Vector3& position) +void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction) { if (sFogOfWarSkip != 0) { @@ -276,6 +276,7 @@ void LocalMap::setPlayerPosition (const Ogre::Vector3& position) texName = mInteriorName + "_" + coordStr(x,y); } mEnvironment->mWindowManager->setPlayerPos(u, v); + mEnvironment->mWindowManager->setPlayerDir(direction.x, -direction.z); // explore radius (squared) const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 13e01b7f4..3bef475ea 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -40,12 +40,13 @@ namespace MWRender Ogre::AxisAlignedBox bounds); /** - * Set the position of the player. + * Set the position & direction of the player. * @remarks This is used to draw a "fog of war" effect * to hide areas on the map the player has not discovered yet. * @param position (OGRE coordinates) + * @param view direction (OGRE coordinates) */ - void setPlayerPosition (const Ogre::Vector3& position); + void updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction); /** * Save the fog of war for the current cell to disk. diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 6b7c21e51..e2aea19c6 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -141,7 +141,7 @@ void RenderingManager::update (float duration){ mRendering.update(duration); - mLocalMap->setPlayerPosition( mRendering.getCamera()->getRealPosition() ); + mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealDirection() ); } void RenderingManager::skyEnable () From ce63d29d4abac02025cb2afd44ef4744d444b640 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 15:26:24 +0100 Subject: [PATCH 16/20] rotate hud player arrow --- apps/openmw/mwgui/layouts.cpp | 10 ++++++++++ apps/openmw/mwgui/layouts.hpp | 2 ++ apps/openmw/mwgui/window_manager.cpp | 1 + files/mygui/openmw_hud_layout.xml | 2 +- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index ebabc6faf..be8c0db17 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -142,3 +142,13 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& v } } } + +void HUD::setPlayerDir(const float x, const float y) +{ + MyGUI::ISubWidget* main = compass->getSubWidgetMain(); + MyGUI::RotatingSkin* rotatingSubskin = main->castType(); + rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); + float angle = std::atan2(x,y); + rotatingSubskin->setAngle(angle); +} + diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 7ae28b4d8..240406018 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -46,6 +46,8 @@ namespace MWGui void setTriangleCount(size_t count); void setBatchCount(size_t count); + void setPlayerDir(const float x, const float y); + MyGUI::ProgressPtr health, magicka, stamina; MyGUI::ImageBox *weapImage, *spellImage; MyGUI::ProgressPtr weapStatus, spellStatus; diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index a263ee2a0..5137a109f 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -433,4 +433,5 @@ void WindowManager::setPlayerPos(const float x, const float y) void WindowManager::setPlayerDir(const float x, const float y) { map->setPlayerDir(x,y); + hud->setPlayerDir(x,y); } diff --git a/files/mygui/openmw_hud_layout.xml b/files/mygui/openmw_hud_layout.xml index 86f4df172..56708eb18 100644 --- a/files/mygui/openmw_hud_layout.xml +++ b/files/mygui/openmw_hud_layout.xml @@ -40,7 +40,7 @@ align="Right Bottom"> - From 789fbb460fe5191c316ff80753f03296a7b2390e Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 15:34:54 +0100 Subject: [PATCH 17/20] move implementation to .cpp --- apps/openmw/mwgui/layouts.cpp | 124 +++++++++++++++++++++++++++++++ apps/openmw/mwgui/layouts.hpp | 135 +++------------------------------- 2 files changed, 136 insertions(+), 123 deletions(-) diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index be8c0db17..195297260 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -152,3 +152,127 @@ void HUD::setPlayerDir(const float x, const float y) rotatingSubskin->setAngle(angle); } +MapWindow::MapWindow() + : Layout("openmw_map_window_layout.xml"), mGlobal(false) +{ + setCoord(500,0,320,300); + setText("WorldButton", "World"); + setImage("Compass", "textures\\compass.dds"); + + // Obviously you should override this later on + setCellName("No Cell Loaded"); + + getWidget(mLocalMap, "LocalMap"); + getWidget(mGlobalMap, "GlobalMap"); + getWidget(mPlayerArrow, "Compass"); + + getWidget(mButton, "WorldButton"); + mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); + + MyGUI::Button* eventbox; + getWidget(eventbox, "EventBox"); + eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); + eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); +} + +void MapWindow::setVisible(bool b) +{ + mMainWidget->setVisible(b); + if (b) + mVisible = true; + else + mVisible = false; +} + +void MapWindow::setCellName(const std::string& cellName) +{ + static_cast(mMainWidget)->setCaption(cellName); +} + +void MapWindow::setCellPrefix(const std::string& prefix) +{ + mPrefix = prefix; +} + +void MapWindow::setActiveCell(const int x, const int y, bool interior) +{ + if (x==mCurX && y==mCurY && mInterior==interior) return; // don't do anything if we're still in the same cell + for (int mx=0; mx<3; ++mx) + { + for (int my=0; my<3; ++my) + { + std::string name = "Map_" + boost::lexical_cast(mx) + "_" + + boost::lexical_cast(my); + + std::string image = mPrefix+"_"+ boost::lexical_cast(x + (mx-1)) + "_" + + boost::lexical_cast(y + (interior ? (my-1) : -1*(my-1))); + + if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) + setImage(name, image); + else + setImage(name, "black.png"); + + if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) + setImage(name+"_fog", image+"_fog"); + else + setImage(name+"_fog", "black.png"); + } + } + mInterior = interior; + mCurX = x; + mCurY = y; +} + +void MapWindow::setPlayerPos(const float x, const float y) +{ + if (mGlobal || mVisible) return; + MyGUI::IntSize size = mLocalMap->getCanvasSize(); + MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); + MyGUI::IntCoord viewsize = mLocalMap->getCoord(); + MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); + mLocalMap->setViewOffset(pos); + + mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); +} + +void MapWindow::setPlayerDir(const float x, const float y) +{ + if (!mVisible) return; + MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); + MyGUI::RotatingSkin* rotatingSubskin = main->castType(); + rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); + float angle = std::atan2(x,y); + rotatingSubskin->setAngle(angle); +} + +void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) +{ + if (_id!=MyGUI::MouseButton::Left) return; + if (!mGlobal) + mLastDragPos = MyGUI::IntPoint(_left, _top); +} + +void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) +{ + if (_id!=MyGUI::MouseButton::Left) return; + + if (!mGlobal) + { + MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; + mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); + + mLastDragPos = MyGUI::IntPoint(_left, _top); + } +} + +void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) +{ + mGlobal = !mGlobal; + mGlobalMap->setVisible(mGlobal); + mLocalMap->setVisible(!mGlobal); + + mButton->setCaption( mGlobal ? "Local" : "World" ); +} + + + diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 240406018..3fa759bf2 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -66,130 +66,20 @@ namespace MWGui class MapWindow : public OEngine::GUI::Layout { public: - MapWindow() - : Layout("openmw_map_window_layout.xml"), mGlobal(false) - { - setCoord(500,0,320,300); - setText("WorldButton", "World"); - setImage("Compass", "textures\\compass.dds"); - - // Obviously you should override this later on - setCellName("No Cell Loaded"); - - getWidget(mLocalMap, "LocalMap"); - getWidget(mGlobalMap, "GlobalMap"); - getWidget(mPlayerArrow, "Compass"); - - getWidget(mButton, "WorldButton"); - mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); - - MyGUI::Button* eventbox; - getWidget(eventbox, "EventBox"); - eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); - eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); - } - - void setVisible(bool b) - { - mMainWidget->setVisible(b); - if (b) - mVisible = true; - else - mVisible = false; - } - - void setCellName(const std::string& cellName) - { - static_cast(mMainWidget)->setCaption(cellName); - } - - // for interiors: cell name, for exteriors: "Cell" - void setCellPrefix(const std::string& prefix) - { - mPrefix = prefix; - } - - void setActiveCell(const int x, const int y, bool interior=false) - { - if (x==mCurX && y==mCurY && mInterior==interior) return; // don't do anything if we're still in the same cell - for (int mx=0; mx<3; ++mx) - { - for (int my=0; my<3; ++my) - { - std::string name = "Map_" + boost::lexical_cast(mx) + "_" - + boost::lexical_cast(my); - - std::string image = mPrefix+"_"+ boost::lexical_cast(x + (mx-1)) + "_" - + boost::lexical_cast(y + (interior ? (my-1) : -1*(my-1))); - - if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) - setImage(name, image); - else - setImage(name, "black.png"); - - if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) - setImage(name+"_fog", image+"_fog"); - else - setImage(name+"_fog", "black.png"); - } - } - mInterior = interior; - mCurX = x; - mCurY = y; - } - - void setPlayerPos(const float x, const float y) - { - if (mGlobal || mVisible) return; - MyGUI::IntSize size = mLocalMap->getCanvasSize(); - MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); - MyGUI::IntCoord viewsize = mLocalMap->getCoord(); - MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); - mLocalMap->setViewOffset(pos); - - mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); - } - - void setPlayerDir(const float x, const float y) - { - if (!mVisible) return; - MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); - MyGUI::RotatingSkin* rotatingSubskin = main->castType(); - rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); - float angle = std::atan2(x,y); - rotatingSubskin->setAngle(angle); - } - - void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) - { - if (_id!=MyGUI::MouseButton::Left) return; - if (!mGlobal) - mLastDragPos = MyGUI::IntPoint(_left, _top); - } - - void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) - { - if (_id!=MyGUI::MouseButton::Left) return; - - if (!mGlobal) - { - MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; - mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); - - mLastDragPos = MyGUI::IntPoint(_left, _top); - } - } - - void onWorldButtonClicked(MyGUI::Widget* _sender) - { - mGlobal = !mGlobal; - mGlobalMap->setVisible(mGlobal); - mLocalMap->setVisible(!mGlobal); - - mButton->setCaption( mGlobal ? "Local" : "World" ); - } + MapWindow(); + void setVisible(bool b); + void setCellName(const std::string& cellName); + void setCellPrefix(const std::string& prefix); + void setActiveCell(const int x, const int y, bool interior=false); + void setPlayerPos(const float x, const float y); + void setPlayerDir(const float x, const float y); + private: + void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onWorldButtonClicked(MyGUI::Widget* _sender); + std::string mPrefix; MyGUI::ScrollView* mLocalMap; MyGUI::ScrollView* mGlobalMap; @@ -199,7 +89,6 @@ namespace MWGui int mCurX, mCurY; bool mInterior; bool mVisible; - bool mGlobal; }; From a1f80e029edff28c3a0464369b5e2c09bc4ba881 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 16:16:31 +0100 Subject: [PATCH 18/20] abstracted some code to be reused for hud --- apps/openmw/mwgui/layouts.cpp | 79 ++++++++++++++++++++--------------- apps/openmw/mwgui/layouts.hpp | 30 ++++++++----- 2 files changed, 65 insertions(+), 44 deletions(-) diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index 195297260..57004906e 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -173,6 +173,8 @@ MapWindow::MapWindow() getWidget(eventbox, "EventBox"); eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); + + LocalMapBase::init(mLocalMap, this); } void MapWindow::setVisible(bool b) @@ -189,40 +191,6 @@ void MapWindow::setCellName(const std::string& cellName) static_cast(mMainWidget)->setCaption(cellName); } -void MapWindow::setCellPrefix(const std::string& prefix) -{ - mPrefix = prefix; -} - -void MapWindow::setActiveCell(const int x, const int y, bool interior) -{ - if (x==mCurX && y==mCurY && mInterior==interior) return; // don't do anything if we're still in the same cell - for (int mx=0; mx<3; ++mx) - { - for (int my=0; my<3; ++my) - { - std::string name = "Map_" + boost::lexical_cast(mx) + "_" - + boost::lexical_cast(my); - - std::string image = mPrefix+"_"+ boost::lexical_cast(x + (mx-1)) + "_" - + boost::lexical_cast(y + (interior ? (my-1) : -1*(my-1))); - - if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) - setImage(name, image); - else - setImage(name, "black.png"); - - if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) - setImage(name+"_fog", image+"_fog"); - else - setImage(name+"_fog", "black.png"); - } - } - mInterior = interior; - mCurX = x; - mCurY = y; -} - void MapWindow::setPlayerPos(const float x, const float y) { if (mGlobal || mVisible) return; @@ -274,5 +242,48 @@ void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) mButton->setCaption( mGlobal ? "Local" : "World" ); } +void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout) +{ + mLocalMap = widget; + mLayout = layout; +} +void LocalMapBase::setCellPrefix(const std::string& prefix) +{ + mPrefix = prefix; +} + +void LocalMapBase::setActiveCell(const int x, const int y, bool interior) +{ + if (x==mCurX && y==mCurY && mInterior==interior) return; // don't do anything if we're still in the same cell + for (int mx=0; mx<3; ++mx) + { + for (int my=0; my<3; ++my) + { + std::string name = "Map_" + boost::lexical_cast(mx) + "_" + + boost::lexical_cast(my); + + std::string image = mPrefix+"_"+ boost::lexical_cast(x + (mx-1)) + "_" + + boost::lexical_cast(y + (interior ? (my-1) : -1*(my-1))); + + MyGUI::ImageBox* box; + mLayout->getWidget(box, name); + MyGUI::ImageBox* fog; + mLayout->getWidget(fog, name+"_fog"); + + if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) + box->setImageTexture(image); + else + box->setImageTexture("black.png"); + + if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) + fog->setImageTexture(image+"_fog"); + else + fog->setImageTexture("black.png"); + } + } + mInterior = interior; + mCurX = x; + mCurY = y; +} diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 3fa759bf2..8029dabe7 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -31,7 +31,24 @@ namespace MWGui { - class HUD : public OEngine::GUI::Layout + class LocalMapBase + { + public: + void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout); + + void setCellPrefix(const std::string& prefix); + void setActiveCell(const int x, const int y, bool interior=false); + + protected: + int mCurX, mCurY; + bool mInterior; + MyGUI::ScrollView* mLocalMap; + std::string mPrefix; + + OEngine::GUI::Layout* mLayout; + }; + + class HUD : public OEngine::GUI::Layout, public LocalMapBase { public: HUD(int width, int height, int fpsLevel); @@ -45,7 +62,6 @@ namespace MWGui void setFPS(float fps); void setTriangleCount(size_t count); void setBatchCount(size_t count); - void setPlayerDir(const float x, const float y); MyGUI::ProgressPtr health, magicka, stamina; @@ -63,31 +79,25 @@ namespace MWGui MyGUI::TextBox* batchcounter; }; - class MapWindow : public OEngine::GUI::Layout + class MapWindow : public OEngine::GUI::Layout, public LocalMapBase { public: MapWindow(); void setVisible(bool b); - void setCellName(const std::string& cellName); - void setCellPrefix(const std::string& prefix); - void setActiveCell(const int x, const int y, bool interior=false); void setPlayerPos(const float x, const float y); void setPlayerDir(const float x, const float y); + void setCellName(const std::string& cellName); private: void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onWorldButtonClicked(MyGUI::Widget* _sender); - std::string mPrefix; - MyGUI::ScrollView* mLocalMap; MyGUI::ScrollView* mGlobalMap; MyGUI::ImageBox* mPlayerArrow; MyGUI::Button* mButton; MyGUI::IntPoint mLastDragPos; - int mCurX, mCurY; - bool mInterior; bool mVisible; bool mGlobal; }; From 7a3034701fb488472da92a95a40a0a1920dbf9e9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 16:51:56 +0100 Subject: [PATCH 19/20] functional HUD map --- apps/openmw/mwgui/layouts.cpp | 13 ++++++++ apps/openmw/mwgui/layouts.hpp | 3 +- apps/openmw/mwgui/window_manager.cpp | 13 ++++++-- files/mygui/openmw_hud_layout.xml | 46 +++++++++++++++++++++++++--- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index 57004906e..34d0cf1b6 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -61,6 +61,8 @@ HUD::HUD(int width, int height, int fpsLevel) setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds"); setSpellStatus(65, 100); setEffect("icons\\s\\tx_s_chameleon.dds"); + + LocalMapBase::init(minimap, this); } void HUD::setFPS(float fps) @@ -152,6 +154,17 @@ void HUD::setPlayerDir(const float x, const float y) rotatingSubskin->setAngle(angle); } +void HUD::setPlayerPos(const float x, const float y) +{ + MyGUI::IntSize size = minimap->getCanvasSize(); + MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); + MyGUI::IntCoord viewsize = minimap->getCoord(); + MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); + + minimap->setViewOffset(pos); + compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); +} + MapWindow::MapWindow() : Layout("openmw_map_window_layout.xml"), mGlobal(false) { diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 8029dabe7..6601850ca 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -63,13 +63,14 @@ namespace MWGui void setTriangleCount(size_t count); void setBatchCount(size_t count); void setPlayerDir(const float x, const float y); + void setPlayerPos(const float x, const float y); MyGUI::ProgressPtr health, magicka, stamina; MyGUI::ImageBox *weapImage, *spellImage; MyGUI::ProgressPtr weapStatus, spellStatus; MyGUI::WidgetPtr effectBox; MyGUI::ImageBox* effect1; - MyGUI::ImageBox* minimap; + MyGUI::ScrollView* minimap; MyGUI::ImageBox* compass; MyGUI::ImageBox* crosshair; diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 5137a109f..fa6dedc77 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -405,17 +405,24 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) { if (!(cell->cell->data.flags & ESM::Cell::Interior)) { + std::string name; if (cell->cell->name != "") - map->setCellName( cell->cell->name ); + name = cell->cell->name; else - map->setCellName( cell->cell->region ); + name = cell->cell->region; + + map->setCellName( name ); + map->setCellPrefix("Cell"); + hud->setCellPrefix("Cell"); map->setActiveCell( cell->cell->data.gridX, cell->cell->data.gridY ); + hud->setActiveCell( cell->cell->data.gridX, cell->cell->data.gridY ); } else { map->setCellName( cell->cell->name ); map->setCellPrefix( cell->cell->name ); + hud->setCellPrefix( cell->cell->name ); } } @@ -423,11 +430,13 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) void WindowManager::setInteriorMapTexture(const int x, const int y) { map->setActiveCell(x,y, true); + hud->setActiveCell(x,y, true); } void WindowManager::setPlayerPos(const float x, const float y) { map->setPlayerPos(x,y); + hud->setPlayerPos(x,y); } void WindowManager::setPlayerDir(const float x, const float y) diff --git a/files/mygui/openmw_hud_layout.xml b/files/mygui/openmw_hud_layout.xml index 56708eb18..20370770e 100644 --- a/files/mygui/openmw_hud_layout.xml +++ b/files/mygui/openmw_hud_layout.xml @@ -38,10 +38,48 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a6259a1b0d83fef93d49ec96638853c525f80ad5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 23 Mar 2012 17:37:56 +0100 Subject: [PATCH 20/20] bugfixes --- apps/openmw/mwgui/layouts.cpp | 4 +++- apps/openmw/mwgui/layouts.hpp | 1 + apps/openmw/mwrender/localmap.cpp | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index 34d0cf1b6..5c5a977d3 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -264,11 +264,12 @@ void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout) void LocalMapBase::setCellPrefix(const std::string& prefix) { mPrefix = prefix; + mChanged = true; } void LocalMapBase::setActiveCell(const int x, const int y, bool interior) { - if (x==mCurX && y==mCurY && mInterior==interior) return; // don't do anything if we're still in the same cell + if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell for (int mx=0; mx<3; ++mx) { for (int my=0; my<3; ++my) @@ -298,5 +299,6 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior) mInterior = interior; mCurX = x; mCurY = y; + mChanged = false; } diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 6601850ca..8d9a41a22 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -44,6 +44,7 @@ namespace MWGui bool mInterior; MyGUI::ScrollView* mLocalMap; std::string mPrefix; + bool mChanged; OEngine::GUI::Layout* mLayout; }; diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 83fe40166..b83a98220 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -153,8 +153,9 @@ void LocalMap::render(const float x, const float y, // make everything visible mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); - mCellCamera->setPosition(Vector3(x, zhigh, y)); - mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); + mCellCamera->setPosition(Vector3(x, zhigh+100000, y)); + //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); + mCellCamera->setFarClipDistance(0); // infinite mCellCamera->setOrthoWindow(xw, yw);