From 2930d4152185d7cec93523ece17a35ef5cbbe886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Tue, 25 Jun 2019 17:01:38 +0200 Subject: [PATCH] AppFwk: Fix of Qt5 OpenGL related problems: Offset + Context deletion. Added option to control the direction of the parallel projection headlight Added optional visualization of point of interest to caf::Viewer --- Fwk/AppFwk/cafViewer/CMakeLists.txt | 1 + .../cafViewer/cafPointOfInterestVisualizer.h | 62 ++++++++++++++++ Fwk/AppFwk/cafViewer/cafViewer.cpp | 73 +++++++++++++++++-- Fwk/AppFwk/cafViewer/cafViewer.h | 7 ++ 4 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 Fwk/AppFwk/cafViewer/cafPointOfInterestVisualizer.h diff --git a/Fwk/AppFwk/cafViewer/CMakeLists.txt b/Fwk/AppFwk/cafViewer/CMakeLists.txt index 02df1adb9b..4de3993271 100644 --- a/Fwk/AppFwk/cafViewer/CMakeLists.txt +++ b/Fwk/AppFwk/cafViewer/CMakeLists.txt @@ -30,6 +30,7 @@ add_library( ${PROJECT_NAME} cafTrackBallBasedNavigation.h cafNavigationPolicy.cpp cafNavigationPolicy.h + cafPointOfInterestVisualizer.h cafOpenGLWidget.cpp cafOpenGLWidget.h cafViewer.cpp diff --git a/Fwk/AppFwk/cafViewer/cafPointOfInterestVisualizer.h b/Fwk/AppFwk/cafViewer/cafPointOfInterestVisualizer.h new file mode 100644 index 0000000000..d46a2f338c --- /dev/null +++ b/Fwk/AppFwk/cafViewer/cafPointOfInterestVisualizer.h @@ -0,0 +1,62 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) CeetronSolutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfVector3.h" + +namespace cvf +{ + class Model; +} + +namespace caf +{ + +class PointOfInterestVisualizer : public cvf::Object +{ +public: + /// Returns the model containing the visualization of the PointOfInterest + /// Must always return the same model. + virtual cvf::Model* model() = 0; + + /// Update the model to show a different point of interest position + virtual void update(cvf::Vec3d pointOfInterest) = 0; +}; + +} + diff --git a/Fwk/AppFwk/cafViewer/cafViewer.cpp b/Fwk/AppFwk/cafViewer/cafViewer.cpp index 431d5f8641..016a7d3134 100644 --- a/Fwk/AppFwk/cafViewer/cafViewer.cpp +++ b/Fwk/AppFwk/cafViewer/cafViewer.cpp @@ -34,12 +34,12 @@ // //################################################################################################## - #include "cafViewer.h" #include "cafCadNavigation.h" #include "cafFrameAnimationControl.h" #include "cafNavigationPolicy.h" +#include "cafPointOfInterestVisualizer.h" #include "cvfCamera.h" #include "cvfDebugTimer.h" @@ -112,7 +112,11 @@ cvf::ref caf::Viewer::sm_openGLContextGroup; /// //-------------------------------------------------------------------------------------------------- caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent) + #if QT_VERSION >= 0x050000 + : caf::OpenGLWidget(contextGroup(), format, nullptr, sharedWidget()), + #else : caf::OpenGLWidget(contextGroup(), format, new QWidget(parent), sharedWidget()), + #endif m_navigationPolicy(nullptr), m_navigationPolicyEnabled(true), m_defaultPerspectiveNearPlaneDistance(0.05), @@ -122,10 +126,15 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent) m_releaseOGLResourcesEachFrame(false), m_isOverlayPaintingEnabled(true), m_offscreenViewportWidth(0), - m_offscreenViewportHeight(0) + m_offscreenViewportHeight(0), + m_parallelProjectionLightDirection(0, 0, -1) // Light directly from behind { + #if QT_VERSION >= 0x050000 + m_layoutWidget = new QWidget(parent); + #else m_layoutWidget = parentWidget(); - + #endif + QHBoxLayout* layout = new QHBoxLayout(m_layoutWidget); layout->addWidget(this); @@ -165,6 +174,7 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent) sm_viewers.push_back(this); } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -419,6 +429,22 @@ void caf::Viewer::optimizeClippingPlanes() //-------------------------------------------------------------------------------------------------- bool caf::Viewer::event(QEvent* e) { + #if QT_VERSION >= 0x050000 + // The most reliable way we have found of detecting when an OpenGL context is about to be destroyed is + // hooking into the QEvent::PlatformSurface event and checking for the SurfaceAboutToBeDestroyed event type. + // From the Qt doc: + // The underlying native surface will be destroyed immediately after this event. + // The SurfaceAboutToBeDestroyed event type is useful as a means of stopping rendering to a platform window before it is destroyed. + if ( e->type() == QEvent::PlatformSurface ) + { + QPlatformSurfaceEvent* platformSurfaceEvent = static_cast(e); + if ( platformSurfaceEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed ) + { + cvfShutdownOpenGLContext(); + } + } + #endif + if (e && m_navigationPolicy.notNull() && m_navigationPolicyEnabled) { switch (e->type()) @@ -618,10 +644,21 @@ void caf::Viewer::paintEvent(QPaintEvent* event) optimizeClippingPlanes(); + if ( m_poiVisualizationManager.notNull() ) + { + m_poiVisualizationManager->update(m_navigationPolicy->pointOfInterest()); + m_mainRendering->scene()->addModel(m_poiVisualizationManager->model()); + } + // Do normal drawing m_renderingSequence->render(myOglContext.p()); CVF_CHECK_OGL(cvfOpenGLContext()); + if ( m_poiVisualizationManager.notNull() ) + { + m_mainRendering->scene()->removeModel(m_poiVisualizationManager->model()); + } + if (isShadersSupported()) { cvfqt::OpenGLContext::restoreOpenGLState(myOglContext.p()); @@ -1146,10 +1183,10 @@ void caf::Viewer::enableParallelProjection(bool enableOrtho) m_mainCamera->setProjectionAsOrtho(1.0, m_mainCamera->nearPlane(), m_mainCamera->farPlane()); this->updateParallelProjectionHeightFromMoveZoom(pointOfInterest); - // Set the light position behind us, far away from the scene + // Set a fake directional light by putting the point far away from the scene float sceneDepth = m_mainCamera->farPlane() - m_mainCamera->nearPlane(); - this->m_renderingSequence->setDefaultFFLightPositional(cvf::Vec3f(0,0, 2 * sceneDepth)); - m_globalUniformSet->setHeadLightPosition(cvf::Vec3f(0,0, 2 * sceneDepth)); + this->m_renderingSequence->setDefaultFFLightPositional(-m_parallelProjectionLightDirection* 10*sceneDepth); + m_globalUniformSet->setHeadLightPosition(-m_parallelProjectionLightDirection* 10*sceneDepth); this->update(); } @@ -1159,7 +1196,7 @@ void caf::Viewer::enableParallelProjection(bool enableOrtho) // so we do not need to update the camera position based on orthoHeight and fieldOfView. // We assume the camera is in a sensible position. - // Set dummy near and far plane. These wll be updated by the optimize clipping planes + // Set dummy near and far plane. These will be updated by the optimize clipping planes m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, 0.1, 1.0); this->m_renderingSequence->setDefaultFFLightPositional(cvf::Vec3f(0.5, 5.0, 7.0)); @@ -1169,6 +1206,28 @@ void caf::Viewer::enableParallelProjection(bool enableOrtho) } } +//-------------------------------------------------------------------------------------------------- +/// Direction in camera coordinates default is (0, 0, -1) directly from behind +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::setParallelProjectionHeadLightDirection(const cvf::Vec3f& direction) +{ + m_parallelProjectionLightDirection = direction; + + float sceneDepth = m_mainCamera->farPlane() - m_mainCamera->nearPlane(); + this->m_renderingSequence->setDefaultFFLightPositional(-m_parallelProjectionLightDirection* 10*sceneDepth); + m_globalUniformSet->setHeadLightPosition(-m_parallelProjectionLightDirection* 10*sceneDepth); + + this->update(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::setPointOfInterestVisualizer(PointOfInterestVisualizer* poiVisualizer) +{ + m_poiVisualizationManager = poiVisualizer; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafViewer/cafViewer.h b/Fwk/AppFwk/cafViewer/cafViewer.h index 2f8401bf84..5cead98591 100644 --- a/Fwk/AppFwk/cafViewer/cafViewer.h +++ b/Fwk/AppFwk/cafViewer/cafViewer.h @@ -65,6 +65,7 @@ namespace caf { class FrameAnimationControl; class NavigationPolicy; class Viewer; + class PointOfInterestVisualizer; } class QInputEvent; @@ -121,6 +122,8 @@ public: void setView( const cvf::Vec3d& alongDirection, const cvf::Vec3d& upDirection ); void zoomAll(); void enableParallelProjection(bool enable); + void setParallelProjectionHeadLightDirection(const cvf::Vec3f& direction); + void setPointOfInterestVisualizer(PointOfInterestVisualizer* poiVisualizer); // Interface for navigation policies void updateParallelProjectionHeightFromMoveZoom(const cvf::Vec3d& pointOfInterest); @@ -224,9 +227,13 @@ private: cvf::Collection m_frameScenes; cvf::Collection m_staticModels; + // Poi visualization + cvf::ref m_poiVisualizationManager; + // Parallel projection light modification cvf::ref m_globalUniformSet; + cvf::Vec3f m_parallelProjectionLightDirection; // Offscreen render objects cvf::ref m_offscreenFbo;