From 72c6b11cf8140cd947140c10d1e8ecd2981baf8c Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 14 Feb 2017 03:55:29 +0100 Subject: [PATCH] Move global map render to the worker thread --- apps/openmw/engine.cpp | 2 +- apps/openmw/mwgui/mapwindow.cpp | 32 +-- apps/openmw/mwgui/mapwindow.hpp | 11 +- apps/openmw/mwgui/windowmanagerimp.cpp | 11 +- apps/openmw/mwgui/windowmanagerimp.hpp | 10 +- apps/openmw/mwrender/globalmap.cpp | 272 ++++++++++++++----------- apps/openmw/mwrender/globalmap.hpp | 19 +- 7 files changed, 217 insertions(+), 140 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index d8090ea0d..e8730a4e8 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -496,7 +496,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) guiRoot->setName("GUI Root"); guiRoot->setNodeMask(MWRender::Mask_GUI); rootNode->addChild(guiRoot); - MWGui::WindowManager* window = new MWGui::WindowManager(mViewer, guiRoot, mResourceSystem.get(), + MWGui::WindowManager* window = new MWGui::WindowManager(mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), mCfgMgr.getLogPath().string() + std::string("/"), myguiResources, mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, mFallbackMap, Version::getOpenmwVersionDescription(mResDir.string())); diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 4708d6753..8002dc48a 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -622,7 +622,7 @@ namespace MWGui // ------------------------------------------------------------------------------------------ - MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender) + MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue) : WindowPinnableBase("openmw_map_window.layout") , LocalMapBase(customMarkers, localMapRender) , NoDrop(drag, mMainWidget) @@ -632,7 +632,7 @@ namespace MWGui , mGlobal(false) , mEventBoxGlobal(NULL) , mEventBoxLocal(NULL) - , mGlobalMapRender(new MWRender::GlobalMap(localMapRender->getRoot())) + , mGlobalMapRender(new MWRender::GlobalMap(localMapRender->getRoot(), workQueue)) , mEditNoteDialog() { static bool registered = false; @@ -774,19 +774,11 @@ namespace MWGui mLastScrollWindowCoordinates = currentCoordinates; } - void MapWindow::renderGlobalMap(Loading::Listener* loadingListener) + void MapWindow::renderGlobalMap() { - mGlobalMapRender->render(loadingListener); + mGlobalMapRender->render(); mGlobalMap->setCanvasSize (mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight()); mGlobalMapImage->setSize(mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight()); - - mGlobalMapTexture.reset(new osgMyGUI::OSGTexture(mGlobalMapRender->getBaseTexture())); - mGlobalMapImage->setRenderItemTexture(mGlobalMapTexture.get()); - mGlobalMapImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f)); - - mGlobalMapOverlayTexture.reset(new osgMyGUI::OSGTexture(mGlobalMapRender->getOverlayTexture())); - mGlobalMapOverlay->setRenderItemTexture(mGlobalMapOverlayTexture.get()); - mGlobalMapOverlay->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f)); } MapWindow::~MapWindow() @@ -940,6 +932,8 @@ namespace MWGui void MapWindow::open() { + ensureGlobalMapLoaded(); + globalMapUpdatePlayer(); } @@ -984,6 +978,20 @@ namespace MWGui rotatingSubskin->setAngle(angle); } + void MapWindow::ensureGlobalMapLoaded() + { + if (!mGlobalMapTexture.get()) + { + mGlobalMapTexture.reset(new osgMyGUI::OSGTexture(mGlobalMapRender->getBaseTexture())); + mGlobalMapImage->setRenderItemTexture(mGlobalMapTexture.get()); + mGlobalMapImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f)); + + mGlobalMapOverlayTexture.reset(new osgMyGUI::OSGTexture(mGlobalMapRender->getOverlayTexture())); + mGlobalMapOverlay->setRenderItemTexture(mGlobalMapOverlayTexture.get()); + mGlobalMapOverlay->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f)); + } + } + void MapWindow::clear() { mMarkers.clear(); diff --git a/apps/openmw/mwgui/mapwindow.hpp b/apps/openmw/mwgui/mapwindow.hpp index 977773179..a0136b1c7 100644 --- a/apps/openmw/mwgui/mapwindow.hpp +++ b/apps/openmw/mwgui/mapwindow.hpp @@ -33,6 +33,11 @@ namespace Loading class Listener; } +namespace SceneUtil +{ + class WorkQueue; +} + namespace MWGui { @@ -193,14 +198,14 @@ namespace MWGui class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase, public NoDrop { public: - MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender); + MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue); virtual ~MapWindow(); void setCellName(const std::string& cellName); virtual void setAlpha(float alpha); - void renderGlobalMap(Loading::Listener* loadingListener); + void renderGlobalMap(); /// adds the marker to the global map /// @param name The ESM::Cell::mName @@ -212,6 +217,8 @@ namespace MWGui void setGlobalMapPlayerPosition (float worldX, float worldY); void setGlobalMapPlayerDir(const float x, const float y); + void ensureGlobalMapLoaded(); + virtual void open(); void onFrame(float dt); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index f679da651..937463ecd 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -30,6 +30,8 @@ #include #include +#include + #include #include @@ -115,11 +117,12 @@ namespace MWGui { WindowManager::WindowManager( - osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem - , const std::string& logpath, const std::string& resourcePath, bool consoleOnlyScripts, + osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, + const std::string& logpath, const std::string& resourcePath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map& fallbackMap, const std::string& versionDescription) : mStore(NULL) , mResourceSystem(resourceSystem) + , mWorkQueue(workQueue) , mViewer(viewer) , mConsoleOnlyScripts(consoleOnlyScripts) , mCurrentModals() @@ -285,7 +288,7 @@ namespace MWGui mRecharge = new Recharge(); mMenu = new MainMenu(w, h, mResourceSystem->getVFS(), mVersionDescription); mLocalMapRender = new MWRender::LocalMap(mViewer->getSceneData()->asGroup()); - mMap = new MapWindow(mCustomMarkers, mDragAndDrop, mLocalMapRender); + mMap = new MapWindow(mCustomMarkers, mDragAndDrop, mLocalMapRender, mWorkQueue); trackWindow(mMap, "map"); mStatsWindow = new StatsWindow(mDragAndDrop); trackWindow(mStatsWindow, "stats"); @@ -373,7 +376,7 @@ namespace MWGui void WindowManager::renderWorldMap() { - mMap->renderGlobalMap(mLoadingScreen); + mMap->renderGlobalMap(); } void WindowManager::setNewGame(bool newgame) diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 17a2e3855..4e2cef8af 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -9,6 +9,8 @@ #include +#include + #include "../mwbase/windowmanager.hpp" #include @@ -57,6 +59,11 @@ namespace Resource class ResourceSystem; } +namespace SceneUtil +{ + class WorkQueue; +} + namespace SDLUtil { class SDLCursorManager; @@ -119,7 +126,7 @@ namespace MWGui typedef std::pair Faction; typedef std::vector FactionList; - WindowManager(osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, + WindowManager(osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map& fallbackMap, const std::string& versionDescription); virtual ~WindowManager(); @@ -382,6 +389,7 @@ namespace MWGui private: const MWWorld::ESMStore* mStore; Resource::ResourceSystem* mResourceSystem; + osg::ref_ptr mWorkQueue; osgMyGUI::Platform* mGuiPlatform; osgViewer::Viewer* mViewer; diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index 50ba14770..0d8a7a039 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -15,6 +15,8 @@ #include #include +#include + #include #include "../mwbase/environment.hpp" @@ -95,8 +97,132 @@ namespace namespace MWRender { - GlobalMap::GlobalMap(osg::Group* root) + class CreateMapWorkItem : public SceneUtil::WorkItem + { + public: + CreateMapWorkItem(int width, int height, int minX, int minY, int maxX, int maxY, int cellSize, const MWWorld::Store& landStore) + : mWidth(width), mHeight(height), mMinX(minX), mMinY(minY), mMaxX(maxX), mMaxY(maxY), mCellSize(cellSize), mLandStore(landStore) + { + } + + virtual void doWork() + { + osg::ref_ptr image = new osg::Image; + image->allocateImage(mWidth, mHeight, 1, GL_RGB, GL_UNSIGNED_BYTE); + unsigned char* data = image->data(); + + osg::ref_ptr alphaImage = new osg::Image; + alphaImage->allocateImage(mWidth, mHeight, 1, GL_ALPHA, GL_UNSIGNED_BYTE); + unsigned char* alphaData = alphaImage->data(); + + for (int x = mMinX; x <= mMaxX; ++x) + { + for (int y = mMinY; y <= mMaxY; ++y) + { + const ESM::Land* land = mLandStore.search (x,y); + + for (int cellY=0; cellY(float(cellX)/float(mCellSize) * 9); + int vertexY = static_cast(float(cellY) / float(mCellSize) * 9); + + int texelX = (x-mMinX) * mCellSize + cellX; + int texelY = (y-mMinY) * mCellSize + cellY; + + unsigned char r,g,b; + + float y2 = 0; + if (land && (land->mDataTypes & ESM::Land::DATA_WNAM)) + y2 = (land->mWnam[vertexY * 9 + vertexX] << 4) / 2048.f; + else + y2 = (SCHAR_MIN << 4) / 2048.f; + if (y2 < 0) + { + r = static_cast(14 * y2 + 38); + g = static_cast(20 * y2 + 56); + b = static_cast(18 * y2 + 51); + } + else if (y2 < 0.3f) + { + if (y2 < 0.1f) + y2 *= 8.f; + else + { + y2 -= 0.1f; + y2 += 0.8f; + } + r = static_cast(66 - 32 * y2); + g = static_cast(48 - 23 * y2); + b = static_cast(33 - 16 * y2); + } + else + { + y2 -= 0.3f; + y2 *= 1.428f; + r = static_cast(34 - 29 * y2); + g = static_cast(25 - 20 * y2); + b = static_cast(17 - 12 * y2); + } + + data[texelY * mWidth * 3 + texelX * 3] = r; + data[texelY * mWidth * 3 + texelX * 3+1] = g; + data[texelY * mWidth * 3 + texelX * 3+2] = b; + + alphaData[texelY * mWidth+ texelX] = (y2 < 0) ? static_cast(0) : static_cast(255); + } + } + } + } + + 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); + + mAlphaTexture = new osg::Texture2D; + mAlphaTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); + mAlphaTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); + mAlphaTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); + mAlphaTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); + mAlphaTexture->setImage(alphaImage); + mAlphaTexture->setResizeNonPowerOfTwoHint(false); + + mOverlayImage = new osg::Image; + mOverlayImage->allocateImage(mWidth, mHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE); + assert(mOverlayImage->isDataContiguous()); + + memset(mOverlayImage->data(), 0, mOverlayImage->getTotalSizeInBytes()); + + 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->setResizeNonPowerOfTwoHint(false); + mOverlayTexture->setInternalFormat(GL_RGBA); + mOverlayTexture->setTextureSize(mWidth, mHeight); + } + + int mWidth, mHeight; + int mMinX, mMinY, mMaxX, mMaxY; + int mCellSize; + const MWWorld::Store& mLandStore; + + osg::ref_ptr mBaseTexture; + osg::ref_ptr mAlphaTexture; + + osg::ref_ptr mOverlayImage; + osg::ref_ptr mOverlayTexture; + }; + + GlobalMap::GlobalMap(osg::Group* root, SceneUtil::WorkQueue* workQueue) : mRoot(root) + , mWorkQueue(workQueue) , mWidth(0) , mHeight(0) , mMinX(0), mMaxX(0) @@ -114,7 +240,7 @@ namespace MWRender removeCamera(*it); } - void GlobalMap::render (Loading::Listener* loadingListener) + void GlobalMap::render () { const MWWorld::ESMStore &esmStore = MWBase::Environment::get().getWorld()->getStore(); @@ -136,100 +262,8 @@ namespace MWRender mWidth = mCellSize*(mMaxX-mMinX+1); mHeight = mCellSize*(mMaxY-mMinY+1); - loadingListener->loadingOn(); - loadingListener->setLabel("Creating map"); - loadingListener->setProgressRange((mMaxX-mMinX+1) * (mMaxY-mMinY+1)); - loadingListener->setProgress(0); - - osg::ref_ptr image = new osg::Image; - image->allocateImage(mWidth, mHeight, 1, GL_RGB, GL_UNSIGNED_BYTE); - unsigned char* data = image->data(); - - osg::ref_ptr alphaImage = new osg::Image; - alphaImage->allocateImage(mWidth, mHeight, 1, GL_ALPHA, GL_UNSIGNED_BYTE); - unsigned char* alphaData = alphaImage->data(); - - for (int x = mMinX; x <= mMaxX; ++x) - { - for (int y = mMinY; y <= mMaxY; ++y) - { - const ESM::Land* land = esmStore.get().search (x,y); - - for (int cellY=0; cellY(float(cellX)/float(mCellSize) * 9); - int vertexY = static_cast(float(cellY) / float(mCellSize) * 9); - - int texelX = (x-mMinX) * mCellSize + cellX; - int texelY = (y-mMinY) * mCellSize + cellY; - - unsigned char r,g,b; - - float y2 = 0; - if (land && (land->mDataTypes & ESM::Land::DATA_WNAM)) - y2 = (land->mWnam[vertexY * 9 + vertexX] << 4) / 2048.f; - else - y2 = (SCHAR_MIN << 4) / 2048.f; - if (y2 < 0) - { - r = static_cast(14 * y2 + 38); - g = static_cast(20 * y2 + 56); - b = static_cast(18 * y2 + 51); - } - else if (y2 < 0.3f) - { - if (y2 < 0.1f) - y2 *= 8.f; - else - { - y2 -= 0.1f; - y2 += 0.8f; - } - r = static_cast(66 - 32 * y2); - g = static_cast(48 - 23 * y2); - b = static_cast(33 - 16 * y2); - } - else - { - y2 -= 0.3f; - y2 *= 1.428f; - r = static_cast(34 - 29 * y2); - g = static_cast(25 - 20 * y2); - b = static_cast(17 - 12 * y2); - } - - data[texelY * mWidth * 3 + texelX * 3] = r; - data[texelY * mWidth * 3 + texelX * 3+1] = g; - data[texelY * mWidth * 3 + texelX * 3+2] = b; - - alphaData[texelY * mWidth+ texelX] = (y2 < 0) ? static_cast(0) : static_cast(255); - } - } - loadingListener->increaseProgress(); - } - } - - 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); - - mAlphaTexture = new osg::Texture2D; - mAlphaTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); - mAlphaTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); - mAlphaTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); - mAlphaTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); - mAlphaTexture->setImage(alphaImage); - mAlphaTexture->setResizeNonPowerOfTwoHint(false); - - clear(); - - loadingListener->loadingOff(); + mWorkItem = new CreateMapWorkItem(mWidth, mHeight, mMinX, mMinY, mMaxX, mMaxY, mCellSize, esmStore.get()); + mWorkQueue->addWorkItem(mWorkItem); } void GlobalMap::worldPosToImageSpace(float x, float z, float& imageX, float& imageY) @@ -334,6 +368,8 @@ namespace MWRender void GlobalMap::exploreCell(int cellX, int cellY, osg::ref_ptr localMapTexture) { + ensureLoaded(); + if (!localMapTexture) return; @@ -348,25 +384,9 @@ namespace MWRender void GlobalMap::clear() { - 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()); + ensureLoaded(); - 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->setResizeNonPowerOfTwoHint(false); - mOverlayTexture->setInternalFormat(GL_RGBA); - mOverlayTexture->setTextureSize(mWidth, mHeight); - } + memset(mOverlayImage->data(), 0, mOverlayImage->getTotalSizeInBytes()); mPendingImageDest.clear(); @@ -377,6 +397,8 @@ namespace MWRender void GlobalMap::write(ESM::GlobalMap& map) { + ensureLoaded(); + map.mBounds.mMinX = mMinX; map.mBounds.mMaxX = mMaxX; map.mBounds.mMinY = mMinY; @@ -417,6 +439,8 @@ namespace MWRender void GlobalMap::read(ESM::GlobalMap& map) { + ensureLoaded(); + const ESM::GlobalMap::Bounds& bounds = map.mBounds; if (bounds.mMaxX-bounds.mMinX < 0) @@ -513,14 +537,33 @@ namespace MWRender osg::ref_ptr GlobalMap::getBaseTexture() { + ensureLoaded(); return mBaseTexture; } osg::ref_ptr GlobalMap::getOverlayTexture() { + ensureLoaded(); return mOverlayTexture; } + void GlobalMap::ensureLoaded() + { + if (mWorkItem) + { + mWorkItem->waitTillDone(); + + mOverlayImage = mWorkItem->mOverlayImage; + mBaseTexture = mWorkItem->mBaseTexture; + mAlphaTexture = mWorkItem->mAlphaTexture; + mOverlayTexture = mWorkItem->mOverlayTexture; + + requestOverlayTextureUpdate(0, 0, mWidth, mHeight, osg::ref_ptr(), true, false); + + mWorkItem = NULL; + } + } + void GlobalMap::markForRemoval(osg::Camera *camera) { CameraVector::iterator found = std::find(mActiveCameras.begin(), mActiveCameras.end(), camera); @@ -549,6 +592,7 @@ namespace MWRender continue; } + ensureLoaded(); mOverlayImage->copySubImage(imageDest.mX, imageDest.mY, 0, imageDest.mImage); it = mPendingImageDest.erase(it); diff --git a/apps/openmw/mwrender/globalmap.hpp b/apps/openmw/mwrender/globalmap.hpp index 1c44439fd..f19f4a91f 100644 --- a/apps/openmw/mwrender/globalmap.hpp +++ b/apps/openmw/mwrender/globalmap.hpp @@ -14,26 +14,28 @@ namespace osg class Camera; } -namespace Loading +namespace ESM { - class Listener; + struct GlobalMap; } -namespace ESM +namespace SceneUtil { - struct GlobalMap; + class WorkQueue; } namespace MWRender { + class CreateMapWorkItem; + class GlobalMap { public: - GlobalMap(osg::Group* root); + GlobalMap(osg::Group* root, SceneUtil::WorkQueue* workQueue); ~GlobalMap(); - void render(Loading::Listener* loadingListener); + void render(); int getWidth() const { return mWidth; } int getHeight() const { return mHeight; } @@ -69,6 +71,8 @@ namespace MWRender osg::ref_ptr getBaseTexture(); osg::ref_ptr getOverlayTexture(); + void ensureLoaded(); + private: /** * Request rendering a 2d quad onto mOverlayTexture. @@ -116,6 +120,9 @@ namespace MWRender // CPU copy of overlay osg::ref_ptr mOverlayImage; + osg::ref_ptr mWorkQueue; + osg::ref_ptr mWorkItem; + int mWidth; int mHeight;