mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 07:23:51 +00:00
Restore display of global map overlay, no exploration yet
This commit is contained in:
parent
72d0a69132
commit
7a1408cfed
4 changed files with 114 additions and 50 deletions
|
@ -582,7 +582,6 @@ namespace MWGui
|
|||
, LocalMapBase(customMarkers, localMapRender)
|
||||
, NoDrop(drag, mMainWidget)
|
||||
, mGlobalMap(0)
|
||||
, mGlobalMapTexture(NULL)
|
||||
, mGlobalMapImage(NULL)
|
||||
, mGlobalMapOverlay(NULL)
|
||||
, mGlobal(false)
|
||||
|
@ -736,17 +735,17 @@ namespace MWGui
|
|||
mGlobalMap->setCanvasSize (mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
|
||||
mGlobalMapImage->setSize(mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
|
||||
|
||||
mGlobalMapTexture = new osgMyGUI::OSGTexture(mGlobalMapRender->getBaseTexture());
|
||||
mGlobalMapImage->setRenderItemTexture(mGlobalMapTexture);
|
||||
mGlobalMapTexture.reset(new osgMyGUI::OSGTexture(mGlobalMapRender->getBaseTexture()));
|
||||
mGlobalMapImage->setRenderItemTexture(mGlobalMapTexture.get());
|
||||
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()
|
||||
{
|
||||
delete mGlobalMapTexture;
|
||||
|
||||
delete mGlobalMapRender;
|
||||
}
|
||||
|
||||
|
|
|
@ -212,7 +212,8 @@ namespace MWGui
|
|||
void globalMapUpdatePlayer();
|
||||
|
||||
MyGUI::ScrollView* mGlobalMap;
|
||||
MyGUI::ITexture* mGlobalMapTexture;
|
||||
std::auto_ptr<MyGUI::ITexture> mGlobalMapTexture;
|
||||
std::auto_ptr<MyGUI::ITexture> mGlobalMapOverlayTexture;
|
||||
MyGUI::ImageBox* mGlobalMapImage;
|
||||
MyGUI::ImageBox* mGlobalMapOverlay;
|
||||
MyGUI::ImageBox* mPlayerArrowLocal;
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
#include <osg/Image>
|
||||
#include <osg/Texture2D>
|
||||
|
||||
#include <osgDB/WriteFile>
|
||||
|
||||
#include <components/loadinglistener/loadinglistener.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
#include <components/files/memorystream.hpp>
|
||||
|
||||
#include <components/esm/globalmap.hpp>
|
||||
|
||||
|
@ -134,7 +137,12 @@ namespace MWRender
|
|||
}
|
||||
|
||||
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->setResizeNonPowerOfTwoHint(false);
|
||||
|
||||
clear();
|
||||
|
||||
|
@ -200,14 +208,25 @@ namespace MWRender
|
|||
|
||||
void GlobalMap::clear()
|
||||
{
|
||||
/*
|
||||
Ogre::uchar* buffer = OGRE_ALLOC_T(Ogre::uchar, mWidth * mHeight * 4, Ogre::MEMCATEGORY_GENERAL);
|
||||
memset(buffer, 0, mWidth * mHeight * 4);
|
||||
if (!mOverlayImage)
|
||||
{
|
||||
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
|
||||
|
||||
mOverlayTexture->load();
|
||||
*/
|
||||
if (!mOverlayTexture)
|
||||
{
|
||||
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)
|
||||
|
@ -217,13 +236,35 @@ namespace MWRender
|
|||
map.mBounds.mMinY = mMinY;
|
||||
map.mBounds.mMaxY = mMaxY;
|
||||
|
||||
/*
|
||||
Ogre::DataStreamPtr encoded = mOverlayImage.encode("png");
|
||||
map.mImageData.resize(encoded->size());
|
||||
encoded->read(&map.mImageData[0], encoded->size());
|
||||
*/
|
||||
std::ostringstream ostream;
|
||||
osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png");
|
||||
if (!readerwriter)
|
||||
{
|
||||
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)
|
||||
{
|
||||
const ESM::GlobalMap::Bounds& bounds = map.mBounds;
|
||||
|
@ -237,17 +278,35 @@ namespace MWRender
|
|||
|| bounds.mMinY > bounds.mMaxY)
|
||||
throw std::runtime_error("invalid map bounds");
|
||||
|
||||
/*
|
||||
Ogre::Image image;
|
||||
Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&map.mImageData[0], map.mImageData.size()));
|
||||
image.load(stream, "png");
|
||||
if (!map.mImageData.size())
|
||||
return;
|
||||
|
||||
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 yLength = (bounds.mMaxY-bounds.mMinY+1);
|
||||
|
||||
// Size of one cell in image space
|
||||
int cellImageSizeSrc = image.getWidth() / xLength;
|
||||
if (int(image.getHeight() / yLength) != cellImageSizeSrc)
|
||||
int cellImageSizeSrc = imageWidth / xLength;
|
||||
if (int(imageHeight / yLength) != cellImageSizeSrc)
|
||||
throw std::runtime_error("cell size must be quadratic");
|
||||
|
||||
// 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 rightDiff = (bounds.mMaxX - mMaxX);
|
||||
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::min(image.getWidth(), image.getWidth() - rightDiff * cellImageSizeSrc),
|
||||
std::min(image.getHeight(), image.getHeight() - bottomDiff * cellImageSizeSrc));
|
||||
std::min(imageWidth, imageWidth - rightDiff * 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::min(mOverlayTexture->getWidth(), mOverlayTexture->getWidth() + rightDiff * cellImageSizeDst),
|
||||
std::min(mOverlayTexture->getHeight(), mOverlayTexture->getHeight() + bottomDiff * cellImageSizeDst));
|
||||
std::min(mWidth, mWidth + rightDiff * cellImageSizeDst),
|
||||
std::min(mHeight, mHeight + bottomDiff * cellImageSizeDst));
|
||||
|
||||
// Looks like there is no interface for blitting from memory with src/dst boxes.
|
||||
// So we create a temporary texture for blitting.
|
||||
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().createManual("@temp",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, image.getWidth(),
|
||||
image.getHeight(), 0, Ogre::PF_A8B8G8R8);
|
||||
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;
|
||||
if (srcBox.mLeft == destBox.mLeft && srcBox.mRight == destBox.mRight
|
||||
&& srcBox.mTop == destBox.mTop && srcBox.mBottom == destBox.mBottom
|
||||
&& imageWidth == mWidth && imageHeight == mHeight)
|
||||
{
|
||||
mOverlayImage->copySubImage(0, 0, 0, image);
|
||||
}
|
||||
else
|
||||
mOverlayTexture->convertToImage(mOverlayImage);
|
||||
|
||||
Ogre::TextureManager::getSingleton().remove("@temp");
|
||||
*/
|
||||
{
|
||||
// TODO:
|
||||
// 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()
|
||||
{
|
||||
return mBaseTexture;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> GlobalMap::getOverlayTexture()
|
||||
{
|
||||
return mOverlayTexture;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
namespace osg
|
||||
{
|
||||
class Texture2D;
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace Loading
|
||||
|
@ -50,7 +51,7 @@ namespace MWRender
|
|||
void read (ESM::GlobalMap& map);
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> getBaseTexture();
|
||||
//osg::ref_ptr<osg::Texture2D> getOverlayTexture();
|
||||
osg::ref_ptr<osg::Texture2D> getOverlayTexture();
|
||||
|
||||
private:
|
||||
int mCellSize;
|
||||
|
@ -58,6 +59,9 @@ namespace MWRender
|
|||
std::vector< std::pair<int,int> > mExploredCells;
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> mBaseTexture;
|
||||
osg::ref_ptr<osg::Texture2D> mOverlayTexture;
|
||||
|
||||
osg::ref_ptr<osg::Image> mOverlayImage;
|
||||
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
|
|
Loading…
Reference in a new issue