1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-24 18:39:59 +00:00

Restore display of global map overlay, no exploration yet

This commit is contained in:
scrawl 2015-05-28 18:49:24 +02:00
parent 72d0a69132
commit 7a1408cfed
4 changed files with 114 additions and 50 deletions

View File

@ -582,7 +582,6 @@ namespace MWGui
, LocalMapBase(customMarkers, localMapRender) , LocalMapBase(customMarkers, localMapRender)
, NoDrop(drag, mMainWidget) , NoDrop(drag, mMainWidget)
, mGlobalMap(0) , mGlobalMap(0)
, mGlobalMapTexture(NULL)
, mGlobalMapImage(NULL) , mGlobalMapImage(NULL)
, mGlobalMapOverlay(NULL) , mGlobalMapOverlay(NULL)
, mGlobal(false) , mGlobal(false)
@ -736,17 +735,17 @@ namespace MWGui
mGlobalMap->setCanvasSize (mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight()); mGlobalMap->setCanvasSize (mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
mGlobalMapImage->setSize(mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight()); mGlobalMapImage->setSize(mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
mGlobalMapTexture = new osgMyGUI::OSGTexture(mGlobalMapRender->getBaseTexture()); mGlobalMapTexture.reset(new osgMyGUI::OSGTexture(mGlobalMapRender->getBaseTexture()));
mGlobalMapImage->setRenderItemTexture(mGlobalMapTexture); mGlobalMapImage->setRenderItemTexture(mGlobalMapTexture.get());
mGlobalMapImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f)); mGlobalMapImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f));
//mGlobalMapOverlay->setImageTexture("GlobalMapOverlay"); mGlobalMapOverlayTexture.reset(new osgMyGUI::OSGTexture(mGlobalMapRender->getOverlayTexture()));
mGlobalMapOverlay->setRenderItemTexture(mGlobalMapOverlayTexture.get());
mGlobalMapOverlay->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f));
} }
MapWindow::~MapWindow() MapWindow::~MapWindow()
{ {
delete mGlobalMapTexture;
delete mGlobalMapRender; delete mGlobalMapRender;
} }

View File

@ -212,7 +212,8 @@ namespace MWGui
void globalMapUpdatePlayer(); void globalMapUpdatePlayer();
MyGUI::ScrollView* mGlobalMap; MyGUI::ScrollView* mGlobalMap;
MyGUI::ITexture* mGlobalMapTexture; std::auto_ptr<MyGUI::ITexture> mGlobalMapTexture;
std::auto_ptr<MyGUI::ITexture> mGlobalMapOverlayTexture;
MyGUI::ImageBox* mGlobalMapImage; MyGUI::ImageBox* mGlobalMapImage;
MyGUI::ImageBox* mGlobalMapOverlay; MyGUI::ImageBox* mGlobalMapOverlay;
MyGUI::ImageBox* mPlayerArrowLocal; MyGUI::ImageBox* mPlayerArrowLocal;

View File

