mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:23:52 +00:00
Do not re-render maps for all active cells during cell transitions
This commit is contained in:
parent
368d1f9d25
commit
ed4ce4609b
9 changed files with 122 additions and 89 deletions
|
@ -350,6 +350,7 @@ namespace MWBase
|
||||||
virtual std::string correctTexturePath(const std::string& path) = 0;
|
virtual std::string correctTexturePath(const std::string& path) = 0;
|
||||||
virtual bool textureExists(const std::string& path) = 0;
|
virtual bool textureExists(const std::string& path) = 0;
|
||||||
|
|
||||||
|
virtual void addCell(MWWorld::CellStore* cell) = 0;
|
||||||
virtual void removeCell(MWWorld::CellStore* cell) = 0;
|
virtual void removeCell(MWWorld::CellStore* cell) = 0;
|
||||||
virtual void writeFog(MWWorld::CellStore* cell) = 0;
|
virtual void writeFog(MWWorld::CellStore* cell) = 0;
|
||||||
|
|
||||||
|
|
|
@ -237,9 +237,6 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
for (int my=0; my<mNumCells; ++my)
|
for (int my=0; my<mNumCells; ++my)
|
||||||
{
|
{
|
||||||
int x = mCurX + (mx - mCellDistance);
|
|
||||||
int y = mCurY + (-1*(my - mCellDistance));
|
|
||||||
|
|
||||||
MapEntry& entry = mMaps[my + mNumCells*mx];
|
MapEntry& entry = mMaps[my + mNumCells*mx];
|
||||||
MyGUI::ImageBox* fog = entry.mFogWidget;
|
MyGUI::ImageBox* fog = entry.mFogWidget;
|
||||||
|
|
||||||
|
@ -249,19 +246,6 @@ namespace MWGui
|
||||||
entry.mFogTexture.reset();
|
entry.mFogTexture.reset();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<osg::Texture2D> tex = mLocalMapRender->getFogOfWarTexture(x, y);
|
|
||||||
if (tex)
|
|
||||||
{
|
|
||||||
entry.mFogTexture.reset(new osgMyGUI::OSGTexture(tex));
|
|
||||||
fog->setRenderItemTexture(entry.mFogTexture.get());
|
|
||||||
fog->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fog->setImageTexture("black");
|
|
||||||
entry.mFogTexture.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,31 +350,18 @@ namespace MWGui
|
||||||
mInterior = interior;
|
mInterior = interior;
|
||||||
mChanged = false;
|
mChanged = false;
|
||||||
|
|
||||||
applyFogOfWar();
|
|
||||||
|
|
||||||
// Update the map textures
|
|
||||||
for (int mx=0; mx<mNumCells; ++mx)
|
for (int mx=0; mx<mNumCells; ++mx)
|
||||||
{
|
{
|
||||||
for (int my=0; my<mNumCells; ++my)
|
for (int my=0; my<mNumCells; ++my)
|
||||||
{
|
{
|
||||||
int mapX = x + (mx - mCellDistance);
|
|
||||||
int mapY = y + (-1*(my - mCellDistance));
|
|
||||||
|
|
||||||
MapEntry& entry = mMaps[my + mNumCells*mx];
|
MapEntry& entry = mMaps[my + mNumCells*mx];
|
||||||
MyGUI::ImageBox* box = entry.mMapWidget;
|
entry.mMapWidget->setRenderItemTexture(nullptr);
|
||||||
|
entry.mFogWidget->setRenderItemTexture(nullptr);
|
||||||
osg::ref_ptr<osg::Texture2D> texture = mLocalMapRender->getMapTexture(mapX, mapY);
|
|
||||||
if (texture)
|
|
||||||
{
|
|
||||||
entry.mMapTexture.reset(new osgMyGUI::OSGTexture(texture));
|
|
||||||
box->setRenderItemTexture(entry.mMapTexture.get());
|
|
||||||
box->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
box->setRenderItemTexture(nullptr);
|
|
||||||
entry.mMapTexture.reset();
|
entry.mMapTexture.reset();
|
||||||
}
|
entry.mFogTexture.reset();
|
||||||
|
|
||||||
|
entry.mCellX = x + (mx - mCellDistance);
|
||||||
|
entry.mCellY = y - (my - mCellDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,22 +375,7 @@ namespace MWGui
|
||||||
|
|
||||||
void LocalMapBase::requestMapRender(const MWWorld::CellStore *cell)
|
void LocalMapBase::requestMapRender(const MWWorld::CellStore *cell)
|
||||||
{
|
{
|
||||||
std::set<const MWWorld::CellStore*> cells;
|
mLocalMapRender->requestMap(cell);
|
||||||
if (!cell->isExterior())
|
|
||||||
cells.insert(cell);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int dX=-mCellDistance; dX<=mCellDistance; ++dX)
|
|
||||||
{
|
|
||||||
for (int dY=-mCellDistance; dY<=mCellDistance; ++dY)
|
|
||||||
{
|
|
||||||
const MWWorld::CellStore* gridCell = MWBase::Environment::get().getWorld()->getExterior (cell->getCell()->getGridX()+dX, cell->getCell()->getGridY()+dY);
|
|
||||||
cells.insert(gridCell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mLocalMapRender->requestMap(cells);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMapBase::redraw()
|
void LocalMapBase::redraw()
|
||||||
|
@ -522,6 +478,68 @@ namespace MWGui
|
||||||
mMarkerUpdateTimer = 0;
|
mMarkerUpdateTimer = 0;
|
||||||
updateMagicMarkers();
|
updateMagicMarkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRequiredMaps();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool widgetCropped(MyGUI::Widget* widget, MyGUI::Widget* cropTo)
|
||||||
|
{
|
||||||
|
MyGUI::IntRect coord = widget->getAbsoluteRect();
|
||||||
|
MyGUI::IntRect croppedCoord = cropTo->getAbsoluteRect();
|
||||||
|
if (coord.left < croppedCoord.left && coord.right < croppedCoord.left)
|
||||||
|
return true;
|
||||||
|
if (coord.left > croppedCoord.right && coord.right > croppedCoord.right)
|
||||||
|
return true;
|
||||||
|
if (coord.top < croppedCoord.top && coord.bottom < croppedCoord.top)
|
||||||
|
return true;
|
||||||
|
if (coord.top > croppedCoord.bottom && coord.bottom > croppedCoord.bottom)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::updateRequiredMaps()
|
||||||
|
{
|
||||||
|
bool needRedraw = false;
|
||||||
|
for (MapEntry& entry : mMaps)
|
||||||
|
{
|
||||||
|
if (widgetCropped(entry.mMapWidget, mLocalMap))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!entry.mMapTexture)
|
||||||
|
{
|
||||||
|
if (!mInterior)
|
||||||
|
requestMapRender(MWBase::Environment::get().getWorld()->getExterior (entry.mCellX, entry.mCellY));
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Texture2D> texture = mLocalMapRender->getMapTexture(entry.mCellX, entry.mCellY);
|
||||||
|
if (texture)
|
||||||
|
{
|
||||||
|
entry.mMapTexture.reset(new osgMyGUI::OSGTexture(texture));
|
||||||
|
entry.mMapWidget->setRenderItemTexture(entry.mMapTexture.get());
|
||||||
|
entry.mMapWidget->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f));
|
||||||
|
needRedraw = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
entry.mMapTexture.reset(new osgMyGUI::OSGTexture("", nullptr));
|
||||||
|
}
|
||||||
|
if (!entry.mFogTexture && mFogOfWarToggled && mFogOfWarEnabled)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Texture2D> tex = mLocalMapRender->getFogOfWarTexture(entry.mCellX, entry.mCellY);
|
||||||
|
if (tex)
|
||||||
|
{
|
||||||
|
entry.mFogTexture.reset(new osgMyGUI::OSGTexture(tex));
|
||||||
|
entry.mFogWidget->setRenderItemTexture(entry.mFogTexture.get());
|
||||||
|
entry.mFogWidget->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry.mFogWidget->setImageTexture("black");
|
||||||
|
entry.mFogTexture.reset(new osgMyGUI::OSGTexture("", nullptr));
|
||||||
|
}
|
||||||
|
needRedraw = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needRedraw)
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMapBase::updateDoorMarkers()
|
void LocalMapBase::updateDoorMarkers()
|
||||||
|
|
|
@ -129,12 +129,14 @@ namespace MWGui
|
||||||
struct MapEntry
|
struct MapEntry
|
||||||
{
|
{
|
||||||
MapEntry(MyGUI::ImageBox* mapWidget, MyGUI::ImageBox* fogWidget)
|
MapEntry(MyGUI::ImageBox* mapWidget, MyGUI::ImageBox* fogWidget)
|
||||||
: mMapWidget(mapWidget), mFogWidget(fogWidget) {}
|
: mMapWidget(mapWidget), mFogWidget(fogWidget), mCellX(0), mCellY(0) {}
|
||||||
|
|
||||||
MyGUI::ImageBox* mMapWidget;
|
MyGUI::ImageBox* mMapWidget;
|
||||||
MyGUI::ImageBox* mFogWidget;
|
MyGUI::ImageBox* mFogWidget;
|
||||||
std::shared_ptr<MyGUI::ITexture> mMapTexture;
|
std::shared_ptr<MyGUI::ITexture> mMapTexture;
|
||||||
std::shared_ptr<MyGUI::ITexture> mFogTexture;
|
std::shared_ptr<MyGUI::ITexture> mFogTexture;
|
||||||
|
int mCellX;
|
||||||
|
int mCellY;
|
||||||
};
|
};
|
||||||
std::vector<MapEntry> mMaps;
|
std::vector<MapEntry> mMaps;
|
||||||
|
|
||||||
|
@ -155,6 +157,8 @@ namespace MWGui
|
||||||
virtual void customMarkerCreated(MyGUI::Widget* marker) {}
|
virtual void customMarkerCreated(MyGUI::Widget* marker) {}
|
||||||
virtual void doorMarkerCreated(MyGUI::Widget* marker) {}
|
virtual void doorMarkerCreated(MyGUI::Widget* marker) {}
|
||||||
|
|
||||||
|
void updateRequiredMaps();
|
||||||
|
|
||||||
void updateMagicMarkers();
|
void updateMagicMarkers();
|
||||||
void addDetectionMarkers(int type);
|
void addDetectionMarkers(int type);
|
||||||
|
|
||||||
|
|
|
@ -976,6 +976,12 @@ namespace MWGui
|
||||||
|
|
||||||
void WindowManager::onFrame (float frameDuration)
|
void WindowManager::onFrame (float frameDuration)
|
||||||
{
|
{
|
||||||
|
bool gameRunning = MWBase::Environment::get().getStateManager()->getState()!=
|
||||||
|
MWBase::StateManager::State_NoGame;
|
||||||
|
|
||||||
|
if (gameRunning)
|
||||||
|
updateMap();
|
||||||
|
|
||||||
if (!mGuiModes.empty())
|
if (!mGuiModes.empty())
|
||||||
{
|
{
|
||||||
GuiModeState& state = mGuiModeStates[mGuiModes.back()];
|
GuiModeState& state = mGuiModeStates[mGuiModes.back()];
|
||||||
|
@ -1019,14 +1025,11 @@ namespace MWGui
|
||||||
if (mLocalMapRender)
|
if (mLocalMapRender)
|
||||||
mLocalMapRender->cleanupCameras();
|
mLocalMapRender->cleanupCameras();
|
||||||
|
|
||||||
if (MWBase::Environment::get().getStateManager()->getState()==
|
if (!gameRunning)
|
||||||
MWBase::StateManager::State_NoGame)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mDragAndDrop->onFrame();
|
mDragAndDrop->onFrame();
|
||||||
|
|
||||||
updateMap();
|
|
||||||
|
|
||||||
mHud->onFrame(frameDuration);
|
mHud->onFrame(frameDuration);
|
||||||
|
|
||||||
mDebugWindow->onFrame(frameDuration);
|
mDebugWindow->onFrame(frameDuration);
|
||||||
|
@ -2163,6 +2166,11 @@ namespace MWGui
|
||||||
tex->unlock();
|
tex->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowManager::addCell(MWWorld::CellStore* cell)
|
||||||
|
{
|
||||||
|
mLocalMapRender->addCell(cell);
|
||||||
|
}
|
||||||
|
|
||||||
void WindowManager::removeCell(MWWorld::CellStore *cell)
|
void WindowManager::removeCell(MWWorld::CellStore *cell)
|
||||||
{
|
{
|
||||||
mLocalMapRender->removeCell(cell);
|
mLocalMapRender->removeCell(cell);
|
||||||
|
|
|
@ -378,6 +378,7 @@ namespace MWGui
|
||||||
virtual std::string correctTexturePath(const std::string& path);
|
virtual std::string correctTexturePath(const std::string& path);
|
||||||
virtual bool textureExists(const std::string& path);
|
virtual bool textureExists(const std::string& path);
|
||||||
|
|
||||||
|
void addCell(MWWorld::CellStore* cell);
|
||||||
void removeCell(MWWorld::CellStore* cell);
|
void removeCell(MWWorld::CellStore* cell);
|
||||||
void writeFog(MWWorld::CellStore* cell);
|
void writeFog(MWWorld::CellStore* cell);
|
||||||
|
|
||||||
|
|
|
@ -256,16 +256,7 @@ bool needUpdate(std::set<std::pair<int, int> >& renderedGrid, std::set<std::pair
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMap::requestMap(std::set<const MWWorld::CellStore*> cells)
|
void LocalMap::requestMap(const MWWorld::CellStore* cell)
|
||||||
{
|
|
||||||
std::set<std::pair<int, int> > grid;
|
|
||||||
for (const MWWorld::CellStore* cell : cells)
|
|
||||||
{
|
|
||||||
if (cell->isExterior())
|
|
||||||
grid.insert(std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const MWWorld::CellStore* cell : cells)
|
|
||||||
{
|
{
|
||||||
if (cell->isExterior())
|
if (cell->isExterior())
|
||||||
{
|
{
|
||||||
|
@ -273,19 +264,22 @@ void LocalMap::requestMap(std::set<const MWWorld::CellStore*> cells)
|
||||||
int cellY = cell->getCell()->getGridY();
|
int cellY = cell->getCell()->getGridY();
|
||||||
|
|
||||||
MapSegment& segment = mSegments[std::make_pair(cellX, cellY)];
|
MapSegment& segment = mSegments[std::make_pair(cellX, cellY)];
|
||||||
if (!needUpdate(segment.mGrid, grid, cellX, cellY))
|
if (!needUpdate(segment.mGrid, mCurrentGrid, cellX, cellY))
|
||||||
{
|
return;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
segment.mGrid = grid;
|
segment.mGrid = mCurrentGrid;
|
||||||
requestExteriorMap(cell);
|
requestExteriorMap(cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
requestInteriorMap(cell);
|
requestInteriorMap(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalMap::addCell(MWWorld::CellStore *cell)
|
||||||
|
{
|
||||||
|
if (cell->isExterior())
|
||||||
|
mCurrentGrid.emplace(cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMap::removeCell(MWWorld::CellStore *cell)
|
void LocalMap::removeCell(MWWorld::CellStore *cell)
|
||||||
|
@ -293,7 +287,11 @@ void LocalMap::removeCell(MWWorld::CellStore *cell)
|
||||||
saveFogOfWar(cell);
|
saveFogOfWar(cell);
|
||||||
|
|
||||||
if (cell->isExterior())
|
if (cell->isExterior())
|
||||||
mSegments.erase(std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY()));
|
{
|
||||||
|
std::pair<int, int> coords = std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
||||||
|
mSegments.erase(coords);
|
||||||
|
mCurrentGrid.erase(coords);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mSegments.clear();
|
mSegments.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,13 +45,12 @@ namespace MWRender
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request a map render for the given cells. Render textures will be immediately created and can be retrieved with the getMapTexture function.
|
* Request a map render for the given cell. Render textures will be immediately created and can be retrieved with the getMapTexture function.
|
||||||
*/
|
*/
|
||||||
void requestMap (std::set<const MWWorld::CellStore*> cells);
|
void requestMap (const MWWorld::CellStore* cell);
|
||||||
|
|
||||||
|
void addCell(MWWorld::CellStore* cell);
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove map and fog textures for the given cell.
|
|
||||||
*/
|
|
||||||
void removeCell (MWWorld::CellStore* cell);
|
void removeCell (MWWorld::CellStore* cell);
|
||||||
|
|
||||||
osg::ref_ptr<osg::Texture2D> getMapTexture (int x, int y);
|
osg::ref_ptr<osg::Texture2D> getMapTexture (int x, int y);
|
||||||
|
@ -110,6 +109,9 @@ namespace MWRender
|
||||||
|
|
||||||
CameraVector mCamerasPendingRemoval;
|
CameraVector mCamerasPendingRemoval;
|
||||||
|
|
||||||
|
typedef std::set<std::pair<int, int> > Grid;
|
||||||
|
Grid mCurrentGrid;
|
||||||
|
|
||||||
struct MapSegment
|
struct MapSegment
|
||||||
{
|
{
|
||||||
MapSegment();
|
MapSegment();
|
||||||
|
@ -124,7 +126,7 @@ namespace MWRender
|
||||||
osg::ref_ptr<osg::Texture2D> mFogOfWarTexture;
|
osg::ref_ptr<osg::Texture2D> mFogOfWarTexture;
|
||||||
osg::ref_ptr<osg::Image> mFogOfWarImage;
|
osg::ref_ptr<osg::Image> mFogOfWarImage;
|
||||||
|
|
||||||
std::set<std::pair<int, int> > mGrid; // the grid that was active at the time of rendering this segment
|
Grid mGrid; // the grid that was active at the time of rendering this segment
|
||||||
|
|
||||||
bool mHasFogState;
|
bool mHasFogState;
|
||||||
};
|
};
|
||||||
|
|
|
@ -431,6 +431,7 @@ namespace MWWorld
|
||||||
insertCell (*cell, true, loadingListener);
|
insertCell (*cell, true, loadingListener);
|
||||||
|
|
||||||
mRendering.addCell(cell);
|
mRendering.addCell(cell);
|
||||||
|
MWBase::Environment::get().getWindowManager()->addCell(cell);
|
||||||
bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior();
|
bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior();
|
||||||
float waterLevel = cell->getWaterLevel();
|
float waterLevel = cell->getWaterLevel();
|
||||||
mRendering.setWaterEnabled(waterEnabled);
|
mRendering.setWaterEnabled(waterEnabled);
|
||||||
|
|
|
@ -112,5 +112,5 @@ local map cell distance
|
||||||
:Default: 1
|
:Default: 1
|
||||||
|
|
||||||
Similar to "exterior cell load distance" in the Cells section, controls how many cells are rendered on the local map.
|
Similar to "exterior cell load distance" in the Cells section, controls how many cells are rendered on the local map.
|
||||||
Values higher than the default may result in longer loading times. Please note that only loaded cells can be rendered,
|
Please note that only loaded cells can be rendered,
|
||||||
so this setting must be lower or equal to "exterior cell load distance" to work properly.
|
so this setting must be lower or equal to "exterior cell load distance" to work properly.
|
||||||
|
|
Loading…
Reference in a new issue