diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 2542ef350e..95d15f1184 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -16,7 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows - compositors characterpreview externalrendering + compositors characterpreview externalrendering globalmap ) add_openmw_dir (mwinput diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index d10ae99794..b526d8e0d4 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -307,6 +307,8 @@ void OMW::Engine::go() //addResourcesDirectory(mResDir); + addResourcesDirectory(mCfgMgr.getCachePath ().string()); + addResourcesDirectory(mResDir / "mygui"); addResourcesDirectory(mResDir / "water"); addResourcesDirectory(mResDir / "gbuffer"); @@ -367,6 +369,7 @@ void OMW::Engine::go() pos.pos[2] = 0; mEnvironment.getWorld()->renderPlayer(); + mEnvironment.getWorld()->renderGlobalMap(); if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName)) { diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index b841e5427a..a725d389de 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -279,6 +279,7 @@ namespace MWBase virtual void togglePlayerLooking(bool enable) = 0; virtual void renderPlayer() = 0; + virtual void renderGlobalMap() = 0; virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; }; diff --git a/apps/openmw/mwgui/map_window.cpp b/apps/openmw/mwgui/map_window.cpp index f92e4ee4fc..b2b8538ba3 100644 --- a/apps/openmw/mwgui/map_window.cpp +++ b/apps/openmw/mwgui/map_window.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" @@ -254,8 +255,11 @@ MapWindow::MapWindow(MWBase::WindowManager& parWindowManager) : getWidget(mLocalMap, "LocalMap"); getWidget(mGlobalMap, "GlobalMap"); + getWidget(mGlobalMapImage, "GlobalMapImage"); getWidget(mPlayerArrow, "Compass"); + mGlobalMap->setVisible (false); + getWidget(mButton, "WorldButton"); mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); mButton->setCaptionWithReplacing("#{sWorld}"); @@ -276,21 +280,22 @@ void MapWindow::setCellName(const std::string& cellName) 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); + 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 ); + MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; - mLastDragPos = MyGUI::IntPoint(_left, _top); - } + if (!mGlobal) + mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); + else + mGlobalMap->setViewOffset( mGlobalMap->getViewOffset() + diff ); + + + mLastDragPos = MyGUI::IntPoint(_left, _top); } void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) @@ -307,3 +312,12 @@ void MapWindow::onPinToggled() { mWindowManager.setMinimapVisibility(!mPinned); } + +void MapWindow::open() +{ + mGlobalMapImage->setImageTexture("GlobalMap.png"); + + Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().getByName("GlobalMap.png"); + mGlobalMap->setCanvasSize (tex->getWidth(), tex->getHeight()); + mGlobalMapImage->setSize(tex->getWidth(), tex->getHeight()); +} diff --git a/apps/openmw/mwgui/map_window.hpp b/apps/openmw/mwgui/map_window.hpp index 1203233bf9..abb6a06536 100644 --- a/apps/openmw/mwgui/map_window.hpp +++ b/apps/openmw/mwgui/map_window.hpp @@ -62,12 +62,15 @@ namespace MWGui void setCellName(const std::string& cellName); + virtual void open(); + 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); MyGUI::ScrollView* mGlobalMap; + MyGUI::ImageBox* mGlobalMapImage; MyGUI::ImageBox* mPlayerArrow; MyGUI::Button* mButton; MyGUI::IntPoint mLastDragPos; diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp new file mode 100644 index 0000000000..2edd325958 --- /dev/null +++ b/apps/openmw/mwrender/globalmap.cpp @@ -0,0 +1,145 @@ +#include "globalmap.hpp" + +#include +#include +#include +#include +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include +#include + +namespace MWRender +{ + + GlobalMap::GlobalMap(const std::string &cacheDir) + : mCacheDir(cacheDir) + { + } + + + void GlobalMap::render () + { + + Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().getByName ("GlobalMap.png"); + + if (tex.isNull ()) + { + + int cellSize = 24; + + Ogre::Image image; + + int width = cellSize*61; + int height = cellSize*61; + + Ogre::uchar data[width * height * 3]; + + for (int x = -30; x <= 30; ++x) + { + for (int y = -30; y <= 30; ++y) + { + ESM::Land* land = MWBase::Environment::get().getWorld ()->getStore ().lands.search (x,y); + + if (land) + { + if (!land->dataLoaded) + { + land->loadData(); + } + } + + for (int cellY=0; cellYlandData->heights[vertexY * ESM::Land::LAND_SIZE + vertexX]; + + + if (landHeight >= 0) + { + if (landHeight >= hillHeight) + { + float factor = std::min(1.f, float(landHeight-hillHeight)/mountainHeight); + r = (hillColour.r * (1-factor) + mountainColour.r * factor) * 255; + g = (hillColour.g * (1-factor) + mountainColour.g * factor) * 255; + b = (hillColour.b * (1-factor) + mountainColour.b * factor) * 255; + } + else + { + float factor = std::min(1.f, float(landHeight)/hillHeight); + r = (groundColour.r * (1-factor) + hillColour.r * factor) * 255; + g = (groundColour.g * (1-factor) + hillColour.g * factor) * 255; + b = (groundColour.b * (1-factor) + hillColour.b * factor) * 255; + } + } + else + { + if (landHeight >= -100) + { + float factor = std::min(1.f, -1*landHeight/100.f); + r = (((waterShallowColour+groundColour)/2).r * (1-factor) + waterShallowColour.r * factor) * 255; + g = (((waterShallowColour+groundColour)/2).g * (1-factor) + waterShallowColour.g * factor) * 255; + b = (((waterShallowColour+groundColour)/2).b * (1-factor) + waterShallowColour.b * factor) * 255; + } + else + { + float factor = std::min(1.f, -1*(landHeight-100)/1000.f); + r = (waterShallowColour.r * (1-factor) + waterDeepColour.r * factor) * 255; + g = (waterShallowColour.g * (1-factor) + waterDeepColour.g * factor) * 255; + b = (waterShallowColour.b * (1-factor) + waterDeepColour.b * factor) * 255; + } + } + + } + else + { + r = waterDeepColour.r * 255; + g = waterDeepColour.g * 255; + b = waterDeepColour.b * 255; + } + + data[texelY * height * 3 + texelX * 3] = r; + data[texelY * height * 3 + texelX * 3+1] = g; + data[texelY * height * 3 + texelX * 3+2] = b; + } + assert(0); + } + } + } + + image.loadDynamicImage (data, width, height, Ogre::PF_B8G8R8); + + image.save (mCacheDir + "/GlobalMap.png"); + + tex = Ogre::TextureManager::getSingleton ().createManual ("GlobalMap.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, width, height, 0, Ogre::PF_B8G8R8, Ogre::TU_DEFAULT); + tex->loadImage(image); + } + tex->load(); + } + +} diff --git a/apps/openmw/mwrender/globalmap.hpp b/apps/openmw/mwrender/globalmap.hpp new file mode 100644 index 0000000000..b7c199dcf0 --- /dev/null +++ b/apps/openmw/mwrender/globalmap.hpp @@ -0,0 +1,23 @@ +#ifndef _GAME_RENDER_GLOBALMAP_H +#define _GAME_RENDER_GLOBALMAP_H + +#include + +namespace MWRender +{ + + class GlobalMap + { + public: + GlobalMap(const std::string& cacheDir); + + void render(); + + private: + std::string mCacheDir; + }; + +} + +#endif + diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 308a016888..603d2e16c2 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -35,6 +35,7 @@ #include "compositors.hpp" #include "npcanimation.hpp" #include "externalrendering.hpp" +#include "globalmap.hpp" using namespace MWRender; using namespace Ogre; @@ -43,7 +44,7 @@ namespace MWRender { RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) - :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine) + : mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine) { // select best shader mode bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); @@ -100,7 +101,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const MaterialManager::getSingleton().setDefaultTextureFiltering(tfo); MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 ); - // Load resources + ResourceGroupManager::getSingleton ().declareResource ("GlobalMap.png", "Texture", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); // causes light flicker in opengl when moving.. @@ -160,6 +162,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mDebugging = new Debugging(mMwRoot, engine); mLocalMap = new MWRender::LocalMap(&mRendering, this); + mGlobalMap = new GlobalMap(cacheDir.string()); + setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); } @@ -176,6 +180,7 @@ RenderingManager::~RenderingManager () delete mOcclusionQuery; delete mCompositors; delete mWater; + delete mGlobalMap; } MWRender::SkyManager* RenderingManager::getSkyManager() @@ -887,4 +892,9 @@ void RenderingManager::setupExternalRendering (MWRender::ExternalRendering& rend rendering.setup (mRendering.getScene()); } +void RenderingManager::renderGlobalMap () +{ + mGlobalMap->render (); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index e994e4909c..24ec8b15b4 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -44,6 +44,7 @@ namespace MWRender class Water; class Compositors; class ExternalRendering; + class GlobalMap; class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { @@ -194,6 +195,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void setupExternalRendering (MWRender::ExternalRendering& rendering); + void renderGlobalMap(); + protected: virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowClosed(Ogre::RenderWindow* rw); @@ -218,6 +221,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList MWRender::Water *mWater; + GlobalMap* mGlobalMap; + OEngine::Render::OgreRenderer &mRendering; MWRender::Objects mObjects; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 8316116186..592f2b4b62 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1237,6 +1237,11 @@ namespace MWWorld mRendering->renderPlayer(mPlayer->getPlayer()); } + void World::renderGlobalMap () + { + mRendering->renderGlobalMap (); + } + void World::setupExternalRendering (MWRender::ExternalRendering& rendering) { mRendering->setupExternalRendering (rendering); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index d48a0ec814..dfb9238f50 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -310,6 +310,7 @@ namespace MWWorld } virtual void renderPlayer(); + virtual void renderGlobalMap(); virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); }; diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index 96afdf8316..024767e90a 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -84,11 +84,7 @@ void Land::loadData() { mEsm->restoreContext(context); - //esm.getHNExact(landData->normals, sizeof(VNML), "VNML"); - if (mEsm->isNextSub("VNML")) - { - mEsm->skipHSubSize(12675); - } + mEsm->getHNExact(landData->normals, sizeof(VNML), "VNML"); VHGT rawHeights; diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index ebc314a280..955fb95181 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -60,7 +60,7 @@ struct Land { float heightOffset; float heights[LAND_NUM_VERTS]; - //float normals[LAND_NUM_VERTS * 3]; + float normals[LAND_NUM_VERTS * 3]; uint16_t textures[LAND_NUM_TEXTURES]; bool usingColours; diff --git a/files/mygui/openmw_map_window.layout b/files/mygui/openmw_map_window.layout index 8b64de22e1..2b9b439062 100644 --- a/files/mygui/openmw_map_window.layout +++ b/files/mygui/openmw_map_window.layout @@ -3,10 +3,6 @@ - - - - @@ -15,9 +11,18 @@ - + + + + + + + + + +