1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-10 21:40:15 +00:00

global map rendering

This commit is contained in:
scrawl 2012-09-20 13:56:37 +02:00
parent 32de090079
commit 86cfc91ef3
14 changed files with 233 additions and 22 deletions

View File

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

View File

@ -307,6 +307,8 @@ void OMW::Engine::go()
//addResourcesDirectory(mResDir); //addResourcesDirectory(mResDir);
addResourcesDirectory(mCfgMgr.getCachePath ().string());
addResourcesDirectory(mResDir / "mygui"); addResourcesDirectory(mResDir / "mygui");
addResourcesDirectory(mResDir / "water"); addResourcesDirectory(mResDir / "water");
addResourcesDirectory(mResDir / "gbuffer"); addResourcesDirectory(mResDir / "gbuffer");
@ -367,6 +369,7 @@ void OMW::Engine::go()
pos.pos[2] = 0; pos.pos[2] = 0;
mEnvironment.getWorld()->renderPlayer(); mEnvironment.getWorld()->renderPlayer();
mEnvironment.getWorld()->renderGlobalMap();
if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName)) if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName))
{ {

View File

@ -279,6 +279,7 @@ namespace MWBase
virtual void togglePlayerLooking(bool enable) = 0; virtual void togglePlayerLooking(bool enable) = 0;
virtual void renderPlayer() = 0; virtual void renderPlayer() = 0;
virtual void renderGlobalMap() = 0;
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
}; };

View File

@ -3,6 +3,7 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <OgreVector2.h> #include <OgreVector2.h>
#include <OgreTextureManager.h>
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -254,8 +255,11 @@ MapWindow::MapWindow(MWBase::WindowManager& parWindowManager) :
getWidget(mLocalMap, "LocalMap"); getWidget(mLocalMap, "LocalMap");
getWidget(mGlobalMap, "GlobalMap"); getWidget(mGlobalMap, "GlobalMap");
getWidget(mGlobalMapImage, "GlobalMapImage");
getWidget(mPlayerArrow, "Compass"); getWidget(mPlayerArrow, "Compass");
mGlobalMap->setVisible (false);
getWidget(mButton, "WorldButton"); getWidget(mButton, "WorldButton");
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
mButton->setCaptionWithReplacing("#{sWorld}"); 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) void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{ {
if (_id!=MyGUI::MouseButton::Left) return; 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) void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{ {
if (_id!=MyGUI::MouseButton::Left) return; if (_id!=MyGUI::MouseButton::Left) return;
if (!mGlobal) MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
{
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff );
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) void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
@ -307,3 +312,12 @@ void MapWindow::onPinToggled()
{ {
mWindowManager.setMinimapVisibility(!mPinned); 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());
}

View File

@ -62,12 +62,15 @@ namespace MWGui
void setCellName(const std::string& cellName); void setCellName(const std::string& cellName);
virtual void open();
private: private:
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); 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 onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onWorldButtonClicked(MyGUI::Widget* _sender); void onWorldButtonClicked(MyGUI::Widget* _sender);
MyGUI::ScrollView* mGlobalMap; MyGUI::ScrollView* mGlobalMap;
MyGUI::ImageBox* mGlobalMapImage;
MyGUI::ImageBox* mPlayerArrow; MyGUI::ImageBox* mPlayerArrow;
MyGUI::Button* mButton; MyGUI::Button* mButton;
MyGUI::IntPoint mLastDragPos; MyGUI::IntPoint mLastDragPos;

View File

@ -0,0 +1,145 @@
#include "globalmap.hpp"
#include <OgreImage.h>
#include <OgreTextureManager.h>
#include <OgreColourValue.h>
#include <OgreHardwareVertexBuffer.h>
#include <OgreRoot.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include <components/esm_store/store.hpp>
#include <components/esm_store/reclists.hpp>
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; cellY<cellSize; ++cellY)
{
for (int cellX=0; cellX<cellSize; ++cellX)
{
int vertexX = float(cellX)/float(cellSize) * ESM::Land::LAND_SIZE;
int vertexY = float(cellY)/float(cellSize) * ESM::Land::LAND_SIZE;
int texelX = (x+30) * cellSize + cellX;
int texelY = (height-1) - ((y+30) * cellSize + cellY);
Ogre::ColourValue waterShallowColour(0.15, 0.2, 0.19);
Ogre::ColourValue waterDeepColour(0.1, 0.14, 0.13);
Ogre::ColourValue groundColour(0.254, 0.19, 0.13);
Ogre::ColourValue mountainColour(0.05, 0.05, 0.05);
Ogre::ColourValue hillColour(0.16, 0.12, 0.08);
float mountainHeight = 15000.f;
float hillHeight = 2500.f;
unsigned char r,g,b;
if (land)
{
float landHeight = land->landData->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();
}
}

View File

@ -0,0 +1,23 @@
#ifndef _GAME_RENDER_GLOBALMAP_H
#define _GAME_RENDER_GLOBALMAP_H
#include <string>
namespace MWRender
{
class GlobalMap
{
public:
GlobalMap(const std::string& cacheDir);
void render();
private:
std::string mCacheDir;
};
}
#endif

View File

@ -35,6 +35,7 @@
#include "compositors.hpp" #include "compositors.hpp"
#include "npcanimation.hpp" #include "npcanimation.hpp"
#include "externalrendering.hpp" #include "externalrendering.hpp"
#include "globalmap.hpp"
using namespace MWRender; using namespace MWRender;
using namespace Ogre; using namespace Ogre;
@ -43,7 +44,7 @@ namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) 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 // select best shader mode
bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); 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().setDefaultTextureFiltering(tfo);
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 ); 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(); ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
// causes light flicker in opengl when moving.. // causes light flicker in opengl when moving..
@ -160,6 +162,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mDebugging = new Debugging(mMwRoot, engine); mDebugging = new Debugging(mMwRoot, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this); mLocalMap = new MWRender::LocalMap(&mRendering, this);
mGlobalMap = new GlobalMap(cacheDir.string());
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
} }
@ -176,6 +180,7 @@ RenderingManager::~RenderingManager ()
delete mOcclusionQuery; delete mOcclusionQuery;
delete mCompositors; delete mCompositors;
delete mWater; delete mWater;
delete mGlobalMap;
} }
MWRender::SkyManager* RenderingManager::getSkyManager() MWRender::SkyManager* RenderingManager::getSkyManager()
@ -887,4 +892,9 @@ void RenderingManager::setupExternalRendering (MWRender::ExternalRendering& rend
rendering.setup (mRendering.getScene()); rendering.setup (mRendering.getScene());
} }
void RenderingManager::renderGlobalMap ()
{
mGlobalMap->render ();
}
} // namespace } // namespace

