forked from mirror/openmw-tes3mp
global map rendering
This commit is contained in:
parent
32de090079
commit
86cfc91ef3
14 changed files with 233 additions and 22 deletions
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <OgreVector2.h>
|
||||
#include <OgreTextureManager.h>
|
||||
|
||||
#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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
145
apps/openmw/mwrender/globalmap.cpp
Normal file
145
apps/openmw/mwrender/globalmap.cpp
Normal 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();
|
||||
}
|
||||
|
||||
}
|
23
apps/openmw/mwrender/globalmap.hpp
Normal file
23
apps/openmw/mwrender/globalmap.hpp
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1237,6 +1237,11 @@ namespace MWWorld
|
|||
mRendering->renderPlayer(mPlayer->getPlayer());
|
||||
}
|
||||
|
||||
void World::renderGlobalMap ()
|
||||
{
|
||||
mRendering->renderGlobalMap ();
|
||||
}
|
||||
|
||||
void World::setupExternalRendering (MWRender::ExternalRendering& rendering)
|
||||
{
|
||||
mRendering->setupExternalRendering (rendering);
|
||||
|
|
|
@ -310,6 +310,7 @@ namespace MWWorld
|
|||
}
|
||||
|
||||
virtual void renderPlayer();
|
||||
virtual void renderGlobalMap();
|
||||
|
||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
<MyGUI type="Layout">
|
||||
<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 -->
|
||||
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="LocalMap">
|
||||
<Property key="CanvasSize" value="1536 1536"/>
|
||||
|
@ -15,9 +11,18 @@
|
|||
<Property key="ImageTexture" value="textures\compass.dds"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position="0 0 1536 1536" name="EventBox" align="ALIGN_STRETCH"/>
|
||||
</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 -->
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="213 233 61 22" align="ALIGN_BOTTOM ALIGN_RIGHT" name="WorldButton">
|
||||
<Property key="ExpandDirection" value="Left"/>
|
||||
|
|
Loading…
Reference in a new issue