From e58e5c2bf5903ae56d973ecf72ce2f73d623f594 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Oct 2014 15:57:01 +1100 Subject: [PATCH] Update overlays independently from multiple viewports. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/overlaymask.cpp | 52 +++++++++++++++++++ apps/opencs/view/render/overlaymask.hpp | 42 +++++++++++++++ .../view/render/pagedworldspacewidget.cpp | 12 ++++- .../view/render/pagedworldspacewidget.hpp | 2 + apps/opencs/view/render/scenewidget.cpp | 18 +++++++ apps/opencs/view/render/scenewidget.hpp | 9 +++- apps/opencs/view/render/textoverlay.cpp | 10 +++- apps/opencs/view/render/textoverlay.hpp | 5 +- 9 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 apps/opencs/view/render/overlaymask.cpp create mode 100644 apps/opencs/view/render/overlaymask.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index eb15a953dc..c14caa7f76 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -82,7 +82,7 @@ opencs_units (view/render opencs_units_noqt (view/render navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight - lightingbright object cell textoverlay + lightingbright object cell textoverlay overlaymask ) opencs_hdrs_noqt (view/render diff --git a/apps/opencs/view/render/overlaymask.cpp b/apps/opencs/view/render/overlaymask.cpp new file mode 100644 index 0000000000..885beeff4e --- /dev/null +++ b/apps/opencs/view/render/overlaymask.cpp @@ -0,0 +1,52 @@ +#include "overlaymask.hpp" + +#include +#include + +#include "textoverlay.hpp" +#include "../../model/world/cellcoordinates.hpp" + +namespace CSVRender +{ + +// ideas from http://www.ogre3d.org/forums/viewtopic.php?f=5&t=44828#p486334 +OverlayMask::OverlayMask(std::map &overlays, Ogre::Viewport* viewport) + : mTextOverlays(overlays), mViewport(viewport) +{ +} + +OverlayMask::~OverlayMask() +{ +} + +void OverlayMask::setViewport(Ogre::Viewport *viewport) +{ + mViewport = viewport; +} + +void OverlayMask::preViewportUpdate(const Ogre::RenderTargetViewportEvent &event) +{ + if(event.source == mViewport) + { + Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); + for(Ogre::OverlayManager::OverlayMapIterator iter = overlayMgr.getOverlayIterator(); + iter.hasMoreElements();) + { + Ogre::Overlay* item = iter.getNext(); + for(Ogre::Overlay::Overlay2DElementsIterator it = item->get2DElementsIterator(); + it.hasMoreElements();) + { + Ogre::OverlayContainer* container = it.getNext(); + container->hide(); + } + } + + std::map::iterator it = mTextOverlays.begin(); + for(; it != mTextOverlays.end(); ++it) + { + it->second->show(true); + } + } +} + +} diff --git a/apps/opencs/view/render/overlaymask.hpp b/apps/opencs/view/render/overlaymask.hpp new file mode 100644 index 0000000000..3a006b1d9d --- /dev/null +++ b/apps/opencs/view/render/overlaymask.hpp @@ -0,0 +1,42 @@ +#ifndef OPENCS_VIEW_OVERLAYMASK_H +#define OPENCS_VIEW_OVERLAYMASK_H + +#include + +namespace Ogre +{ + class Viewport; + class RendertargetViewportEvent; +} + +namespace CSMWorld +{ + class CellCoordinates; +} + +namespace CSVRender +{ + class TextOverlay; + + class OverlayMask : public Ogre::RenderTargetListener + { + + std::map &mTextOverlays; + Ogre::Viewport* mViewport; + + public: + + OverlayMask(std::map &overlays, + Ogre::Viewport* viewport); + + virtual ~OverlayMask(); + + void setViewport(Ogre::Viewport *viewport); + + protected: + + virtual void preViewportUpdate(const Ogre::RenderTargetViewportEvent &event) override; + }; +} + +#endif // OPENCS_VIEW_OVERLAYMASK_H diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index eed481c12f..83694bff67 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -15,6 +15,7 @@ #include #include "textoverlay.hpp" +#include "overlaymask.hpp" #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtable.hpp" @@ -89,6 +90,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() it->second->setDesc(region); it->second->update(); } + modified = true; } ++iter; } @@ -155,6 +157,11 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() textDisp->setDesc(desc); // FIXME: config setting textDisp->update(); mTextOverlays.insert(std::make_pair(*iter, textDisp)); + if(!mOverlayMask) + { + mOverlayMask = new OverlayMask(mTextOverlays, getViewport()); + addRenderTargetListener(mOverlayMask); + } modified = true; } @@ -289,7 +296,7 @@ std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) : WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"), - mControlElements(NULL), mDisplayCellCoord(true) + mControlElements(NULL), mDisplayCellCoord(true), mOverlayMask(NULL) { QAbstractItemModel *cells = document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells); @@ -317,6 +324,9 @@ CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() { delete iter->second; } + + removeRenderTargetListener(mOverlayMask); + delete mOverlayMask; } void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 10b2e29b0f..17b6d10c53 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -12,6 +12,7 @@ namespace CSVRender { class TextOverlay; + class OverlayMask; class PagedWorldspaceWidget : public WorldspaceWidget { @@ -24,6 +25,7 @@ namespace CSVRender CSVWidget::SceneToolToggle *mControlElements; bool mDisplayCellCoord; std::map mTextOverlays; + OverlayMask *mOverlayMask; private: diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 15471d655c..5e5a929ec7 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -190,6 +190,24 @@ namespace CSVRender } } + void SceneWidget::addRenderTargetListener(Ogre::RenderTargetListener *listener) + { + mWindow->addListener(listener); + } + + void SceneWidget::removeRenderTargetListener(Ogre::RenderTargetListener *listener) + { + mWindow->removeListener(listener); + } + + Ogre::Viewport *SceneWidget::getViewport() + { + if (!mWindow) + updateOgreWindow(); + + return mViewport; + } + Ogre::SceneManager *SceneWidget::getSceneManager() { return mSceneMgr; diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 07804007a2..f53e935f41 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -16,6 +16,7 @@ namespace Ogre class RenderWindow; class Viewport; class OverlaySystem; + class RenderTargetListener; } namespace CSVWidget @@ -51,6 +52,12 @@ namespace CSVRender void setNavigation (Navigation *navigation); ///< \attention The ownership of \a navigation is not transferred to *this. + void addRenderTargetListener(Ogre::RenderTargetListener *listener); + + void removeRenderTargetListener(Ogre::RenderTargetListener *listener); + + Ogre::Viewport *getViewport(); + Ogre::SceneManager *getSceneManager(); Ogre::Camera *getCamera(); @@ -86,7 +93,7 @@ namespace CSVRender void setLighting (Lighting *lighting); ///< \attention The ownership of \a lighting is not transferred to *this. - Ogre::Camera* mCamera; + Ogre::Camera* mCamera; Ogre::SceneManager* mSceneMgr; Ogre::RenderWindow* mWindow; Ogre::Viewport *mViewport; diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index d26dda5075..e64ff51e39 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -217,13 +217,21 @@ TextOverlay::~TextOverlay() overlayMgr->destroy(mOverlay); } +void TextOverlay::show(bool show) +{ + if(show) + mContainer->show(); + else + mContainer->hide(); +} + void TextOverlay::enable(bool enable) { if(enable == mOverlay->isVisible()) return; mEnabled = enable; - if (enable) + if(enable) mOverlay->show(); else mOverlay->hide(); diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index 75c5ba2ed2..c44fd9d1f1 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -49,12 +49,13 @@ namespace CSVRender TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String &id); virtual ~TextOverlay(); - void enable(bool enable); + void enable(bool enable); // controlled from scene widget toolbar visibility mask + void show(bool show); // for updating from render target listener bool isEnabled(); void setCaption(const Ogre::String& text); void setDesc(const Ogre::String& text); void update(); - QRect container(); + QRect container(); // for detection of mouse click on the overlay Ogre::String getCaption() { return mCaption; } // FIXME: debug Ogre::String getDesc() { return mDesc; } };