From 94df2114c13024e592cf94907eb79a1f00900226 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 7 Mar 2020 10:31:00 +0400 Subject: [PATCH] Store fog of war as a PNG image instead of TGA (bug #5108) --- CHANGELOG.md | 1 + apps/openmw/mwgui/mapwindow.cpp | 1 + apps/openmw/mwrender/localmap.cpp | 10 +++--- components/esm/fogstate.cpp | 54 +++++++++++++++++++++++++++++++ components/esm/savedgame.cpp | 2 +- 5 files changed, 61 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bfd756b5e..df17289bfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -154,6 +154,7 @@ Bug #5104: Black Dart's enchantment doesn't trigger at low Enchant levels Bug #5105: NPCs start combat with werewolves from any distance Bug #5106: Still can jump even when encumbered + Bug #5108: Savegame bloating due to inefficient fog textures format Bug #5110: ModRegion with a redundant numerical argument breaks script execution Bug #5112: Insufficient magicka for current spell not reflected on HUD icon Bug #5113: Unknown alchemy question mark not centered diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index bc65ee0213..372e0f64dc 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -209,6 +209,7 @@ namespace MWGui MyGUI::IntCoord(mx*mMapWidgetSize, my*mMapWidgetSize, mMapWidgetSize, mMapWidgetSize), MyGUI::Align::Top | MyGUI::Align::Left); fog->setDepth(Local_FogLayer); + fog->setColour(MyGUI::Colour(0, 0, 0)); map->setNeedMouseFocus(false); fog->setNeedMouseFocus(false); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 7bd202e7e0..81d925e331 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -692,12 +692,10 @@ void LocalMap::MapSegment::loadFogOfWar(const ESM::FogTexture &esm) return; } - // TODO: deprecate tga and use raw data instead - - osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("tga"); + osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png"); if (!readerwriter) { - Log(Debug::Error) << "Error: Unable to load fog, can't find a tga ReaderWriter" ; + Log(Debug::Error) << "Error: Unable to load fog, can't find a png ReaderWriter" ; return; } @@ -726,10 +724,10 @@ void LocalMap::MapSegment::saveFogOfWar(ESM::FogTexture &fog) const std::ostringstream ostream; - osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("tga"); + osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png"); if (!readerwriter) { - Log(Debug::Error) << "Error: Unable to write fog, can't find a tga ReaderWriter"; + Log(Debug::Error) << "Error: Unable to write fog, can't find a png ReaderWriter"; return; } diff --git a/components/esm/fogstate.cpp b/components/esm/fogstate.cpp index 18235066d4..444da7ac95 100644 --- a/components/esm/fogstate.cpp +++ b/components/esm/fogstate.cpp @@ -3,10 +3,60 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include + +#include +#include + +#include "savedgame.hpp" + +void convertFogOfWar(std::vector& imageData) +{ + if (imageData.empty()) + { + return; + } + + osgDB::ReaderWriter* tgaReader = osgDB::Registry::instance()->getReaderWriterForExtension("tga"); + if (!tgaReader) + { + Log(Debug::Error) << "Error: Unable to load fog, can't find a tga ReaderWriter"; + return; + } + + Files::IMemStream in(&imageData[0], imageData.size()); + + osgDB::ReaderWriter::ReadResult result = tgaReader->readImage(in); + if (!result.success()) + { + Log(Debug::Error) << "Error: Failed to read fog: " << result.message() << " code " << result.status(); + return; + } + + osgDB::ReaderWriter* pngWriter = osgDB::Registry::instance()->getReaderWriterForExtension("png"); + if (!pngWriter) + { + Log(Debug::Error) << "Error: Unable to write fog, can't find a png ReaderWriter"; + return; + } + + std::ostringstream ostream; + osgDB::ReaderWriter::WriteResult png = pngWriter->writeImage(*result.getImage(), ostream); + if (!png.success()) + { + Log(Debug::Error) << "Error: Unable to write fog: " << png.message() << " code " << png.status(); + return; + } + + std::string str = ostream.str(); + imageData = std::vector(str.begin(), str.end()); +} + void ESM::FogState::load (ESMReader &esm) { esm.getHNOT(mBounds, "BOUN"); esm.getHNOT(mNorthMarkerAngle, "ANGL"); + int dataFormat = esm.getFormat(); while (esm.isNextSub("FTEX")) { esm.getSubHeader(); @@ -18,6 +68,10 @@ void ESM::FogState::load (ESMReader &esm) size_t imageSize = esm.getSubSize()-sizeof(int)*2; tex.mImageData.resize(imageSize); esm.getExact(&tex.mImageData[0], imageSize); + + if (dataFormat < 6) + convertFogOfWar(tex.mImageData); + mFogTextures.push_back(tex); } } diff --git a/components/esm/savedgame.cpp b/components/esm/savedgame.cpp index ea9fef4fbf..633f7c9fd0 100644 --- a/components/esm/savedgame.cpp +++ b/components/esm/savedgame.cpp @@ -5,7 +5,7 @@ #include "defs.hpp" unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE; -int ESM::SavedGame::sCurrentFormat = 5; +int ESM::SavedGame::sCurrentFormat = 6; void ESM::SavedGame::load (ESMReader &esm) {