View File

@ -44,6 +44,7 @@ namespace MWRender
class Water; class Water;
class Compositors; class Compositors;
class ExternalRendering; class ExternalRendering;
class GlobalMap;
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener {
@ -194,6 +195,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void setupExternalRendering (MWRender::ExternalRendering& rendering); void setupExternalRendering (MWRender::ExternalRendering& rendering);
void renderGlobalMap();
protected: protected:
virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowResized(Ogre::RenderWindow* rw);
virtual void windowClosed(Ogre::RenderWindow* rw); virtual void windowClosed(Ogre::RenderWindow* rw);
@ -218,6 +221,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
MWRender::Water *mWater; MWRender::Water *mWater;
GlobalMap* mGlobalMap;
OEngine::Render::OgreRenderer &mRendering; OEngine::Render::OgreRenderer &mRendering;
MWRender::Objects mObjects; MWRender::Objects mObjects;

View File

@ -1237,6 +1237,11 @@ namespace MWWorld
mRendering->renderPlayer(mPlayer->getPlayer()); mRendering->renderPlayer(mPlayer->getPlayer());
} }
void World::renderGlobalMap ()
{
mRendering->renderGlobalMap ();
}
void World::setupExternalRendering (MWRender::ExternalRendering& rendering) void World::setupExternalRendering (MWRender::ExternalRendering& rendering)
{ {
mRendering->setupExternalRendering (rendering); mRendering->setupExternalRendering (rendering);

View File

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

View File

@ -84,11 +84,7 @@ void Land::loadData()
{ {
mEsm->restoreContext(context); mEsm->restoreContext(context);
//esm.getHNExact(landData->normals, sizeof(VNML), "VNML"); mEsm->getHNExact(landData->normals, sizeof(VNML), "VNML");
if (mEsm->isNextSub("VNML"))
{
mEsm->skipHSubSize(12675);
}
VHGT rawHeights; VHGT rawHeights;

View File

@ -60,7 +60,7 @@ struct Land
{ {
float heightOffset; float heightOffset;
float heights[LAND_NUM_VERTS]; float heights[LAND_NUM_VERTS];
//float normals[LAND_NUM_VERTS * 3]; float normals[LAND_NUM_VERTS * 3];
uint16_t textures[LAND_NUM_TEXTURES]; uint16_t textures[LAND_NUM_TEXTURES];
bool usingColours; bool usingColours;

View File

@ -3,10 +3,6 @@
<MyGUI type="Layout"> <MyGUI type="Layout">
<Widget type="Window" skin="MW_Window_Pinnable" layer="Windows" position="0 0 300 300" name="_Main"> <Widget type="Window" skin="MW_Window_Pinnable" layer="Windows" position="0 0 300 300" name="_Main">
<!-- Global map -->
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="GlobalMap">
</Widget>
<!-- Local map --> <!-- Local map -->
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="LocalMap"> <Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="LocalMap">
<Property key="CanvasSize" value="1536 1536"/> <Property key="CanvasSize" value="1536 1536"/>
@ -15,9 +11,18 @@
<Property key="ImageTexture" value="textures\compass.dds"/> <Property key="ImageTexture" value="textures\compass.dds"/>
</Widget> </Widget>
<Widget type="Button" skin="" position="0 0 1536 1536" name="EventBox" align="ALIGN_STRETCH"/>
</Widget> </Widget>
<!-- Global map -->
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="GlobalMap">
<Property key="CanvasSize" value="1536 1536"/>
<Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Stretch" name="GlobalMapImage">
</Widget>
</Widget>
<Widget type="Button" skin="" position="0 0 300 300" name="EventBox" align="ALIGN_STRETCH"/>
<!-- World button --> <!-- World button -->
<Widget type="AutoSizedButton" skin="MW_Button" position="213 233 61 22" align="ALIGN_BOTTOM ALIGN_RIGHT" name="WorldButton"> <Widget type="AutoSizedButton" skin="MW_Button" position="213 233 61 22" align="ALIGN_BOTTOM ALIGN_RIGHT" name="WorldButton">
<Property key="ExpandDirection" value="Left"/> <Property key="ExpandDirection" value="Left"/>