diff --git a/ApplicationCode/UserInterface/RIViewer.cpp b/ApplicationCode/UserInterface/RIViewer.cpp index 204a2a66d6..6187c278f7 100644 --- a/ApplicationCode/UserInterface/RIViewer.cpp +++ b/ApplicationCode/UserInterface/RIViewer.cpp @@ -62,11 +62,12 @@ RIViewer::RIViewer(const QGLFormat& format, QWidget* parent) axisCross->setAxisLabels("E", "N", "Z"); m_mainRendering->addOverlayItem(axisCross, cvf::OverlayItem::BOTTOM_LEFT, cvf::OverlayItem::VERTICAL); - setReleaseOGLResourcesEachFrame(true); + this->enableOverlyPainting(true); + this->setReleaseOGLResourcesEachFrame(true); QColor c; QPalette p = QApplication::palette(); - QColor frameAndTextColor(255, 255, 255, 200); + QColor frameAndTextColor(255, 255, 255, 255); p.setColor(QPalette::Window, QColor(144, 173, 208, 180)); p.setColor(QPalette::WindowText, frameAndTextColor); @@ -427,10 +428,10 @@ cvf::Part* RIViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, c void RIViewer::paintOverlayItems(QPainter* painter) { // No support for overlay items using SW rendering yet. - if (!isShadersSupported()) - { - return; - } + //if (!isShadersSupported()) + //{ + // return; + //} int columnWidth = 200; int margin = 5; diff --git a/ApplicationCode/UserInterface/RIViewer.h b/ApplicationCode/UserInterface/RIViewer.h index b09ce90448..349f415783 100644 --- a/ApplicationCode/UserInterface/RIViewer.h +++ b/ApplicationCode/UserInterface/RIViewer.h @@ -95,6 +95,7 @@ private: cvf::ref m_legend1; cvf::ref m_legend2; + caf::PdmPointer m_reservoirView; }; diff --git a/VisualizationModules/LibRender/cvfOverlayItem.h b/VisualizationModules/LibRender/cvfOverlayItem.h index d196c29e16..a419c93015 100644 --- a/VisualizationModules/LibRender/cvfOverlayItem.h +++ b/VisualizationModules/LibRender/cvfOverlayItem.h @@ -43,7 +43,8 @@ public: TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, - BOTTOM_RIGHT + BOTTOM_RIGHT, + UNMANAGED }; enum LayoutDirection @@ -56,10 +57,17 @@ public: virtual Vec2ui sizeHint() = 0; // In Pixels virtual Vec2ui maximumSize() = 0; // In Pixels virtual Vec2ui minimumSize() = 0; // In Pixels + + cvf::Vec2i unmanagedPosition() const { return m_unmanagedPosition; } + void setUnmanagedPosition(cvf::Vec2i val) { m_unmanagedPosition = val; } virtual void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) = 0; virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) = 0; virtual bool pick(int oglXCoord, int oglYCoord, const Vec2i& position, const Vec2ui& size); + +private: + Vec2i m_unmanagedPosition; + }; } diff --git a/VisualizationModules/LibViewing/cvfRendering.cpp b/VisualizationModules/LibViewing/cvfRendering.cpp index a250346712..e5664f7397 100644 --- a/VisualizationModules/LibViewing/cvfRendering.cpp +++ b/VisualizationModules/LibViewing/cvfRendering.cpp @@ -308,6 +308,25 @@ void Rendering::renderOverlayItems(OpenGLContext* oglContext, bool useSoftwareRe item->render(oglContext, rect.min(), Vec2ui(static_cast(rect.width()), static_cast(rect.height()))); } } + + for (size_t i = 0; i < m_overlayItems.size(); i++) + { + OverlayItemLayout item = m_overlayItems.at(i); + if ((item.corner == OverlayItem::UNMANAGED) ) + { + Vec2ui size = item.overlayItem->sizeHint(); + Vec2i pos = item.overlayItem->unmanagedPosition(); + + if (useSoftwareRendering) + { + item.overlayItem->renderSoftware(oglContext, pos, size); + } + else + { + item.overlayItem->render(oglContext, pos, size); + } + } + } } diff --git a/cafViewer/cafViewer.cpp b/cafViewer/cafViewer.cpp index 97ac316856..ccc4e257db 100644 --- a/cafViewer/cafViewer.cpp +++ b/cafViewer/cafViewer.cpp @@ -26,6 +26,8 @@ #include "cvfRenderQueueSorter.h" #include "cvfScene.h" #include "cvfModel.h" +#include "cvfTextureImage.h" +#include "cvfOverlayImage.h" #include "cvfqtOpenGLContext.h" @@ -62,7 +64,8 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent) m_maxFarPlaneDistance(cvf::UNDEFINED_DOUBLE), m_releaseOGLResourcesEachFrame(false), m_paintCounter(0), - m_navigationPolicyEnabled(true) + m_navigationPolicyEnabled(true), + m_isOverlyPaintingEnabled(true) { m_layoutWidget = parentWidget(); @@ -89,6 +92,11 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent) this->setNavigationPolicy(new caf::CadNavigation); + m_overlayTextureImage = new cvf::TextureImage; + m_overlayImage = new cvf::OverlayImage(m_overlayTextureImage.p()); + m_overlayImage->setBlending(cvf::OverlayImage::TEXTURE_ALPHA); + m_overlayImage->setUnmanagedPosition(cvf::Vec2i(0,0)); + setupMainRendering(); setupRenderingSequence(); @@ -121,6 +129,8 @@ void caf::Viewer::setupMainRendering() { m_mainRendering->renderEngine()->enableForcedImmediateMode(true); } + + updateOverlayImagePresence(); } //-------------------------------------------------------------------------------------------------- @@ -358,6 +368,7 @@ void caf::Viewer::resizeGL(int width, int height) void caf::Viewer::enablePerfInfoHud(bool enable) { m_showPerfInfoHud = enable; + updateOverlayImagePresence(); } @@ -391,6 +402,66 @@ void caf::Viewer::paintEvent(QPaintEvent* event) return; } + // If Qt overlay painting is enabled, paint to an QImage, and set it to the cvf::OverlayImage + + if (m_isOverlyPaintingEnabled || m_showPerfInfoHud) + { + // Set up image to draw to, and painter + if (m_overlayPaintingQImage.size() != this->size()) + { + m_overlayPaintingQImage = QImage(this->size(), QImage::Format_ARGB32); + } + + m_overlayPaintingQImage.fill(Qt::transparent); + QPainter overlyPainter(&m_overlayPaintingQImage); + + // Call virtual method to allow subclasses to paint on the OpenGlCanvas + + if (m_isOverlyPaintingEnabled) + { + this->paintOverlayItems(&overlyPainter); + } + + // Draw performance overlay + + if (m_showPerfInfoHud ) + { + cvfqt::PerformanceInfoHud hud; + hud.addStrings(m_renderingSequence->performanceInfo()); + hud.addStrings(*m_mainCamera); + hud.addString(QString("PaintCount: %1").arg(m_paintCounter++)); + hud.draw(&overlyPainter, width(), height()); + } + + // Convert the QImage into the cvf::TextureImage, + // handling vertical mirroring and (possible) byteswapping + + if (m_overlayTextureImage->height() != this->height() || m_overlayTextureImage->width() != this->width()) + { + m_overlayTextureImage->allocate(this->width(), this->height()); + } + + int height = m_overlayTextureImage->height(); + int width = m_overlayTextureImage->width(); + +#pragma omp parallel for + for (int y = 0 ; y < height; ++y) + { + int negy = height - 1 - y; + for (int x = 0 ; x < width; ++x) + { + // Should probably do direct conversion on byte level. Would be faster + // QImage.bits() and cvf::TextureImage.ptr() (casting away const) + QRgb qtRgbaVal = m_overlayPaintingQImage.pixel(x, negy); + cvf::Color4ub cvfRgbVal(qRed(qtRgbaVal), qGreen(qtRgbaVal), qBlue(qtRgbaVal), qAlpha(qtRgbaVal)); + m_overlayTextureImage->setPixel(x, y, cvfRgbVal); + } + } + + m_overlayImage->setImage(m_overlayTextureImage.p()); + m_overlayImage->setPixelSize(cvf::Vec2ui(this->width(), this->height())); + } + #if QT_VERSION >= 0x040600 // Qt 4.6 painter.beginNativePainting(); @@ -417,17 +488,7 @@ void caf::Viewer::paintEvent(QPaintEvent* event) painter.endNativePainting(); #endif - // Call virtual method to allow subclasses to paint on the OpenGlCanvas - this->paintOverlayItems(&painter); - - if (m_showPerfInfoHud && isShadersSupported()) - { - cvfqt::PerformanceInfoHud hud; - hud.addStrings(m_renderingSequence->performanceInfo()); - hud.addStrings(*m_mainCamera); - hud.addString(QString("PaintCount: %1").arg(m_paintCounter++)); - hud.draw(&painter, width(), height()); - } + } //-------------------------------------------------------------------------------------------------- @@ -696,3 +757,35 @@ int caf::Viewer::currentFrameIndex() else return 0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool caf::Viewer::isOverlyPaintingEnabled() const +{ + return m_isOverlyPaintingEnabled; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::enableOverlyPainting(bool val) +{ + m_isOverlyPaintingEnabled = val; + updateOverlayImagePresence(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::updateOverlayImagePresence() +{ + if (m_isOverlyPaintingEnabled || m_showPerfInfoHud) + { + m_mainRendering->addOverlayItem(m_overlayImage.p(), cvf::OverlayItem::UNMANAGED, cvf::OverlayItem::VERTICAL); + } + else + { + m_mainRendering->removeOverlayItem(m_overlayImage.p()); + } +} + diff --git a/cafViewer/cafViewer.h b/cafViewer/cafViewer.h index d3708ba00c..e9ad4bf13e 100644 --- a/cafViewer/cafViewer.h +++ b/cafViewer/cafViewer.h @@ -26,9 +26,6 @@ #include "cvfVector3.h" #include "cvfOpenGL.h" - -//#include "cvfManipulatorTrackball.h" - #include "cafOpenGLWidget.h" @@ -39,6 +36,8 @@ namespace cvf { class RenderSequence; class OverlayScalarMapperLegend; class HitItemCollection; + class OverlayImage; + class TextureImage; } namespace caf { @@ -100,6 +99,11 @@ public: bool rayPick(int winPosX, int winPosY, cvf::HitItemCollection* pickedPoints) ; + // QPainter based drawing on top of the OpenGL graphics + + bool isOverlyPaintingEnabled() const; + void enableOverlyPainting(bool val); + // Performance information for debugging etc. void enablePerfInfoHud(bool enable); bool isPerfInfoHudEnabled(); @@ -131,10 +135,9 @@ protected: virtual void paintEvent(QPaintEvent* event); // Support the navigation policy concept - virtual bool event( QEvent* e ); - cvf::ref - m_navigationPolicy; - bool m_navigationPolicyEnabled; + virtual bool event( QEvent* e ); + cvf::ref m_navigationPolicy; + bool m_navigationPolicyEnabled; // Actual rendering objects cvf::ref m_renderingSequence; @@ -142,31 +145,35 @@ protected: cvf::ref m_mainCamera; cvf::ref m_mainRendering; - double m_minNearPlaneDistance; - double m_maxFarPlaneDistance; + double m_minNearPlaneDistance; + double m_maxFarPlaneDistance; private: - void updateCamera(int width, int height); + void updateCamera(int width, int height); - void releaseOGlResourcesForCurrentFrame(); - void debugShowRenderingSequencePartNames(); + void releaseOGlResourcesForCurrentFrame(); + void debugShowRenderingSequencePartNames(); - bool m_showPerfInfoHud; - size_t m_paintCounter; - bool m_releaseOGLResourcesEachFrame; - QPointer m_layoutWidget; + bool m_showPerfInfoHud; + size_t m_paintCounter; + bool m_releaseOGLResourcesEachFrame; + QPointer m_layoutWidget; + bool m_isOverlyPaintingEnabled; + cvf::ref m_overlayTextureImage; + cvf::ref m_overlayImage; + QImage m_overlayPaintingQImage; + void updateOverlayImagePresence(); // System to make sure we share OpenGL resources - static Viewer* sharedWidget(); - static cvf::OpenGLContextGroup* contextGroup(); - static std::list - sm_viewers; + static Viewer* sharedWidget(); + static cvf::OpenGLContextGroup* contextGroup(); + static std::list sm_viewers; static cvf::ref - sm_openGLContextGroup; + sm_openGLContextGroup; - caf::FrameAnimationControl* m_animationControl; - cvf::Collection m_frameScenes; + caf::FrameAnimationControl* m_animationControl; + cvf::Collection m_frameScenes; }; } // End namespace caf