@ -5,8 +5,11 @@
#include <osg/Image> #include <osg/Image>
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osgDB/WriteFile>
#include <components/loadinglistener/loadinglistener.hpp> #include <components/loadinglistener/loadinglistener.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/files/memorystream.hpp>
#include <components/esm/globalmap.hpp> #include <components/esm/globalmap.hpp>
@ -134,7 +137,12 @@ namespace MWRender
} }
mBaseTexture = new osg::Texture2D; mBaseTexture = new osg::Texture2D;
mBaseTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
mBaseTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
mBaseTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
mBaseTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
mBaseTexture->setImage(image); mBaseTexture->setImage(image);
mBaseTexture->setResizeNonPowerOfTwoHint(false);
clear(); clear();
@ -200,14 +208,25 @@ namespace MWRender
void GlobalMap::clear() void GlobalMap::clear()
{ {
/* if (!mOverlayImage)
Ogre::uchar* buffer = OGRE_ALLOC_T(Ogre::uchar, mWidth * mHeight * 4, Ogre::MEMCATEGORY_GENERAL); {
memset(buffer, 0, mWidth * mHeight * 4); mOverlayImage = new osg::Image;
mOverlayImage->allocateImage(mWidth, mHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE);
assert(mOverlayImage->isDataContiguous());
}
memset(mOverlayImage->data(), 0, mOverlayImage->getTotalSizeInBytes());
mOverlayImage->dirty();
mOverlayImage.loadDynamicImage(&buffer[0], mWidth, mHeight, 1, Ogre::PF_A8B8G8R8, true); // pass ownership of buffer to image if (!mOverlayTexture)
{
mOverlayTexture->load(); mOverlayTexture = new osg::Texture2D;
*/ mOverlayTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
mOverlayTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
mOverlayTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
mOverlayTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
mOverlayTexture->setImage(mOverlayImage);
mOverlayTexture->setResizeNonPowerOfTwoHint(false);
}
} }
void GlobalMap::write(ESM::GlobalMap& map) void GlobalMap::write(ESM::GlobalMap& map)
@ -217,13 +236,35 @@ namespace MWRender
map.mBounds.mMinY = mMinY; map.mBounds.mMinY = mMinY;
map.mBounds.mMaxY = mMaxY; map.mBounds.mMaxY = mMaxY;
/* std::ostringstream ostream;
Ogre::DataStreamPtr encoded = mOverlayImage.encode("png"); osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png");
map.mImageData.resize(encoded->size()); if (!readerwriter)
encoded->read(&map.mImageData[0], encoded->size()); {
*/ std::cerr << "Can't write map overlay: no png readerwriter found" << std::endl;
return;
}
osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*mOverlayImage, ostream);
if (!result.success())
{
std::cerr << "Can't write map overlay: " << result.message() << std::endl;
return;
}
std::string data = ostream.str();
map.mImageData = std::vector<char>(data.begin(), data.end());
} }
struct Box
{
int mLeft, mRight, mTop, mBottom;
Box(int left, int right, int top, int bottom)
: mLeft(left), mRight(right), mTop(top), mBottom(bottom)
{
}
};
void GlobalMap::read(ESM::GlobalMap& map) void GlobalMap::read(ESM::GlobalMap& map)
{ {
const ESM::GlobalMap::Bounds& bounds = map.mBounds; const ESM::GlobalMap::Bounds& bounds = map.mBounds;
@ -237,17 +278,35 @@ namespace MWRender
|| bounds.mMinY > bounds.mMaxY) || bounds.mMinY > bounds.mMaxY)
throw std::runtime_error("invalid map bounds"); throw std::runtime_error("invalid map bounds");
/* if (!map.mImageData.size())
Ogre::Image image; return;
Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&map.mImageData[0], map.mImageData.size()));
image.load(stream, "png"); Files::IMemStream istream(&map.mImageData[0], map.mImageData.size());
osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png");
if (!readerwriter)
{
std::cerr << "Can't read map overlay: no png readerwriter found" << std::endl;
return;
}
osgDB::ReaderWriter::ReadResult result = readerwriter->readImage(istream);
if (!result.success())
{
std::cerr << "Can't read map overlay: " << result.message() << std::endl;
return;
}
osg::ref_ptr<osg::Image> image = result.getImage();
int imageWidth = image->s();
int imageHeight = image->t();
int xLength = (bounds.mMaxX-bounds.mMinX+1); int xLength = (bounds.mMaxX-bounds.mMinX+1);
int yLength = (bounds.mMaxY-bounds.mMinY+1); int yLength = (bounds.mMaxY-bounds.mMinY+1);
// Size of one cell in image space // Size of one cell in image space
int cellImageSizeSrc = image.getWidth() / xLength; int cellImageSizeSrc = imageWidth / xLength;
if (int(image.getHeight() / yLength) != cellImageSizeSrc) if (int(imageHeight / yLength) != cellImageSizeSrc)
throw std::runtime_error("cell size must be quadratic"); throw std::runtime_error("cell size must be quadratic");
// If cell bounds of the currently loaded content and the loaded savegame do not match, // If cell bounds of the currently loaded content and the loaded savegame do not match,
@ -266,39 +325,40 @@ namespace MWRender
int topDiff = (bounds.mMaxY - mMaxY); int topDiff = (bounds.mMaxY - mMaxY);
int rightDiff = (bounds.mMaxX - mMaxX); int rightDiff = (bounds.mMaxX - mMaxX);
int bottomDiff = (mMinY - bounds.mMinY); int bottomDiff = (mMinY - bounds.mMinY);
Ogre::Image::Box srcBox ( std::max(0, leftDiff * cellImageSizeSrc),
Box srcBox ( std::max(0, leftDiff * cellImageSizeSrc),
std::max(0, topDiff * cellImageSizeSrc), std::max(0, topDiff * cellImageSizeSrc),
std::min(image.getWidth(), image.getWidth() - rightDiff * cellImageSizeSrc), std::min(imageWidth, imageWidth - rightDiff * cellImageSizeSrc),
std::min(image.getHeight(), image.getHeight() - bottomDiff * cellImageSizeSrc)); std::min(imageHeight, imageHeight - bottomDiff * cellImageSizeSrc));
Ogre::Image::Box destBox ( std::max(0, -leftDiff * cellImageSizeDst), Box destBox ( std::max(0, -leftDiff * cellImageSizeDst),
std::max(0, -topDiff * cellImageSizeDst), std::max(0, -topDiff * cellImageSizeDst),
std::min(mOverlayTexture->getWidth(), mOverlayTexture->getWidth() + rightDiff * cellImageSizeDst), std::min(mWidth, mWidth + rightDiff * cellImageSizeDst),
std::min(mOverlayTexture->getHeight(), mOverlayTexture->getHeight() + bottomDiff * cellImageSizeDst)); std::min(mHeight, mHeight + bottomDiff * cellImageSizeDst));
// Looks like there is no interface for blitting from memory with src/dst boxes. if (srcBox.mLeft == destBox.mLeft && srcBox.mRight == destBox.mRight
// So we create a temporary texture for blitting. && srcBox.mTop == destBox.mTop && srcBox.mBottom == destBox.mBottom
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().createManual("@temp", && imageWidth == mWidth && imageHeight == mHeight)
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, image.getWidth(), {
image.getHeight(), 0, Ogre::PF_A8B8G8R8); mOverlayImage->copySubImage(0, 0, 0, image);
tex->loadImage(image); }
mOverlayTexture->load();
mOverlayTexture->getBuffer()->blit(tex->getBuffer(), srcBox, destBox);
if (srcBox.left == destBox.left && srcBox.right == destBox.right
&& srcBox.top == destBox.top && srcBox.bottom == destBox.bottom
&& int(image.getWidth()) == mWidth && int(image.getHeight()) == mHeight)
mOverlayImage = image;
else else
mOverlayTexture->convertToImage(mOverlayImage); {
// TODO:
Ogre::TextureManager::getSingleton().remove("@temp"); // Dimensions don't match. This could mean a changed map region, or a changed map resolution.
*/ // In the latter case, we'll want to use filtering.
// Create a RTT Camera and draw the image onto mOverlayImage in the next frame?
}
mOverlayImage->dirty();
} }
osg::ref_ptr<osg::Texture2D> GlobalMap::getBaseTexture() osg::ref_ptr<osg::Texture2D> GlobalMap::getBaseTexture()
{ {
return mBaseTexture; return mBaseTexture;
} }
osg::ref_ptr<osg::Texture2D> GlobalMap::getOverlayTexture()
{
return mOverlayTexture;
}
} }

View File

@ -9,6 +9,7 @@
namespace osg namespace osg
{ {
class Texture2D; class Texture2D;
class Image;
} }
namespace Loading namespace Loading
@ -50,7 +51,7 @@ namespace MWRender
void read (ESM::GlobalMap& map); void read (ESM::GlobalMap& map);
osg::ref_ptr<osg::Texture2D> getBaseTexture(); osg::ref_ptr<osg::Texture2D> getBaseTexture();
//osg::ref_ptr<osg::Texture2D> getOverlayTexture(); osg::ref_ptr<osg::Texture2D> getOverlayTexture();
private: private:
int mCellSize; int mCellSize;
@ -58,6 +59,9 @@ namespace MWRender
std::vector< std::pair<int,int> > mExploredCells; std::vector< std::pair<int,int> > mExploredCells;
osg::ref_ptr<osg::Texture2D> mBaseTexture; osg::ref_ptr<osg::Texture2D> mBaseTexture;
osg::ref_ptr<osg::Texture2D> mOverlayTexture;
osg::ref_ptr<osg::Image> mOverlayImage;
int mWidth; int mWidth;
int mHeight; int mHeight;