Add support in VizFwk for using QOpenGLWidget derived view widget (#11091)

* Refactor to deprecate existing QGLWidget derived widget

Renamed cvfqt::OpenGLWidget to cvfqt::GLWidget_deprecated
Renamed cvfqt::CvfBoundQGLContext to cvfqt::CvfBoundQGLContext_deprecated
Renamed cvfqt::OpenGLContext to cvfqt::OpenGLContext_QGLContextAdapter_deprecated
Added cvf::OpenGLUtils

* Marked existing QtMinimal and QtMultiView as deprecated

* Additional deprecated renaming

* Added missing type

* Added missing include

* Fixes to get snippets up and running before introducing new OpenGL widgets

* Added class for OpenGLInfo

* Refactored cvf::OpenGLContext and cvf::OpenGLContextGroup, and added first cut impl of cvfqt::GLWidget and cvfqt::OpenGLWidget

* Removed unused TriggerTBBCopy.txt

* Initial support for compilation on Qt6

* Added QtMinimal and QtMinimal_GLWidget

* Refactored SnippetRunner to handle utilize cvfqt::OpenGLWidget

* Removed unused code

* Fixes and workarounds from compiling on linux

* Fixes by clang-format (#11056)

Co-authored-by: sigurdp <sigurdp@users.noreply.github.com>

* Added QTMultiView test app based on cvfqt::OpenGLWidget

* Removed includes of QOpenGLFunctions

* Modifications for compile with Qt6

* Added test bench for cvfqt::OpenGLWidget

* Minor fixes

* Force to use Qt5

* Fixes by cmake-format

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: sigurdp <sigurdp@users.noreply.github.com>
This commit is contained in:
Sigurd Pettersen
2024-01-23 08:48:05 +01:00
committed by GitHub
parent 576f15dd15
commit 10a579fac5
105 changed files with 7017 additions and 1003 deletions

View File

@@ -3,6 +3,13 @@ cmake_minimum_required(VERSION 3.15)
project(VizFramework)
if (CEE_CEEVIZ_ROOT)
message(STATUS "CEE_CEEVIZ_ROOT: ${CEE_CEEVIZ_ROOT}")
else()
set(CEE_CEEVIZ_ROOT ${PROJECT_SOURCE_DIR})
message(STATUS "Setting CEE_CEEVIZ_ROOT to ${CEE_CEEVIZ_ROOT}")
endif()
# Determine if we're being run stand-alone or invoked from some other project
set(CEE_STAND_ALONE ON)
if (PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
@@ -20,6 +27,8 @@ if (CEE_STAND_ALONE)
endif()
include(CMake/Utils/ceeDetermineCompilerFlags.cmake)
set(CMAKE_CXX_STANDARD 17)
endif()
@@ -44,36 +53,46 @@ add_subdirectory(ThirdParty/FreeType)
add_subdirectory(LibUtilities)
option(CEE_BUILD_GUI_QT "Build GUI library for Qt" ON)
if (CEE_BUILD_GUI_QT)
option(CEE_USE_QT5 "Use Qt5" ON)
option(CEE_USE_QT6 "Use Qt6" OFF)
option(CEE_USE_QT5 "Use Qt5" OFF)
add_subdirectory(LibGuiQt)
endif()
if (CEE_STAND_ALONE)
option(CEE_BUILD_UNIT_TESTS "Build unit tests" ON)
if (CEE_BUILD_UNIT_TESTS)
add_subdirectory(Tests)
endif()
option(CEE_BUILD_TEST_APPS "Build test apps" ON)
if (CEE_BUILD_TEST_APPS)
# For now, build the snippet libs here
add_subdirectory(Tests/SnippetsBasis)
endif()
if (CEE_BUILD_GUI_QT)
add_subdirectory(TestApps/Qt/QtMinimal)
add_subdirectory(TestApps/Qt/QtMultiView)
add_subdirectory(TestApps/Qt/QtSnippetRunner)
endif()
if (CEE_BUILD_UNIT_TESTS OR CEE_BUILD_TEST_APPS)
# Add CeeViz's root source dir as a preprocessor directive so unit tests and test apps can determine where to find the resources they want.
add_definitions(-DCVF_CEEVIZ_ROOT_SOURCE_DIR="${CEE_CEEVIZ_ROOT}")
endif()
if (WIN32)
add_subdirectory(TestApps/Win32/Win32SnippetRunner)
if (CEE_BUILD_UNIT_TESTS)
add_subdirectory(Tests)
endif()
if (CEE_BUILD_TEST_APPS)
# For now, build the snippet libs here
add_subdirectory(Tests/SnippetsBasis)
if (CEE_BUILD_GUI_QT)
add_subdirectory(TestApps/Qt/QtMinimal)
add_subdirectory(TestApps/Qt/QtMultiView)
add_subdirectory(TestApps/Qt/QtTestBenchOpenGLWidget)
add_subdirectory(TestApps/Qt/QtSnippetRunner)
if (CEE_USE_QT5)
add_subdirectory(TestApps/Qt/QtMinimal_GLWidget)
add_subdirectory(TestApps/Qt/QtMinimal_deprecated)
add_subdirectory(TestApps/Qt/QtMultiView_deprecated)
endif()
endif()
if (WIN32)
add_subdirectory(TestApps/Win32/Win32SnippetRunner)
endif()
endif()

View File

@@ -112,5 +112,11 @@ target_include_directories(${PROJECT_NAME}
${CMAKE_CURRENT_SOURCE_DIR}
)
if (UNIX AND NOT APPLE)
# Our core library has dependencies on librt and libpthread for timers and mutex.
target_link_libraries(${PROJECT_NAME} -lrt -lpthread)
endif()
set(PROJECT_FILES ${CEE_HEADER_FILES} ${CEE_SOURCE_FILES})
source_group("" FILES ${PROJECT_FILES})

View File

@@ -68,7 +68,7 @@
// Makes it easier to check on the current GCC version
#ifdef __GNUC__
// 40302 means version 4.3.2.
# define CVF_GCC_VER (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
#define CVF_GCC_VER (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
#endif
// Helper macro to disable (ignore) compiler warnings on GCC
@@ -80,6 +80,15 @@
#define CVF_GCC_DIAGNOSTIC_IGNORE(OPTION_STRING)
#endif
// Helper macros for push/pop of GCC diagnostics, available from GCC 4.6.x
#if defined(__GNUC__) && (CVF_GCC_VER >= 40600)
#define CVF_GCC_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
#define CVF_GCC_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#else
#define CVF_GCC_DIAGNOSTIC_PUSH
#define CVF_GCC_DIAGNOSTIC_POP
#endif
#if defined(CVF_LINUX) || defined(CVF_IOS) || defined(CVF_OSX) || defined(CVF_ANDROID)
// Used by int64_t on *nix below
@@ -123,6 +132,13 @@ typedef __int64 int64;
typedef int64_t int64;
#endif
// 64bit unsigned integer support via the int64 type
#ifdef WIN32
typedef unsigned __int64 uint64;
#elif defined(CVF_LINUX) || defined(CVF_IOS) || defined(CVF_OSX) || defined(CVF_ANDROID)
typedef uint64_t uint64;
#endif
}
#include "cvfConfigCore.h"

View File

@@ -57,6 +57,7 @@
#include "cvfFlags.h"
#include "cvfFunctorRange.h"
#include "cvfLogger.h"
#include "cvfLogManager.h"
#include "cvfMath.h"
#include "cvfMatrix4.h"
#include "cvfObject.h"

View File

@@ -9,6 +9,11 @@ endif()
# Use our strict compile flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STRICT_CXX_FLAGS}")
# For now, disable warning about unknown pragmas locally here (due to usage of OpenMP)
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas")
endif()
set(CEE_HEADER_FILES
cvfArrowGenerator.h

View File

@@ -10,19 +10,31 @@ endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_BASE_CXX_FLAGS}")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long")
# Due to usage of OpenMP, disable warning about unknown pragmas
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long -Wno-unknown-pragmas")
endif()
find_package(OpenGL)
find_package(Qt5 COMPONENTS REQUIRED Core Gui Widgets OpenGL)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets Qt5::OpenGL)
message(STATUS "In LibGuiQt, CEE_USE_QT6=${CEE_USE_QT6}")
message(STATUS "In LibGuiQt, CEE_USE_QT5=${CEE_USE_QT5}")
if (CEE_USE_QT6)
find_package(Qt6 COMPONENTS REQUIRED Core Gui Widgets OpenGLWidgets)
set(QT_LIBRARIES Qt6::Core Qt6::Gui Qt6::Widgets Qt6::OpenGLWidgets )
elseif (CEE_USE_QT5)
find_package(Qt5 COMPONENTS REQUIRED Core Gui Widgets OpenGL)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets Qt5::OpenGL)
else()
message(FATAL_ERROR "No supported Qt version selected for build")
endif()
set(CEE_HEADER_FILES
cvfqtBasicAboutDialog.h
cvfqtCvfBoundQGLContext.h
cvfqtMouseState.h
cvfqtOpenGLContext.h
cvfqtOpenGLWidget.h
cvfqtPerformanceInfoHud.h
cvfqtUtils.h
@@ -30,14 +42,21 @@ cvfqtUtils.h
set(CEE_SOURCE_FILES
cvfqtBasicAboutDialog.cpp
cvfqtCvfBoundQGLContext.cpp
cvfqtMouseState.cpp
cvfqtOpenGLContext.cpp
cvfqtOpenGLWidget.cpp
cvfqtPerformanceInfoHud.cpp
cvfqtUtils.cpp
)
if (CEE_USE_QT5)
set(CEE_HEADER_FILES ${CEE_HEADER_FILES} cvfqtGLWidget.h)
set(CEE_SOURCE_FILES ${CEE_SOURCE_FILES} cvfqtGLWidget.cpp)
set(CEE_HEADER_FILES ${CEE_HEADER_FILES} cvfqtCvfBoundQGLContext_deprecated.h)
set(CEE_SOURCE_FILES ${CEE_SOURCE_FILES} cvfqtCvfBoundQGLContext_deprecated.cpp)
set(CEE_HEADER_FILES ${CEE_HEADER_FILES} cvfqtGLWidget_deprecated.h)
set(CEE_SOURCE_FILES ${CEE_SOURCE_FILES} cvfqtGLWidget_deprecated.cpp)
endif()
add_library(${PROJECT_NAME} ${CEE_HEADER_FILES} ${CEE_SOURCE_FILES})
target_include_directories(${PROJECT_NAME}
@@ -58,6 +77,5 @@ source_group("" FILES ${PROJECT_FILES})
# Unity Build
if (CMAKE_UNITY_BUILD)
set_source_files_properties (cvfqtOpenGLWidget.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
set_source_files_properties (cvfqtOpenGLContext.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
set_source_files_properties (cvfqtGLWidget_deprecated.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
endif()

View File

@@ -255,8 +255,7 @@ void BasicAboutDialog::create()
// Library version
if (m_showLibraryVersion)
{
QString ver;
ver.sprintf("%s.%s%s-%s", CVF_MAJOR_VERSION, CVF_MINOR_VERSION, CVF_SPECIAL_BUILD, CVF_BUILD_NUMBER);
QString ver = QString("%1.%2%3-%4").arg(CVF_MAJOR_VERSION).arg(CVF_MINOR_VERSION).arg(CVF_SPECIAL_BUILD).arg(CVF_BUILD_NUMBER);
addStringPairToVerInfoLayout("Library ver.: ", ver, verInfoLayout, insertRow++);
}

View File

@@ -0,0 +1,150 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfOpenGLCapabilities.h"
#include "cvfqtCvfBoundQGLContext_deprecated.h"
namespace cvfqt {
//==================================================================================================
///
/// \class cvfqt::OpenGLContext_QGLContextAdapter_deprecated
/// \ingroup GuiQt
///
/// Derived OpenGLContext that adapts a Qt QGLContext
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
OpenGLContext_QGLContextAdapter_deprecated::OpenGLContext_QGLContextAdapter_deprecated(cvf::OpenGLContextGroup* contextGroup, QGLContext* backingQGLContext)
: cvf::OpenGLContext(contextGroup)
{
m_qtGLContext = backingQGLContext;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
OpenGLContext_QGLContextAdapter_deprecated::~OpenGLContext_QGLContextAdapter_deprecated()
{
m_qtGLContext = NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OpenGLContext_QGLContextAdapter_deprecated::makeCurrent()
{
CVF_ASSERT(m_qtGLContext);
m_qtGLContext->makeCurrent();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool OpenGLContext_QGLContextAdapter_deprecated::isCurrent() const
{
if (m_qtGLContext)
{
if (QGLContext::currentContext() == m_qtGLContext)
{
return true;
}
}
return false;
}
//==================================================================================================
///
/// \class cvfqt::CvfBoundQGLContext_deprecated
/// \ingroup GuiQt
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CvfBoundQGLContext_deprecated::CvfBoundQGLContext_deprecated(cvf::OpenGLContextGroup* contextGroup, const QGLFormat & format)
: QGLContext(format)
{
m_cvfGLContext = new OpenGLContext_QGLContextAdapter_deprecated(contextGroup, this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CvfBoundQGLContext_deprecated::~CvfBoundQGLContext_deprecated()
{
if (m_cvfGLContext.notNull())
{
// TODO
// Need to resolve the case where the Qt QGLcontext (that we're deriving from) is deleted
// and we are still holding a reference to one or more OpenGLContext objects
// By the time we get here we expect that we're holding the only reference
CVF_ASSERT(m_cvfGLContext->refCount() == 1);
m_cvfGLContext = NULL;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OpenGLContext* CvfBoundQGLContext_deprecated::cvfOpenGLContext() const
{
return const_cast<cvf::OpenGLContext*>(m_cvfGLContext.p());
}
} // namespace cvfqt

View File

@@ -0,0 +1,84 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfOpenGLContext.h"
#include <QGLContext>
namespace cvfqt {
//==================================================================================================
//
// Derived OpenGLContext that adapts a Qt QGLContext
//
//==================================================================================================
class OpenGLContext_QGLContextAdapter_deprecated : public cvf::OpenGLContext
{
public:
OpenGLContext_QGLContextAdapter_deprecated(cvf::OpenGLContextGroup* contextGroup, QGLContext* backingQGLContext);
virtual ~OpenGLContext_QGLContextAdapter_deprecated();
virtual void makeCurrent();
virtual bool isCurrent() const;
private:
QGLContext* m_qtGLContext;
};
//==================================================================================================
//
// Utility class used to piggyback OpenGLContext onto Qt's QGLContext
//
//==================================================================================================
class CvfBoundQGLContext_deprecated : public QGLContext
{
public:
CvfBoundQGLContext_deprecated(cvf::OpenGLContextGroup* contextGroup, const QGLFormat & format);
virtual ~CvfBoundQGLContext_deprecated();
cvf::OpenGLContext* cvfOpenGLContext() const;
private:
cvf::ref<cvf::OpenGLContext> m_cvfGLContext;
};
}

View File

@@ -0,0 +1,518 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfqtGLWidget.h"
#include "cvfOpenGLContextGroup.h"
#include "cvfOpenGLContext.h"
#include "cvfLogManager.h"
#include "cvfTrace.h"
#include <QPointer>
#include <QEvent>
#include <QOpenGLContext>
#include <QPlatformSurfaceEvent>
namespace cvfqt {
//==================================================================================================
//
//
//
//==================================================================================================
class ForwardingOpenGLContext_GLWidget : public cvf::OpenGLContext
{
public:
ForwardingOpenGLContext_GLWidget(cvf::OpenGLContextGroup* contextGroup, QGLWidget* ownerQtGLWidget)
: cvf::OpenGLContext(contextGroup),
m_ownerQtGLWidget(ownerQtGLWidget)
{
CVF_ASSERT(contextGroup);
// In our current usage pattern the owner widget (and its contained Qt OpenGL context) must already be initialized/created
CVF_ASSERT(m_ownerQtGLWidget);
CVF_ASSERT(m_ownerQtGLWidget->isValid());
CVF_ASSERT(m_ownerQtGLWidget->context());
CVF_ASSERT(m_ownerQtGLWidget->context()->isValid());
}
virtual void makeCurrent()
{
if (m_ownerQtGLWidget)
{
m_ownerQtGLWidget->makeCurrent();
}
}
virtual bool isCurrent() const
{
const QGLContext* ownersQGLContext = m_ownerQtGLWidget ? m_ownerQtGLWidget->context() : NULL;
if (ownersQGLContext && QGLContext::currentContext() == ownersQGLContext)
{
return true;
}
return false;
}
virtual cvf::OglId defaultFramebufferObject() const
{
if (m_ownerQtGLWidget)
{
const QGLContext* ownersQGLContext = m_ownerQtGLWidget->context();
const QOpenGLContext* ownersQOpenGLContext = ownersQGLContext ? ownersQGLContext->contextHandle() : NULL;
return ownersQOpenGLContext ? ownersQOpenGLContext->defaultFramebufferObject() : 0;
}
return 0;
}
private:
QPointer<QGLWidget> m_ownerQtGLWidget;
};
//==================================================================================================
///
/// \class cvfqt::GLWidget
/// \ingroup GuiQt
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor, use this for the first or only widget in your application.
//--------------------------------------------------------------------------------------------------
GLWidget::GLWidget(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent, Qt::WindowFlags f)
: QGLWidget(format, parent, NULL, f),
m_cvfOpenGLContextGroup(contextGroup),
m_logger(CVF_GET_LOGGER("cee.cvf.qt"))
{
// Must pass a context group
CVF_ASSERT(m_cvfOpenGLContextGroup.notNull());
// Only the first widget in a context group can be created using this constructor
// All following widgets must be created using the constructor overload that takes a shareWidget
CVF_ASSERT(m_cvfOpenGLContextGroup->contextCount() == 0);
// The isValid() call will return true if the widget has a valid GL rendering context; otherwise returns false.
// The widget will be invalid if the system has no OpenGL support.
if (!isValid())
{
CVF_LOG_ERROR(m_logger, "Widget creation failed, the system has no OpenGL support");
return;
}
// The Qt docs for QGLWidget and all previous experience indicates that it is OK to do OpenGL related
// initialization in QGLWidget's constructor (contrary to QOpenGLWidget).
// Note that the Qt docs still hint that initialization should be deferred to initializeGL(). If we ever
// experience problems related to doing initialization here, we should probably move the initialization.
// Since we're in the constructor we must ensure this widget's context is current before initialization
makeCurrent();
const QGLContext* myQtGLContext = context();
CVF_ASSERT(myQtGLContext);
CVF_ASSERT(myQtGLContext->isValid());
CVF_ASSERT(QGLContext::currentContext() == myQtGLContext);
m_cvfForwardingOpenGLContext = new ForwardingOpenGLContext_GLWidget(m_cvfOpenGLContextGroup.p(), this);
if (!m_cvfOpenGLContextGroup->initializeContextGroup(m_cvfForwardingOpenGLContext.p()))
{
CVF_LOG_ERROR(m_logger, "Error initializing context group");
}
// Install our event filter
installEventFilter(this);
// If we're using Qt5 or above, we can get hold of a QOpenGLContext from our QGLContext
// Connect to QOpenGLContext's aboutToBeDestroyed signal so we get notified when Qt's OpenGL context is about to be destroyed
connect(myQtGLContext->contextHandle(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::qtOpenGLContextAboutToBeDestroyed);
}
//--------------------------------------------------------------------------------------------------
/// Constructor, creates a widget sharing the OpenGL resources with the specified widget.
//--------------------------------------------------------------------------------------------------
GLWidget::GLWidget(GLWidget* shareWidget, QWidget* parent , Qt::WindowFlags f)
: QGLWidget(shareWidget->context()->requestedFormat(), parent, shareWidget, f),
m_logger(CVF_GET_LOGGER("cee.cvf.qt"))
{
// Note that when calling QGLWidget's constructor in the initializer list above, we *must* use the
// constructor overload that takes a format as its first parameter. If we do not do this, the default QGLFormat
// will be used, and it may not be compatible with the format of the shareWidget.
// We grab hold of the format from the shareWidget, but note that we do that by calling requestedFormat()
// instead of just format() to ensure that the format being requested here is the same as the one that was actually used
// in the "first widget constructor" and not whatever format the first widget ended up with after construction.
// Requires that a share widget is passed in as parameter
CVF_ASSERT(shareWidget);
// If the share widget doesn't have a CVF OpenGL context something went wrong when it was created and we cannot continue
cvf::ref<cvf::OpenGLContext> shareContext = shareWidget->cvfOpenGLContext();
CVF_ASSERT(shareContext.notNull());
if (!isValid())
{
CVF_LOG_ERROR(m_logger, "Widget creation failed, the system has no OpenGL support");
return;
}
// We need to check if we actually got a context that shares resources with the passed shareWidget.
if (!isSharing())
{
CVF_LOG_ERROR(m_logger, "Widget creation failed, unable to create a shared OpenGL context");
return;
}
// Since we're in the constructor we must ensure this widget's context is current before initialization
makeCurrent();
const QGLContext* myQtGLContext = context();
CVF_ASSERT(myQtGLContext);
CVF_ASSERT(myQtGLContext->isValid());
CVF_ASSERT(QGLContext::currentContext() == myQtGLContext);
m_cvfOpenGLContextGroup = shareContext->group();
CVF_ASSERT(m_cvfOpenGLContextGroup.notNull());
m_cvfForwardingOpenGLContext = new ForwardingOpenGLContext_GLWidget(m_cvfOpenGLContextGroup.p(), this);
// Normally, the context group should already be initialized when the first widget in the group was created.
// Still, for good measure do an initialization here. It will amount to a no-op if context group is already initialized
if (!m_cvfOpenGLContextGroup->initializeContextGroup(m_cvfForwardingOpenGLContext.p()))
{
CVF_LOG_ERROR(m_logger, "Error initializing context group using sharing widget");
}
// Install our event filter
installEventFilter(this);
// If we're using Qt5 or above, we can get hold of a QOpenGLContext from our QGLContext
// Connect to QOpenGLContext's aboutToBeDestroyed signal so we get notified when Qt's OpenGL context is about to be destroyed
connect(myQtGLContext->contextHandle(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::qtOpenGLContextAboutToBeDestroyed);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
GLWidget::~GLWidget()
{
cvf::Trace::show("GLWidget::~GLWidget()");
// Make sure we disconnect from the aboutToBeDestroyed signal since after this destructor has been
// called, out object is dangling and the call to the slot will cause a crash
const QGLContext* myQtGLContext = context();
const QOpenGLContext* myQtOpenGLContext = myQtGLContext ? myQtGLContext->contextHandle() : NULL;
if (myQtOpenGLContext)
{
disconnect(myQtOpenGLContext, &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::qtOpenGLContextAboutToBeDestroyed);
}
// For Qt5, our testing indicates that once we hit the widget's destructor it may be too late
// to try and do any cleanup of OpenGL resources. Most of the time it works, but typically it will fail when
// we're shutting down the application by closing the main window. In such cases it seems that the OpenGL
// context cannot be made current anymore.
//
// One solution to this is to do an explicit shutdown of the context while before the system
// start shutting down. One traditional way of doing this is to iterate over all GLWidgets and call
// the cvfShutdownOpenGLContext() explicitly, eg from QMainWindow::closeEvent()
//
// In our quest to get a notification just before the QGLContext dies we have also tried to go via
// QGLContext's QOpenGLContext and connect to the aboutToBeDestroyed signal. This signal does indeed trigger
// before the QGLContext dies, but it seems that at this point we are no longer able to make the context
// current which is a requirement before we can do our OpenGL related cleanup.
//
// Another promising solution that seems to work reliably is to install an event filter and respond to
// the QEvent::PlatformSurface event. See our eventFilter() override
// For Qt4 it seems that doing OpenGL related cleanup in the destructor is OK
// We're able to make the context current and delete any OpenGL resources necessary through the cvfShutdownOpenGLContext();
// Note that calling this function is safe even if the context has already been shut down.
// It may however fail/assert if the context hasn't already been shut down and if we're unable to make the OpenGL context current
cvfShutdownOpenGLContext();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OpenGLContext* GLWidget::cvfOpenGLContext()
{
return m_cvfForwardingOpenGLContext.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GLWidget::cvfShutdownOpenGLContext()
{
if (m_cvfForwardingOpenGLContext.notNull())
{
makeCurrent();
// If we're not able to make the context current, the eventual un-initialize that will happen
// in the context group when we remove the last context will fail.
const QGLContext* myContext = context();
const QGLContext* currContext = QGLContext::currentContext();
if (myContext != currContext)
{
CVF_LOG_WARNING(m_logger, "Could not make the widget's OpenGL context current for context shutdown");
}
m_cvfOpenGLContextGroup->contextAboutToBeShutdown(m_cvfForwardingOpenGLContext.p());
m_cvfForwardingOpenGLContext = NULL;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GLWidget::initializeGL()
{
//cvf::Trace::show("GLWidget::initializeGL()");
// According to Qt doc this function is called once before the first call to paintGL() or resizeGL(),
// and then once whenever the widget has been assigned a new QGLContext. There is no need to call makeCurrent() because
// this has already been done when this function is called.
if (m_cvfForwardingOpenGLContext.isNull())
{
CVF_LOG_ERROR(m_logger, "Unexpected error in GLWidget::initializeGL(), no forwarding OpenGL context present");
return;
}
// Initialization of context group should already be done, but for good measure
CVF_ASSERT(m_cvfOpenGLContextGroup.notNull());
if (!m_cvfOpenGLContextGroup->isContextGroupInitialized())
{
CVF_LOG_DEBUG(m_logger, "Doing late initialization of context group in GLWidget::initializeGL()");
if (!m_cvfOpenGLContextGroup->initializeContextGroup(m_cvfForwardingOpenGLContext.p()))
{
CVF_LOG_ERROR(m_logger, "Initialization of context group in GLWidget::initializeGL() failed");
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GLWidget::resizeGL(int /*width*/, int /*height*/)
{
// Intentionally empty, and no implementation in QGLWidget::resizeGL() either.
// Should normally be implemented in derived class
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GLWidget::paintGL()
{
// No implementation here and no significant implementation in QGLWidget either.
// In Qt4 QGLWidget::paintGL() does nothing. In Qt5 QGLWidget::paintGL() merely clears the depth and color buffer.
// Derived classes must reimplement this function in order to do painting.
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GLWidget::qtOpenGLContextAboutToBeDestroyed()
{
//cvf::Trace::show("GLWidget::qtOpenGLContextAboutToBeDestroyed()");
cvfShutdownOpenGLContext();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool GLWidget::eventFilter(QObject* watched, QEvent* event)
{
// 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 (event->type() == QEvent::PlatformSurface)
{
QPlatformSurfaceEvent* platformSurfaceEvent = static_cast<QPlatformSurfaceEvent*>(event);
if (platformSurfaceEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed)
{
CVF_LOG_DEBUG(m_logger, "Shutting down OpenGL context in response to platform surface about to be destroyed");
cvfShutdownOpenGLContext();
}
}
// Reading the Qt docs it can seem like reparenting of the QGLWidget might pose a problem for us.
// According to the doc, a change of parent will cause the widget's QGLContext to be deleted and a new one
// to be created. In Qt4, this does indeed seem to happen, whereas for Qt5 it does not. Still, it appears that Qt4 makes
// an effort to make the new QGLContext compatible with the old one, and does some tricks to set up temporary OpenGL
// resource sharing so that we may not actually be affected by this since we're actually not storing any references to
// the QGLContext, but accessing it indirectly through the widget in our ForwardingOpenGLContext.
// May also want to look out for
if (event->type() == QEvent::ParentChange)
{
CVF_LOG_DEBUG(m_logger, "cvfqt::GLWidget has been reparented. This may cause OpenGL issues");
}
else if (event->type() == QEvent::ParentAboutToChange)
{
CVF_LOG_DEBUG(m_logger, "cvfqt::GLWidget is about to change parent. This may cause OpenGL issues");
}
return QGLWidget::eventFilter(watched, event);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GLWidget::logOpenGLInfo()
{
CVF_LOG_INFO(m_logger, "Starting logging of OpenGL info (cvfqt::GLWidget)...");
cvf::String sQtVerInfo = cvf::String("Qt version: %1 (run-time=%2)").arg(QT_VERSION_STR).arg(qVersion());
CVF_LOG_INFO(m_logger, sQtVerInfo);
if (!context() || !isValid())
{
CVF_LOG_WARNING(m_logger, "QGLWidget does not have a valid GL rendering context, reported info will not be correct!");
}
// Log output from querying Qt
CVF_LOG_INFO(m_logger, "Qt OpenGL format info:");
const QGLFormat qglFormat = format();
const QGLFormat::OpenGLContextProfile profile = qglFormat.profile();
const QGLFormat::OpenGLVersionFlags qglVersionFlags = QGLFormat::openGLVersionFlags();
cvf::String sInfo = cvf::String(" info: version %1.%2, depthSize: %3, software: %4, doubleBuffer: %5, sampleBuffers: %6 (size: %7)")
.arg(qglFormat.majorVersion()).arg(qglFormat.minorVersion())
.arg(qglFormat.depthBufferSize())
.arg(qglFormat.directRendering() ? "no" : "yes")
.arg(qglFormat.doubleBuffer() ? "yes" : "no")
.arg(qglFormat.sampleBuffers() ? "yes" : "no")
.arg(qglFormat.samples());
CVF_LOG_INFO(m_logger, sInfo);
cvf::String sProfile = "UNKNOWN";
if (profile == QGLFormat::NoProfile) sProfile = "NoProfile";
else if (profile == QGLFormat::CoreProfile) sProfile = "CoreProfile";
else if (profile == QGLFormat::CompatibilityProfile) sProfile = "CompatibilityProfile";
CVF_LOG_INFO(m_logger, " context profile: " + sProfile);
cvf::String sVersionsPresent = cvf::String(" versions present: 1.1: %1, 2.0: %2, 2.1: %3, 3.0: %4, 3.3: %5, 4.0: %6, ES2: %7")
.arg(qglVersionFlags & QGLFormat::OpenGL_Version_1_1 ? "yes" : "no")
.arg(qglVersionFlags & QGLFormat::OpenGL_Version_2_0 ? "yes" : "no")
.arg(qglVersionFlags & QGLFormat::OpenGL_Version_2_1 ? "yes" : "no")
.arg(qglVersionFlags & QGLFormat::OpenGL_Version_3_0 ? "yes" : "no")
.arg(qglVersionFlags & QGLFormat::OpenGL_Version_3_3 ? "yes" : "no")
.arg(qglVersionFlags & QGLFormat::OpenGL_Version_4_0 ? "yes" : "no")
.arg(qglVersionFlags & QGLFormat::OpenGL_ES_Version_2_0 ? "yes" : "no");
CVF_LOG_INFO(m_logger, sVersionsPresent);
CVF_LOG_INFO(m_logger, " is sharing: " + cvf::String(isSharing() ? "yes" : "no"));
// Log the information we have gathered when initializing the context group
const cvf::OpenGLInfo oglInfo = m_cvfOpenGLContextGroup->info();
CVF_LOG_INFO(m_logger, "OpenGL info:");
CVF_LOG_INFO(m_logger, " version: " + oglInfo.version());
CVF_LOG_INFO(m_logger, " vendor: " + oglInfo.vendor());
CVF_LOG_INFO(m_logger, " renderer: " + oglInfo.renderer());
// Lastly, query OpenGL implementation directly if this context is current
GLint smoothLineWidthRange[2] = { -1, -1 };
GLint smoothPointSizeRange[2] = { -1, -1 };
GLint aliasedLineWidthRange[2] = { -1, -1 };
GLint aliasedPointSizeRange[2] = { -1, -1 };
// Note that GL_LINE_WIDTH_RANGE and GL_SMOOTH_LINE_WIDTH_RANGE are synonyms (0x0B22)
// Likewise for GL_POINT_SIZE_RANGE and GL_SMOOTH_POINT_SIZE_RANGE are synonyms (0x0B12)
#ifndef GL_ALIASED_LINE_WIDTH_RANGE
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
#endif
#ifndef GL_ALIASED_POINT_SIZE_RANGE
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
#endif
const bool thisContextIsCurrent = context() == QGLContext::currentContext();
if (thisContextIsCurrent)
{
glGetIntegerv(GL_LINE_WIDTH_RANGE, smoothLineWidthRange);
glGetIntegerv(GL_POINT_SIZE_RANGE, smoothPointSizeRange);
if (qglVersionFlags & QGLFormat::OpenGL_Version_1_2)
{
glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, aliasedLineWidthRange);
glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, aliasedPointSizeRange);
}
}
else
{
CVF_LOG_WARNING(m_logger, "Cannot query OpenGL directly, QGLWidget's context is not current");
}
cvf::String sLineInfo = cvf::String("OpenGL line width range: aliased lines: %1 to %2, smooth lines: %3 to %4").arg(aliasedLineWidthRange[0]).arg(aliasedLineWidthRange[1]).arg(smoothLineWidthRange[0]).arg(smoothLineWidthRange[1]);
cvf::String sPointInfo = cvf::String("OpenGL point size range: aliased points: %1 to %2, smooth points: %3 to %4").arg(aliasedPointSizeRange[0]).arg(aliasedPointSizeRange[1]).arg(smoothPointSizeRange[0]).arg(smoothPointSizeRange[1]);
CVF_LOG_INFO(m_logger, sLineInfo);
CVF_LOG_INFO(m_logger, sPointInfo);
CVF_LOG_INFO(m_logger, "Finished logging of OpenGL info");
}
} // namespace cvfqt

View File

@@ -0,0 +1,86 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include <QGLWidget>
namespace cvf {
class OpenGLContext;
class OpenGLContextGroup;
class Logger;
}
namespace cvfqt {
//==================================================================================================
//
//
//
//==================================================================================================
class GLWidget : public QGLWidget
{
public:
GLWidget(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent, Qt::WindowFlags f = Qt::WindowFlags());
GLWidget(GLWidget* shareWidget, QWidget* parent , Qt::WindowFlags f = Qt::WindowFlags());
~GLWidget();
cvf::OpenGLContext* cvfOpenGLContext();
void cvfShutdownOpenGLContext();
void logOpenGLInfo();
protected:
virtual void initializeGL();
virtual void resizeGL(int width, int height);
virtual void paintGL();
virtual bool eventFilter(QObject* watched, QEvent* event);
private:
void qtOpenGLContextAboutToBeDestroyed();
private:
cvf::ref<cvf::OpenGLContextGroup> m_cvfOpenGLContextGroup;
cvf::ref<cvf::OpenGLContext> m_cvfForwardingOpenGLContext;
cvf::ref<cvf::Logger> m_logger;
};
}

View File

@@ -0,0 +1,164 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfOpenGLContextGroup.h"
#include "cvfqtCvfBoundQGLContext_deprecated.h"
#include "cvfqtGLWidget_deprecated.h"
namespace cvfqt {
//==================================================================================================
///
/// \class cvfqt::GLWidget_deprecated
/// \ingroup GuiQt
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
GLWidget_deprecated::GLWidget_deprecated(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent, Qt::WindowFlags f)
: QGLWidget(new CvfBoundQGLContext_deprecated(contextGroup, format), parent, NULL, f)
{
// This constructor can only be used with an empty context group!
// We're not able to check this up front, but assert that the count is 1 by the time we get here
CVF_ASSERT(contextGroup->contextCount() == 1);
if (isValid())
{
cvf::ref<cvf::OpenGLContext> myContext = cvfOpenGLContext();
if (myContext.notNull())
{
// We must ensure the context is current before initialization
makeCurrent();
contextGroup->initializeContextGroup(myContext.p());
}
}
}
//--------------------------------------------------------------------------------------------------
/// Constructor
///
/// Tries to create a widget that shares OpenGL resources with \a shareWidget
/// To check if creation was actually successful, you must call isValidContext() on the context
/// of the newly created widget. For example:
/// \code
/// myNewWidget->cvfOpenGLContext()->isValidContext();
/// \endcode
///
/// If the context is not valid, sharing failed and the newly created widget/context be discarded.
//--------------------------------------------------------------------------------------------------
GLWidget_deprecated::GLWidget_deprecated(GLWidget_deprecated* shareWidget, QWidget* parent , Qt::WindowFlags f)
: QGLWidget(new CvfBoundQGLContext_deprecated(shareWidget->cvfOpenGLContext()->group(), shareWidget->format()), parent, shareWidget, f)
{
CVF_ASSERT(shareWidget);
cvf::ref<cvf::OpenGLContext> shareContext = shareWidget->cvfOpenGLContext();
CVF_ASSERT(shareContext.notNull());
cvf::ref<cvf::OpenGLContext> myContext = cvfOpenGLContext();
if (myContext.notNull())
{
cvf::OpenGLContextGroup* myOwnerContextGroup = myContext->group();
CVF_ASSERT(myOwnerContextGroup == shareContext->group());
// We need to check if we actually got a context that shares resources with shareWidget.
if (isSharing())
{
if (isValid())
{
makeCurrent();
myOwnerContextGroup->initializeContextGroup(myContext.p());
}
}
else
{
// If we didn't, we need to remove the newly created context from the group it has been added to since
// the construction process above has already optimistically added the new context to the existing group.
// In this case, the newly context is basically defunct so we just shut it down (which will also remove it from the group)
// Normally, we would need to ensure the context is current before calling shutdown, but in this case we are not the last
// context in the group so there should be no need for cleaning up resources.
myOwnerContextGroup->contextAboutToBeShutdown(myContext.p());
CVF_ASSERT(myContext->group() == NULL);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OpenGLContext* GLWidget_deprecated::cvfOpenGLContext() const
{
const QGLContext* qglContext = context();
const CvfBoundQGLContext_deprecated* contextBinding = dynamic_cast<const CvfBoundQGLContext_deprecated*>(qglContext);
CVF_ASSERT(contextBinding);
return contextBinding->cvfOpenGLContext();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GLWidget_deprecated::cvfShutdownOpenGLContext()
{
// It should be safe to call shutdown multiple times so this call should
// amount to a no-op if the user has already shut down the context
cvf::ref<cvf::OpenGLContext> myContext = cvfOpenGLContext();
if (myContext.notNull())
{
cvf::OpenGLContextGroup* myOwnerContextGroup = myContext->group();
// If shutdown has already been called, the context is no longer member of any group
if (myOwnerContextGroup)
{
makeCurrent();
myOwnerContextGroup->contextAboutToBeShutdown(myContext.p());
}
}
}
} // namespace cvfqt

View File

@@ -0,0 +1,66 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include <QGLWidget>
namespace cvf
{
class OpenGLContext;
class OpenGLContextGroup;
}
namespace cvfqt {
//==================================================================================================
//
// Derived QGLWidget
//
//==================================================================================================
class GLWidget_deprecated : public QGLWidget
{
public:
GLWidget_deprecated(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent, Qt::WindowFlags f = Qt::WindowFlags());
GLWidget_deprecated(GLWidget_deprecated* shareWidget, QWidget* parent , Qt::WindowFlags f = Qt::WindowFlags());
cvf::OpenGLContext* cvfOpenGLContext() const;
void cvfShutdownOpenGLContext();
};
}

View File

@@ -34,117 +34,301 @@
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfOpenGLContextGroup.h"
#include "cvfqtCvfBoundQGLContext.h"
#include "cvfqtOpenGLWidget.h"
#include "cvfTrace.h"
#include "cvfString.h"
#include "cvfOpenGLContext.h"
#include "cvfLogManager.h"
#include <QOpenGLContext>
#include <QPointer>
#include <QEvent>
#include <QPlatformSurfaceEvent>
namespace cvfqt {
//==================================================================================================
///
/// \class cvfqt::OpenGLWidget
/// \ingroup GuiQt
///
///
///
//
//
//
//==================================================================================================
class ForwardingOpenGLContext_OpenGLWidget : public cvf::OpenGLContext
{
public:
ForwardingOpenGLContext_OpenGLWidget(cvf::OpenGLContextGroup* contextGroup, QOpenGLWidget* ownerQtOpenGLWidget)
: cvf::OpenGLContext(contextGroup),
m_ownerQtOpenGLWidget(ownerQtOpenGLWidget)
{
CVF_ASSERT(contextGroup);
// In our current usage pattern the owner widget (and its contained Qt OpenGL context)
// must already be initialized/created
CVF_ASSERT(m_ownerQtOpenGLWidget);
CVF_ASSERT(m_ownerQtOpenGLWidget->isValid());
CVF_ASSERT(m_ownerQtOpenGLWidget->context());
CVF_ASSERT(m_ownerQtOpenGLWidget->context()->isValid());
}
virtual void makeCurrent()
{
if (m_ownerQtOpenGLWidget)
{
m_ownerQtOpenGLWidget->makeCurrent();
}
}
virtual bool isCurrent() const
{
QOpenGLContext* ownersContext = m_ownerQtOpenGLWidget ? m_ownerQtOpenGLWidget->context() : NULL;
if (ownersContext && QOpenGLContext::currentContext() == ownersContext)
{
return true;
}
return false;
}
virtual cvf::OglId defaultFramebufferObject() const
{
if (m_ownerQtOpenGLWidget)
{
return m_ownerQtOpenGLWidget->defaultFramebufferObject();
}
return 0;
}
QOpenGLWidget* ownerQtOpenGLWidget()
{
return m_ownerQtOpenGLWidget;
}
private:
QPointer<QOpenGLWidget> m_ownerQtOpenGLWidget;
};
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
OpenGLWidget::OpenGLWidget(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent, Qt::WindowFlags f)
: QGLWidget(new CvfBoundQGLContext(contextGroup, format), parent, NULL, f)
OpenGLWidget::OpenGLWidget(cvf::OpenGLContextGroup* contextGroup, QWidget* parent, Qt::WindowFlags f)
: QOpenGLWidget(parent, f),
m_instanceNumber(-1),
m_initializationState(UNINITIALIZED),
m_cvfOpenGlContextGroup(contextGroup),
m_logger(CVF_GET_LOGGER("cee.cvf.qt"))
{
// This constructor can only be used with an empty context group!
// We're not able to check this up front, but assert that the count is 1 by the time we get here
CVF_ASSERT(contextGroup->contextCount() == 1);
static int sl_nextInstanceNumber = 0;
m_instanceNumber = sl_nextInstanceNumber++;
if (isValid())
{
cvf::ref<cvf::OpenGLContext> myContext = cvfOpenGLContext();
if (myContext.notNull())
{
myContext->initializeContext();
}
}
CVF_LOG_DEBUG(m_logger, cvf::String("OpenGLWidget[%1]::OpenGLWidget()").arg(m_instanceNumber));
CVF_ASSERT(m_cvfOpenGlContextGroup.notNull());
}
//--------------------------------------------------------------------------------------------------
/// Constructor
///
/// Tries to create a widget that shares OpenGL resources with \a shareWidget
/// To check if creation was actually successful, you must call isValidContext() on the context
/// of the newly created widget. For example:
/// \code
/// myNewWidget->cvfOpenGLContext()->isValidContext();
/// \endcode
///
/// If the context is not valid, sharing failed and the newly created widget/context be discarded.
///
//--------------------------------------------------------------------------------------------------
OpenGLWidget::OpenGLWidget(OpenGLWidget* shareWidget, QWidget* parent , Qt::WindowFlags f)
: QGLWidget(new CvfBoundQGLContext(shareWidget->cvfOpenGLContext()->group(), shareWidget->format()), parent, shareWidget, f)
OpenGLWidget::~OpenGLWidget()
{
CVF_ASSERT(shareWidget);
cvf::ref<cvf::OpenGLContext> shareContext = shareWidget->cvfOpenGLContext();
CVF_ASSERT(shareContext.notNull());
CVF_LOG_DEBUG(m_logger, cvf::String("OpenGLWidget[%1]::~OpenGLWidget()").arg(m_instanceNumber));
cvf::ref<cvf::OpenGLContext> myContext = cvfOpenGLContext();
if (myContext.notNull())
if (m_initializationState == IS_INITIALIZED)
{
// We need to check if we actually got a context that shares resources with shareWidget.
if (isSharing())
// Make sure we disconnect from the aboutToBeDestroyed signal since after this destructor has been
// called, our object is dangling and the call to the slot will cause a crash
QOpenGLContext* myQtOpenGLContext = context();
if (myQtOpenGLContext)
{
if (isValid())
disconnect(myQtOpenGLContext, &QOpenGLContext::aboutToBeDestroyed, this, &OpenGLWidget::qtOpenGLContextAboutToBeDestroyed);
}
}
shutdownCvfOpenGLContext();
}
//--------------------------------------------------------------------------------------------------
/// This is where we do the custom initialization needed for the Qt binding to work
///
/// Note that if you re-implement this function in your subclass, you must make
/// sure to call the base class.
//--------------------------------------------------------------------------------------------------
void OpenGLWidget::initializeGL()
{
CVF_LOG_DEBUG(m_logger, cvf::String("OpenGLWidget[%1]::initializeGL()").arg(m_instanceNumber));
if (!isValid())
{
CVF_LOG_WARNING(m_logger, cvf::String("OpenGLWidget[%1]: Widget is not valid for initialization").arg(m_instanceNumber));
}
// According to Qt doc this function is called once before the first call to paintGL() or resizeGL().
// Further it is stated that this widget's QOpenGLContext is already current.
// We should be able to assume that we will only be called with a create, valid and current QOpenGLContext
//
// Note that in some scenarios, such as when a widget get reparented, initializeGL() ends up being called
// multiple times in the lifetime of the widget. In those cases, the widget's associated context is first destroyed
// and then a new one is created. This is then followed by a new call to initializeGL() where all OpenGL resources must get reinitialized.
QOpenGLContext* myQtOpenGLContext = context();
CVF_ASSERT(myQtOpenGLContext);
CVF_ASSERT(myQtOpenGLContext->isValid());
CVF_ASSERT(QOpenGLContext::currentContext() == myQtOpenGLContext);
if (m_initializationState != IS_INITIALIZED)
{
CVF_LOG_DEBUG(m_logger, cvf::String("OpenGLWidget[%1]: Starting internal initialization").arg(m_instanceNumber));
// This should either be the first call or the result of a destroy/recreate cycle
CVF_ASSERT(m_cvfForwardingOpenGlContext.isNull());
// Try and detect the situation where the user is trying to associate incompatible widgets/contexts in the same cvf OpenGLContextGroup
// The assert below will fail if two incompatible OpenGL contexts end up in the same context group
if (m_cvfOpenGlContextGroup->contextCount() > 0)
{
for (size_t i = 0; i < m_cvfOpenGlContextGroup->contextCount(); i++)
{
CVF_ASSERT(myContext->group() == shareContext->group());
myContext->initializeContext();
ForwardingOpenGLContext_OpenGLWidget* existingFwdContext = dynamic_cast<ForwardingOpenGLContext_OpenGLWidget*>(m_cvfOpenGlContextGroup->context(i));
QOpenGLWidget* existingWidget = existingFwdContext ? existingFwdContext->ownerQtOpenGLWidget() : NULL;
QOpenGLContext* existingQtContext = existingWidget ? existingWidget->context() : NULL;
if (existingQtContext)
{
// Assert that these two contexts are actually sharing OpenGL resources
CVF_ASSERT(QOpenGLContext::areSharing(existingQtContext, myQtOpenGLContext));
}
}
}
else
// Create the actual wrapper/forwarding OpenGL context that implements the cvf::OpenGLContext that we need
cvf::ref<ForwardingOpenGLContext_OpenGLWidget> myCvfContext = new ForwardingOpenGLContext_OpenGLWidget(m_cvfOpenGlContextGroup.p(), this);
// Possibly initialize the context group
if (!m_cvfOpenGlContextGroup->isContextGroupInitialized())
{
// If we didn't, we need to remove the newly created context from the group it has been added to since
// the construction process above has already optimistically added the new context to the existing group.
// In this case, the newly context is basically defunct so we just shut it down (which will also remove it from the group)
myContext->shutdownContext();
CVF_ASSERT(myContext->group() == NULL);
if (!m_cvfOpenGlContextGroup->initializeContextGroup(myCvfContext.p()))
{
CVF_LOG_ERROR(m_logger, cvf::String("OpenGLWidget[%1]: OpenGL context creation failed, could not initialize context group").arg(m_instanceNumber));
return;
}
}
// All is well, so store pointer to the cvf OpenGL context
m_cvfForwardingOpenGlContext = myCvfContext;
const InitializationState prevInitState = m_initializationState;
m_initializationState = IS_INITIALIZED;
// Connect to signal so we get notified when Qt's OpenGL context is about to be destroyed
connect(myQtOpenGLContext, &QOpenGLContext::aboutToBeDestroyed, this, &OpenGLWidget::qtOpenGLContextAboutToBeDestroyed);
if (prevInitState == UNINITIALIZED)
{
// Call overridable notification function to indicate that OpenGL has been initialized
// Don't do this if we're being re-initialized
onWidgetOpenGLReady();
}
// Trigger a repaint if we're being re-initialized
if (prevInitState == PENDING_REINITIALIZATION)
{
update();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OpenGLContext* OpenGLWidget::cvfOpenGLContext() const
void OpenGLWidget::resizeGL(int /*w*/, int /*h*/)
{
const QGLContext* qglContext = context();
const CvfBoundQGLContext* contextBinding = dynamic_cast<const CvfBoundQGLContext*>(qglContext);
CVF_ASSERT(contextBinding);
return contextBinding->cvfOpenGLContext();
// Empty, should normally be implemented in derived class
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OpenGLWidget::paintGL()
{
// No implementation here (nor in QOpenGLWidget::paintGL())
// Derived classes must re-implement this function in order to do painting.
//
// Typical code would go something like this:
// cvf::OpenGLContext* currentOglContext = cvfOpenGLContext();
// myRenderSequence->render(currentOglContext);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OpenGLWidget::cvfShutdownOpenGLContext()
cvf::OpenGLContext* OpenGLWidget::cvfOpenGLContext()
{
// It should be safe to call shutdown multiple times so this call should
// amount to a no-op if the user has already shut down the context
cvf::ref<cvf::OpenGLContext> myContext = cvfOpenGLContext();
if (myContext.notNull())
return m_cvfForwardingOpenGlContext.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int OpenGLWidget::instanceNumber() const
{
return m_instanceNumber;
}
//--------------------------------------------------------------------------------------------------
/// Notification function that will be called after internal CVF OpenGL initialization has
/// successfully completed. This includes both the creation of the CVF OpenGLContext and
/// successful initialization of the OpenGL context group
///
/// Can be re-implemented in derived classes to take any needed actions.
//--------------------------------------------------------------------------------------------------
void OpenGLWidget::onWidgetOpenGLReady()
{
// Base implementation does nothing
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OpenGLWidget::qtOpenGLContextAboutToBeDestroyed()
{
CVF_LOG_DEBUG(m_logger, cvf::String("OpenGLWidget[%1]::qtOpenGLContextAboutToBeDestroyed()").arg(m_instanceNumber));
if (m_cvfForwardingOpenGlContext.notNull())
{
myContext->shutdownContext();
CVF_LOG_DEBUG(m_logger, cvf::String("OpenGLWidget[%1]: Shutting down CVF OpenGL context since Qt context is about to be destroyed").arg(m_instanceNumber));
shutdownCvfOpenGLContext();
}
if (m_initializationState == IS_INITIALIZED)
{
m_initializationState = PENDING_REINITIALIZATION;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OpenGLWidget::shutdownCvfOpenGLContext()
{
if (m_cvfForwardingOpenGlContext.notNull())
{
makeCurrent();
m_cvfOpenGlContextGroup->contextAboutToBeShutdown(m_cvfForwardingOpenGlContext.p());
m_cvfForwardingOpenGlContext = NULL;
}
}
} // namespace cvfqt

View File

@@ -34,33 +34,63 @@
//
//##################################################################################################
#pragma once
#include <QtOpenGL/QGLWidget>
#include "cvfBase.h"
#include "cvfObject.h"
namespace cvf
{
#include <QOpenGLWidget>
namespace cvf {
class OpenGLContext;
class OpenGLContextGroup;
class Logger;
}
namespace cvfqt {
//==================================================================================================
//
// Derived QGLWidget
//
//
//==================================================================================================
class OpenGLWidget : public QGLWidget
class OpenGLWidget : public QOpenGLWidget
{
public:
OpenGLWidget(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent, Qt::WindowFlags f = 0);
OpenGLWidget(OpenGLWidget* shareWidget, QWidget* parent , Qt::WindowFlags f = 0);
OpenGLWidget(cvf::OpenGLContextGroup* contextGroup, QWidget* parent, Qt::WindowFlags f = Qt::WindowFlags());
~OpenGLWidget();
cvf::OpenGLContext* cvfOpenGLContext() const;
void cvfShutdownOpenGLContext();
cvf::OpenGLContext* cvfOpenGLContext();
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
int instanceNumber() const;
virtual void onWidgetOpenGLReady();
private:
void qtOpenGLContextAboutToBeDestroyed();
void shutdownCvfOpenGLContext();
private:
enum InitializationState
{
UNINITIALIZED,
PENDING_REINITIALIZATION,
IS_INITIALIZED
};
int m_instanceNumber;
InitializationState m_initializationState;
cvf::ref<cvf::OpenGLContextGroup> m_cvfOpenGlContextGroup;
cvf::ref<cvf::OpenGLContext> m_cvfForwardingOpenGlContext;
cvf::ref<cvf::Logger> m_logger;
};
}
}

View File

@@ -45,8 +45,15 @@
#pragma warning( disable : 4365 )
#endif
CVF_GCC_DIAGNOSTIC_PUSH
#if defined (CVF_GCC_VER) && (CVF_GCC_VER >= 70400)
CVF_GCC_DIAGNOSTIC_IGNORE("-Wimplicit-fallthrough=")
#endif
#include "cvfTinyXmlFused.hpp"
CVF_GCC_DIAGNOSTIC_POP
#ifdef _MSC_VER
#pragma warning( pop )
#endif

View File

@@ -45,8 +45,10 @@ cvfOpenGL.h
cvfOpenGLCapabilities.h
cvfOpenGLContext.h
cvfOpenGLContextGroup.h
cvfOpenGLInfo.h
cvfOpenGLResourceManager.h
cvfOpenGLTypes.h
cvfOpenGLUtils.h
cvfOverlayAxisCross.h
cvfOverlayScalarMapperLegend.h
cvfOverlayColorLegend.h
@@ -122,7 +124,9 @@ cvfOglRc.cpp
cvfOpenGLCapabilities.cpp
cvfOpenGLContext.cpp
cvfOpenGLContextGroup.cpp
cvfOpenGLInfo.cpp
cvfOpenGLResourceManager.cpp
cvfOpenGLUtils.cpp
cvfOpenGL.cpp
cvfOverlayAxisCross.cpp
cvfOverlayScalarMapperLegend.cpp

View File

@@ -485,8 +485,13 @@ void FramebufferObject::useDefaultWindowFramebuffer(OpenGLContext* oglContext)
{
CVF_CALLSITE_OPENGL(oglContext);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);
const OglId defaultFBO = oglContext->defaultFramebufferObject();
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
if (defaultFBO == 0)
{
glDrawBuffer(GL_BACK);
}
CVF_CHECK_OGL(oglContext);
}

View File

@@ -61,6 +61,7 @@
#include "cvfOpenGLContextGroup.h"
#include "cvfOpenGLResourceManager.h"
#include "cvfOpenGLTypes.h"
#include "cvfOpenGLUtils.h"
#include "cvfOverlayAxisCross.h"
#include "cvfOverlayColorLegend.h"
#include "cvfOverlayImage.h"

View File

@@ -59,8 +59,7 @@ namespace cvf {
/// The context will be added unconditionally to the \a contextGroup group
//--------------------------------------------------------------------------------------------------
OpenGLContext::OpenGLContext(OpenGLContextGroup* contextGroup)
: m_contextGroup(contextGroup),
m_isValid(false)
: m_contextGroup(contextGroup)
{
CVF_ASSERT(m_contextGroup);
m_contextGroup->addContext(this);
@@ -74,8 +73,6 @@ OpenGLContext::~OpenGLContext()
{
//Trace::show("OpenGLContext destructor");
m_isValid = false;
// Context group is holding references to contexts, so by the time we get to this
// destructor the link to the context group must already be broken
CVF_ASSERT(m_contextGroup == NULL);
@@ -87,8 +84,7 @@ OpenGLContext::~OpenGLContext()
//--------------------------------------------------------------------------------------------------
bool OpenGLContext::isContextValid() const
{
// Also check on context group, since it may have been set to NULL after valid flag was set
if (m_contextGroup && m_isValid)
if (m_contextGroup && m_contextGroup->isContextGroupInitialized())
{
return true;
}
@@ -102,59 +98,9 @@ bool OpenGLContext::isContextValid() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool OpenGLContext::initializeContext()
OglId OpenGLContext::defaultFramebufferObject() const
{
makeCurrent();
if (!m_contextGroup)
{
return false;
}
if (!m_contextGroup->isContextGroupInitialized())
{
if (!m_contextGroup->initializeContextGroup(this))
{
return false;
}
}
m_isValid = true;
return true;
}
//--------------------------------------------------------------------------------------------------
/// Prepare the context for deletion
///
/// Prepares the context for deletion by removing the context from its context group. If this is the
/// last context in the context group, this function will also try and delete the context group's
/// OpenGL resources.
///
/// \warning After calling this function the context is no longer usable and should be deleted.
/// \warning May try and make the context current in order to free resources if this context
/// is the last context in the context group.
//--------------------------------------------------------------------------------------------------
void OpenGLContext::shutdownContext()
{
if (m_contextGroup)
{
CVF_ASSERT(m_contextGroup->containsContext(this));
// If our ref count is down to 1, there is probably something strange going on.
// Since one reference to us is being held by the context group, this means that the
// caller ISN'T holding a reference which may give him a nast surprise when this function returns!
CVF_ASSERT(refCount() > 1);
// This call will remove the context from the group AND clean up resources in the
// group if we are the last context in the group
m_contextGroup->contextAboutToBeShutdown(this);
}
CVF_ASSERT(m_contextGroup == NULL);
m_isValid = false;
return 0;
}

View File

@@ -39,6 +39,7 @@
#include "cvfObject.h"
#include "cvfOpenGLContextGroup.h"
#include "cvfOpenGLTypes.h"
namespace cvf {
@@ -58,11 +59,10 @@ public:
virtual ~OpenGLContext();
bool isContextValid() const;
virtual bool initializeContext();
virtual void shutdownContext();
virtual void makeCurrent() = 0;
virtual bool isCurrent() const = 0;
virtual OglId defaultFramebufferObject() const;
OpenGLContextGroup* group();
const OpenGLContextGroup* group() const;
@@ -71,7 +71,6 @@ public:
private:
OpenGLContextGroup* m_contextGroup; // Raw pointer (to avoid circular reference) to the context group that this context belongs to.
bool m_isValid; // Will be set to true after successful initialization
friend class OpenGLContextGroup;
};

View File

@@ -42,6 +42,7 @@
#include "cvfOpenGLResourceManager.h"
#include "cvfOpenGLCapabilities.h"
#include "cvfLogManager.h"
#include "cvfTrace.h"
#include <memory.h>
@@ -75,6 +76,8 @@ OpenGLContextGroup::OpenGLContextGroup()
m_glewContextStruct(NULL),
m_wglewContextStruct(NULL)
{
//Trace::show("OpenGLContextGroup constructor");
m_resourceManager = new OpenGLResourceManager;
m_logger = CVF_GET_LOGGER("cee.cvf.OpenGL");
m_capabilities = new OpenGLCapabilities;
@@ -105,7 +108,10 @@ OpenGLContextGroup::~OpenGLContextGroup()
m_contexts.clear();
uninitializeContextGroup();
if (m_isInitialized)
{
uninitializeContextGroup();
}
}
@@ -129,6 +135,8 @@ bool OpenGLContextGroup::isContextGroupInitialized() const
//--------------------------------------------------------------------------------------------------
bool OpenGLContextGroup::initializeContextGroup(OpenGLContext* currentContext)
{
//Trace::show("OpenGLContextGroup::initializeContextGroup()");
CVF_ASSERT(currentContext);
CVF_ASSERT(currentContext->isCurrent());
CVF_ASSERT(containsContext(currentContext));
@@ -139,20 +147,27 @@ bool OpenGLContextGroup::initializeContextGroup(OpenGLContext* currentContext)
if (!initializeGLEW(currentContext))
{
CVF_LOG_ERROR(m_logger.p(), "Failed to intitialize GLEW in context group");
return false;
}
configureCapablititesFromGLEW(currentContext);
configureCapabilitiesFromGLEW(currentContext);
#ifdef WIN32
if (!initializeWGLEW(currentContext))
{
CVF_LOG_ERROR(m_logger.p(), "Failed to intitialize WGLEW in context group");
return false;
}
#endif
#endif
CVF_LOG_DEBUG(m_logger.p(), "OpenGL initialized in context group");
CVF_LOG_DEBUG(m_logger.p(), " version: " + m_info.version());
CVF_LOG_DEBUG(m_logger.p(), " vendor: " + m_info.vendor());
CVF_LOG_DEBUG(m_logger.p(), " renderer: " + m_info.renderer());
m_isInitialized = true;
}
@@ -165,10 +180,12 @@ bool OpenGLContextGroup::initializeContextGroup(OpenGLContext* currentContext)
//--------------------------------------------------------------------------------------------------
void OpenGLContextGroup::uninitializeContextGroup()
{
//Trace::show("OpenGLContextGroup::uninitializeContextGroup()");
CVF_ASSERT(m_contexts.empty());
CVF_ASSERT(!m_resourceManager->hasAnyOpenGLResources());
// Just replace capablities with a new object
// Just replace capabilities with a new object
m_capabilities = new OpenGLCapabilities;
#ifdef CVF_USE_GLEW
@@ -186,28 +203,30 @@ void OpenGLContextGroup::uninitializeContextGroup()
//--------------------------------------------------------------------------------------------------
/// Called by OpenGLContext objects when they are being shut down
/// Prepare a context for deletion
///
/// This function will remove the context \a contextToShutdown from the context group.
/// If \a contextToShutdown is the last context in the group, all resources in the group's
/// This function will remove the context \a currentContextToShutdown from the context group.
/// If \a currentContextToShutdown is the last context in the group, all resources in the group's
/// resource manager will be deleted and the context group will be reset to uninitialized.
///
/// \warning This function may try and make the context passed in \a contextToShutdown curreent!
/// \warning The passed context must be the current OpenGL context!
/// \warning After calling this function the context is no longer usable and should be deleted.
//--------------------------------------------------------------------------------------------------
void OpenGLContextGroup::contextAboutToBeShutdown(OpenGLContext* contextToShutdown)
void OpenGLContextGroup::contextAboutToBeShutdown(OpenGLContext* currentContextToShutdown)
{
CVF_ASSERT(contextToShutdown);
CVF_ASSERT(containsContext(contextToShutdown));
//Trace::show("OpenGLContextGroup::contextAboutToBeShutdown()");
CVF_ASSERT(currentContextToShutdown);
CVF_ASSERT(containsContext(currentContextToShutdown));
// If this is the last context in the group, we'll delete all the OpenGL resources in the s resource manager before we go
bool shouldUninitializeGroup = false;
if (contextCount() == 1)
{
CVF_ASSERT(m_resourceManager.notNull());
if (m_resourceManager->hasAnyOpenGLResources() && contextToShutdown->isContextValid())
if (m_resourceManager->hasAnyOpenGLResources() && currentContextToShutdown->isContextValid())
{
contextToShutdown->makeCurrent();
m_resourceManager->deleteAllOpenGLResources(contextToShutdown);
m_resourceManager->deleteAllOpenGLResources(currentContextToShutdown);
}
shouldUninitializeGroup = true;
@@ -217,12 +236,12 @@ void OpenGLContextGroup::contextAboutToBeShutdown(OpenGLContext* contextToShutdo
// Since one reference to the context is being held by this context group, this means that the
// caller isn't holding a reference to the context. In this case the context object will evaporate
// during the call below, and the caller will most likely get a nasty surprise
CVF_ASSERT(contextToShutdown->refCount() > 1);
CVF_ASSERT(currentContextToShutdown->refCount() > 1);
// Make sure we set the back pointer before removing it from our collection
// since the removal from the list may actually trigger destruction of the context (see comment above)
contextToShutdown->m_contextGroup = NULL;
m_contexts.erase(contextToShutdown);
currentContextToShutdown->m_contextGroup = NULL;
m_contexts.erase(currentContextToShutdown);
if (shouldUninitializeGroup)
{
@@ -239,11 +258,23 @@ void OpenGLContextGroup::contextAboutToBeShutdown(OpenGLContext* contextToShutdo
//--------------------------------------------------------------------------------------------------
bool OpenGLContextGroup::initializeGLEW(OpenGLContext* currentContext)
{
//Trace::show("OpenGLContextGroup::initializeGLEW()");
CVF_ASSERT(currentContext);
CVF_ASSERT(m_glewContextStruct == NULL);
#ifdef CVF_USE_GLEW
// Usage of GLEW requires that we have a standard OpenGL implementation available (not any Qt wrapper etc)
// Supposedly the version string should always contain at least one '.'
// Try and test this by querying the OpenGL version number and assume that there is no OpenGL available if it fails
const String sVersion(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
if (sVersion.find(".") == String::npos)
{
CVF_LOG_ERROR(m_logger, "Error initializing OpenGL functions, probe for OpenGL version failed. No valid OpenGL context is current");
return false;
}
// Since we're sometimes (when using Core OpenGL) seeing some OGL errors from GLEW, check before and after call to help find them
CVF_CHECK_OGL(currentContext);
@@ -253,6 +284,7 @@ bool OpenGLContextGroup::initializeGLEW(OpenGLContext* currentContext)
GLenum err = glewContextInit(theContextStruct);
if (err != GLEW_OK)
{
CVF_LOG_ERROR(m_logger, String("Error initializing GLEW, glewContextInit() returned %1").arg(err));
delete theContextStruct;
return false;
}
@@ -261,6 +293,10 @@ bool OpenGLContextGroup::initializeGLEW(OpenGLContext* currentContext)
CVF_CHECK_OGL(currentContext);
String sVendor(reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
String sRenderer(reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
m_info.setOpenGLStrings(sVersion, sVendor, sRenderer);
#else
CVF_FAIL_MSG("Not implemented");
@@ -315,7 +351,7 @@ bool OpenGLContextGroup::initializeWGLEW(OpenGLContext* currentContext)
///
/// \warning The passed context must be current and GLEW must already be initialized!
//--------------------------------------------------------------------------------------------------
void OpenGLContextGroup::configureCapablititesFromGLEW(OpenGLContext* currentContext)
void OpenGLContextGroup::configureCapabilitiesFromGLEW(OpenGLContext* currentContext)
{
#ifdef CVF_USE_GLEW
CVF_CALLSITE_GLEW(currentContext);
@@ -362,6 +398,15 @@ size_t OpenGLContextGroup::contextCount() const
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OpenGLContext* OpenGLContextGroup::context(size_t index)
{
return m_contexts.at(index);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -432,6 +477,15 @@ OpenGLCapabilities* OpenGLContextGroup::capabilities()
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
OpenGLInfo OpenGLContextGroup::info() const
{
return m_info;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -40,6 +40,8 @@
#include "cvfObject.h"
#include "cvfCollection.h"
#include "cvfLogger.h"
#include "cvfOpenGLCapabilities.h"
#include "cvfOpenGLInfo.h"
struct GLEWContextStruct;
struct WGLEWContextStruct;
@@ -48,7 +50,6 @@ namespace cvf {
class OpenGLContext;
class OpenGLResourceManager;
class OpenGLCapabilities;
//==================================================================================================
@@ -63,24 +64,27 @@ public:
virtual ~OpenGLContextGroup();
bool isContextGroupInitialized() const;
bool initializeContextGroup(OpenGLContext* currentContext);
void contextAboutToBeShutdown(OpenGLContext* currentContextToShutdown);
size_t contextCount() const;
OpenGLContext* context(size_t index);
bool containsContext(const OpenGLContext* context) const;
OpenGLResourceManager* resourceManager();
Logger* logger();
OpenGLCapabilities* capabilities();
OpenGLInfo info() const;
GLEWContextStruct* glewContextStruct();
WGLEWContextStruct* wglewContextStruct();
private:
bool initializeContextGroup(OpenGLContext* currentContext);
void uninitializeContextGroup();
void contextAboutToBeShutdown(OpenGLContext* contextToShutdown);
bool initializeGLEW(OpenGLContext* currentContext);
bool initializeWGLEW(OpenGLContext* currentContext);
void configureCapablititesFromGLEW(OpenGLContext* currentContext);
void configureCapabilitiesFromGLEW(OpenGLContext* currentContext);
void addContext(OpenGLContext* contextToAdd);
private:
@@ -89,6 +93,7 @@ private:
ref<OpenGLResourceManager> m_resourceManager; // Resource manager that is shared between all contexts in this group
ref<Logger> m_logger;
ref<OpenGLCapabilities> m_capabilities; // Capabilities of the contexts in this group context
OpenGLInfo m_info;
GLEWContextStruct* m_glewContextStruct; // Pointer to the GLEW context struct
WGLEWContextStruct* m_wglewContextStruct; // Pointer to the GLEW context struct

View File

@@ -36,58 +36,66 @@
#include "cvfBase.h"
#include "cvfqtCvfBoundQGLContext.h"
#include "cvfqtOpenGLContext.h"
namespace cvfqt {
#include "cvfOpenGLInfo.h"
namespace cvf {
//==================================================================================================
///
/// \class cvfqt::CvfBoundQGLContext
/// \ingroup GuiQt
/// \class cvf::OpenGLInfo
/// \ingroup Render
///
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CvfBoundQGLContext::CvfBoundQGLContext(cvf::OpenGLContextGroup* contextGroup, const QGLFormat & format)
: QGLContext(format)
OpenGLInfo::OpenGLInfo()
{
m_cvfGLContext = new OpenGLContext(contextGroup, this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CvfBoundQGLContext::~CvfBoundQGLContext()
OpenGLInfo::~OpenGLInfo()
{
if (m_cvfGLContext.notNull())
{
// TODO
// Need to resolve the case where the Qt QGLcontext (that we're deriving from) is deleted
// and we are still holding a reference to one or more OpenGLContext objects
// By the time we get here we expect that we're holding the only reference
CVF_ASSERT(m_cvfGLContext->refCount() == 1);
m_cvfGLContext = NULL;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OpenGLContext* CvfBoundQGLContext::cvfOpenGLContext() const
String OpenGLInfo::version() const
{
return const_cast<cvf::OpenGLContext*>(m_cvfGLContext.p());
return m_version;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String OpenGLInfo::vendor() const
{
return m_vendor;
}
} // namespace cvfqt
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String OpenGLInfo::renderer() const
{
return m_renderer;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OpenGLInfo::setOpenGLStrings(String version, String vendor, String renderer)
{
m_version = version;
m_vendor = vendor;
m_renderer = renderer;
}
} // namespace cvf

View File

@@ -37,28 +37,32 @@
#pragma once
#include "cvfOpenGLContext.h"
#include "cvfString.h"
#include <QtOpenGL/QGLContext>
namespace cvfqt {
namespace cvf {
//==================================================================================================
//
// Utility class used to piggyback OpenGLContext onto Qt's QGLContext
//
//
//==================================================================================================
class CvfBoundQGLContext : public QGLContext
class OpenGLInfo
{
public:
CvfBoundQGLContext(cvf::OpenGLContextGroup* contextGroup, const QGLFormat & format);
virtual ~CvfBoundQGLContext();
OpenGLInfo();
~OpenGLInfo();
cvf::OpenGLContext* cvfOpenGLContext() const;
String version() const;
String vendor() const;
String renderer() const;
void setOpenGLStrings(String version, String vendor, String renderer);
private:
cvf::ref<cvf::OpenGLContext> m_cvfGLContext;
String m_version;
String m_vendor;
String m_renderer;
};
}

View File

@@ -36,105 +36,30 @@
#include "cvfBase.h"
#include "cvfOpenGLUtils.h"
#include "cvfOpenGL.h"
#include "cvfqtOpenGLContext.h"
#include "cvfqtCvfBoundQGLContext.h"
#include "cvfOpenGLContextGroup.h"
#include "cvfOpenGLContext.h"
#include "cvfOpenGLCapabilities.h"
namespace cvfqt {
namespace cvf {
//==================================================================================================
///
/// \class cvfqt::OpenGLContext
/// \ingroup GuiQt
/// \class cvf::OpenGLUtils
/// \ingroup Render
///
/// Derived OpenGLContext that adapts a Qt QGLContext
/// Static class providing OpenGL helpers
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Store the current OpenGL context settings by using OpenGL's built in push methods.
///
/// Note: This call MUST be matched with a corresponding popOpenGLState() call.
//--------------------------------------------------------------------------------------------------
OpenGLContext::OpenGLContext(cvf::OpenGLContextGroup* contextGroup, QGLContext* backingQGLContext)
: cvf::OpenGLContext(contextGroup),
m_isCoreOpenGLProfile(false),
m_majorVersion(0),
m_minorVersion(0)
{
m_qtGLContext = backingQGLContext;
CVF_ASSERT(m_qtGLContext);
QGLFormat glFormat = m_qtGLContext->format();
m_majorVersion = glFormat.majorVersion();
m_minorVersion = glFormat.minorVersion();
m_isCoreOpenGLProfile = (glFormat.profile() == QGLFormat::CoreProfile) ? true : false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
OpenGLContext::~OpenGLContext()
{
m_qtGLContext = NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool OpenGLContext::initializeContext()
{
if (!cvf::OpenGLContext::initializeContext())
{
return false;
}
// Possibly override setting for fixed function support
if (m_isCoreOpenGLProfile)
{
group()->capabilities()->setSupportsFixedFunction(false);
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OpenGLContext::makeCurrent()
{
CVF_ASSERT(m_qtGLContext);
m_qtGLContext->makeCurrent();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool OpenGLContext::isCurrent() const
{
if (m_qtGLContext)
{
if (QGLContext::currentContext() == m_qtGLContext)
{
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
/// Make an effort to save current OpenGL state. Must be matched by a call to restoreOpenGLState()
//--------------------------------------------------------------------------------------------------
void OpenGLContext::saveOpenGLState(cvf::OpenGLContext* oglContext)
void OpenGLUtils::pushOpenGLState(OpenGLContext* oglContext)
{
CVF_CALLSITE_OPENGL(oglContext);
const cvf::OpenGLCapabilities* oglCaps = oglContext->capabilities();
@@ -178,9 +103,11 @@ void OpenGLContext::saveOpenGLState(cvf::OpenGLContext* oglContext)
//--------------------------------------------------------------------------------------------------
/// Restore OpenGL state that has been saved by saveOpenGLState()
/// Set back the stored OpenGL context settings by using OpenGL's built in pop methods.
///
/// Note: This call MUST be matched with a corresponding pushOpenGLState() call.
//--------------------------------------------------------------------------------------------------
void OpenGLContext::restoreOpenGLState(cvf::OpenGLContext* oglContext)
void OpenGLUtils::popOpenGLState(OpenGLContext* oglContext)
{
CVF_CALLSITE_OPENGL(oglContext);
const cvf::OpenGLCapabilities* oglCaps = oglContext->capabilities();
@@ -212,7 +139,7 @@ void OpenGLContext::restoreOpenGLState(cvf::OpenGLContext* oglContext)
glPopAttrib();
CVF_CHECK_OGL(oglContext);
// Currently not pushing vertex attribs, so comment out the pop
//glPopClientAttrib();
@@ -221,6 +148,5 @@ void OpenGLContext::restoreOpenGLState(cvf::OpenGLContext* oglContext)
}
} // namespace cvfqt
} // namespace cvf

View File

@@ -0,0 +1,58 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
namespace cvf {
class OpenGLContext;
//==================================================================================================
//
//
//
//==================================================================================================
class OpenGLUtils
{
public:
static void pushOpenGLState(OpenGLContext* oglContext);
static void popOpenGLState(OpenGLContext* oglContext);
};
}

View File

@@ -172,6 +172,8 @@ void RenderingScissor::unApplyOpenGL(OpenGLContext* oglContext)
m_scissorBoxToRestore[1],
m_scissorBoxToRestore[2],
m_scissorBoxToRestore[3]);
CVF_CHECK_OGL(oglContext);
}
}

View File

@@ -181,6 +181,16 @@ bool Shader::compile(OpenGLContext* oglContext)
String errStr = String("Error compiling shader: '%1'\n").arg(m_shaderName);
errStr += "GLSL details:\n";
errStr += shaderInfoLog(oglContext);
// {
// errStr += "Shader prog:\n";
// std::vector<String> progArr = m_source.split("\n");
// for (size_t i = 0; i < progArr.size(); ++i)
// {
// errStr += String("%1: %2\n").arg(static_cast<int>(i + 1), 3).arg(progArr[i]);
// }
// }
CVF_LOG_RENDER_ERROR(oglContext, errStr);
return false;
}

View File

@@ -1,8 +1,14 @@
project(LibUtilities)
# Use our strict compile flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STRICT_CXX_FLAGS}")
# Use our strict compile flags only on windows since C++17 gives too
# much trouble in the JPEG code when using GCC
if (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STRICT_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_BASE_CXX_FLAGS}")
endif()
if (CMAKE_COMPILER_IS_GNUCXX)
# Don't allow the compiler to assume strict aliasing when doing optimizations (the culprit is JPEG code)

View File

@@ -46,6 +46,9 @@
CVF_GCC_DIAGNOSTIC_IGNORE("-Wconversion")
CVF_GCC_DIAGNOSTIC_IGNORE("-Wunused-parameter")
CVF_GCC_DIAGNOSTIC_IGNORE("-Wshift-negative-value")
CVF_GCC_DIAGNOSTIC_IGNORE("-Wimplicit-fallthrough=")
CVF_GCC_DIAGNOSTIC_IGNORE("-Wmisleading-indentation")
#ifdef WIN32
#include <windows.h>
@@ -56,6 +59,12 @@ CVF_GCC_DIAGNOSTIC_IGNORE("-Wunused-parameter")
#include <stdlib.h>
#endif
// !!!
// Big time hack since C++17 does not allow register storage class specifier
#define register
// Doxygen conditional section to hide contents of the cvfu_jpgFreeImage namespace
/// \cond CVF_NEVER_INCLUDE
@@ -25126,7 +25135,7 @@ SetMemoryIO(FreeImageIO *io) {
//
// Design and implementation by
// - Ryan Rubley <ryan@lostreality.org>
// - Herv<72> Drolon (drolon@infonie.fr)
// - Herv<72> Drolon (drolon@infonie.fr)
//
// This file is part of FreeImage 3
//

View File

@@ -1,7 +1,7 @@
project(QtMinimal)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_BASE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STANDARD_CXX_FLAGS}")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long")
@@ -10,6 +10,17 @@ endif()
find_package(OpenGL)
if (CEE_USE_QT6)
find_package(Qt6 COMPONENTS REQUIRED OpenGLWidgets)
set(QT_LIBRARIES Qt6::OpenGLWidgets )
elseif (CEE_USE_QT5)
find_package(Qt5 REQUIRED COMPONENTS Widgets)
set(QT_LIBRARIES Qt5::Widgets)
else()
message(FATAL_ERROR "No supported Qt version selected for build")
endif()
include_directories(${LibCore_SOURCE_DIR})
include_directories(${LibGeometry_SOURCE_DIR})
include_directories(${LibRender_SOURCE_DIR})
@@ -17,34 +28,27 @@ include_directories(${LibViewing_SOURCE_DIR})
include_directories(${LibGuiQt_SOURCE_DIR})
set(CEE_LIBS LibGuiQt LibViewing LibRender LibGeometry LibCore)
set(CEE_SOURCE_FILES
set(CEE_CODE_FILES
QMMain.cpp
QMMainWindow.cpp
QMMainWindow.h
QMWidget.cpp
QMWidget.h
)
# Headers that need MOCing
set(MOC_HEADER_FILES
QMMainWindow.h
QMWidget.h
)
# Qt
if (CEE_USE_QT5)
find_package(Qt5 COMPONENTS REQUIRED Core Gui Widgets OpenGL)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets Qt5::OpenGL)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES} )
else()
message(FATAL_ERROR "No supported Qt version selected for build")
if (CEE_USE_QT6)
qt_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES})
elseif (CEE_USE_QT5)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES})
endif()
set(SYSTEM_LIBRARIES)
if (CMAKE_COMPILER_IS_GNUCXX)
set(SYSTEM_LIBRARIES -lrt -lpthread)
endif(CMAKE_COMPILER_IS_GNUCXX)
add_executable(${PROJECT_NAME} ${CEE_SOURCE_FILES} ${MOC_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CEE_LIBS} ${OPENGL_LIBRARIES} ${QT_LIBRARIES} ${SYSTEM_LIBRARIES})
add_executable(${PROJECT_NAME} ${CEE_CODE_FILES} ${MOC_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CEE_LIBS} ${OPENGL_LIBRARIES} ${QT_LIBRARIES})

View File

@@ -34,12 +34,10 @@
//
//##################################################################################################
#include "cvfLibCore.h"
#include "QMMainWindow.h"
#include <QtGlobal>
#include <QApplication>
#include <locale.h>
@@ -50,6 +48,9 @@
//--------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
cvf::LogManager* logManager = cvf::LogManager::instance();
logManager->logger("cee.cvf.OpenGL")->setLevel(cvf::Logger::LL_DEBUG);
QApplication app(argc, argv);
// On Linux, Qt will use the system locale, force number formatting settings back to "C" locale

View File

@@ -34,7 +34,6 @@
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
@@ -49,8 +48,6 @@
#include <QMenu>
#include <QMenuBar>
using cvf::ref;
//--------------------------------------------------------------------------------------------------
@@ -63,41 +60,57 @@ QMMainWindow::QMMainWindow()
setCentralWidget(mainFrame);
m_contextGroup = new cvf::OpenGLContextGroup;
m_vizWidget = new QMWidget(m_contextGroup.p(), mainFrame);
// Pass pointer to ourselves to get notified when the vizWidget is ready for use and we can load our default scene
m_vizWidget = new QMWidget(m_contextGroup.p(), mainFrame, this);
m_vizWidget->setFocus();
frameLayout->addWidget(m_vizWidget);
m_createDefaultSceneAction = new QAction("Default Scene", this);
m_clearSceneAction = new QAction("Clear Scene", this);
connect(m_createDefaultSceneAction, SIGNAL(triggered()), SLOT(slotCreateDefaultScene()));
connect(m_clearSceneAction, SIGNAL(triggered()), SLOT(slotClearScene()));
QMenu* menu = menuBar()->addMenu("&Scenes");
menu->addAction(m_createDefaultSceneAction);
menu->addAction("Default Scene", this, SLOT(slotCreateDefaultScene()));
menu->addSeparator();
menu->addAction(m_clearSceneAction);
slotCreateDefaultScene();
menu->addAction("Clear Scene", this, SLOT(slotClearScene()));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMMainWindow::handleVizWidgetIsOpenGLReady()
{
slotCreateDefaultScene();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMMainWindow::slotCreateDefaultScene()
{
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
const bool useShaders = true;
CVF_ASSERT(m_contextGroup->isContextGroupInitialized());
cvf::ShaderProgramGenerator spGen("SimpleHeadlight", cvf::ShaderSourceProvider::instance());
spGen.configureStandardHeadlightColor();
cvf::ref<cvf::ShaderProgram> shaderProg = spGen.generate();
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createSphere(2, 10, 10, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE));
cvf::ref<cvf::Effect> eff = new cvf::Effect;
if (useShaders)
{
eff->setShaderProgram(shaderProg.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::GREEN)));
}
else
{
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE));
}
ref<cvf::Part> part = new cvf::Part;
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName("MySphere");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
@@ -109,10 +122,18 @@ void QMMainWindow::slotCreateDefaultScene()
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createBox(cvf::Vec3f(5, 0, 0), 2, 3, 4, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::RED));
cvf::ref<cvf::Effect> eff = new cvf::Effect;
if (useShaders)
{
eff->setShaderProgram(shaderProg.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::YELLOW)));
}
else
{
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::RED));
}
ref<cvf::Part> part = new cvf::Part;
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName("MyBox");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
@@ -122,7 +143,7 @@ void QMMainWindow::slotCreateDefaultScene()
model->updateBoundingBoxesRecursive();
ref<cvf::Scene> scene = new cvf::Scene;
cvf::ref<cvf::Scene> scene = new cvf::Scene;
scene->addModel(model.p());
CVF_ASSERT(m_vizWidget);
@@ -140,15 +161,3 @@ void QMMainWindow::slotClearScene()
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMMainWindow::closeEvent(QCloseEvent* /*event*/)
{
CVF_ASSERT(m_contextGroup.notNull());
CVF_ASSERT(m_vizWidget);
// Shut down the CeeViz OpenGL context contained in the widget
// Deletes all OpenGL resources and removes context from context group
m_vizWidget->cvfShutdownOpenGLContext();
}

View File

@@ -40,8 +40,8 @@
#include "cvfObject.h"
#include "cvfOpenGLContextGroup.h"
#include <QtGlobal>
#include <QMainWindow>
#include <QPointer>
class QMWidget;
@@ -58,17 +58,14 @@ class QMMainWindow : public QMainWindow
public:
QMMainWindow();
void handleVizWidgetIsOpenGLReady();
private slots:
void slotCreateDefaultScene();
void slotClearScene();
private:
void closeEvent(QCloseEvent* event);
private:
cvf::ref<cvf::OpenGLContextGroup> m_contextGroup;
QMWidget* m_vizWidget;
QAction* m_createDefaultSceneAction;
QAction* m_clearSceneAction;
QPointer<QMWidget> m_vizWidget;
};

View File

@@ -34,31 +34,44 @@
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QMWidget.h"
#include "QMMainWindow.h"
#include "cvfqtOpenGLContext.h"
#include "cvfRendering.h"
#include "cvfRenderSequence.h"
#include "cvfScene.h"
#include "cvfCamera.h"
#include "cvfManipulatorTrackball.h"
#include "cvfOverlayAxisCross.h"
#include "cvfFixedAtlasFont.h"
#include "cvfRayIntersectSpec.h"
#include "cvfHitItemCollection.h"
#include "cvfHitItem.h"
#include "cvfTrace.h"
#include "cvfPart.h"
#include <QMouseEvent>
using cvf::ref;
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMWidget::QMWidget(cvf::OpenGLContextGroup* contextGroup, QWidget* parent)
: cvfqt::OpenGLWidget(contextGroup, QGLFormat(), parent)
QMWidget::QMWidget(cvf::OpenGLContextGroup* contextGroup, QWidget* parent, QMMainWindow* mainWindow)
: cvfqt::OpenGLWidget(contextGroup, parent),
m_mainWindow(mainWindow)
{
CVF_ASSERT(contextGroup);
m_camera = new cvf::Camera;
ref<cvf::Rendering> rendering = new cvf::Rendering;
cvf::ref<cvf::Rendering> rendering = new cvf::Rendering;
rendering->setCamera(m_camera.p());
rendering->addOverlayItem(new cvf::OverlayAxisCross(m_camera.p(), new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD)));
@@ -69,7 +82,6 @@ QMWidget::QMWidget(cvf::OpenGLContextGroup* contextGroup, QWidget* parent)
m_trackball->setCamera(m_camera.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -77,17 +89,15 @@ QMWidget::~QMWidget()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget::setScene(cvf::Scene* scene)
{
ref<cvf::Rendering> rendering = m_renderSequence->firstRendering();
cvf::ref<cvf::Rendering> rendering = m_renderSequence->firstRendering();
CVF_ASSERT(rendering.notNull());
rendering->setScene(scene);
if (scene)
{
cvf::BoundingBox bb = scene->boundingBox();
@@ -101,48 +111,32 @@ void QMWidget::setScene(cvf::Scene* scene)
update();
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void QMWidget::resizeGL(int width, int height)
void QMWidget::resizeGL(int w, int h)
{
if (m_camera.notNull())
{
m_camera->viewport()->set(0, 0, width, height);
m_camera->viewport()->set(0, 0, w, h);
m_camera->setProjectionAsPerspective(m_camera->fieldOfViewYDeg(), m_camera->nearPlane(), m_camera->farPlane());
}
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void QMWidget::paintEvent(QPaintEvent* /*event*/)
void QMWidget::paintGL()
{
QPainter painter(this);
makeCurrent();
cvf::OpenGLContext* currentOglContext = cvfOpenGLContext();
CVF_ASSERT(currentOglContext);
CVF_CHECK_OGL(currentOglContext);
painter.beginNativePainting();
cvfqt::OpenGLContext::saveOpenGLState(currentOglContext);
if (m_renderSequence.notNull())
{
m_renderSequence->render(currentOglContext);
}
cvfqt::OpenGLContext::restoreOpenGLState(currentOglContext);
painter.endNativePainting();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -151,19 +145,24 @@ void QMWidget::mouseMoveEvent(QMouseEvent* event)
if (m_renderSequence.isNull()) return;
Qt::MouseButtons mouseBn = event->buttons();
int posX = event->x();
int posY = height() - event->y();
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
const int posX = event->position().toPoint().x();
const int posY = height() - event->position().toPoint().y();
#else
const int posX = event->x();
const int posY = height() - event->y();
#endif
cvf::ManipulatorTrackball::NavigationType navType = cvf::ManipulatorTrackball::NONE;
if (mouseBn == Qt::LeftButton)
{
navType = cvf::ManipulatorTrackball::PAN;
}
else if (mouseBn == Qt::RightButton)
else if (mouseBn == Qt::RightButton)
{
navType = cvf::ManipulatorTrackball::ROTATE;
}
else if (mouseBn == (Qt::LeftButton | Qt::RightButton) || mouseBn == Qt::MidButton)
else if (mouseBn == (Qt::LeftButton | Qt::RightButton) || mouseBn == Qt::MiddleButton)
{
navType = cvf::ManipulatorTrackball::WALK;
}
@@ -180,7 +179,6 @@ void QMWidget::mouseMoveEvent(QMouseEvent* event)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -188,10 +186,19 @@ void QMWidget::mousePressEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
if (event->buttons() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier)
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
const int posX = event->position().toPoint().x();
const int posY = height() - event->position().toPoint().y();
#else
const int posX = event->x();
const int posY = height() - event->y();
#endif
if (event->buttons() == Qt::LeftButton &&
event->modifiers() == Qt::ControlModifier)
{
cvf::Rendering* r = m_renderSequence->firstRendering();
ref<cvf::RayIntersectSpec> ris = r->rayIntersectSpecFromWindowCoordinates(event->x(), height() - event->y());
cvf::ref<cvf::RayIntersectSpec> ris = r->rayIntersectSpecFromWindowCoordinates(posX, posY);
cvf::HitItemCollection hic;
if (r->rayIntersect(*ris, &hic))
@@ -207,7 +214,6 @@ void QMWidget::mousePressEvent(QMouseEvent* event)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -215,3 +221,15 @@ void QMWidget::mouseReleaseEvent(QMouseEvent* /*event*/)
{
m_trackball->endNavigation();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget::onWidgetOpenGLReady()
{
if (m_mainWindow)
{
m_mainWindow->handleVizWidgetIsOpenGLReady();
}
}

View File

@@ -34,7 +34,6 @@
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
@@ -46,6 +45,9 @@
#include "cvfqtOpenGLWidget.h"
#include <QPointer>
class QMMainWindow;
//==================================================================================================
@@ -55,26 +57,27 @@
//==================================================================================================
class QMWidget : public cvfqt::OpenGLWidget
{
Q_OBJECT
public:
QMWidget(cvf::OpenGLContextGroup* contextGroup, QWidget* parent);
QMWidget(cvf::OpenGLContextGroup* contextGroup, QWidget* parent, QMMainWindow* mainWindow);
~QMWidget();
void setScene(cvf::Scene* scene);
protected:
void resizeGL(int width, int height);
void paintEvent(QPaintEvent *event);
virtual void resizeGL(int w, int h);
virtual void paintGL();
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
virtual void mouseMoveEvent(QMouseEvent* event);
virtual void mousePressEvent(QMouseEvent* event);
virtual void mouseReleaseEvent(QMouseEvent* event);
private:
virtual void onWidgetOpenGLReady();
private:
QPointer<QMMainWindow> m_mainWindow;
cvf::ref<cvf::RenderSequence> m_renderSequence;
cvf::ref<cvf::Camera> m_camera;
cvf::ref<cvf::ManipulatorTrackball> m_trackball;
};

View File

@@ -0,0 +1,47 @@
project(QtMinimal_GLWidget)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STANDARD_CXX_FLAGS}")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long")
endif()
find_package(OpenGL)
if (CEE_USE_QT5)
find_package(Qt5 REQUIRED COMPONENTS Widgets OpenGL)
set(QT_LIBRARIES Qt5::Widgets Qt5::OpenGL)
else()
message(FATAL_ERROR "No supported Qt version selected for build")
endif()
include_directories(${LibCore_SOURCE_DIR})
include_directories(${LibGeometry_SOURCE_DIR})
include_directories(${LibRender_SOURCE_DIR})
include_directories(${LibViewing_SOURCE_DIR})
include_directories(${LibGuiQt_SOURCE_DIR})
set(CEE_LIBS LibGuiQt LibViewing LibRender LibGeometry LibCore)
set(CEE_SOURCE_FILES
QMMain_GLW.cpp
QMMainWindow_GLW.cpp
QMWidget_GLW.cpp
)
# Headers that need MOCing
set(MOC_HEADER_FILES
QMMainWindow_GLW.h
QMWidget_GLW.h
)
if (CEE_USE_QT5)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES})
endif()
add_executable(${PROJECT_NAME} ${CEE_SOURCE_FILES} ${MOC_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CEE_LIBS} ${OPENGL_LIBRARIES} ${QT_LIBRARIES})

View File

@@ -0,0 +1,153 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QMMainWindow_GLW.h"
#include "QMWidget_GLW.h"
#include <QFrame>
#include <QHBoxLayout>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
using cvf::ref;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMMainWindow_GLW::QMMainWindow_GLW()
{
QFrame* mainFrame = new QFrame;
QHBoxLayout* frameLayout = new QHBoxLayout(mainFrame);
setCentralWidget(mainFrame);
m_contextGroup = new cvf::OpenGLContextGroup;
m_vizWidget = new QMWidget_GLW(m_contextGroup.p(), mainFrame);
m_vizWidget->setFocus();
frameLayout->addWidget(m_vizWidget);
m_createDefaultSceneAction = new QAction("Default Scene", this);
m_clearSceneAction = new QAction("Clear Scene", this);
connect(m_createDefaultSceneAction, SIGNAL(triggered()), SLOT(slotCreateDefaultScene()));
connect(m_clearSceneAction, SIGNAL(triggered()), SLOT(slotClearScene()));
QMenu* menu = menuBar()->addMenu("&Scenes");
menu->addAction(m_createDefaultSceneAction);
menu->addSeparator();
menu->addAction(m_clearSceneAction);
slotCreateDefaultScene();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMMainWindow_GLW::slotCreateDefaultScene()
{
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createSphere(2, 10, 10, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE));
ref<cvf::Part> part = new cvf::Part;
part->setName("MySphere");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
model->addPart(part.p());
}
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createBox(cvf::Vec3f(5, 0, 0), 2, 3, 4, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::RED));
ref<cvf::Part> part = new cvf::Part;
part->setName("MyBox");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
model->addPart(part.p());
}
model->updateBoundingBoxesRecursive();
ref<cvf::Scene> scene = new cvf::Scene;
scene->addModel(model.p());
CVF_ASSERT(m_vizWidget);
m_vizWidget->setScene(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMMainWindow_GLW::slotClearScene()
{
CVF_ASSERT(m_vizWidget);
m_vizWidget->setScene(NULL);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMMainWindow_GLW::closeEvent(QCloseEvent* /*event*/)
{
CVF_ASSERT(m_contextGroup.notNull());
CVF_ASSERT(m_vizWidget);
// Shut down the CeeViz OpenGL context contained in the widget
// Deletes all OpenGL resources and removes context from context group
m_vizWidget->cvfShutdownOpenGLContext();
}

View File

@@ -0,0 +1,73 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfOpenGLContextGroup.h"
#include <QMainWindow>
class QMWidget_GLW;
//==================================================================================================
//
//
//
//==================================================================================================
class QMMainWindow_GLW : public QMainWindow
{
Q_OBJECT
public:
QMMainWindow_GLW();
private slots:
void slotCreateDefaultScene();
void slotClearScene();
private:
void closeEvent(QCloseEvent* event);
private:
cvf::ref<cvf::OpenGLContextGroup> m_contextGroup;
QMWidget_GLW* m_vizWidget;
QAction* m_createDefaultSceneAction;
QAction* m_clearSceneAction;
};

View File

@@ -0,0 +1,63 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "QMMainWindow_GLW.h"
#include "QApplication"
#include <locale.h>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// On Linux, Qt will use the system locale, force number formatting settings back to "C" locale
setlocale(LC_NUMERIC,"C");
QMMainWindow_GLW window;
QString platform = cvf::System::is64Bit() ? "(64bit)" : "(32bit)";
window.setWindowTitle("Qt Minimal GLWidget " + platform);
window.resize(1000, 800);;
window.show();
return app.exec();
}

View File

@@ -0,0 +1,215 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QMWidget_GLW.h"
#include <QMouseEvent>
using cvf::ref;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMWidget_GLW::QMWidget_GLW(cvf::OpenGLContextGroup* contextGroup, QWidget* parent)
: cvfqt::GLWidget(contextGroup, QGLFormat(), parent)
{
m_camera = new cvf::Camera;
ref<cvf::Rendering> rendering = new cvf::Rendering;
rendering->setCamera(m_camera.p());
rendering->addOverlayItem(new cvf::OverlayAxisCross(m_camera.p(), new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD)));
m_renderSequence = new cvf::RenderSequence;
m_renderSequence->addRendering(rendering.p());
m_trackball = new cvf::ManipulatorTrackball;
m_trackball->setCamera(m_camera.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMWidget_GLW::~QMWidget_GLW()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_GLW::setScene(cvf::Scene* scene)
{
ref<cvf::Rendering> rendering = m_renderSequence->firstRendering();
CVF_ASSERT(rendering.notNull());
rendering->setScene(scene);
if (scene)
{
cvf::BoundingBox bb = scene->boundingBox();
if (bb.isValid())
{
m_camera->fitView(bb, -cvf::Vec3d::Z_AXIS, cvf::Vec3d::Y_AXIS);
m_trackball->setRotationPoint(bb.center());
}
}
update();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_GLW::resizeGL(int width, int height)
{
if (m_camera.notNull())
{
m_camera->viewport()->set(0, 0, width, height);
m_camera->setProjectionAsPerspective(m_camera->fieldOfViewYDeg(), m_camera->nearPlane(), m_camera->farPlane());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_GLW::paintEvent(QPaintEvent* /*event*/)
{
QPainter painter(this);
makeCurrent();
cvf::OpenGLContext* currentOglContext = cvfOpenGLContext();
CVF_ASSERT(currentOglContext);
CVF_CHECK_OGL(currentOglContext);
painter.beginNativePainting();
cvf::OpenGLUtils::pushOpenGLState(currentOglContext);
if (m_renderSequence.notNull())
{
m_renderSequence->render(currentOglContext);
}
cvf::OpenGLUtils::popOpenGLState(currentOglContext);
painter.endNativePainting();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_GLW::mouseMoveEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
Qt::MouseButtons mouseBn = event->buttons();
int posX = event->x();
int posY = height() - event->y();
cvf::ManipulatorTrackball::NavigationType navType = cvf::ManipulatorTrackball::NONE;
if (mouseBn == Qt::LeftButton)
{
navType = cvf::ManipulatorTrackball::PAN;
}
else if (mouseBn == Qt::RightButton)
{
navType = cvf::ManipulatorTrackball::ROTATE;
}
else if (mouseBn == (Qt::LeftButton | Qt::RightButton) || mouseBn == Qt::MiddleButton)
{
navType = cvf::ManipulatorTrackball::WALK;
}
if (navType != m_trackball->activeNavigation())
{
m_trackball->startNavigation(navType, posX, posY);
}
bool needRedraw = m_trackball->updateNavigation(posX, posY);
if (needRedraw)
{
update();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_GLW::mousePressEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
if (event->buttons() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier)
{
cvf::Rendering* r = m_renderSequence->firstRendering();
ref<cvf::RayIntersectSpec> ris = r->rayIntersectSpecFromWindowCoordinates(event->x(), height() - event->y());
cvf::HitItemCollection hic;
if (r->rayIntersect(*ris, &hic))
{
cvf::HitItem* item = hic.firstItem();
CVF_ASSERT(item && item->part());
cvf::Vec3d isect = item->intersectionPoint();
m_trackball->setRotationPoint(isect);
cvf::Trace::show("hitting part: '%s' coords: %.3f %.3f %.3f", item->part()->name().toAscii().ptr(), isect.x(), isect.y(), isect.z());
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_GLW::mouseReleaseEvent(QMouseEvent* /*event*/)
{
m_trackball->endNavigation();
}

View File

@@ -0,0 +1,79 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfRenderSequence.h"
#include "cvfManipulatorTrackball.h"
#include "cvfScene.h"
#include "cvfOpenGLContextGroup.h"
#include "cvfqtGLWidget.h"
//==================================================================================================
//
//
//
//==================================================================================================
class QMWidget_GLW : public cvfqt::GLWidget
{
Q_OBJECT
public:
QMWidget_GLW(cvf::OpenGLContextGroup* contextGroup, QWidget* parent);
~QMWidget_GLW();
void setScene(cvf::Scene* scene);
protected:
void resizeGL(int width, int height);
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
private:
cvf::ref<cvf::RenderSequence> m_renderSequence;
cvf::ref<cvf::Camera> m_camera;
cvf::ref<cvf::ManipulatorTrackball> m_trackball;
};

View File

@@ -0,0 +1,50 @@
project(QtMinimal_deprecated)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_BASE_CXX_FLAGS}")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long")
endif()
find_package(OpenGL)
include_directories(${LibCore_SOURCE_DIR})
include_directories(${LibGeometry_SOURCE_DIR})
include_directories(${LibRender_SOURCE_DIR})
include_directories(${LibViewing_SOURCE_DIR})
include_directories(${LibGuiQt_SOURCE_DIR})
set(CEE_LIBS LibGuiQt LibViewing LibRender LibGeometry LibCore)
set(CEE_SOURCE_FILES
QMMain_deprecated.cpp
QMMainWindow_deprecated.cpp
QMWidget_deprecated.cpp
)
# Headers that need MOCing
set(MOC_HEADER_FILES
QMMainWindow_deprecated.h
QMWidget_deprecated.h
)
# Qt
if (CEE_USE_QT5)
find_package(Qt5 COMPONENTS REQUIRED Core Gui Widgets OpenGL)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets Qt5::OpenGL)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES} )
else()
message(FATAL_ERROR "No supported Qt version selected for build")
endif()
set(SYSTEM_LIBRARIES)
if (CMAKE_COMPILER_IS_GNUCXX)
set(SYSTEM_LIBRARIES -lrt -lpthread)
endif(CMAKE_COMPILER_IS_GNUCXX)
add_executable(${PROJECT_NAME} ${CEE_SOURCE_FILES} ${MOC_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CEE_LIBS} ${OPENGL_LIBRARIES} ${QT_LIBRARIES} ${SYSTEM_LIBRARIES})

View File

@@ -0,0 +1,154 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QMMainWindow_deprecated.h"
#include "QMWidget_deprecated.h"
#include <QFrame>
#include <QHBoxLayout>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
using cvf::ref;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMMainWindow_deprecated::QMMainWindow_deprecated()
{
QFrame* mainFrame = new QFrame;
QHBoxLayout* frameLayout = new QHBoxLayout(mainFrame);
setCentralWidget(mainFrame);
m_contextGroup = new cvf::OpenGLContextGroup;
m_vizWidget = new QMWidget_deprecated(m_contextGroup.p(), mainFrame);
m_vizWidget->setFocus();
frameLayout->addWidget(m_vizWidget);
m_createDefaultSceneAction = new QAction("Default Scene", this);
m_clearSceneAction = new QAction("Clear Scene", this);
connect(m_createDefaultSceneAction, SIGNAL(triggered()), SLOT(slotCreateDefaultScene()));
connect(m_clearSceneAction, SIGNAL(triggered()), SLOT(slotClearScene()));
QMenu* menu = menuBar()->addMenu("&Scenes");
menu->addAction(m_createDefaultSceneAction);
menu->addSeparator();
menu->addAction(m_clearSceneAction);
slotCreateDefaultScene();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMMainWindow_deprecated::slotCreateDefaultScene()
{
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createSphere(2, 10, 10, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE));
ref<cvf::Part> part = new cvf::Part;
part->setName("MySphere");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
model->addPart(part.p());
}
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createBox(cvf::Vec3f(5, 0, 0), 2, 3, 4, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::RED));
ref<cvf::Part> part = new cvf::Part;
part->setName("MyBox");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
model->addPart(part.p());
}
model->updateBoundingBoxesRecursive();
ref<cvf::Scene> scene = new cvf::Scene;
scene->addModel(model.p());
CVF_ASSERT(m_vizWidget);
m_vizWidget->setScene(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMMainWindow_deprecated::slotClearScene()
{
CVF_ASSERT(m_vizWidget);
m_vizWidget->setScene(NULL);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMMainWindow_deprecated::closeEvent(QCloseEvent* /*event*/)
{
CVF_ASSERT(m_contextGroup.notNull());
CVF_ASSERT(m_vizWidget);
// Shut down the CeeViz OpenGL context contained in the widget
// Deletes all OpenGL resources and removes context from context group
m_vizWidget->cvfShutdownOpenGLContext();
}

View File

@@ -0,0 +1,74 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfOpenGLContextGroup.h"
#include <QtGlobal>
#include <QMainWindow>
class QMWidget_deprecated;
//==================================================================================================
//
//
//
//==================================================================================================
class QMMainWindow_deprecated : public QMainWindow
{
Q_OBJECT
public:
QMMainWindow_deprecated();
private slots:
void slotCreateDefaultScene();
void slotClearScene();
private:
void closeEvent(QCloseEvent* event);
private:
cvf::ref<cvf::OpenGLContextGroup> m_contextGroup;
QMWidget_deprecated* m_vizWidget;
QAction* m_createDefaultSceneAction;
QAction* m_clearSceneAction;
};

View File

@@ -0,0 +1,65 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "QMMainWindow_deprecated.h"
#include <QtGlobal>
#include <QApplication>
#include <locale.h>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// On Linux, Qt will use the system locale, force number formatting settings back to "C" locale
setlocale(LC_NUMERIC,"C");
QMMainWindow_deprecated window;
QString platform = cvf::System::is64Bit() ? "(64bit)" : "(32bit)";
window.setWindowTitle("Qt Minimal deprecated" + platform);
window.resize(1000, 800);;
window.show();
return app.exec();
}

View File

@@ -0,0 +1,215 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QMWidget_deprecated.h"
#include <QMouseEvent>
using cvf::ref;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMWidget_deprecated::QMWidget_deprecated(cvf::OpenGLContextGroup* contextGroup, QWidget* parent)
: cvfqt::GLWidget_deprecated(contextGroup, QGLFormat(), parent)
{
m_camera = new cvf::Camera;
ref<cvf::Rendering> rendering = new cvf::Rendering;
rendering->setCamera(m_camera.p());
rendering->addOverlayItem(new cvf::OverlayAxisCross(m_camera.p(), new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD)));
m_renderSequence = new cvf::RenderSequence;
m_renderSequence->addRendering(rendering.p());
m_trackball = new cvf::ManipulatorTrackball;
m_trackball->setCamera(m_camera.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMWidget_deprecated::~QMWidget_deprecated()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_deprecated::setScene(cvf::Scene* scene)
{
ref<cvf::Rendering> rendering = m_renderSequence->firstRendering();
CVF_ASSERT(rendering.notNull());
rendering->setScene(scene);
if (scene)
{
cvf::BoundingBox bb = scene->boundingBox();
if (bb.isValid())
{
m_camera->fitView(bb, -cvf::Vec3d::Z_AXIS, cvf::Vec3d::Y_AXIS);
m_trackball->setRotationPoint(bb.center());
}
}
update();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_deprecated::resizeGL(int width, int height)
{
if (m_camera.notNull())
{
m_camera->viewport()->set(0, 0, width, height);
m_camera->setProjectionAsPerspective(m_camera->fieldOfViewYDeg(), m_camera->nearPlane(), m_camera->farPlane());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_deprecated::paintEvent(QPaintEvent* /*event*/)
{
QPainter painter(this);
makeCurrent();
cvf::OpenGLContext* currentOglContext = cvfOpenGLContext();
CVF_ASSERT(currentOglContext);
CVF_CHECK_OGL(currentOglContext);
painter.beginNativePainting();
cvf::OpenGLUtils::pushOpenGLState(currentOglContext);
if (m_renderSequence.notNull())
{
m_renderSequence->render(currentOglContext);
}
cvf::OpenGLUtils::popOpenGLState(currentOglContext);
painter.endNativePainting();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_deprecated::mouseMoveEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
Qt::MouseButtons mouseBn = event->buttons();
int posX = event->x();
int posY = height() - event->y();
cvf::ManipulatorTrackball::NavigationType navType = cvf::ManipulatorTrackball::NONE;
if (mouseBn == Qt::LeftButton)
{
navType = cvf::ManipulatorTrackball::PAN;
}
else if (mouseBn == Qt::RightButton)
{
navType = cvf::ManipulatorTrackball::ROTATE;
}
else if (mouseBn == (Qt::LeftButton | Qt::RightButton) || mouseBn == Qt::MiddleButton)
{
navType = cvf::ManipulatorTrackball::WALK;
}
if (navType != m_trackball->activeNavigation())
{
m_trackball->startNavigation(navType, posX, posY);
}
bool needRedraw = m_trackball->updateNavigation(posX, posY);
if (needRedraw)
{
update();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_deprecated::mousePressEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
if (event->buttons() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier)
{
cvf::Rendering* r = m_renderSequence->firstRendering();
ref<cvf::RayIntersectSpec> ris = r->rayIntersectSpecFromWindowCoordinates(event->x(), height() - event->y());
cvf::HitItemCollection hic;
if (r->rayIntersect(*ris, &hic))
{
cvf::HitItem* item = hic.firstItem();
CVF_ASSERT(item && item->part());
cvf::Vec3d isect = item->intersectionPoint();
m_trackball->setRotationPoint(isect);
cvf::Trace::show("hitting part: '%s' coords: %.3f %.3f %.3f", item->part()->name().toAscii().ptr(), isect.x(), isect.y(), isect.z());
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMWidget_deprecated::mouseReleaseEvent(QMouseEvent* /*event*/)
{
m_trackball->endNavigation();
}

View File

@@ -0,0 +1,80 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfRenderSequence.h"
#include "cvfManipulatorTrackball.h"
#include "cvfScene.h"
#include "cvfOpenGLContextGroup.h"
#include "cvfqtGLWidget_deprecated.h"
//==================================================================================================
//
//
//
//==================================================================================================
class QMWidget_deprecated : public cvfqt::GLWidget_deprecated
{
Q_OBJECT
public:
QMWidget_deprecated(cvf::OpenGLContextGroup* contextGroup, QWidget* parent);
~QMWidget_deprecated();
void setScene(cvf::Scene* scene);
protected:
void resizeGL(int width, int height);
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
private:
cvf::ref<cvf::RenderSequence> m_renderSequence;
cvf::ref<cvf::Camera> m_camera;
cvf::ref<cvf::ManipulatorTrackball> m_trackball;
};

View File

@@ -1,7 +1,7 @@
project(QtMultiView)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_BASE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STANDARD_CXX_FLAGS}")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long")
@@ -10,21 +10,35 @@ endif()
find_package(OpenGL)
if (CEE_USE_QT6)
find_package(Qt6 COMPONENTS REQUIRED OpenGLWidgets)
set(QT_LIBRARIES Qt6::OpenGLWidgets )
elseif (CEE_USE_QT5)
find_package(Qt5 REQUIRED COMPONENTS Widgets)
set(QT_LIBRARIES Qt5::Widgets)
else()
message(FATAL_ERROR "No supported Qt version selected for build")
endif()
include_directories(${LibCore_SOURCE_DIR})
include_directories(${LibGeometry_SOURCE_DIR})
include_directories(${LibRender_SOURCE_DIR})
include_directories(${LibViewing_SOURCE_DIR})
include_directories(${LibGuiQt_SOURCE_DIR})
include_directories(${LibUtilities_SOURCE_DIR})
include_directories(${LibGuiQt_SOURCE_DIR})
set(CEE_LIBS LibUtilities LibGuiQt LibViewing LibRender LibGeometry LibIo LibCore)
set(EXTERNAL_LIBS)
set(CEE_LIBS LibGuiQt LibUtilities LibViewing LibRender LibGeometry LibIo LibCore)
set(CEE_SOURCE_FILES
set(CEE_CODE_FILES
QMVFactory.cpp
QMVFactory.h
QMVMain.cpp
QMVMainWindow.cpp
QMVMainWindow.h
QMVWidget.cpp
QMVWidget.h
)
# Headers that need MOCing
@@ -33,19 +47,12 @@ QMVMainWindow.h
QMVWidget.h
)
# Qt
if (CEE_USE_QT5)
find_package(Qt5 COMPONENTS REQUIRED Core Gui Widgets OpenGL)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets Qt5::OpenGL)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES} )
else()
message(FATAL_ERROR "No supported Qt version selected for build")
if (CEE_USE_QT6)
qt_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES})
elseif (CEE_USE_QT5)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES})
endif()
set(SYSTEM_LIBRARIES)
if (CMAKE_COMPILER_IS_GNUCXX)
set(SYSTEM_LIBRARIES -lrt -lpthread)
endif(CMAKE_COMPILER_IS_GNUCXX)
add_executable(${PROJECT_NAME} ${CEE_CODE_FILES} ${MOC_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CEE_LIBS} ${OPENGL_LIBRARIES} ${QT_LIBRARIES})
add_executable(${PROJECT_NAME} ${CEE_SOURCE_FILES} ${MOC_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CEE_LIBS} ${OPENGL_LIBRARIES} ${QT_LIBRARIES} ${SYSTEM_LIBRARIES})

View File

@@ -34,7 +34,6 @@
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
@@ -46,7 +45,6 @@
//==================================================================================================
//
//
@@ -56,8 +54,9 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVModelFactory::QMVModelFactory(bool useShaders)
: m_useShaders(useShaders)
QMVModelFactory::QMVModelFactory(bool useShaders, const cvf::OpenGLCapabilities& capabilities)
: m_useShaders(useShaders),
m_capabilities(capabilities)
{
}
@@ -65,24 +64,27 @@ QMVModelFactory::QMVModelFactory(bool useShaders)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Model> QMVModelFactory::createSphereAndBox()
cvf::ref<cvf::Model> QMVModelFactory::createSphereAndBox()
{
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createSphere(2, 10, 10, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE));
cvf::ref<cvf::Effect> eff = new cvf::Effect;
if (m_useShaders)
{
ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
cvf::ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
eff->setShaderProgram(prog.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::GREEN)));
}
else
{
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE));
}
ref<cvf::Part> part = new cvf::Part;
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName("MySphere");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
@@ -94,16 +96,19 @@ ref<cvf::Model> QMVModelFactory::createSphereAndBox()
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createBox(cvf::Vec3f(5, 0, 0), 2, 3, 4, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::RED));
cvf::ref<cvf::Effect> eff = new cvf::Effect;
if (m_useShaders)
{
ref<cvf::ShaderProgram> prog = createProgramUnlit();
cvf::ref<cvf::ShaderProgram> prog = createProgramUnlit();
eff->setShaderProgram(prog.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::GREEN)));
}
else
{
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::RED));
}
ref<cvf::Part> part = new cvf::Part;
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName("MyBox");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
@@ -120,9 +125,10 @@ ref<cvf::Model> QMVModelFactory::createSphereAndBox()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Model> QMVModelFactory::createSpheres()
cvf::ref<cvf::Model> QMVModelFactory::createSpheres()
{
cvfu::PartCompoundGenerator gen;
gen.setUseShaders(m_useShaders);
gen.setPartDistribution(cvf::Vec3i(5, 5, 5));
gen.setNumEffects(8);
gen.useRandomEffectAssignment(false);
@@ -132,9 +138,9 @@ ref<cvf::Model> QMVModelFactory::createSpheres()
cvf::Collection<cvf::Part> parts;
gen.generateSpheres(20, 20, &parts);
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
cvf::ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
size_t i;
for (i = 0; i < parts.size(); i++)
@@ -158,9 +164,10 @@ ref<cvf::Model> QMVModelFactory::createSpheres()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Model> QMVModelFactory::createBoxes()
cvf::ref<cvf::Model> QMVModelFactory::createBoxes()
{
cvfu::PartCompoundGenerator gen;
gen.setUseShaders(m_useShaders);
gen.setPartDistribution(cvf::Vec3i(5, 5, 5));
gen.setNumEffects(8);
gen.useRandomEffectAssignment(false);
@@ -170,9 +177,9 @@ ref<cvf::Model> QMVModelFactory::createBoxes()
cvf::Collection<cvf::Part> parts;
gen.generateBoxes(&parts);
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
cvf::ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
size_t i;
for (i = 0; i < parts.size(); i++)
@@ -196,9 +203,10 @@ ref<cvf::Model> QMVModelFactory::createBoxes()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Model> QMVModelFactory::createTriangles()
cvf::ref<cvf::Model> QMVModelFactory::createTriangles()
{
cvfu::PartCompoundGenerator gen;
gen.setUseShaders(m_useShaders);
gen.setPartDistribution(cvf::Vec3i(5, 5, 5));
gen.setNumEffects(8);
gen.useRandomEffectAssignment(false);
@@ -208,9 +216,9 @@ ref<cvf::Model> QMVModelFactory::createTriangles()
cvf::Collection<cvf::Part> parts;
gen.generateTriangles(&parts);
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
cvf::ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
size_t i;
for (i = 0; i < parts.size(); i++)
@@ -234,11 +242,11 @@ ref<cvf::Model> QMVModelFactory::createTriangles()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::ShaderProgram> QMVModelFactory::createProgramStandardHeadlightColor()
cvf::ref<cvf::ShaderProgram> QMVModelFactory::createProgramStandardHeadlightColor()
{
cvf::ShaderProgramGenerator gen("StandardHeadlightColor", cvf::ShaderSourceProvider::instance());
gen.configureStandardHeadlightColor();
ref<cvf::ShaderProgram> prog = gen.generate();
cvf::ref<cvf::ShaderProgram> prog = gen.generate();
return prog;
}
@@ -246,13 +254,13 @@ ref<cvf::ShaderProgram> QMVModelFactory::createProgramStandardHeadlightColor()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::ShaderProgram> QMVModelFactory::createProgramUnlit()
cvf::ref<cvf::ShaderProgram> QMVModelFactory::createProgramUnlit()
{
cvf::ShaderProgramGenerator gen("Unlit", cvf::ShaderSourceProvider::instance());
gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard);
gen.addFragmentCode(cvf::ShaderSourceRepository::src_Color);
gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Unlit);
ref<cvf::ShaderProgram> prog = gen.generate();
cvf::ref<cvf::ShaderProgram> prog = gen.generate();
return prog;
}
@@ -275,9 +283,9 @@ QMVSceneFactory::QMVSceneFactory(QMVModelFactory* modelFactory)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Scene> QMVSceneFactory::createNumberedScene(int sceneNumber)
cvf::ref<cvf::Scene> QMVSceneFactory::createNumberedScene(int sceneNumber)
{
ref<cvf::Model> model;
cvf::ref<cvf::Model> model;
switch (sceneNumber)
{
case 0: model = m_modelFactory->createSphereAndBox(); break;
@@ -293,9 +301,9 @@ ref<cvf::Scene> QMVSceneFactory::createNumberedScene(int sceneNumber)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Scene> QMVSceneFactory::createFromModel(cvf::Model* model)
cvf::ref<cvf::Scene> QMVSceneFactory::createFromModel(cvf::Model* model)
{
ref<cvf::Scene> scene = new cvf::Scene;
cvf::ref<cvf::Scene> scene = new cvf::Scene;
if (model)
{
@@ -316,9 +324,9 @@ ref<cvf::Scene> QMVSceneFactory::createFromModel(cvf::Model* model)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::RenderSequence> QMVRenderSequenceFactory::createFromScene(cvf::Scene* scene)
cvf::ref<cvf::RenderSequence> QMVRenderSequenceFactory::createFromScene(cvf::Scene* scene)
{
ref<cvf::Rendering> rendering = new cvf::Rendering;
cvf::ref<cvf::Rendering> rendering = new cvf::Rendering;
rendering->renderEngine()->enableItemCountUpdate(true);
rendering->setScene(scene);
@@ -334,7 +342,7 @@ ref<cvf::RenderSequence> QMVRenderSequenceFactory::createFromScene(cvf::Scene* s
}
}
ref<cvf::RenderSequence> renderSeq = new cvf::RenderSequence;
cvf::ref<cvf::RenderSequence> renderSeq = new cvf::RenderSequence;
renderSeq->addRendering(rendering.p());
return renderSeq;

View File

@@ -34,10 +34,8 @@
//
//##################################################################################################
#pragma once
using cvf::ref;
//==================================================================================================
@@ -48,19 +46,20 @@ using cvf::ref;
class QMVModelFactory
{
public:
QMVModelFactory(bool useShaders);
QMVModelFactory(bool useShaders, const cvf::OpenGLCapabilities& capabilities);
ref<cvf::Model> createSphereAndBox();
ref<cvf::Model> createSpheres();
ref<cvf::Model> createBoxes();
ref<cvf::Model> createTriangles();
cvf::ref<cvf::Model> createSphereAndBox();
cvf::ref<cvf::Model> createSpheres();
cvf::ref<cvf::Model> createBoxes();
cvf::ref<cvf::Model> createTriangles();
private:
ref<cvf::ShaderProgram> createProgramStandardHeadlightColor();
ref<cvf::ShaderProgram> createProgramUnlit();
cvf::ref<cvf::ShaderProgram> createProgramStandardHeadlightColor();
cvf::ref<cvf::ShaderProgram> createProgramUnlit();
private:
bool m_useShaders;
cvf::OpenGLCapabilities m_capabilities;
};
@@ -75,8 +74,8 @@ class QMVSceneFactory
public:
QMVSceneFactory(QMVModelFactory* modelFactory);
ref<cvf::Scene> createNumberedScene(int sceneNumber);
ref<cvf::Scene> createFromModel(cvf::Model* model);
cvf::ref<cvf::Scene> createNumberedScene(int sceneNumber);
cvf::ref<cvf::Scene> createFromModel(cvf::Model* model);
private:
QMVModelFactory* m_modelFactory;
@@ -92,6 +91,6 @@ private:
class QMVRenderSequenceFactory
{
public:
ref<cvf::RenderSequence> createFromScene(cvf::Scene* model);
cvf::ref<cvf::RenderSequence> createFromScene(cvf::Scene* model);
};

View File

@@ -34,15 +34,14 @@
//
//##################################################################################################
#include "cvfLibCore.h"
#include "QMVMainWindow.h"
#include <QApplication>
#include "QtOpenGL/qgl.h"
#include <locale.h>
#include <clocale>
//--------------------------------------------------------------------------------------------------
@@ -50,19 +49,30 @@
//--------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
// It seems that if we are using paintEvent() instead of paintGL() to
// draw we might have to set OpenGL as the preferred paint engine
//QGL::setPreferredPaintEngine(QPaintEngine::OpenGL);
// Enables resource sharing between QOpenGLWidget instances that belong to different top-level windows
// Must be enabled if we want to create multiple OpenGL widgets in the same context group and they're not sitting as direct children of the same widget.
// Enable here so we can experiment with creating widgets as floating dialogs
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
// Can be used as a work-around if OpenGL scene appears as black in combination with remote desktop for Win7 clients
// See: https://bugreports.qt.io/browse/QTBUG-47975
//QSurfaceFormat surface;
//surface.setAlphaBufferSize(8);
//QSurfaceFormat::setDefaultFormat(surface);
QApplication app(argc, argv);
cvf::LogManager* logManager = cvf::LogManager::instance();
logManager->logger("cee.cvf.OpenGL")->setLevel(4);
// On Linux, Qt will use the system locale, force number formatting settings back to "C" locale
setlocale(LC_NUMERIC,"C");
QMVMainWindow window;
QString platform = cvf::System::is64Bit() ? "(64bit)" : "(32bit)";
window.setWindowTitle("Qt MultiView " + platform);
window.resize(1000, 800);;
window.resize(1000, 800);
window.show();
return app.exec();

View File

@@ -34,7 +34,6 @@
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
@@ -53,8 +52,6 @@
#include <QStatusBar>
#include <QLabel>
using cvf::ref;
//--------------------------------------------------------------------------------------------------
@@ -70,98 +67,72 @@ QMVMainWindow::QMVMainWindow()
setCentralWidget(mainFrame);
QMenu* widgetsMenu = menuBar()->addMenu("&Widgets");
m_createWidgetsAsFloatingDialogsAction = new QAction("Create Widgets as Floating Dialogs", this);
m_createWidgetsAsFloatingDialogsAction->setCheckable(true);
m_recycleScenesInWidgetConfigAction = new QAction("Recycle Scenes When Changing Widget Config", this);
m_recycleScenesInWidgetConfigAction->setCheckable(true);
m_softwareRenderingWidgetsAction = new QAction("Software Rendering in Widgets", this);
m_softwareRenderingWidgetsAction->setCheckable(true);
connect(m_softwareRenderingWidgetsAction, SIGNAL(toggled(bool)), SLOT(slotSoftwareRenderingWidgets(bool)));
m_configNumWidgets1Action = new QAction("1 Widget", this);
m_configNumWidgets2Action = new QAction("2 Widgets", this);
m_configNumWidgets4Action = new QAction("4 Widgets", this);
m_configNumWidgetsNoneAction = new QAction("No Widgets", this);
connect(m_configNumWidgets1Action, SIGNAL(triggered()), SLOT(slotConfigNumVizWidgets()));
connect(m_configNumWidgets2Action, SIGNAL(triggered()), SLOT(slotConfigNumVizWidgets()));
connect(m_configNumWidgets4Action, SIGNAL(triggered()), SLOT(slotConfigNumVizWidgets()));
connect(m_configNumWidgetsNoneAction, SIGNAL(triggered()), SLOT(slotConfigNumVizWidgets()));
m_configNumWidgets1Action = new QAction("1 Widget", this);
m_configNumWidgets2Action = new QAction("2 Widgets", this);
m_configNumWidgets4Action = new QAction("4 Widgets", this);
m_configNumWidgetsNoneAction= new QAction("No Widgets", this);
connect(m_configNumWidgets1Action, SIGNAL(triggered()), SLOT(slotConfigNumWidgets()));
connect(m_configNumWidgets2Action, SIGNAL(triggered()), SLOT(slotConfigNumWidgets()));
connect(m_configNumWidgets4Action, SIGNAL(triggered()), SLOT(slotConfigNumWidgets()));
connect(m_configNumWidgetsNoneAction, SIGNAL(triggered()), SLOT(slotConfigNumWidgets()));
m_createSphereAndBoxSceneAction = new QAction("Sphere And Box Scene", this);
m_createSpheresSceneAction = new QAction("Spheres Scene", this);
m_createBoxesSceneAction = new QAction("Boxes Scene", this);
m_createTrianglesSceneAction = new QAction("Triangles Scene", this);
m_allWidgetsDifferentSceneAction = new QAction("All Widgets Show Different Scene", this);
m_clearSceneAction = new QAction("Clear Scene", this);
connect(m_createSphereAndBoxSceneAction, SIGNAL(triggered()), SLOT(slotCreateSphereAndBoxScene()));
connect(m_createSpheresSceneAction, SIGNAL(triggered()), SLOT(slotCreateSpheresScene()));
connect(m_createBoxesSceneAction, SIGNAL(triggered()), SLOT(slotCreateBoxesScene()));
connect(m_createTrianglesSceneAction, SIGNAL(triggered()), SLOT(slotCreateTrianglesScene()));
connect(m_allWidgetsDifferentSceneAction, SIGNAL(triggered()), SLOT(slotAllWidgetsDifferentScene()));
connect(m_clearSceneAction, SIGNAL(triggered()), SLOT(slotClearScene()));
m_useBufferObjectsAction = new QAction("Use Buffer Objects", this);
m_useClientVertexArraysAction = new QAction("Use Client Vertex Arrays", this);
connect(m_useBufferObjectsAction, SIGNAL(triggered()), SLOT(slotUseBufferObjects()));
connect(m_useClientVertexArraysAction, SIGNAL(triggered()), SLOT(slotUseClientVertexArrays()));
m_deleteAllResourcesInResourceManagerAction = new QAction("Delete All Resources In Resource Manager", this);
connect(m_deleteAllResourcesInResourceManagerAction, SIGNAL(triggered()), SLOT(slotDeleteAllResourcesInResourceManager()));
QMenu* widgetsMenu = menuBar()->addMenu("&Widgets");
widgetsMenu->addAction(m_recycleScenesInWidgetConfigAction);
widgetsMenu->addAction(m_createWidgetsAsFloatingDialogsAction);
widgetsMenu->addSeparator();
widgetsMenu->addAction(m_softwareRenderingWidgetsAction);
widgetsMenu->addAction(m_recycleScenesInWidgetConfigAction);
widgetsMenu->addSeparator();
widgetsMenu->addAction(m_configNumWidgets1Action);
widgetsMenu->addAction(m_configNumWidgets2Action);
widgetsMenu->addAction(m_configNumWidgets4Action);
widgetsMenu->addAction(m_configNumWidgetsNoneAction);
widgetsMenu->addSeparator();
widgetsMenu->addAction("Delete First Widget", this, SLOT(slotDeleteFirstVizWidget()));
widgetsMenu->addAction("Delete Second Widget", this, SLOT(slotDeleteSecondVizWidget()));
QMenu* scenesMenu = menuBar()->addMenu("&Scenes");
scenesMenu->addAction(m_createSphereAndBoxSceneAction);
scenesMenu->addAction(m_createSpheresSceneAction);
scenesMenu->addAction(m_createBoxesSceneAction);
scenesMenu->addAction(m_createTrianglesSceneAction);
m_useShadersAction = new QAction("Use Shaders When Creating Scenes", this);
m_useShadersAction->setCheckable(true);
m_useShadersAction->setChecked(true);
scenesMenu->addAction(m_useShadersAction);
scenesMenu->addSeparator();
scenesMenu->addAction(m_allWidgetsDifferentSceneAction);
scenesMenu->addAction("Sphere And Box Scene", this, SLOT(slotCreateSphereAndBoxScene()));
scenesMenu->addAction("Spheres Scene", this, SLOT(slotCreateSpheresScene()));
scenesMenu->addAction("Boxes Scene", this, SLOT(slotCreateBoxesScene()));
scenesMenu->addAction("Triangles Scene", this, SLOT(slotCreateTrianglesScene()));
scenesMenu->addSeparator();
scenesMenu->addAction(m_clearSceneAction);
scenesMenu->addAction("All Widgets Show Different Scene", this, SLOT(slotAllWidgetsDifferentScene()));
scenesMenu->addSeparator();
scenesMenu->addAction("Clear Scene", this, SLOT(slotClearScene()));
QMenu* renderingMenu = menuBar()->addMenu("&Rendering");
renderingMenu->addAction(m_useBufferObjectsAction);
renderingMenu->addAction(m_useClientVertexArraysAction);
renderingMenu->addAction("Use Buffer Objects", this, SLOT(slotUseBufferObjects()));
renderingMenu->addAction("Use Client Vertex Arrays", this, SLOT(slotUseClientVertexArrays()));
QMenu* testMenu = menuBar()->addMenu("&Test");
testMenu->addAction(m_deleteAllResourcesInResourceManagerAction);
testMenu->addAction("Delete All Resources In Resource Manager", this, SLOT(slotDeleteAllResourcesInResourceManager()));
testMenu->addAction("Delete or Release OpenGL Resources in All Widgets", this, SLOT(slotDeleteOrReleaseOpenGLResourcesInAllVizWidgets()));
// Must create context group before launching any widgets
m_contextGroup = new cvf::OpenGLContextGroup;
createVizWidgets(1, m_softwareRenderingWidgetsAction->isChecked(), false);
slotCreateSphereAndBoxScene();
createVizWidgets(1, false);
QTimer* timer = new QTimer;
connect(timer, SIGNAL(timeout()), SLOT(slotUpdateStatusbar()));
timer->start(250);
/*
{
QWidget* myWidget = new QWidget;
QGridLayout* layout = new QGridLayout(myWidget);
QLabel* l1 = new QLabel("JALLA", myWidget);
QLabel* l2 = new QLabel("BALLA", myWidget);
QLabel* l3 = new QLabel("TRALLA", myWidget);
layout->addWidget(l1, 0, 0);
layout->addWidget(l2, 0, 1);
layout->addWidget(l3, 1, 1);
QStatusBar* sb = statusBar();
//sb->addPermanentWidget(new QLabel("JALLA"));
sb->addPermanentWidget(myWidget);
}
*/
}
@@ -197,7 +168,7 @@ int QMVMainWindow::vizWidgetCount()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::createVizWidgets(int numWidgets, bool software, bool recycleScenes)
void QMVMainWindow::createVizWidgets(int numWidgets, bool recycleScenes)
{
CVF_ASSERT(numWidgets <= MAX_NUM_WIDGETS);
@@ -209,40 +180,39 @@ void QMVMainWindow::createVizWidgets(int numWidgets, bool software, bool recycle
deleteAllVizWidgets();
QWidget* parentWidget = centralWidget();
QGridLayout* layout = dynamic_cast<QGridLayout*>(parentWidget->layout());
CVF_ASSERT(layout);
// Note that creating the widgets as floating dialogs will only work if the
// Qt::AA_ShareOpenGLContexts has been set using QApplication::setAttribute(Qt::AA_ShareOpenGLContexts) before Application object is constructed
const bool createAsDialogs = m_createWidgetsAsFloatingDialogsAction->isChecked();
QGLFormat oglFormat;
if (software)
{
oglFormat.setOption(QGL::IndirectRendering);
}
QWidget* parentWidget = centralWidget();
// The context group that all the contexts end up in
CVF_ASSERT(m_contextGroup.notNull());
CVF_ASSERT(m_contextGroup->contextCount() == 0);
QMVWidget* shareWidget = NULL;
int i;
for (i = 0; i < numWidgets; i++)
{
QMVWidget* newWidget = NULL;
if (shareWidget)
if (createAsDialogs)
{
newWidget = new QMVWidget(shareWidget, parentWidget);
newWidget = new QMVWidget(m_contextGroup.p(), i, parentWidget, Qt::Dialog);
newWidget->resize(600, 400);
newWidget->show();
}
else
{
newWidget = new QMVWidget(m_contextGroup.p(), oglFormat, parentWidget);
shareWidget = newWidget;
newWidget = new QMVWidget(m_contextGroup.p(), i, parentWidget);
QGridLayout* layout = parentWidget ? dynamic_cast<QGridLayout*>(parentWidget->layout()) : NULL;
if (layout)
{
int row = i/2;
int col = i-2*row;
layout->addWidget(newWidget, row, col);
}
}
int row = i/2;
int col = i-2*row;
layout->addWidget(newWidget, row, col);
m_vizWidgets[i] = newWidget;
}
@@ -256,12 +226,12 @@ void QMVMainWindow::createVizWidgets(int numWidgets, bool software, bool recycle
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::deleteAllOpenGLResourcesInAllVizWidgets()
void QMVMainWindow::deleteOrReleaseOpenGLResourcesInAllVizWidgets()
{
cvf::OpenGLResourceManager* resourceManager = m_contextGroup.notNull() ? m_contextGroup->resourceManager() : NULL;
// Will be set to one of the OpenGL contexts so we can use it in final evict call
cvf::OpenGLContext* someOglContext = NULL;
// The loop below should not be needed now that we can clean up resources
// by calling on the resource manager, but leave it as long as deleteOrReleaseOpenGLResources() is in place
// Loops over all the widgets and deletes/releases the OpenGL resources for each of them
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
@@ -272,19 +242,42 @@ void QMVMainWindow::deleteAllOpenGLResourcesInAllVizWidgets()
cvf::OpenGLContext* oglContext = vizWidget->cvfOpenGLContext();
CVF_ASSERT(oglContext);
CVF_ASSERT(oglContext->isCurrent());
someOglContext = oglContext;
cvf::RenderSequence* renderSeq = vizWidget->renderSequence();
if (renderSeq)
{
renderSeq->deleteOrReleaseOpenGLResources(oglContext);
}
CVF_ASSERT(resourceManager);
resourceManager->deleteAllOpenGLResources(oglContext);
}
}
cvf::OpenGLResourceManager* resourceManager = m_contextGroup.notNull() ? m_contextGroup->resourceManager() : NULL;
if (resourceManager && someOglContext)
{
resourceManager->evictOrphanedOpenGLResources(someOglContext);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::deleteAllOpenGLResourcesInResourceManager()
{
if (m_contextGroup.notNull())
{
cvf::OpenGLResourceManager* rcMgr = m_contextGroup->resourceManager();
CVF_ASSERT(rcMgr);
if (m_contextGroup->contextCount() > 0)
{
// Grab any context in the group
cvf::OpenGLContext* oglContext = m_contextGroup->context(0);
oglContext->makeCurrent();
rcMgr->deleteAllOpenGLResources(oglContext);
}
}
}
//--------------------------------------------------------------------------------------------------
///
@@ -294,7 +287,9 @@ void QMVMainWindow::deleteAllVizWidgets()
QWidget* parentWidget = centralWidget();
QLayout* layout = parentWidget->layout();
deleteAllOpenGLResourcesInAllVizWidgets();
// Should not be needed, but left for experimentation
//deleteOrReleaseOpenGLResourcesInAllVizWidgets();
//deleteAllOpenGLResourcesInResourceManager();
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
@@ -310,6 +305,21 @@ void QMVMainWindow::deleteAllVizWidgets()
CVF_ASSERT(m_contextGroup.isNull() || m_contextGroup->contextCount() == 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::deleteVizWidgetAt(int index)
{
QWidget* parentWidget = centralWidget();
QLayout* layout = parentWidget->layout();
if (m_vizWidgets[index])
{
layout->removeWidget(m_vizWidgets[index]);
delete m_vizWidgets[index];
m_vizWidgets[index] = NULL;
}
}
//--------------------------------------------------------------------------------------------------
///
@@ -323,7 +333,7 @@ void QMVMainWindow::setSceneInAllVizWidgets(cvf::Scene* scene)
{
if (m_vizWidgets[i] != NULL)
{
ref<cvf::RenderSequence> renderSeq = factory.createFromScene(scene);
cvf::ref<cvf::RenderSequence> renderSeq = factory.createFromScene(scene);
m_vizWidgets[i]->setRenderSequence(renderSeq.p());
}
}
@@ -348,7 +358,7 @@ void QMVMainWindow::spreadScenesAcrossVizWidgets(cvf::Collection<cvf::Scene>* sc
cvf::Scene* scene = (sceneCollection->size() > i) ? sceneCollection->at(i) : NULL;
if (scene)
{
ref<cvf::RenderSequence> renderSeq = factory.createFromScene(scene);
cvf::ref<cvf::RenderSequence> renderSeq = factory.createFromScene(scene);
vizWidget->setRenderSequence(renderSeq.p());
}
}
@@ -439,49 +449,56 @@ void QMVMainWindow::setRenderModeInAllModels(cvf::DrawableGeo::RenderMode render
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::closeEvent(QCloseEvent*)
{
deleteAllOpenGLResourcesInAllVizWidgets();
// Should not be needed any more, but left for experimentation
//deleteOrReleaseOpenGLResourcesInAllVizWidgets();
//deleteAllOpenGLResourcesInResourceManager();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotSoftwareRenderingWidgets(bool software)
{
int currNumWidgets = vizWidgetCount();
// Just recreate with the same number of widgets
createVizWidgets(currNumWidgets, software, m_recycleScenesInWidgetConfigAction->isChecked());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotConfigNumWidgets()
void QMVMainWindow::slotConfigNumVizWidgets()
{
QObject* senderAct = sender();
bool software = m_softwareRenderingWidgetsAction->isChecked();
bool recycleScenes = m_recycleScenesInWidgetConfigAction->isChecked();
if (senderAct == m_configNumWidgets1Action) createVizWidgets(1, software, recycleScenes);
else if (senderAct == m_configNumWidgets2Action) createVizWidgets(2, software, recycleScenes);
else if (senderAct == m_configNumWidgets4Action) createVizWidgets(4, software, recycleScenes);
else if (senderAct == m_configNumWidgetsNoneAction) createVizWidgets(0, software, recycleScenes);
if (senderAct == m_configNumWidgets1Action) createVizWidgets(1, recycleScenes);
else if (senderAct == m_configNumWidgets2Action) createVizWidgets(2, recycleScenes);
else if (senderAct == m_configNumWidgets4Action) createVizWidgets(4, recycleScenes);
else if (senderAct == m_configNumWidgetsNoneAction) createVizWidgets(0, recycleScenes);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotDeleteFirstVizWidget()
{
deleteVizWidgetAt(0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotDeleteSecondVizWidget()
{
deleteVizWidgetAt(1);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotCreateSphereAndBoxScene()
{
QMVModelFactory modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
// Without initialization we're not getting the correct capabilities
CVF_ASSERT(m_contextGroup->isContextGroupInitialized());
QMVModelFactory modelFactory(m_useShadersAction->isChecked(), *m_contextGroup->capabilities());
QMVSceneFactory sceneFactory(&modelFactory);
ref<cvf::Model> model = modelFactory.createSphereAndBox();
ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
cvf::ref<cvf::Model> model = modelFactory.createSphereAndBox();
cvf::ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
@@ -492,11 +509,14 @@ void QMVMainWindow::slotCreateSphereAndBoxScene()
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotCreateSpheresScene()
{
QMVModelFactory modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
// Without initialization we're not getting the correct capabilities
CVF_ASSERT(m_contextGroup->isContextGroupInitialized());
QMVModelFactory modelFactory(m_useShadersAction->isChecked(), *m_contextGroup->capabilities());
QMVSceneFactory sceneFactory(&modelFactory);
ref<cvf::Model> model = modelFactory.createSpheres();
ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
cvf::ref<cvf::Model> model = modelFactory.createSpheres();
cvf::ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
@@ -507,11 +527,14 @@ void QMVMainWindow::slotCreateSpheresScene()
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotCreateBoxesScene()
{
QMVModelFactory modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
// Without initialization we're not getting the correct capabilities
CVF_ASSERT(m_contextGroup->isContextGroupInitialized());
QMVModelFactory modelFactory(m_useShadersAction->isChecked(), *m_contextGroup->capabilities());
QMVSceneFactory sceneFactory(&modelFactory);
ref<cvf::Model> model = modelFactory.createBoxes();
ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
cvf::ref<cvf::Model> model = modelFactory.createBoxes();
cvf::ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
@@ -522,11 +545,14 @@ void QMVMainWindow::slotCreateBoxesScene()
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotCreateTrianglesScene()
{
QMVModelFactory modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
// Without initialization we're not getting the correct capabilities
CVF_ASSERT(m_contextGroup->isContextGroupInitialized());
QMVModelFactory modelFactory(m_useShadersAction->isChecked(), *m_contextGroup->capabilities());
QMVSceneFactory sceneFactory(&modelFactory);
ref<cvf::Model> model = modelFactory.createTriangles();
ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
cvf::ref<cvf::Model> model = modelFactory.createTriangles();
cvf::ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
@@ -537,7 +563,10 @@ void QMVMainWindow::slotCreateTrianglesScene()
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotAllWidgetsDifferentScene()
{
QMVModelFactory modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
// Without initialization we're not getting the correct capabilities
CVF_ASSERT(m_contextGroup->isContextGroupInitialized());
QMVModelFactory modelFactory(m_useShadersAction->isChecked(), *m_contextGroup->capabilities());
QMVSceneFactory sceneFactory(&modelFactory);
QMVRenderSequenceFactory renderSeqFactory;
@@ -546,8 +575,8 @@ void QMVMainWindow::slotAllWidgetsDifferentScene()
{
if (m_vizWidgets[i] != NULL)
{
ref<cvf::Scene> scene = sceneFactory.createNumberedScene(i);
ref<cvf::RenderSequence> renderSeq = renderSeqFactory.createFromScene(scene.p());
cvf::ref<cvf::Scene> scene = sceneFactory.createNumberedScene(i);
cvf::ref<cvf::RenderSequence> renderSeq = renderSeqFactory.createFromScene(scene.p());
m_vizWidgets[i]->setRenderSequence(renderSeq.p());
}
}
@@ -597,23 +626,16 @@ void QMVMainWindow::slotUseClientVertexArrays()
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotDeleteAllResourcesInResourceManager()
{
if (m_contextGroup.notNull())
{
cvf::OpenGLResourceManager* rcMgr = m_contextGroup->resourceManager();
CVF_ASSERT(rcMgr);
QMVWidget* vizWidget = m_vizWidgets[0];
cvf::OpenGLContext* oglContext = vizWidget ? vizWidget->cvfOpenGLContext() : NULL;
if (oglContext)
{
oglContext->makeCurrent();
rcMgr->deleteAllOpenGLResources(oglContext);
}
}
redrawAllVizWidgets();
deleteAllOpenGLResourcesInResourceManager();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotDeleteOrReleaseOpenGLResourcesInAllVizWidgets()
{
deleteOrReleaseOpenGLResourcesInAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
@@ -640,14 +662,20 @@ void QMVMainWindow::slotUpdateStatusbar()
if (renderSeq)
{
cvf::PerformanceInfo pi = renderSeq->performanceInfo();
QGLFormat oglFormat = vizWidget->format();
QString hwSw = oglFormat.testOption(QGL::IndirectRendering) ? "sw" : "hw";
QString viewMsg = QString("V%1(%2) #p=%3 #t=%4 ").arg(i).arg(hwSw).arg(pi.visiblePartsCount).arg((pi.triangleCount));
QString viewMsg = QString("V%1 #p=%2 #t=%3 ").arg(i).arg(pi.visiblePartsCount).arg((pi.triangleCount));
msg += viewMsg;
}
}
}
if (m_contextGroup.notNull())
{
const cvf::OpenGLInfo info = m_contextGroup->info();
msg += QString(" | ") + QString::fromStdString(info.renderer().toStdString());
}
QStatusBar* sb = statusBar();
sb->showMessage(msg);
}

View File

@@ -34,20 +34,18 @@
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfCollection.h"
#include "cvfDrawableGeo.h"
#include <QtGlobal>
#include <QMainWindow>
#include <QPointer>
class QMVWidget;
namespace cvf {
class View;
class Scene;
class OpenGLResourceManager;
class OpenGLContextGroup;
@@ -70,22 +68,24 @@ public:
private:
int vizWidgetCount();
void createVizWidgets(int numWidgets, bool software, bool recycleScenes);
void deleteAllOpenGLResourcesInAllVizWidgets();
void createVizWidgets(int numWidgets, bool recycleScenes);
void deleteAllOpenGLResourcesInResourceManager();
void deleteOrReleaseOpenGLResourcesInAllVizWidgets();
void deleteAllVizWidgets();
void deleteVizWidgetAt(int index);
void setSceneInAllVizWidgets(cvf::Scene* scene);
void spreadScenesAcrossVizWidgets(cvf::Collection<cvf::Scene>* sceneCollection);
void gatherAllScenes(cvf::Collection<cvf::Scene>* sceneCollection);
void redrawAllVizWidgets();
void setRenderModeInAllModels(cvf::DrawableGeo::RenderMode renderMode);
// Protected overrides
protected:
virtual void closeEvent(QCloseEvent* pCE);
private slots:
void slotSoftwareRenderingWidgets(bool);
void slotConfigNumWidgets();
void slotConfigNumVizWidgets();
void slotDeleteFirstVizWidget();
void slotDeleteSecondVizWidget();
void slotCreateSphereAndBoxScene();
void slotCreateSpheresScene();
@@ -98,31 +98,22 @@ private slots:
void slotUseClientVertexArrays();
void slotDeleteAllResourcesInResourceManager();
void slotDeleteOrReleaseOpenGLResourcesInAllVizWidgets();
void slotUpdateStatusbar();
private:
static const int MAX_NUM_WIDGETS = 4;
cvf::ref<cvf::OpenGLContextGroup> m_contextGroup;
QMVWidget* m_vizWidgets[MAX_NUM_WIDGETS];
QPointer<QMVWidget> m_vizWidgets[MAX_NUM_WIDGETS];
QAction* m_createWidgetsAsFloatingDialogsAction;
QAction* m_recycleScenesInWidgetConfigAction;
QAction* m_softwareRenderingWidgetsAction;
QAction* m_configNumWidgets1Action;
QAction* m_configNumWidgets2Action;
QAction* m_configNumWidgets4Action;
QAction* m_configNumWidgetsNoneAction;
QAction* m_createSphereAndBoxSceneAction;
QAction* m_createSpheresSceneAction;
QAction* m_createBoxesSceneAction;
QAction* m_createTrianglesSceneAction;
QAction* m_allWidgetsDifferentSceneAction;
QAction* m_clearSceneAction;
QAction* m_useBufferObjectsAction;
QAction* m_useClientVertexArraysAction;
QAction* m_deleteAllResourcesInResourceManagerAction;
QAction* m_useShadersAction;
};

View File

@@ -34,7 +34,6 @@
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
@@ -42,43 +41,23 @@
#include "QMVWidget.h"
#include "cvfqtOpenGLContext.h"
#include <QMouseEvent>
using cvf::ref;
#include <QPainter>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVWidget::QMVWidget(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent)
: cvfqt::OpenGLWidget(contextGroup, format, parent)
QMVWidget::QMVWidget(cvf::OpenGLContextGroup* contextGroup, int indexOfWidget, QWidget* parent, Qt::WindowFlags f)
: cvfqt::OpenGLWidget(contextGroup, parent, f),
m_indexOfWidget(indexOfWidget),
m_paintCount(0)
{
m_trackball = new cvf::ManipulatorTrackball;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVWidget::QMVWidget(QMVWidget* shareWidget, QWidget* parent)
: cvfqt::OpenGLWidget(shareWidget, parent)
{
m_trackball = new cvf::ManipulatorTrackball;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVWidget::~QMVWidget()
{
cvfShutdownOpenGLContext();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -114,6 +93,14 @@ cvf::RenderSequence* QMVWidget::renderSequence()
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OpenGLContext* QMVWidget::cvfOpenGLContext()
{
return cvfqt::OpenGLWidget::cvfOpenGLContext();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -125,10 +112,6 @@ void QMVWidget::resizeGL(int width, int height)
camera->viewport()->set(0, 0, width, height);
camera->setProjectionAsPerspective(camera->fieldOfViewYDeg(), camera->nearPlane(), camera->farPlane());
}
else
{
glViewport(0, 0, width, height);
}
}
@@ -141,7 +124,7 @@ void QMVWidget::paintGL()
CVF_ASSERT(currentOglContext);
CVF_CHECK_OGL(currentOglContext);
cvfqt::OpenGLContext::saveOpenGLState(currentOglContext);
cvf::OpenGLUtils::pushOpenGLState(currentOglContext);
if (m_renderSequence.notNull())
{
@@ -149,11 +132,17 @@ void QMVWidget::paintGL()
}
else
{
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// Reddish background for empty widgets
glClearColor(0.9f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
cvfqt::OpenGLContext::restoreOpenGLState(currentOglContext);
cvf::OpenGLUtils::popOpenGLState(currentOglContext);
m_paintCount++;
QPainter p(this);
p.setPen(Qt::red);
p.drawText(10, 20, QString("VP%1, paint count: %2").arg(m_indexOfWidget).arg(m_paintCount));
}
@@ -183,8 +172,13 @@ void QMVWidget::mouseMoveEvent(QMouseEvent* event)
if (m_renderSequence.isNull()) return;
Qt::MouseButtons mouseBn = event->buttons();
int posX = event->x();
int posY = height() - event->y();
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
const int posX = event->position().toPoint().x();
const int posY = height() - event->position().toPoint().y();
#else
const int posX = event->x();
const int posY = height() - event->y();
#endif
cvf::ManipulatorTrackball::NavigationType navType = cvf::ManipulatorTrackball::NONE;
if (mouseBn == Qt::LeftButton)
@@ -195,7 +189,7 @@ void QMVWidget::mouseMoveEvent(QMouseEvent* event)
{
navType = cvf::ManipulatorTrackball::ROTATE;
}
else if (mouseBn == (Qt::LeftButton | Qt::RightButton) || mouseBn == Qt::MidButton)
else if (mouseBn == (Qt::LeftButton | Qt::RightButton) || mouseBn == Qt::MiddleButton)
{
navType = cvf::ManipulatorTrackball::WALK;
}
@@ -220,10 +214,18 @@ void QMVWidget::mousePressEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
const int posX = event->position().toPoint().x();
const int posY = height() - event->position().toPoint().y();
#else
const int posX = event->x();
const int posY = height() - event->y();
#endif
if (event->buttons() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier)
{
cvf::Rendering* r = m_renderSequence->firstRendering();
ref<cvf::RayIntersectSpec> ris = r->rayIntersectSpecFromWindowCoordinates(event->x(), height() - event->y());
cvf::ref<cvf::RayIntersectSpec> ris = r->rayIntersectSpecFromWindowCoordinates(posX, posY);
cvf::HitItemCollection hic;
if (r->rayIntersect(*ris, &hic))
@@ -247,3 +249,5 @@ void QMVWidget::mouseReleaseEvent(QMouseEvent* /*event*/)
{
m_trackball->endNavigation();
}

View File

@@ -34,12 +34,12 @@
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfRenderSequence.h"
#include "cvfManipulatorTrackball.h"
#include "cvfqtOpenGLWidget.h"
@@ -53,13 +53,13 @@ class QMVWidget : public cvfqt::OpenGLWidget
Q_OBJECT
public:
QMVWidget(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent);
QMVWidget(QMVWidget* shareWidget, QWidget* parent);
~QMVWidget();
QMVWidget(cvf::OpenGLContextGroup* contextGroup, int indexOfWidget, QWidget* parent, Qt::WindowFlags f = Qt::WindowFlags());
void setRenderSequence(cvf::RenderSequence* renderSequence);
cvf::RenderSequence* renderSequence();
cvf::OpenGLContext* cvfOpenGLContext();
private:
void resizeGL(int width, int height);
void paintGL();
@@ -70,8 +70,10 @@ private:
void mouseReleaseEvent(QMouseEvent* event);
private:
cvf::ref<cvf::RenderSequence> m_renderSequence;
int m_indexOfWidget;
int m_paintCount;
cvf::ref<cvf::ManipulatorTrackball> m_trackball;
cvf::ref<cvf::RenderSequence> m_renderSequence;
};

View File

@@ -0,0 +1,51 @@
project(QtMultiView_deprecated)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_BASE_CXX_FLAGS}")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long")
endif()
find_package(OpenGL)
include_directories(${LibCore_SOURCE_DIR})
include_directories(${LibGeometry_SOURCE_DIR})
include_directories(${LibRender_SOURCE_DIR})
include_directories(${LibViewing_SOURCE_DIR})
include_directories(${LibGuiQt_SOURCE_DIR})
include_directories(${LibUtilities_SOURCE_DIR})
set(CEE_LIBS LibUtilities LibGuiQt LibViewing LibRender LibGeometry LibIo LibCore)
set(EXTERNAL_LIBS)
set(CEE_SOURCE_FILES
QMVFactory_deprecated.cpp
QMVMain_deprecated.cpp
QMVMainWindow_deprecated.cpp
QMVWidget_deprecated.cpp
)
# Headers that need MOCing
set(MOC_HEADER_FILES
QMVMainWindow_deprecated.h
QMVWidget_deprecated.h
)
# Qt
if (CEE_USE_QT5)
find_package(Qt5 COMPONENTS REQUIRED Core Gui Widgets OpenGL)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets Qt5::OpenGL)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES} )
else()
message(FATAL_ERROR "No supported Qt version selected for build")
endif()
set(SYSTEM_LIBRARIES)
if (CMAKE_COMPILER_IS_GNUCXX)
set(SYSTEM_LIBRARIES -lrt -lpthread)
endif(CMAKE_COMPILER_IS_GNUCXX)
add_executable(${PROJECT_NAME} ${CEE_SOURCE_FILES} ${MOC_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CEE_LIBS} ${OPENGL_LIBRARIES} ${QT_LIBRARIES} ${SYSTEM_LIBRARIES})

View File

@@ -0,0 +1,341 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "cvfuPartCompoundGenerator.h"
#include "QMVFactory_deprecated.h"
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVModelFactory_deprecated::QMVModelFactory_deprecated(bool useShaders)
: m_useShaders(useShaders)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Model> QMVModelFactory_deprecated::createSphereAndBox()
{
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createSphere(2, 10, 10, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE));
if (m_useShaders)
{
ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
eff->setShaderProgram(prog.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::GREEN)));
}
ref<cvf::Part> part = new cvf::Part;
part->setName("MySphere");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
model->addPart(part.p());
}
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createBox(cvf::Vec3f(5, 0, 0), 2, 3, 4, &builder);
ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::RED));
if (m_useShaders)
{
ref<cvf::ShaderProgram> prog = createProgramUnlit();
eff->setShaderProgram(prog.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::GREEN)));
}
ref<cvf::Part> part = new cvf::Part;
part->setName("MyBox");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
model->addPart(part.p());
}
model->updateBoundingBoxesRecursive();
return model;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Model> QMVModelFactory_deprecated::createSpheres()
{
cvfu::PartCompoundGenerator gen;
gen.setPartDistribution(cvf::Vec3i(5, 5, 5));
gen.setNumEffects(8);
gen.useRandomEffectAssignment(false);
gen.setExtent(cvf::Vec3f(3,3,3));
gen.setOrigin(cvf::Vec3f(-1.5f, -1.5f, -1.5f));
cvf::Collection<cvf::Part> parts;
gen.generateSpheres(20, 20, &parts);
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
size_t i;
for (i = 0; i < parts.size(); i++)
{
cvf::Part* part = parts[i].p();
if (m_useShaders)
{
cvf::Effect* eff = part->effect();
eff->setShaderProgram(prog.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::INDIGO)));
}
model->addPart(part);
}
model->updateBoundingBoxesRecursive();
return model;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Model> QMVModelFactory_deprecated::createBoxes()
{
cvfu::PartCompoundGenerator gen;
gen.setPartDistribution(cvf::Vec3i(5, 5, 5));
gen.setNumEffects(8);
gen.useRandomEffectAssignment(false);
gen.setExtent(cvf::Vec3f(3,3,3));
gen.setOrigin(cvf::Vec3f(-1.5f, -1.5f, -1.5f));
cvf::Collection<cvf::Part> parts;
gen.generateBoxes(&parts);
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
size_t i;
for (i = 0; i < parts.size(); i++)
{
cvf::Part* part = parts[i].p();
if (m_useShaders)
{
cvf::Effect* eff = part->effect();
eff->setShaderProgram(prog.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::CYAN)));
}
model->addPart(part);
}
model->updateBoundingBoxesRecursive();
return model;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Model> QMVModelFactory_deprecated::createTriangles()
{
cvfu::PartCompoundGenerator gen;
gen.setPartDistribution(cvf::Vec3i(5, 5, 5));
gen.setNumEffects(8);
gen.useRandomEffectAssignment(false);
gen.setExtent(cvf::Vec3f(3,3,3));
gen.setOrigin(cvf::Vec3f(-1.5f, -1.5f, -1.5f));
cvf::Collection<cvf::Part> parts;
gen.generateTriangles(&parts);
ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
ref<cvf::ShaderProgram> prog = createProgramStandardHeadlightColor();
size_t i;
for (i = 0; i < parts.size(); i++)
{
cvf::Part* part = parts[i].p();
if (m_useShaders)
{
cvf::Effect* eff = part->effect();
eff->setShaderProgram(prog.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::GOLD)));
}
model->addPart(part);
}
model->updateBoundingBoxesRecursive();
return model;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::ShaderProgram> QMVModelFactory_deprecated::createProgramStandardHeadlightColor()
{
cvf::ShaderProgramGenerator gen("StandardHeadlightColor", cvf::ShaderSourceProvider::instance());
gen.configureStandardHeadlightColor();
ref<cvf::ShaderProgram> prog = gen.generate();
return prog;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::ShaderProgram> QMVModelFactory_deprecated::createProgramUnlit()
{
cvf::ShaderProgramGenerator gen("Unlit", cvf::ShaderSourceProvider::instance());
gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard);
gen.addFragmentCode(cvf::ShaderSourceRepository::src_Color);
gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Unlit);
ref<cvf::ShaderProgram> prog = gen.generate();
return prog;
}
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVSceneFactory_deprecated::QMVSceneFactory_deprecated(QMVModelFactory_deprecated* modelFactory)
: m_modelFactory(modelFactory)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Scene> QMVSceneFactory_deprecated::createNumberedScene(int sceneNumber)
{
ref<cvf::Model> model;
switch (sceneNumber)
{
case 0: model = m_modelFactory->createSphereAndBox(); break;
case 1: model = m_modelFactory->createSpheres(); break;
case 2: model = m_modelFactory->createBoxes(); break;
default: model = m_modelFactory->createTriangles(); break;
}
return createFromModel(model.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::Scene> QMVSceneFactory_deprecated::createFromModel(cvf::Model* model)
{
ref<cvf::Scene> scene = new cvf::Scene;
if (model)
{
scene->addModel(model);
}
return scene;
}
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<cvf::RenderSequence> QMVRenderSequenceFactory_deprecated::createFromScene(cvf::Scene* scene)
{
ref<cvf::Rendering> rendering = new cvf::Rendering;
rendering->renderEngine()->enableItemCountUpdate(true);
rendering->setScene(scene);
cvf::Camera* cam = rendering->camera();
rendering->addOverlayItem(new cvf::OverlayAxisCross(cam, new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD)));
if (scene)
{
cvf::BoundingBox bb = scene->boundingBox();
if (bb.isValid())
{
cam->fitView(bb, -cvf::Vec3d::Z_AXIS, cvf::Vec3d::Y_AXIS);
}
}
ref<cvf::RenderSequence> renderSeq = new cvf::RenderSequence;
renderSeq->addRendering(rendering.p());
return renderSeq;
}

View File

@@ -0,0 +1,97 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
using cvf::ref;
//==================================================================================================
//
//
//
//==================================================================================================
class QMVModelFactory_deprecated
{
public:
QMVModelFactory_deprecated(bool useShaders);
ref<cvf::Model> createSphereAndBox();
ref<cvf::Model> createSpheres();
ref<cvf::Model> createBoxes();
ref<cvf::Model> createTriangles();
private:
ref<cvf::ShaderProgram> createProgramStandardHeadlightColor();
ref<cvf::ShaderProgram> createProgramUnlit();
private:
bool m_useShaders;
};
//==================================================================================================
//
//
//
//==================================================================================================
class QMVSceneFactory_deprecated
{
public:
QMVSceneFactory_deprecated(QMVModelFactory_deprecated* modelFactory);
ref<cvf::Scene> createNumberedScene(int sceneNumber);
ref<cvf::Scene> createFromModel(cvf::Model* model);
private:
QMVModelFactory_deprecated* m_modelFactory;
};
//==================================================================================================
//
//
//
//==================================================================================================
class QMVRenderSequenceFactory_deprecated
{
public:
ref<cvf::RenderSequence> createFromScene(cvf::Scene* model);
};

View File

@@ -0,0 +1,653 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QMVMainWindow_deprecated.h"
#include "QMVWidget_deprecated.h"
#include "QMVFactory_deprecated.h"
#include <QTimer>
#include <QFrame>
#include <QHBoxLayout>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QStatusBar>
#include <QLabel>
using cvf::ref;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVMainWindow_deprecated::QMVMainWindow_deprecated()
{
memset(m_vizWidgets, 0, sizeof(m_vizWidgets));
QFrame* mainFrame = new QFrame;
QGridLayout* frameLayout = new QGridLayout;
mainFrame->setLayout(frameLayout);
setCentralWidget(mainFrame);
m_recycleScenesInWidgetConfigAction = new QAction("Recycle Scenes When Changing Widget Config", this);
m_recycleScenesInWidgetConfigAction->setCheckable(true);
m_softwareRenderingWidgetsAction = new QAction("Software Rendering in Widgets", this);
m_softwareRenderingWidgetsAction->setCheckable(true);
connect(m_softwareRenderingWidgetsAction, SIGNAL(toggled(bool)), SLOT(slotSoftwareRenderingWidgets(bool)));
m_configNumWidgets1Action = new QAction("1 Widget", this);
m_configNumWidgets2Action = new QAction("2 Widgets", this);
m_configNumWidgets4Action = new QAction("4 Widgets", this);
m_configNumWidgetsNoneAction= new QAction("No Widgets", this);
connect(m_configNumWidgets1Action, SIGNAL(triggered()), SLOT(slotConfigNumWidgets()));
connect(m_configNumWidgets2Action, SIGNAL(triggered()), SLOT(slotConfigNumWidgets()));
connect(m_configNumWidgets4Action, SIGNAL(triggered()), SLOT(slotConfigNumWidgets()));
connect(m_configNumWidgetsNoneAction, SIGNAL(triggered()), SLOT(slotConfigNumWidgets()));
m_createSphereAndBoxSceneAction = new QAction("Sphere And Box Scene", this);
m_createSpheresSceneAction = new QAction("Spheres Scene", this);
m_createBoxesSceneAction = new QAction("Boxes Scene", this);
m_createTrianglesSceneAction = new QAction("Triangles Scene", this);
m_allWidgetsDifferentSceneAction = new QAction("All Widgets Show Different Scene", this);
m_clearSceneAction = new QAction("Clear Scene", this);
connect(m_createSphereAndBoxSceneAction, SIGNAL(triggered()), SLOT(slotCreateSphereAndBoxScene()));
connect(m_createSpheresSceneAction, SIGNAL(triggered()), SLOT(slotCreateSpheresScene()));
connect(m_createBoxesSceneAction, SIGNAL(triggered()), SLOT(slotCreateBoxesScene()));
connect(m_createTrianglesSceneAction, SIGNAL(triggered()), SLOT(slotCreateTrianglesScene()));
connect(m_allWidgetsDifferentSceneAction, SIGNAL(triggered()), SLOT(slotAllWidgetsDifferentScene()));
connect(m_clearSceneAction, SIGNAL(triggered()), SLOT(slotClearScene()));
m_useBufferObjectsAction = new QAction("Use Buffer Objects", this);
m_useClientVertexArraysAction = new QAction("Use Client Vertex Arrays", this);
connect(m_useBufferObjectsAction, SIGNAL(triggered()), SLOT(slotUseBufferObjects()));
connect(m_useClientVertexArraysAction, SIGNAL(triggered()), SLOT(slotUseClientVertexArrays()));
m_deleteAllResourcesInResourceManagerAction = new QAction("Delete All Resources In Resource Manager", this);
connect(m_deleteAllResourcesInResourceManagerAction, SIGNAL(triggered()), SLOT(slotDeleteAllResourcesInResourceManager()));
QMenu* widgetsMenu = menuBar()->addMenu("&Widgets");
widgetsMenu->addAction(m_recycleScenesInWidgetConfigAction);
widgetsMenu->addSeparator();
widgetsMenu->addAction(m_softwareRenderingWidgetsAction);
widgetsMenu->addSeparator();
widgetsMenu->addAction(m_configNumWidgets1Action);
widgetsMenu->addAction(m_configNumWidgets2Action);
widgetsMenu->addAction(m_configNumWidgets4Action);
widgetsMenu->addAction(m_configNumWidgetsNoneAction);
QMenu* scenesMenu = menuBar()->addMenu("&Scenes");
scenesMenu->addAction(m_createSphereAndBoxSceneAction);
scenesMenu->addAction(m_createSpheresSceneAction);
scenesMenu->addAction(m_createBoxesSceneAction);
scenesMenu->addAction(m_createTrianglesSceneAction);
scenesMenu->addSeparator();
scenesMenu->addAction(m_allWidgetsDifferentSceneAction);
scenesMenu->addSeparator();
scenesMenu->addAction(m_clearSceneAction);
QMenu* renderingMenu = menuBar()->addMenu("&Rendering");
renderingMenu->addAction(m_useBufferObjectsAction);
renderingMenu->addAction(m_useClientVertexArraysAction);
QMenu* testMenu = menuBar()->addMenu("&Test");
testMenu->addAction(m_deleteAllResourcesInResourceManagerAction);
// Must create context group before launching any widgets
m_contextGroup = new cvf::OpenGLContextGroup;
createVizWidgets(1, m_softwareRenderingWidgetsAction->isChecked(), false);
slotCreateSphereAndBoxScene();
QTimer* timer = new QTimer;
connect(timer, SIGNAL(timeout()), SLOT(slotUpdateStatusbar()));
timer->start(250);
/*
{
QWidget* myWidget = new QWidget;
QGridLayout* layout = new QGridLayout(myWidget);
QLabel* l1 = new QLabel("JALLA", myWidget);
QLabel* l2 = new QLabel("BALLA", myWidget);
QLabel* l3 = new QLabel("TRALLA", myWidget);
layout->addWidget(l1, 0, 0);
layout->addWidget(l2, 0, 1);
layout->addWidget(l3, 1, 1);
QStatusBar* sb = statusBar();
//sb->addPermanentWidget(new QLabel("JALLA"));
sb->addPermanentWidget(myWidget);
}
*/
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVMainWindow_deprecated::~QMVMainWindow_deprecated()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int QMVMainWindow_deprecated::vizWidgetCount()
{
int count = 0;
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i])
{
count++;
}
}
return count;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::createVizWidgets(int numWidgets, bool software, bool recycleScenes)
{
CVF_ASSERT(numWidgets <= MAX_NUM_WIDGETS);
cvf::Collection<cvf::Scene> sceneCollection;
if (recycleScenes)
{
gatherAllScenes(&sceneCollection);
}
deleteAllVizWidgets();
QWidget* parentWidget = centralWidget();
QGridLayout* layout = dynamic_cast<QGridLayout*>(parentWidget->layout());
CVF_ASSERT(layout);
QGLFormat oglFormat;
if (software)
{
oglFormat.setOption(QGL::IndirectRendering);
}
// The context group that all the contexts end up in
CVF_ASSERT(m_contextGroup.notNull());
CVF_ASSERT(m_contextGroup->contextCount() == 0);
QMVWidget_deprecated* shareWidget = NULL;
int i;
for (i = 0; i < numWidgets; i++)
{
QMVWidget_deprecated* newWidget = NULL;
if (shareWidget)
{
newWidget = new QMVWidget_deprecated(shareWidget, parentWidget);
}
else
{
newWidget = new QMVWidget_deprecated(m_contextGroup.p(), oglFormat, parentWidget);
shareWidget = newWidget;
}
int row = i/2;
int col = i-2*row;
layout->addWidget(newWidget, row, col);
m_vizWidgets[i] = newWidget;
}
if (recycleScenes)
{
spreadScenesAcrossVizWidgets(&sceneCollection);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::deleteAllOpenGLResourcesInAllVizWidgets()
{
cvf::OpenGLResourceManager* resourceManager = m_contextGroup.notNull() ? m_contextGroup->resourceManager() : NULL;
// The loop below should not be needed now that we can clean up resources
// by calling on the resource manager, but leave it as long as deleteOrReleaseOpenGLResources() is in place
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
QMVWidget_deprecated* vizWidget = m_vizWidgets[i];
if (vizWidget)
{
vizWidget->makeCurrent();
cvf::OpenGLContext* oglContext = vizWidget->cvfOpenGLContext();
CVF_ASSERT(oglContext);
CVF_ASSERT(oglContext->isCurrent());
cvf::RenderSequence* renderSeq = vizWidget->renderSequence();
if (renderSeq)
{
renderSeq->deleteOrReleaseOpenGLResources(oglContext);
}
CVF_ASSERT(resourceManager);
resourceManager->deleteAllOpenGLResources(oglContext);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::deleteAllVizWidgets()
{
QWidget* parentWidget = centralWidget();
QLayout* layout = parentWidget->layout();
deleteAllOpenGLResourcesInAllVizWidgets();
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i])
{
layout->removeWidget(m_vizWidgets[i]);
delete m_vizWidgets[i];
m_vizWidgets[i] = NULL;
}
}
CVF_ASSERT(m_contextGroup.isNull() || m_contextGroup->contextCount() == 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::setSceneInAllVizWidgets(cvf::Scene* scene)
{
QMVRenderSequenceFactory_deprecated factory;
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
ref<cvf::RenderSequence> renderSeq = factory.createFromScene(scene);
m_vizWidgets[i]->setRenderSequence(renderSeq.p());
}
}
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::spreadScenesAcrossVizWidgets(cvf::Collection<cvf::Scene>* sceneCollection)
{
QMVRenderSequenceFactory_deprecated factory;
cvf::uint i;
for (i = 0; i < static_cast<cvf::uint>(MAX_NUM_WIDGETS); i++)
{
QMVWidget_deprecated* vizWidget = m_vizWidgets[i];
if (vizWidget)
{
cvf::Scene* scene = (sceneCollection->size() > i) ? sceneCollection->at(i) : NULL;
if (scene)
{
ref<cvf::RenderSequence> renderSeq = factory.createFromScene(scene);
vizWidget->setRenderSequence(renderSeq.p());
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::gatherAllScenes(cvf::Collection<cvf::Scene>* sceneCollection)
{
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
cvf::RenderSequence* renderSeq = m_vizWidgets[i]->renderSequence();
cvf::Rendering* rendering = renderSeq ? renderSeq->firstRendering() : NULL;
cvf::Scene* scene = rendering ? rendering->scene() : NULL;
if (scene)
{
sceneCollection->push_back(scene);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::redrawAllVizWidgets()
{
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
m_vizWidgets[i]->update();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::setRenderModeInAllModels(cvf::DrawableGeo::RenderMode renderMode)
{
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
cvf::RenderSequence* renderSeq = m_vizWidgets[i]->renderSequence();
cvf::Rendering* rendering = renderSeq ? renderSeq->firstRendering() : NULL;
cvf::Scene* scene = rendering ? rendering->scene() : NULL;
if (scene)
{
cvf::Collection<cvf::Part> allParts;
scene->allParts(&allParts);
size_t numParts = allParts.size();
size_t partIdx;
for (partIdx = 0; partIdx < numParts; partIdx++)
{
cvf::Part* part = allParts.at(partIdx);
cvf::uint lod;
for (lod = 0; lod < cvf::Part::MAX_NUM_LOD_LEVELS; lod++)
{
cvf::DrawableGeo* drawableGeo = dynamic_cast<cvf::DrawableGeo*>(part->drawable(lod));
if (drawableGeo)
{
drawableGeo->setRenderMode(renderMode);
}
}
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::closeEvent(QCloseEvent*)
{
deleteAllOpenGLResourcesInAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotSoftwareRenderingWidgets(bool software)
{
int currNumWidgets = vizWidgetCount();
// Just recreate with the same number of widgets
createVizWidgets(currNumWidgets, software, m_recycleScenesInWidgetConfigAction->isChecked());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotConfigNumWidgets()
{
QObject* senderAct = sender();
bool software = m_softwareRenderingWidgetsAction->isChecked();
bool recycleScenes = m_recycleScenesInWidgetConfigAction->isChecked();
if (senderAct == m_configNumWidgets1Action) createVizWidgets(1, software, recycleScenes);
else if (senderAct == m_configNumWidgets2Action) createVizWidgets(2, software, recycleScenes);
else if (senderAct == m_configNumWidgets4Action) createVizWidgets(4, software, recycleScenes);
else if (senderAct == m_configNumWidgetsNoneAction) createVizWidgets(0, software, recycleScenes);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotCreateSphereAndBoxScene()
{
QMVModelFactory_deprecated modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
QMVSceneFactory_deprecated sceneFactory(&modelFactory);
ref<cvf::Model> model = modelFactory.createSphereAndBox();
ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotCreateSpheresScene()
{
QMVModelFactory_deprecated modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
QMVSceneFactory_deprecated sceneFactory(&modelFactory);
ref<cvf::Model> model = modelFactory.createSpheres();
ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotCreateBoxesScene()
{
QMVModelFactory_deprecated modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
QMVSceneFactory_deprecated sceneFactory(&modelFactory);
ref<cvf::Model> model = modelFactory.createBoxes();
ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotCreateTrianglesScene()
{
QMVModelFactory_deprecated modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
QMVSceneFactory_deprecated sceneFactory(&modelFactory);
ref<cvf::Model> model = modelFactory.createTriangles();
ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotAllWidgetsDifferentScene()
{
QMVModelFactory_deprecated modelFactory(!m_softwareRenderingWidgetsAction->isChecked());
QMVSceneFactory_deprecated sceneFactory(&modelFactory);
QMVRenderSequenceFactory_deprecated renderSeqFactory;
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
ref<cvf::Scene> scene = sceneFactory.createNumberedScene(i);
ref<cvf::RenderSequence> renderSeq = renderSeqFactory.createFromScene(scene.p());
m_vizWidgets[i]->setRenderSequence(renderSeq.p());
}
}
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotClearScene()
{
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
m_vizWidgets[i]->setRenderSequence(NULL);
}
}
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotUseBufferObjects()
{
setRenderModeInAllModels(cvf::DrawableGeo::BUFFER_OBJECT);
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotUseClientVertexArrays()
{
setRenderModeInAllModels(cvf::DrawableGeo::VERTEX_ARRAY);
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotDeleteAllResourcesInResourceManager()
{
if (m_contextGroup.notNull())
{
cvf::OpenGLResourceManager* rcMgr = m_contextGroup->resourceManager();
CVF_ASSERT(rcMgr);
QMVWidget_deprecated* vizWidget = m_vizWidgets[0];
cvf::OpenGLContext* oglContext = vizWidget ? vizWidget->cvfOpenGLContext() : NULL;
if (oglContext)
{
oglContext->makeCurrent();
rcMgr->deleteAllOpenGLResources(oglContext);
}
}
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow_deprecated::slotUpdateStatusbar()
{
cvf::OpenGLResourceManager* resourceManager = m_contextGroup.notNull() ? m_contextGroup->resourceManager() : NULL;
QString msg = "N/A ";
if (resourceManager)
{
cvf::uint boCount = resourceManager->bufferObjectCount();
double boMemUsageMB = static_cast<double>(resourceManager->bufferObjectMemoryUsage())/(1024.0*1024.0);
msg = QString("#bo=%1 (MB=%2) | ").arg(boCount).arg(boMemUsageMB, 0, 'f', 3);
}
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
QMVWidget_deprecated* vizWidget = m_vizWidgets[i];
if (vizWidget)
{
cvf::RenderSequence* renderSeq = vizWidget->renderSequence();
if (renderSeq)
{
cvf::PerformanceInfo pi = renderSeq->performanceInfo();
QGLFormat oglFormat = vizWidget->format();
QString hwSw = oglFormat.testOption(QGL::IndirectRendering) ? "sw" : "hw";
QString viewMsg = QString("V%1(%2) #p=%3 #t=%4 ").arg(i).arg(hwSw).arg(pi.visiblePartsCount).arg((pi.triangleCount));
msg += viewMsg;
}
}
}
QStatusBar* sb = statusBar();
sb->showMessage(msg);
}

View File

@@ -0,0 +1,128 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfCollection.h"
#include "cvfDrawableGeo.h"
#include <QtGlobal>
#include <QMainWindow>
class QMVWidget_deprecated;
namespace cvf {
class View;
class Scene;
class OpenGLResourceManager;
class OpenGLContextGroup;
}
//==================================================================================================
//
//
//
//==================================================================================================
class QMVMainWindow_deprecated : public QMainWindow
{
Q_OBJECT
public:
QMVMainWindow_deprecated();
~QMVMainWindow_deprecated();
private:
int vizWidgetCount();
void createVizWidgets(int numWidgets, bool software, bool recycleScenes);
void deleteAllOpenGLResourcesInAllVizWidgets();
void deleteAllVizWidgets();
void setSceneInAllVizWidgets(cvf::Scene* scene);
void spreadScenesAcrossVizWidgets(cvf::Collection<cvf::Scene>* sceneCollection);
void gatherAllScenes(cvf::Collection<cvf::Scene>* sceneCollection);
void redrawAllVizWidgets();
void setRenderModeInAllModels(cvf::DrawableGeo::RenderMode renderMode);
// Protected overrides
protected:
virtual void closeEvent(QCloseEvent* pCE);
private slots:
void slotSoftwareRenderingWidgets(bool);
void slotConfigNumWidgets();
void slotCreateSphereAndBoxScene();
void slotCreateSpheresScene();
void slotCreateBoxesScene();
void slotCreateTrianglesScene();
void slotAllWidgetsDifferentScene();
void slotClearScene();
void slotUseBufferObjects();
void slotUseClientVertexArrays();
void slotDeleteAllResourcesInResourceManager();
void slotUpdateStatusbar();
private:
static const int MAX_NUM_WIDGETS = 4;
cvf::ref<cvf::OpenGLContextGroup> m_contextGroup;
QMVWidget_deprecated* m_vizWidgets[MAX_NUM_WIDGETS];
QAction* m_recycleScenesInWidgetConfigAction;
QAction* m_softwareRenderingWidgetsAction;
QAction* m_configNumWidgets1Action;
QAction* m_configNumWidgets2Action;
QAction* m_configNumWidgets4Action;
QAction* m_configNumWidgetsNoneAction;
QAction* m_createSphereAndBoxSceneAction;
QAction* m_createSpheresSceneAction;
QAction* m_createBoxesSceneAction;
QAction* m_createTrianglesSceneAction;
QAction* m_allWidgetsDifferentSceneAction;
QAction* m_clearSceneAction;
QAction* m_useBufferObjectsAction;
QAction* m_useClientVertexArraysAction;
QAction* m_deleteAllResourcesInResourceManagerAction;
};

View File

@@ -0,0 +1,69 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "QMVMainWindow_deprecated.h"
#include <QApplication>
#include "QtOpenGL/qgl.h"
#include <locale.h>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
// It seems that if we are using paintEvent() instead of paintGL() to
// draw we might have to set OpenGL as the preferred paint engine
//QGL::setPreferredPaintEngine(QPaintEngine::OpenGL);
QApplication app(argc, argv);
// On Linux, Qt will use the system locale, force number formatting settings back to "C" locale
setlocale(LC_NUMERIC,"C");
QMVMainWindow_deprecated window;
QString platform = cvf::System::is64Bit() ? "(64bit)" : "(32bit)";
window.setWindowTitle("Qt MultiView " + platform);
window.resize(1000, 800);;
window.show();
return app.exec();
}

View File

@@ -0,0 +1,247 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QMVWidget_deprecated.h"
#include <QMouseEvent>
using cvf::ref;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVWidget_deprecated::QMVWidget_deprecated(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent)
: cvfqt::GLWidget_deprecated(contextGroup, format, parent)
{
m_trackball = new cvf::ManipulatorTrackball;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVWidget_deprecated::QMVWidget_deprecated(QMVWidget_deprecated* shareWidget, QWidget* parent)
: cvfqt::GLWidget_deprecated(shareWidget, parent)
{
m_trackball = new cvf::ManipulatorTrackball;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVWidget_deprecated::~QMVWidget_deprecated()
{
cvfShutdownOpenGLContext();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget_deprecated::setRenderSequence(cvf::RenderSequence* renderSequence)
{
m_trackball->setCamera(NULL);
m_renderSequence = renderSequence;
if (m_renderSequence.notNull())
{
// Camera extracted from first rendering of the view
cvf::Camera* camera = currentCamera();
camera->viewport()->set(0, 0, width(), height());
camera->setProjectionAsPerspective(camera->fieldOfViewYDeg(), camera->nearPlane(), camera->farPlane());
m_trackball->setCamera(camera);
cvf::BoundingBox bb = m_renderSequence->boundingBox();
if (bb.isValid())
{
m_trackball->setRotationPoint(bb.center());
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::RenderSequence* QMVWidget_deprecated::renderSequence()
{
return m_renderSequence.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget_deprecated::resizeGL(int width, int height)
{
cvf::Camera* camera = currentCamera();
if (camera)
{
camera->viewport()->set(0, 0, width, height);
camera->setProjectionAsPerspective(camera->fieldOfViewYDeg(), camera->nearPlane(), camera->farPlane());
}
else
{
glViewport(0, 0, width, height);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget_deprecated::paintGL()
{
cvf::OpenGLContext* currentOglContext = cvfOpenGLContext();
CVF_ASSERT(currentOglContext);
CVF_CHECK_OGL(currentOglContext);
cvf::OpenGLUtils::pushOpenGLState(currentOglContext);
if (m_renderSequence.notNull())
{
m_renderSequence->render(currentOglContext);
}
else
{
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
cvf::OpenGLUtils::popOpenGLState(currentOglContext);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Camera* QMVWidget_deprecated::currentCamera()
{
if (m_renderSequence.notNull())
{
cvf::Rendering* rendering = m_renderSequence->firstRendering();
if (rendering)
{
return rendering->camera();
}
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget_deprecated::mouseMoveEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
Qt::MouseButtons mouseBn = event->buttons();
int posX = event->x();
int posY = height() - event->y();
cvf::ManipulatorTrackball::NavigationType navType = cvf::ManipulatorTrackball::NONE;
if (mouseBn == Qt::LeftButton)
{
navType = cvf::ManipulatorTrackball::PAN;
}
else if (mouseBn == Qt::RightButton)
{
navType = cvf::ManipulatorTrackball::ROTATE;
}
else if (mouseBn == (Qt::LeftButton | Qt::RightButton) || mouseBn == Qt::MiddleButton)
{
navType = cvf::ManipulatorTrackball::WALK;
}
if (navType != m_trackball->activeNavigation())
{
m_trackball->startNavigation(navType, posX, posY);
}
bool needRedraw = m_trackball->updateNavigation(posX, posY);
if (needRedraw)
{
update();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget_deprecated::mousePressEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
if (event->buttons() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier)
{
cvf::Rendering* r = m_renderSequence->firstRendering();
ref<cvf::RayIntersectSpec> ris = r->rayIntersectSpecFromWindowCoordinates(event->x(), height() - event->y());
cvf::HitItemCollection hic;
if (r->rayIntersect(*ris, &hic))
{
cvf::HitItem* item = hic.firstItem();
CVF_ASSERT(item && item->part());
cvf::Vec3d isect = item->intersectionPoint();
m_trackball->setRotationPoint(isect);
cvf::Trace::show("hitting part: '%s' coords: %.3f %.3f %.3f", item->part()->name().toAscii().ptr(), isect.x(), isect.y(), isect.z());
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget_deprecated::mouseReleaseEvent(QMouseEvent* /*event*/)
{
m_trackball->endNavigation();
}

View File

@@ -0,0 +1,77 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfRenderSequence.h"
#include "cvfManipulatorTrackball.h"
#include "cvfqtGLWidget_deprecated.h"
//==================================================================================================
//
//
//
//==================================================================================================
class QMVWidget_deprecated : public cvfqt::GLWidget_deprecated
{
Q_OBJECT
public:
QMVWidget_deprecated(cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent);
QMVWidget_deprecated(QMVWidget_deprecated* shareWidget, QWidget* parent);
~QMVWidget_deprecated();
void setRenderSequence(cvf::RenderSequence* renderSequence);
cvf::RenderSequence* renderSequence();
private:
void resizeGL(int width, int height);
void paintGL();
cvf::Camera* currentCamera();
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
private:
cvf::ref<cvf::RenderSequence> m_renderSequence;
cvf::ref<cvf::ManipulatorTrackball> m_trackball;
};

View File

@@ -35,6 +35,15 @@ QSRStdInclude.cpp
QSRTranslateEvent.cpp
)
set(CEE_HEADER_FILES
QSRCommandLineArgs.h
QSRPropertiesPanel.h
QSRRunPanel.h
QSRSnippetWidget.h
QSRStdInclude.h
QSRTranslateEvent.h
)
# Headers that need MOCing
set(MOC_HEADER_FILES
QSRMainWindow.h
@@ -43,8 +52,13 @@ QSRRunPanel.h
QSRSnippetWidget.h
)
# Qt
if (CEE_USE_QT5)
if (CEE_USE_QT6)
find_package(Qt6 COMPONENTS REQUIRED OpenGLWidgets)
set(QT_LIBRARIES Qt6::OpenGLWidgets )
qt_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES})
elseif (CEE_USE_QT5)
find_package(Qt5 COMPONENTS REQUIRED Core Gui Widgets OpenGL)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets Qt5::OpenGL)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES} )
@@ -57,5 +71,5 @@ if (CMAKE_COMPILER_IS_GNUCXX)
set(SYSTEM_LIBRARIES -lrt -lpthread)
endif(CMAKE_COMPILER_IS_GNUCXX)
add_executable(${PROJECT_NAME} ${CEE_SOURCE_FILES} ${MOC_SOURCE_FILES})
add_executable(${PROJECT_NAME} ${CEE_SOURCE_FILES} ${CEE_HEADER_FILES} ${MOC_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CEE_LIBS} ${OPENGL_LIBRARIES} ${QT_LIBRARIES} ${SYSTEM_LIBRARIES})

View File

@@ -37,7 +37,7 @@
#pragma once
class QStringList;
#include <QStringList>
//==================================================================================================

View File

@@ -60,9 +60,12 @@ int main(int argc, char *argv[])
// On Linux, Qt will use the system locale, force number formatting settings back to "C" locale
setlocale(LC_NUMERIC,"C");
// These directories are correct when running from within visual studio
cvf::String testDataDir = "../../../Tests/TestData/";
cvf::String shaderDir = "../../../Tests/SnippetsBasis/Shaders/";
cvf::String testDataDir = "";
cvf::String shaderDir = "";
#ifdef CVF_CEEVIZ_ROOT_SOURCE_DIR
testDataDir = CVF_CEEVIZ_ROOT_SOURCE_DIR "/Tests/TestData/";
shaderDir = CVF_CEEVIZ_ROOT_SOURCE_DIR "/Tests/SnippetsBasis/Shaders/";
#endif
{
QSRCommandLineArgs cmdLineArgs;
@@ -95,6 +98,8 @@ int main(int argc, char *argv[])
// Comment in this line to be able to read the glsl directly from file
//cvf::ShaderSourceProvider::instance()->setSourceRepository(new cvf::ShaderSourceRepositoryFile("../../../LibRender/glsl/"));
cvf::LogManager* logManager = cvf::LogManager::instance();
logManager->logger("cee.cvf.OpenGL")->setLevel(cvf::Logger::LL_DEBUG);
QSRMainWindow window;
window.resize(1000, 800);;

View File

@@ -127,7 +127,7 @@ void QSRMainWindow::createActions()
}
m_activateLastUsedSnippetAction = new QAction("Load last used snippet", this);
m_activateLastUsedSnippetAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
m_activateLastUsedSnippetAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_L));
connect(m_activateLastUsedSnippetAction, SIGNAL(triggered()), SLOT(slotRunLastUsedSnippet()));
m_closeCurrentSnippetAction = new QAction("Close Current Snippet", this);
@@ -136,19 +136,19 @@ void QSRMainWindow::createActions()
// View menu
m_showHUDAction = new QAction("Show HUD", this);
m_showHUDAction->setCheckable(true);
m_showHUDAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_H));
m_showHUDAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_H));
connect(m_showHUDAction, SIGNAL(triggered()), SLOT(slotShowHUD()));
m_redrawAction = new QAction("Redraw view", this);
m_redrawAction ->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
m_redrawAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));
connect(m_redrawAction, SIGNAL(triggered()), SLOT(slotViewRedraw()));
m_multipleRedrawAction = new QAction("Redraw 10 times", this);
m_multipleRedrawAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
m_multipleRedrawAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_M));
connect(m_multipleRedrawAction, SIGNAL(triggered()), SLOT(slotViewMultipleRedraw()));
m_multipleRedrawManyAction = new QAction("Redraw 50 times", this);
m_multipleRedrawManyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_M));
m_multipleRedrawManyAction->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_M));
connect(m_multipleRedrawManyAction, SIGNAL(triggered()), SLOT(slotViewMultipleRedrawMany()));
@@ -302,8 +302,22 @@ void QSRMainWindow::createDockPanels()
//--------------------------------------------------------------------------------------------------
void QSRMainWindow::executeTestSnippetInNewWidget(const cvf::String& snippetId, TestSnippet* snippet)
{
cvf::Trace::show("Executing snippet: %s", snippetId.toAscii().ptr());
closeCurrentSnippet();
QWidget* parentWidget = centralWidget();
CVF_ASSERT(m_contextGroup.notNull());
#ifdef QSR_USE_OPENGLWIDGET
QSurfaceFormat surfFormat;
surfFormat.setSamples(m_formatMultisampleAction->isChecked() ? 8 : 0);
m_currentSnippetWidget = new QSRSnippetWidget(snippet, m_contextGroup.p(), parentWidget);
m_currentSnippetWidget->setFormat(surfFormat);
#else
QGLFormat glFormat;
glFormat.setDirectRendering(!m_formatSoftwareAction->isChecked());
@@ -320,9 +334,11 @@ void QSRMainWindow::executeTestSnippetInNewWidget(const cvf::String& snippetId,
// For FSAA, use with glEnable(GL_MULTISAMPLE);
//glFormat.setSampleBuffers(true);
QWidget* parentWidget = centralWidget();
CVF_ASSERT(m_contextGroup.notNull());
m_currentSnippetWidget = new QSRSnippetWidget(snippet, m_contextGroup.p(), glFormat, parentWidget);
#endif
m_currentSnippetWidget->setFocus();
if (m_formatMultisampleAction->isChecked())
@@ -344,7 +360,7 @@ void QSRMainWindow::executeTestSnippetInNewWidget(const cvf::String& snippetId,
// Store ID of this 'last run' snippet in registry
QSettings settings("Ceetron", "SnippetRunner");
settings.setValue("LastUsedSnippetID", snippetId.toAscii().ptr());
settings.setValue("LastUsedSnippetID", cvfqt::Utils::toQString(snippetId));
repaint();
}
@@ -537,6 +553,9 @@ void QSRMainWindow::slotViewMultipleRedrawMany()
//--------------------------------------------------------------------------------------------------
void QSRMainWindow::slotSaveFrameBufferToFile()
{
#ifdef QSR_USE_OPENGLWIDGET
cvf::Trace::show("NOT IMPLEMENTED!!");
#else
if (!m_currentSnippetWidget)
{
cvf::Trace::show("No current widget");
@@ -556,7 +575,7 @@ void QSRMainWindow::slotSaveFrameBufferToFile()
{
cvf::Trace::show("FAILED to saved image: %s", (const char*)fileName.toLatin1());
}
#endif
}
@@ -740,32 +759,49 @@ void QSRMainWindow::slotShowHelp()
}
// OpenGL info
cvf::OpenGLContext* currentOglContext = m_currentSnippetWidget->cvfOpenGLContext();
if (currentOglContext)
{
cvf::OpenGLInfo cvfOglInfo = currentOglContext->group()->info();
oglInfo = QString("OpenGL info:");
oglInfo += QString("\nversion:\t") + reinterpret_cast<const char*>(glGetString(GL_VERSION));
oglInfo += QString("\nrenderer:\t") + reinterpret_cast<const char*>(glGetString(GL_RENDERER));
oglInfo += QString("\nvendor:\t") + reinterpret_cast<const char*>(glGetString(GL_VENDOR));
oglInfo += QString("\nglsl ver.:\t") + reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
oglInfo += QString("\nversion: ") + cvfqt::Utils::toQString(cvfOglInfo.version());
oglInfo += QString("\nrenderer: ") + cvfqt::Utils::toQString(cvfOglInfo.renderer());
oglInfo += QString("\nvendor: ") + cvfqt::Utils::toQString(cvfOglInfo.vendor());
}
#ifdef QSR_USE_OPENGLWIDGET
{
oglInfo += "\n\nReported by Qt:";
QGLFormat currrentFormat = m_currentSnippetWidget->format();
oglInfo += "\n\nReported by Qt QSurfaceFormat:";
QSurfaceFormat currrentFormat = m_currentSnippetWidget->format();
oglInfo += QString("\nOpenGL version:\t%1.%2").arg(currrentFormat.majorVersion()).arg(currrentFormat.minorVersion());
switch (currrentFormat.profile())
{
case QGLFormat::NoProfile: oglInfo += "\nProfile:\t\tNoProfile (GLver < 3.3)"; break;
case QGLFormat::CoreProfile: oglInfo += "\nProfile:\t\tCoreProfile"; break;
case QGLFormat::CompatibilityProfile: oglInfo += "\nProfile:\t\tCompatibilityProfile"; break;
case QSurfaceFormat::NoProfile: oglInfo += "\nProfile:NoProfile (GLver < 3.3)"; break;
case QSurfaceFormat::CoreProfile: oglInfo += "\nProfile:CoreProfile"; break;
case QSurfaceFormat::CompatibilityProfile: oglInfo += "\nProfile:CompatibilityProfile"; break;
}
oglInfo += QString("\nColor buffer size:\t<%1 %2 %3 %4>").arg(currrentFormat.redBufferSize()).arg(currrentFormat.greenBufferSize()).arg(currrentFormat.blueBufferSize()).arg(currrentFormat.alphaBufferSize());
oglInfo += QString("\nDepth buffer size:\t%1").arg(currrentFormat.depthBufferSize());
oglInfo += QString("\nColor buffer size:<%1 %2 %3 %4>").arg(currrentFormat.redBufferSize()).arg(currrentFormat.greenBufferSize()).arg(currrentFormat.blueBufferSize()).arg(currrentFormat.alphaBufferSize());
oglInfo += QString("\nDepth buffer size:%1").arg(currrentFormat.depthBufferSize());
}
#else
{
oglInfo += "\n\nReported by Qt QGLFormat:";
QGLFormat currrentFormat = m_currentSnippetWidget->format();
oglInfo += QString("\nOpenGL version:\t%1.%2").arg(currrentFormat.majorVersion()).arg(currrentFormat.minorVersion());
switch (currrentFormat.profile())
{
case QGLFormat::NoProfile: oglInfo += "\nProfile:NoProfile (GLver < 3.3)"; break;
case QGLFormat::CoreProfile: oglInfo += "\nProfile:CoreProfile"; break;
case QGLFormat::CompatibilityProfile: oglInfo += "\nProfile:CompatibilityProfile"; break;
}
oglInfo += QString("\nColor buffer size:<%1 %2 %3 %4>").arg(currrentFormat.redBufferSize()).arg(currrentFormat.greenBufferSize()).arg(currrentFormat.blueBufferSize()).arg(currrentFormat.alphaBufferSize());
oglInfo += QString("\nDepth buffer size:%1").arg(currrentFormat.depthBufferSize());
}
#endif
}
QMessageBox dlg(this);

View File

@@ -40,10 +40,10 @@
#include "QSRTranslateEvent.h"
#include "cvfqtPerformanceInfoHud.h"
#include "cvfqtOpenGLContext.h"
#include <math.h>
#include <QPainter>
#include <QMouseEvent>
using cvfu::TestSnippet;
@@ -53,8 +53,13 @@ using cvfu::TestSnippet;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
#ifdef QSR_USE_OPENGLWIDGET
QSRSnippetWidget::QSRSnippetWidget(TestSnippet* snippet, cvf::OpenGLContextGroup* contextGroup, QWidget* parent)
: OglWidgetBaseClass(contextGroup, parent),
#else
QSRSnippetWidget::QSRSnippetWidget(TestSnippet* snippet, cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent)
: cvfqt::OpenGLWidget(contextGroup, format, parent),
: OglWidgetBaseClass(contextGroup, format, parent),
#endif
m_drawHUD(false),
m_lastSetRenderMode(DrawableGeo::VERTEX_ARRAY),
m_enableMultisampleWhenDrawing(false)
@@ -88,8 +93,6 @@ QSRSnippetWidget::~QSRSnippetWidget()
m_snippet->destroySnippet();
m_snippet = NULL;
}
cvfShutdownOpenGLContext();
}
@@ -526,6 +529,8 @@ void QSRSnippetWidget::showModelStatistics()
//--------------------------------------------------------------------------------------------------
void QSRSnippetWidget::initializeGL()
{
OglWidgetBaseClass::initializeGL();
CVF_ASSERT(m_snippet.notNull());
cvf::OpenGLContext* currentOglContext = cvfOpenGLContext();
@@ -534,6 +539,7 @@ void QSRSnippetWidget::initializeGL()
bool bInitOK = m_snippet->initializeSnippet(currentOglContext);
CVF_ASSERT(bInitOK);
CVF_UNUSED(bInitOK);
CVF_CHECK_OGL(currentOglContext);
@@ -595,7 +601,7 @@ void QSRSnippetWidget::paintEvent(QPaintEvent* /*event*/)
painter.beginNativePainting();
CVF_CHECK_OGL(currentOglContext);
cvfqt::OpenGLContext::saveOpenGLState(currentOglContext);
cvf::OpenGLUtils::pushOpenGLState(currentOglContext);
CVF_CHECK_OGL(currentOglContext);
if (m_enableMultisampleWhenDrawing)
@@ -612,7 +618,7 @@ void QSRSnippetWidget::paintEvent(QPaintEvent* /*event*/)
glDisable(GL_MULTISAMPLE);
}
cvfqt::OpenGLContext::restoreOpenGLState(currentOglContext);
cvf::OpenGLUtils::popOpenGLState(currentOglContext);
CVF_CHECK_OGL(currentOglContext);
if (postEventAction == cvfu::REDRAW)

View File

@@ -45,22 +45,35 @@
#include "cvfuTestSnippet.h"
#include "cvfqtOpenGLWidget.h"
class QTimer;
#define QSR_USE_OPENGLWIDGET
#ifdef QSR_USE_OPENGLWIDGET
#include "cvfqtOpenGLWidget.h"
typedef cvfqt::OpenGLWidget OglWidgetBaseClass;
#else
#include "cvfqtGLWidget.h"
typedef cvfqt::GLWidget OglWidgetBaseClass;
#endif
//==================================================================================================
//
//
//
//==================================================================================================
class QSRSnippetWidget : public cvfqt::OpenGLWidget
class QSRSnippetWidget : public OglWidgetBaseClass
{
Q_OBJECT
public:
#ifdef QSR_USE_OPENGLWIDGET
QSRSnippetWidget(cvfu::TestSnippet* snippet, cvf::OpenGLContextGroup* contextGroup, QWidget* parent);
#else
QSRSnippetWidget(cvfu::TestSnippet* snippet, cvf::OpenGLContextGroup* contextGroup, const QGLFormat& format, QWidget* parent);
#endif
~QSRSnippetWidget();
cvfu::TestSnippet* snippet();

View File

@@ -51,7 +51,7 @@ cvfu::MouseEvent QSRTranslateEvent::translateMouseEvent(int widgetHeight, const
Qt::MouseButtons qtButtons = event.buttons();
cvfu::MouseButtons buttons = cvfu::NoButton;
if (qtButtons & Qt::LeftButton) buttons |= cvfu::LeftButton;
if (qtButtons & Qt::MidButton) buttons |= cvfu::MiddleButton;
if (qtButtons & Qt::MiddleButton) buttons |= cvfu::MiddleButton;
if (qtButtons & Qt::RightButton) buttons |= cvfu::RightButton;
Qt::KeyboardModifiers qtModifiers = event.modifiers();
@@ -69,7 +69,7 @@ cvfu::MouseEvent QSRTranslateEvent::translateMouseEvent(int widgetHeight, const
cvfu::MouseButton QSRTranslateEvent::translateMouseButton(Qt::MouseButton qtMouseButton)
{
if (qtMouseButton == Qt::LeftButton) return cvfu::LeftButton;
if (qtMouseButton == Qt::MidButton) return cvfu::MiddleButton;
if (qtMouseButton == Qt::MiddleButton) return cvfu::MiddleButton;
if (qtMouseButton == Qt::RightButton) return cvfu::RightButton;
return cvfu::NoButton;

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -0,0 +1,58 @@
project(QtTestBenchOpenGLWidget)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STANDARD_CXX_FLAGS}")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long")
endif()
find_package(OpenGL)
if (CEE_USE_QT6)
find_package(Qt6 COMPONENTS REQUIRED OpenGLWidgets)
set(QT_LIBRARIES Qt6::OpenGLWidgets )
elseif (CEE_USE_QT5)
find_package(Qt5 REQUIRED COMPONENTS Widgets)
set(QT_LIBRARIES Qt5::Widgets)
else()
message(FATAL_ERROR "No supported Qt version selected for build")
endif()
include_directories(${LibCore_SOURCE_DIR})
include_directories(${LibGeometry_SOURCE_DIR})
include_directories(${LibRender_SOURCE_DIR})
include_directories(${LibViewing_SOURCE_DIR})
include_directories(${LibUtilities_SOURCE_DIR})
include_directories(${LibGuiQt_SOURCE_DIR})
set(CEE_LIBS LibGuiQt LibUtilities LibViewing LibRender LibGeometry LibIo LibCore)
set(CEE_CODE_FILES
QTBMain.cpp
QTBMainWindow.cpp
QTBMainWindow.h
QTBSceneFactory.cpp
QTBSceneFactory.h
QTBVizWidget.cpp
QTBVizWidget.h
)
# Headers that need MOCing
set(MOC_HEADER_FILES
QTBMainWindow.h
QTBVizWidget.h
)
if (CEE_USE_QT6)
qt_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES})
elseif (CEE_USE_QT5)
qt5_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES})
endif()
add_executable(${PROJECT_NAME} ${CEE_CODE_FILES} ${MOC_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CEE_LIBS} ${OPENGL_LIBRARIES} ${QT_LIBRARIES})

View File

@@ -0,0 +1,103 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include <QApplication>
#include "QTBMainWindow.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
// Used to get registry settings in the right place
QCoreApplication::setOrganizationName("CeetronSolutions");
QCoreApplication::setApplicationName("QtTestBenchOpenGLWidget");
// Note!
// The Qt::AA_ShareOpenGLContexts setting is needed when we have multiple viz widgets in flight
// and we have a setup where these widgets belong to different top-level windows, or end up
// belonging to different top-level windows through re-parenting.
// This is indeed the situation we encounter in this test application.
// For example:
// * Two viz widgets inside the same central widget => OK
// * Two viz widgets docked inside two different dock widgets => OK
// * One viz widget in docked dock widget and one viz widget in central widget => OK
// * Two viz widgets as different top level windows => FAIL
// * One viz widget in docked dock widget and one viz widget in floating dock widget => FAIL
// * One viz widget in central widget and one widget as top level window => FAIL
//
// In the failing situations the viz widgets should really belong to different context groups (which
// has it own implications), but as a workaround we can use the Qt::AA_ShareOpenGLContexts flag
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
// May want to do some further experimentation with these as well
//QApplication::setAttribute(Qt::AA_NativeWindows);
//QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
//QApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
//QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
//QApplication::setAttribute(Qt::AA_UseOpenGLES);
cvf::LogManager* logManager = cvf::LogManager::instance();
logManager->logger("cee.cvf.OpenGL")->setLevel(cvf::Logger::LL_DEBUG);
// To display logging from GLWidget::logOpenGLInfo()
logManager->logger("cee.cvf.qt")->setLevel(cvf::Logger::LL_INFO);
// For even more output
logManager->logger("cee.cvf.qt")->setLevel(cvf::Logger::LL_DEBUG);
QApplication app(argc, argv);
QTBMainWindow mainWindow;
mainWindow.setWindowTitle(QString("QtTestBenchOpenGLWidget (qtVer=%1)").arg(qVersion()));
mainWindow.resize(1000, 800);
mainWindow.show();
const int appRetCode = app.exec();
return appRetCode;
}

View File

@@ -0,0 +1,676 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QTBMainWindow.h"
#include "QTBVizWidget.h"
#include "QTBSceneFactory.h"
#include "cvfqtUtils.h"
#include <QFrame>
#include <QHBoxLayout>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QDockWidget>
#include <QSettings>
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QTBMainWindow::QTBMainWindow()
{
QFrame* mainFrame = new QFrame(this);
QVBoxLayout* layout = new QVBoxLayout(mainFrame);
mainFrame->setLayout(layout);
setCentralWidget(mainFrame);
m_dockWidget_1 = new QDockWidget("MyDockWidget_1", this);
m_dockWidget_1->setObjectName("myDockWidget_1");
addDockWidget(Qt::LeftDockWidgetArea, m_dockWidget_1);
m_dockWidget_2 = new QDockWidget("MyDockWidget_2", this);
m_dockWidget_2->setObjectName("myDockWidget_2");
addDockWidget(Qt::LeftDockWidgetArea, m_dockWidget_2);
resizeDocks({ m_dockWidget_1, m_dockWidget_2 }, { 200, 200 }, Qt::Horizontal);
//loadWinGeoAndDockToolBarLayout();
// The common context group must be created before launching any widgets
// If we don't create one, each widget will get its own context group
m_commonContextGroup = new cvf::OpenGLContextGroup;
addVizWidget(AddToCentralWidget);
addVizWidget(InDockWidget_1);
addVizWidget(InDockWidget_2);
addVizWidget(AsNewTopLevelWidget);
{
QMenu* menu = menuBar()->addMenu("&Widgets");
menu->addAction("Add VizWidget into CentralWidget", this, SLOT(slotAddVizWidget()))->setData(AddToCentralWidget);
menu->addAction("Add VizWidget as TopLevel", this, SLOT(slotAddVizWidget()))->setData(AsNewTopLevelWidget);
menu->addAction("Add VizWidget into DockWidget_1", this, SLOT(slotAddVizWidget()))->setData(InDockWidget_1);
menu->addAction("Add VizWidget into DockWidget_2", this, SLOT(slotAddVizWidget()))->setData(InDockWidget_2);
menu->addSeparator();
menu->addAction("Delete VizWidget", this, SLOT(slotDeleteVizWidget()));
menu->addSeparator();
menu->addAction("Reparent VizWidget into CentralWidget", this, SLOT(slotReparentVizWidgetIntoCentralWidget()));
menu->addAction("Reparent VizWidget as Top Level", this, SLOT(slotReparentVizWidgetAsTopLevel()));
menu->addAction("Move VizWidget to DockWidget_1", this, SLOT(slotMoveVizWidgetToDockWidget_1()));
menu->addAction("Move VizWidget to DockWidget_2", this, SLOT(slotMoveVizWidgetToDockWidget_2()));
menu->addSeparator();
menu->addAction("Reparent ALL VizWidgets into CentralWidget", this, SLOT(slotReparentAllVizWidgetsIntoCentralWidget()));
menu->addSeparator();
menu->addAction("Refresh VizWidget arr", this, SLOT(slotRefreshVizWidgetArr()));
}
{
QMenu* menu = menuBar()->addMenu("&Activate");
connect(menu, SIGNAL(aboutToShow()), SLOT(slotAboutToShowActivateMenu()));
}
{
QMenu* menu = menuBar()->addMenu("&Scenes");
menu->addAction("Create test scene", this, SLOT(slotCreateTestScene()));
menu->addAction("Clear scene", this, SLOT(slotClearScene()));
}
{
QMenu* menu = menuBar()->addMenu("&Test");
menu->addAction("Save layout", this, SLOT(slotSaveLayout()));
menu->addAction("Restore layout", this, SLOT(slotRestoreLayout()));
menu->addSeparator();
menu->addAction("Grab a native handle", this, SLOT(slotGrabNativeHandle()));
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QTBMainWindow::~QTBMainWindow()
{
cvf::Trace::show("QTBMainWindow::~QTBMainWindow()");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::addVizWidget(NewWidgetPlacement newWidgetPlacement)
{
// Guard against creating duplicate viewers inside dock widgets
if (newWidgetPlacement == InDockWidget_1 && m_dockWidget_1->widget())
{
cvf::Trace::show("DockWidget_1 already contains a viewer");
return;
}
if (newWidgetPlacement == InDockWidget_2 && m_dockWidget_2->widget())
{
cvf::Trace::show("DockWidget_2 already contains a viewer");
return;
}
removeStaleEntriesFromVizWidgetArr();
QWidget* parentToUseOnConstruction = this;
//QWidget* parentToUseOnConstruction = NULL;
// Use the common context group if we have one - otherwise create a new context group per widget
cvf::ref<cvf::OpenGLContextGroup> contextGroupToUse = m_commonContextGroup;
if (contextGroupToUse.isNull())
{
contextGroupToUse = new cvf::OpenGLContextGroup;
}
QTBVizWidget* newVizWidget = newVizWidget = new QTBVizWidget(contextGroupToUse.p(), parentToUseOnConstruction, this);
m_vizWidgetArr.push_back(newVizWidget);
// Place the widget where instructed
if (newWidgetPlacement == AddToCentralWidget)
{
centralWidget()->layout()->addWidget(newVizWidget);
}
else if (newWidgetPlacement == AsNewTopLevelWidget)
{
newVizWidget->setParent(nullptr);
newVizWidget->resize(400, 300);
newVizWidget->move(50, 200);
newVizWidget->show();
}
else if (newWidgetPlacement == InDockWidget_1)
{
m_dockWidget_1->setWidget(newVizWidget);
newVizWidget->show();
}
else if (newWidgetPlacement == InDockWidget_2)
{
m_dockWidget_2->setWidget(newVizWidget);
newVizWidget->show();
}
assignViewTitlesToVizWidgetsInArr();
decideNewActiveVizWidgetAndHighlight();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::handleVizWidgetIsOpenGLReady(QTBVizWidget* vizWidget)
{
cvf::Trace::show("QTBMainWindow::handleVizWidgetIsOpenGLReady()");
CVF_ASSERT(vizWidget->isValid());
cvf::OpenGLContext* oglContext = vizWidget->cvfOpenGLContext();
cvf::OpenGLContextGroup* oglContextGroup = oglContext->group();
CVF_ASSERT(oglContextGroup->isContextGroupInitialized());
if (m_commonContextGroup.notNull())
{
CVF_ASSERT(m_commonContextGroup == oglContextGroup);
CVF_ASSERT(m_commonContextGroup->containsContext(oglContext));
populateAllValidVizWidgetsWithTestScene(true);
}
else
{
populateAllValidVizWidgetsWithTestScene(false);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::populateAllValidVizWidgetsWithTestScene(bool allWidgetsShareSameScene)
{
if (allWidgetsShareSameScene)
{
cvf::ref<cvf::Scene> sceneToShow;
// Look for an existing scene
for (auto vizWidget : m_vizWidgetArr)
{
if (vizWidget->isValid() && vizWidget->scene())
{
sceneToShow = vizWidget->scene();
break;
}
}
if (sceneToShow.isNull())
{
QTBVizWidget* firstValidVizWidget = nullptr;
for (auto vizWidget : m_vizWidgetArr)
{
if (vizWidget->isValid())
{
firstValidVizWidget = vizWidget;
break;
}
}
if (!firstValidVizWidget)
{
cvf::Trace::show("Could not find any valid VizWidgets");
return;
}
cvf::OpenGLContext* oglContext = firstValidVizWidget->cvfOpenGLContext();
CVF_ASSERT(oglContext);
const cvf::OpenGLCapabilities capabilities = *(oglContext->capabilities());
const bool useShaders = capabilities.supportsOpenGL2();
QTBSceneFactory sceneFactory(useShaders);
sceneToShow = sceneFactory.createTestScene(capabilities);
}
for (auto vizWidget : m_vizWidgetArr)
{
vizWidget->setScene(sceneToShow.p());
vizWidget->update();
}
}
else
{
for (auto vizWidget : m_vizWidgetArr)
{
if (vizWidget->isValid() && !vizWidget->scene())
{
cvf::OpenGLContext* oglContext = vizWidget->cvfOpenGLContext();
CVF_ASSERT(oglContext);
const cvf::OpenGLCapabilities capabilities = *(oglContext->capabilities());
const bool useShaders = capabilities.supportsOpenGL2();
QTBSceneFactory sceneFactory(useShaders);
cvf::ref<cvf::Scene> scene = sceneFactory.createTestScene(capabilities);
vizWidget->setScene(scene.p());
vizWidget->update();
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::removeStaleEntriesFromVizWidgetArr()
{
std::vector<QPointer<QTBVizWidget> > oldArr = m_vizWidgetArr;
m_vizWidgetArr.clear();
for (size_t i = 0; i < oldArr.size(); i++)
{
QTBVizWidget* vizWidget = oldArr[i];
if (vizWidget)
{
m_vizWidgetArr.push_back(vizWidget);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::assignViewTitlesToVizWidgetsInArr()
{
for (size_t i = 0; i < m_vizWidgetArr.size(); i++)
{
QTBVizWidget* vizWidget = m_vizWidgetArr[i];
if (vizWidget)
{
vizWidget->setViewTitle(cvf::String("view_%1").arg(static_cast<int>(i)));
vizWidget->update();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::String> QTBMainWindow::vizWidgetNames()
{
std::vector<cvf::String> nameArr;
for (auto vizWidget : m_vizWidgetArr)
{
nameArr.push_back(vizWidget->viewTitle());
}
return nameArr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::decideNewActiveVizWidgetAndHighlight()
{
// For now, simply choose the last one
m_activeVizWidgetName = "";
const std::vector<cvf::String> nameArr = vizWidgetNames();
if (nameArr.size() > 0)
{
m_activeVizWidgetName = nameArr.back();
}
highlightActiveVizWidget();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::highlightActiveVizWidget()
{
for (auto vizWidget : m_vizWidgetArr)
{
const bool isActive = vizWidget->viewTitle() == m_activeVizWidgetName;
vizWidget->setViewTitleHighlighted(isActive);
vizWidget->update();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QTBVizWidget* QTBMainWindow::getActiveVizWidget()
{
if (m_vizWidgetArr.size() == 0)
{
cvf::Trace::show("Could not get active VizWidget, no widgets present");
return nullptr;
}
for (auto vizWidget : m_vizWidgetArr)
{
if (vizWidget->viewTitle() == m_activeVizWidgetName)
{
return vizWidget;
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::saveWinGeoAndDockToolBarLayout()
{
QSettings settings;
settings.setValue("winGeometry", saveGeometry());
settings.setValue("dockAndToolBarLayout", saveState(0));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::loadWinGeoAndDockToolBarLayout()
{
QSettings settings;
QVariant winGeo = settings.value("winGeometry");
QVariant layout = settings.value("dockAndToolBarLayout");
if (winGeo.isValid())
{
if (restoreGeometry(winGeo.toByteArray()))
{
if (layout.isValid())
{
restoreState(layout.toByteArray(), 0);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::closeEvent(QCloseEvent* event)
{
cvf::Trace::show("QTBMainWindow::closeEvent()");
QMainWindow::closeEvent(event);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotAddVizWidget()
{
QAction* senderAction = dynamic_cast<QAction*>(sender());
const int newWidgetPlacementInt = senderAction->data().toInt();
NewWidgetPlacement newWidgetPlacement = static_cast<NewWidgetPlacement>(newWidgetPlacementInt);
addVizWidget(newWidgetPlacement);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotDeleteVizWidget()
{
removeStaleEntriesFromVizWidgetArr();
QTBVizWidget* vizWidget = getActiveVizWidget();
if (!vizWidget)
{
return;
}
delete vizWidget;
removeStaleEntriesFromVizWidgetArr();
assignViewTitlesToVizWidgetsInArr();
decideNewActiveVizWidgetAndHighlight();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotReparentVizWidgetIntoCentralWidget()
{
QTBVizWidget* vizWidget = getActiveVizWidget();
if (!vizWidget)
{
return;
}
CVF_ASSERT(vizWidget->isValid());
centralWidget()->layout()->addWidget(vizWidget);
vizWidget->show();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotReparentVizWidgetAsTopLevel()
{
QTBVizWidget* vizWidget = getActiveVizWidget();
if (!vizWidget)
{
return;
}
CVF_ASSERT(vizWidget->isValid());
vizWidget->setParent(nullptr);
vizWidget->move(100, 100);
vizWidget->resize(600, 400);
vizWidget->show();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotMoveVizWidgetToDockWidget_1()
{
if (m_dockWidget_1->widget())
{
cvf::Trace::show("DockWidget_1 already contains a vizWiget");
return;
}
QTBVizWidget* vizWidget = getActiveVizWidget();
if (!vizWidget)
{
return;
}
CVF_ASSERT(vizWidget->isValid());
m_dockWidget_1->setWidget(vizWidget);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotMoveVizWidgetToDockWidget_2()
{
if (m_dockWidget_2->widget())
{
cvf::Trace::show("DockWidget_2 already contains a vizWiget");
return;
}
QTBVizWidget* vizWidget = getActiveVizWidget();
if (!vizWidget)
{
return;
}
CVF_ASSERT(vizWidget->isValid());
m_dockWidget_2->setWidget(vizWidget);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotReparentAllVizWidgetsIntoCentralWidget()
{
for (size_t i = 0; i < m_vizWidgetArr.size(); i++)
{
QTBVizWidget* vizWidget = m_vizWidgetArr[i];
if (vizWidget)
{
centralWidget()->layout()->addWidget(vizWidget);
vizWidget->show();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotRefreshVizWidgetArr()
{
const size_t numWidgetsBefore = m_vizWidgetArr.size();
removeStaleEntriesFromVizWidgetArr();
assignViewTitlesToVizWidgetsInArr();
const size_t numWidgetsAfter = m_vizWidgetArr.size();
cvf::Trace::show("Refreshed VizWidgetArr, oldCount=%d newCount=%d", numWidgetsBefore, numWidgetsAfter);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotAboutToShowActivateMenu()
{
QMenu* senderMenu = dynamic_cast<QMenu*>(sender());
CVF_ASSERT(senderMenu);
senderMenu->clear();
const std::vector<cvf::String> nameArr = vizWidgetNames();
for (auto widgetName : nameArr)
{
const QString qstrWidgetName(cvfqt::Utils::toQString(widgetName));
senderMenu->addAction(qstrWidgetName, this, SLOT(slotSomeVizWidgetActivated()))->setData(qstrWidgetName);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotSomeVizWidgetActivated()
{
QAction* senderAction = dynamic_cast<QAction*>(sender());
CVF_ASSERT(senderAction);
const QString qstrWidgetName = senderAction->data().toString();
m_activeVizWidgetName = cvfqt::Utils::toString(qstrWidgetName);
highlightActiveVizWidget();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotCreateTestScene()
{
if (m_vizWidgetArr.size() == 0)
{
return;
}
const bool allWidgetsShareSameScene = m_commonContextGroup.notNull() ? true : false;
populateAllValidVizWidgetsWithTestScene(allWidgetsShareSameScene);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotClearScene()
{
for (size_t i = 0; i < m_vizWidgetArr.size(); i++)
{
QTBVizWidget* vizWidget = m_vizWidgetArr[i];
CVF_ASSERT(vizWidget);
vizWidget->setScene(nullptr);
vizWidget->update();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotSaveLayout()
{
saveWinGeoAndDockToolBarLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotRestoreLayout()
{
loadWinGeoAndDockToolBarLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBMainWindow::slotGrabNativeHandle()
{
QTBVizWidget* vizWidget = getActiveVizWidget();
if (!vizWidget)
{
return;
}
CVF_ASSERT(vizWidget->isValid());
cvf::String vizWidgetName = vizWidget->viewTitle();
cvf::Trace::show("Trying to get native handle for %s by calling QWidget::winId()", vizWidgetName.toAscii().ptr());
// Calling this seems to wreak havoc for Qt itself.
// For Qt5 it seems that under certain circumstances it will work, BUT for Qt6 it basically breaks the entire app
WId theWinId = vizWidget->winId();
cvf::Trace::show("Got WinId = 0x%x", (cvf::uint64)(theWinId));
}

View File

@@ -0,0 +1,118 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "QTBVizWidget.h"
#include <QMainWindow>
#include <QPointer>
//==================================================================================================
//
//
//
//==================================================================================================
class QTBMainWindow : public QMainWindow
{
Q_OBJECT
public:
QTBMainWindow();
~QTBMainWindow();
void handleVizWidgetIsOpenGLReady(QTBVizWidget* vizWidget);
private:
enum NewWidgetPlacement
{
AddToCentralWidget,
AsNewTopLevelWidget,
InDockWidget_1,
InDockWidget_2
};
private:
void addVizWidget(NewWidgetPlacement newWidgetPlacement);
void populateAllValidVizWidgetsWithTestScene(bool allWidgetsShareSameScene);
void removeStaleEntriesFromVizWidgetArr();
void assignViewTitlesToVizWidgetsInArr();
std::vector<cvf::String> vizWidgetNames();
void decideNewActiveVizWidgetAndHighlight();
void highlightActiveVizWidget();
QTBVizWidget* getActiveVizWidget();
void saveWinGeoAndDockToolBarLayout();
void loadWinGeoAndDockToolBarLayout();
virtual void closeEvent(QCloseEvent* event);
private slots:
void slotAddVizWidget();
void slotDeleteVizWidget();
void slotReparentVizWidgetIntoCentralWidget();
void slotReparentVizWidgetAsTopLevel();
void slotMoveVizWidgetToDockWidget_1();
void slotMoveVizWidgetToDockWidget_2();
void slotReparentAllVizWidgetsIntoCentralWidget();
void slotRefreshVizWidgetArr();
void slotAboutToShowActivateMenu();
void slotSomeVizWidgetActivated();
void slotCreateTestScene();
void slotClearScene();
void slotSaveLayout();
void slotRestoreLayout();
void slotGrabNativeHandle();
private:
cvf::ref<cvf::OpenGLContextGroup> m_commonContextGroup;
std::vector<QPointer<QTBVizWidget>> m_vizWidgetArr;
cvf::String m_activeVizWidgetName;
QPointer<QDockWidget> m_dockWidget_1;
QPointer<QDockWidget> m_dockWidget_2;
QPointer<QAction> m_setWorkingVizWidgetFirstAction;
QPointer<QAction> m_setWorkingVizWidgetLastAction;
};

View File

@@ -0,0 +1,291 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QTBSceneFactory.h"
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QTBSceneFactory::QTBSceneFactory(bool useShaders)
: m_useShaders(useShaders)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Scene> QTBSceneFactory::createTestScene(const cvf::OpenGLCapabilities& capabilities) const
{
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
cvf::ShaderProgramGenerator spGen("MyStandardHeadlight", cvf::ShaderSourceProvider::instance());
spGen.configureStandardHeadlightColor();
cvf::ref<cvf::ShaderProgram> shaderProg = spGen.generate();
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createSphere(2, 10, 10, &builder);
cvf::ref<cvf::Effect> eff = new cvf::Effect;
if (m_useShaders)
{
eff->setShaderProgram(shaderProg.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::GREEN)));
}
else
{
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE));
}
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName("MySphere");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
model->addPart(part.p());
}
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createBox(cvf::Vec3f(5, 0, 0), 2, 3, 4, &builder);
cvf::ref<cvf::Effect> eff = new cvf::Effect;
if (m_useShaders)
{
eff->setShaderProgram(shaderProg.p());
eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(cvf::Color3::YELLOW)));
}
else
{
eff->setRenderState(new cvf::RenderStateMaterial_FF(cvf::Color3::RED));
}
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName("MyBox");
part->setDrawable(0, builder.drawableGeo().p());
part->setEffect(eff.p());
model->addPart(part.p());
}
model->addPart(createTexturedPart(capabilities).p());
model->addPart(createDrawableTextPart(capabilities).p());
model->updateBoundingBoxesRecursive();
cvf::ref<cvf::Scene> scene = new cvf::Scene;
scene->addModel(model.p());
return scene;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> QTBSceneFactory::createQuadGeoWithTexCoords(const cvf::Vec3f& origin, const cvf::Vec3f& u, const cvf::Vec3f& v)
{
cvf::ref<cvf::Vec3fArray> vertices = new cvf::Vec3fArray(4);
vertices->set(0, origin);
vertices->set(1, origin + u);
vertices->set(2, origin + u + v);
vertices->set(3, origin + v);
cvf::ref<cvf::Vec2fArray> texCoords = new cvf::Vec2fArray(4);
texCoords->set(0, cvf::Vec2f(0, 0));
texCoords->set(1, cvf::Vec2f(1, 0));
texCoords->set(2, cvf::Vec2f(1, 1));
texCoords->set(3, cvf::Vec2f(0, 1));
const cvf::uint conns[6] = { 0, 1, 2, 0, 2, 3};
cvf::ref<cvf::UIntArray> indices = new cvf::UIntArray(conns, 6);
cvf::ref<cvf::PrimitiveSetIndexedUInt> primSet = new cvf::PrimitiveSetIndexedUInt(cvf::PT_TRIANGLES);
primSet->setIndices(indices.p());
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray(vertices.p());
geo->setTextureCoordArray(texCoords.p());
geo->addPrimitiveSet(primSet.p());
geo->computeNormals();
return geo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::TextureImage> QTBSceneFactory::create4x4ColoredImage()
{
// Create a simple 4x4 texture with 16 unique colors
cvf::ref<cvf::TextureImage> textureImage = new cvf::TextureImage;
{
cvf::ref<cvf::Color4ubArray> textureData = new cvf::Color4ubArray;
textureData->reserve(16);
textureData->add(cvf::Color4ub(cvf::Color3::RED));
textureData->add(cvf::Color4ub(cvf::Color3::GREEN));
textureData->add(cvf::Color4ub(cvf::Color3::BLUE));
textureData->add(cvf::Color4ub(cvf::Color3::YELLOW));
textureData->add(cvf::Color4ub(cvf::Color3::CYAN));
textureData->add(cvf::Color4ub(cvf::Color3::MAGENTA));
textureData->add(cvf::Color4ub(cvf::Color3::INDIGO));
textureData->add(cvf::Color4ub(cvf::Color3::OLIVE));
textureData->add(cvf::Color4ub(cvf::Color3::LIGHT_GRAY));
textureData->add(cvf::Color4ub(cvf::Color3::BROWN));
textureData->add(cvf::Color4ub(cvf::Color3::CRIMSON));
textureData->add(cvf::Color4ub(cvf::Color3::DARK_BLUE));
textureData->add(cvf::Color4ub(cvf::Color3::DARK_CYAN));
textureData->add(cvf::Color4ub(cvf::Color3::DARK_GREEN));
textureData->add(cvf::Color4ub(cvf::Color3::DARK_MAGENTA));
textureData->add(cvf::Color4ub(cvf::Color3::DARK_ORANGE));
textureImage->setData(textureData->ptr()->ptr(), 4, 4);
}
CVF_ASSERT(textureImage->pixel(1, 0) == cvf::Color4ub(cvf::Color3::GREEN));
CVF_ASSERT(textureImage->pixel(2, 0) == cvf::Color4ub(cvf::Color3::BLUE));
return textureImage;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> QTBSceneFactory::createTexturedPart(const cvf::OpenGLCapabilities& capabilities) const
{
cvf::ref<cvf::DrawableGeo> geo = createQuadGeoWithTexCoords(cvf::Vec3f(2, 2, 0), cvf::Vec3f(2, 0, 0), cvf::Vec3f(0, 3, 0));
cvf::ref<cvf::TextureImage> textureImage = create4x4ColoredImage();
cvf::ref<cvf::Effect> eff = new cvf::Effect;
if (m_useShaders)
{
cvf::ref<cvf::Texture> texture = new cvf::Texture(textureImage.p());
cvf::ref<cvf::Sampler> sampler = new cvf::Sampler;
sampler->setMinFilter(cvf::Sampler::LINEAR);
sampler->setMagFilter(cvf::Sampler::NEAREST);
sampler->setWrapModeS(cvf::Sampler::REPEAT);
sampler->setWrapModeT(cvf::Sampler::REPEAT);
cvf::ref<cvf::RenderStateTextureBindings> textureBindings = new cvf::RenderStateTextureBindings;
textureBindings->addBinding(texture.p(), sampler.p(), "u_texture2D");
eff->setRenderState(textureBindings.p());
cvf::ShaderProgramGenerator spGen("MyTexturedStandardHeadlight", cvf::ShaderSourceProvider::instance());
spGen.configureStandardHeadlightTexture();
cvf::ref<cvf::ShaderProgram> shaderProg = spGen.generate();
eff->setShaderProgram(shaderProg.p());
}
else
{
cvf::ref<cvf::Texture2D_FF> texture = new cvf::Texture2D_FF(textureImage.p());
texture->setMinFilter(cvf::Texture2D_FF::LINEAR);
texture->setMagFilter(cvf::Texture2D_FF::NEAREST);
texture->setWrapMode(cvf::Texture2D_FF::REPEAT);
cvf::ref<cvf::RenderStateTextureMapping_FF> textureMapping = new cvf::RenderStateTextureMapping_FF(texture.p());
eff->setRenderState(textureMapping.p());
}
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName("MyTexturedQuad");
part->setDrawable(0, geo.p());
part->setEffect(eff.p());
return part;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> QTBSceneFactory::createDrawableTextPart(const cvf::OpenGLCapabilities& capabilities) const
{
static int sl_callCount = 0;
cvf::String textStr = cvf::String("Test text string %1").arg(sl_callCount++);
cvf::ref<cvf::DrawableText> drawableText = new cvf::DrawableText;
drawableText->setFont(new cvf::FixedAtlasFont(cvf::FixedAtlasFont::LARGE));
drawableText->setTextColor(cvf::Color3::RED);
drawableText->addText(textStr, cvf::Vec3f(2, 2, 0));
drawableText->setCheckPosVisible(false);
cvf::ref<cvf::RenderStateBlending> blending = new cvf::RenderStateBlending;
blending->configureTransparencyBlending();
cvf::ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState(blending.p());
if (m_useShaders)
{
cvf::ShaderProgramGenerator spGen("MyTextShaderProgram", cvf::ShaderSourceProvider::instance());
spGen.addVertexCode(cvf::ShaderSourceRepository::vs_MinimalTexture);
spGen.addFragmentCode(cvf::ShaderSourceRepository::fs_Text);
cvf::ref<cvf::ShaderProgram> shaderProg = spGen.generate();
shaderProg->disableUniformTrackingForUniform("u_texture2D");
shaderProg->disableUniformTrackingForUniform("u_color");
eff->setShaderProgram(shaderProg.p());
}
cvf::ref<cvf::Part> part = new cvf::Part;
part->setDrawable(drawableText.p());
part->setEffect(eff.p());
return part;
}

View File

@@ -34,40 +34,31 @@
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfScene.h"
#include "cvfOpenGLContext.h"
class QGLContext;
namespace cvfqt {
//==================================================================================================
//
// Derived OpenGLContext that adapts a Qt QGLContext
//
//
//==================================================================================================
class OpenGLContext : public cvf::OpenGLContext
class QTBSceneFactory
{
public:
OpenGLContext(cvf::OpenGLContextGroup* contextGroup, QGLContext* backingQGLContext);
virtual ~OpenGLContext();
QTBSceneFactory(bool useShaders);
virtual bool initializeContext();
virtual void makeCurrent();
virtual bool isCurrent() const;
static void saveOpenGLState(cvf::OpenGLContext* oglContext);
static void restoreOpenGLState(cvf::OpenGLContext* oglContext);
cvf::ref<cvf::Scene> createTestScene(const cvf::OpenGLCapabilities& capabilities) const;
private:
QGLContext* m_qtGLContext;
bool m_isCoreOpenGLProfile; // This is a Core OpenGL profile. Implies OpenGL version of 3.2 or more
int m_majorVersion; // OpenGL version as reported by Qt
int m_minorVersion;
cvf::ref<cvf::Part> createTexturedPart(const cvf::OpenGLCapabilities& capabilities) const;
cvf::ref<cvf::Part> createDrawableTextPart(const cvf::OpenGLCapabilities& capabilities) const;
static cvf::ref<cvf::DrawableGeo> createQuadGeoWithTexCoords(const cvf::Vec3f& origin, const cvf::Vec3f& u, const cvf::Vec3f& v);
static cvf::ref<cvf::TextureImage> create4x4ColoredImage();
private:
bool m_useShaders;
};
}

View File

@@ -0,0 +1,333 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "cvfLibRender.h"
#include "cvfLibGeometry.h"
#include "cvfLibViewing.h"
#include "QTBVizWidget.h"
#include "QTBMainWindow.h"
#include <QMouseEvent>
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QTBVizWidget::QTBVizWidget(cvf::OpenGLContextGroup* contextGroup, QWidget* parent, QTBMainWindow* mainWindow)
: cvfqt::OpenGLWidget(contextGroup, parent),
m_mainWindow(mainWindow)
{
cvf::Trace::show("QTBVizWidget[%d]::QTBVizWidget()", instanceNumber());
initializeMembers();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::initializeMembers()
{
m_camera = new cvf::Camera;
cvf::ref<cvf::Rendering> rendering = new cvf::Rendering;
rendering->setCamera(m_camera.p());
cvf::ref<cvf::FixedAtlasFont> font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD);
rendering->addOverlayItem(new cvf::OverlayAxisCross(m_camera.p(), font.p()));
m_titleOverlayTextBox = new cvf::OverlayTextBox(font.p());
m_titleOverlayTextBox->setText("N/A");
m_titleOverlayTextBox->setSizeToFitText();
m_titleOverlayTextBox->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::TOP_LEFT);
rendering->addOverlayItem(m_titleOverlayTextBox.p());
m_renderSequence = new cvf::RenderSequence;
m_renderSequence->addRendering(rendering.p());
m_trackball = new cvf::ManipulatorTrackball;
m_trackball->setCamera(m_camera.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::onWidgetOpenGLReady()
{
cvf::Trace::show("QTBVizWidget[%d]::onWidgetOpenGLReady()", instanceNumber());
m_mainWindow->handleVizWidgetIsOpenGLReady(this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QTBVizWidget::~QTBVizWidget()
{
cvf::Trace::show("QTBVizWidget[%d]::~QTBVizWidget()", instanceNumber());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::setViewTitle(cvf::String viewTitle)
{
if (m_titleOverlayTextBox.isNull())
{
return;
}
m_titleOverlayTextBox->setText(viewTitle);
m_titleOverlayTextBox->setSizeToFitText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::String QTBVizWidget::viewTitle()
{
if (m_titleOverlayTextBox.isNull())
{
return cvf::String();
}
return m_titleOverlayTextBox->text();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::setViewTitleHighlighted(bool highlighted)
{
if (m_titleOverlayTextBox.isNull())
{
return;
}
const cvf::Color3f clr = highlighted ? cvf::Color3f(1.0f, 0.2f, 0.2f) : cvf::Color3f(0.2f, 0.2f, 1.0f);
m_titleOverlayTextBox->setBackgroundColor(clr);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::setScene(cvf::Scene* scene)
{
cvf::ref<cvf::Rendering> rendering = m_renderSequence->firstRendering();
CVF_ASSERT(rendering.notNull());
rendering->setScene(scene);
if (scene)
{
cvf::BoundingBox bb = scene->boundingBox();
if (bb.isValid())
{
m_camera->fitView(bb, -cvf::Vec3d::Z_AXIS, cvf::Vec3d::Y_AXIS);
m_trackball->setRotationPoint(bb.center());
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Scene* QTBVizWidget::scene()
{
cvf::ref<cvf::Rendering> rendering = m_renderSequence->firstRendering();
CVF_ASSERT(rendering.notNull());
return rendering->scene();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OpenGLContext* QTBVizWidget::cvfOpenGLContext()
{
return cvfqt::OpenGLWidget::cvfOpenGLContext();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::initializeGL()
{
cvf::Trace::show("QTBVizWidget[%d]::initializeGL()", instanceNumber());
cvfqt::OpenGLWidget::initializeGL();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::resizeGL(int width, int height)
{
cvf::Trace::show("QTBVizWidget[%d]::resizeGL() w=%d h=%d", instanceNumber(), width, height);
if (m_camera.notNull())
{
m_camera->viewport()->set(0, 0, width, height);
m_camera->setProjectionAsPerspective(m_camera->fieldOfViewYDeg(), m_camera->nearPlane(), m_camera->farPlane());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::paintGL()
{
const int w = width();
const int h = height();
cvf::Trace::show("QTBVizWidget[%d]::paintGL(), w=%d h=%d", instanceNumber(), w, h);
// According to Qt docs, context should already be current
cvf::OpenGLContext* currentOglContext = cvfOpenGLContext();
CVF_ASSERT(currentOglContext);
CVF_CHECK_OGL(currentOglContext);
cvf::OpenGLUtils::pushOpenGLState(currentOglContext);
if (m_renderSequence.notNull())
{
m_renderSequence->render(currentOglContext);
}
cvf::OpenGLUtils::popOpenGLState(currentOglContext);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::mouseMoveEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
Qt::MouseButtons mouseBn = event->buttons();
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
const int posX = event->position().toPoint().x();
const int posY = height() - event->position().toPoint().y();
#else
const int posX = event->x();
const int posY = height() - event->y();
#endif
cvf::ManipulatorTrackball::NavigationType navType = cvf::ManipulatorTrackball::NONE;
if (mouseBn == Qt::LeftButton)
{
navType = cvf::ManipulatorTrackball::PAN;
}
else if (mouseBn == Qt::RightButton)
{
navType = cvf::ManipulatorTrackball::ROTATE;
}
else if (mouseBn == (Qt::LeftButton | Qt::RightButton) || mouseBn == Qt::MiddleButton)
{
navType = cvf::ManipulatorTrackball::WALK;
}
if (navType != m_trackball->activeNavigation())
{
m_trackball->startNavigation(navType, posX, posY);
}
bool needRedraw = m_trackball->updateNavigation(posX, posY);
if (needRedraw)
{
update();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::mousePressEvent(QMouseEvent* event)
{
if (m_renderSequence.isNull()) return;
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
const int posX = event->position().toPoint().x();
const int posY = height() - event->position().toPoint().y();
#else
const int posX = event->x();
const int posY = height() - event->y();
#endif
if (event->buttons() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier)
{
cvf::Rendering* r = m_renderSequence->firstRendering();
cvf::ref<cvf::RayIntersectSpec> ris = r->rayIntersectSpecFromWindowCoordinates(posX, posY);
cvf::HitItemCollection hic;
if (r->rayIntersect(*ris, &hic))
{
cvf::HitItem* item = hic.firstItem();
CVF_ASSERT(item && item->part());
cvf::Vec3d isect = item->intersectionPoint();
m_trackball->setRotationPoint(isect);
cvf::Trace::show("hitting part: '%s' coords: %.3f %.3f %.3f", item->part()->name().toAscii().ptr(), isect.x(), isect.y(), isect.z());
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::mouseReleaseEvent(QMouseEvent* /*event*/)
{
m_trackball->endNavigation();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QTBVizWidget::closeEvent(QCloseEvent* event)
{
cvf::Trace::show("QTBVizWidget[%d]::closeEvent()", instanceNumber());
cvfqt::OpenGLWidget::closeEvent(event);
}

View File

@@ -0,0 +1,95 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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 <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfRenderSequence.h"
#include "cvfManipulatorTrackball.h"
#include "cvfScene.h"
#include "cvfOpenGLContextGroup.h"
#include "cvfOverlayTextBox.h"
#include "cvfqtOpenGLWidget.h"
#include <QPointer>
class QTBMainWindow;
//==================================================================================================
//
//
//
//==================================================================================================
class QTBVizWidget : public cvfqt::OpenGLWidget
{
Q_OBJECT
public:
QTBVizWidget(cvf::OpenGLContextGroup* contextGroup, QWidget* parent, QTBMainWindow* mainWindow);
~QTBVizWidget();
void setViewTitle(cvf::String viewTitle);
cvf::String viewTitle();
void setViewTitleHighlighted(bool highlighted);
void setScene(cvf::Scene* scene);
cvf::Scene* scene();
cvf::OpenGLContext* cvfOpenGLContext();
private:
virtual void initializeGL();
virtual void resizeGL(int width, int height);
virtual void paintGL();
virtual void mousePressEvent(QMouseEvent* event);
virtual void mouseMoveEvent(QMouseEvent* event);
virtual void mouseReleaseEvent(QMouseEvent* event);
virtual void closeEvent(QCloseEvent *event);
void initializeMembers();
virtual void onWidgetOpenGLReady();
private:
QPointer<QTBMainWindow> m_mainWindow;
cvf::ref<cvf::RenderSequence> m_renderSequence;
cvf::ref<cvf::Camera> m_camera;
cvf::ref<cvf::ManipulatorTrackball> m_trackball;
cvf::ref<cvf::OverlayTextBox> m_titleOverlayTextBox;
};

View File

@@ -119,7 +119,9 @@ bool Win32OpenGLContext::createHardwareContext(HWND hWnd)
m_hDC = hDC;
m_hRC = hRC;
if (initializeContext())
cvf::OpenGLContextGroup* ownerContextGroup = group();
CVF_ASSERT(ownerContextGroup);
if (ownerContextGroup->initializeContextGroup(this))
{
return true;
}
@@ -136,7 +138,11 @@ bool Win32OpenGLContext::createHardwareContext(HWND hWnd)
void Win32OpenGLContext::shutdownContext()
{
// Clears up resources and removes us from our group
cvf::OpenGLContext::shutdownContext();
cvf::OpenGLContextGroup* ownerContextGroup = group();
CVF_ASSERT(ownerContextGroup);
makeCurrent();
ownerContextGroup->contextAboutToBeShutdown(this);
if (m_hRC)
{
@@ -165,7 +171,14 @@ void Win32OpenGLContext::makeCurrent()
{
if (m_hDC && m_hRC)
{
wglMakeCurrent(m_hDC, m_hRC);
HGLRC currRCBefore = wglGetCurrentContext();
if (currRCBefore != m_hRC)
{
wglMakeCurrent(m_hDC, m_hRC);
HGLRC currRCAfter = wglGetCurrentContext();
CVF_ASSERT(currRCAfter = m_hRC);
CVF_UNUSED(currRCAfter);
}
}
}
@@ -177,7 +190,8 @@ bool Win32OpenGLContext::isCurrent() const
{
if (m_hDC && m_hRC)
{
if (wglGetCurrentContext() == m_hRC)
HGLRC currRC = wglGetCurrentContext();
if (currRC == m_hRC)
{
return true;
}

View File

@@ -52,7 +52,7 @@ public:
~Win32OpenGLContext();
bool createHardwareContext(HWND hWnd);
virtual void shutdownContext();
void shutdownContext();
virtual void makeCurrent();
virtual bool isCurrent() const;

View File

@@ -69,11 +69,11 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCm
UNREFERENCED_PARAMETER(lpCmdLine);
cvf::ShaderSourceProvider* shaderProvider = cvf::ShaderSourceProvider::instance();
shaderProvider->setSourceRepository(new cvf::ShaderSourceRepositoryFile("../../../LibRender/glsl/"));
shaderProvider->addFileSearchDirectory("../../../Tests/SnippetsBasis/Shaders/");
shaderProvider->setSourceRepository(new cvf::ShaderSourceRepositoryFile(CVF_CEEVIZ_ROOT_SOURCE_DIR "/LibRender/glsl/"));
shaderProvider->addFileSearchDirectory(CVF_CEEVIZ_ROOT_SOURCE_DIR "/Tests/SnippetsBasis/Shaders/");
shaderProvider->addFileSearchDirectory("./");
const cvf::String testDataDir = "../../../Tests/TestData/";
const cvf::String testDataDir = CVF_CEEVIZ_ROOT_SOURCE_DIR "/Tests/TestData/";
cvfu::SnippetFactory* factoryBasis = new SnippetFactoryBasis;
factoryBasis->setTestDataDir(testDataDir);
@@ -168,7 +168,8 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
{
//ref<cvfu::TestSnippet> snippet = SnippetRegistry::instance()->createSnippet("snip::MinimalModel");
//ref<cvfu::TestSnippet> snippet = SnippetRegistry::instance()->createSnippet("snip::Highlight");
ref<cvfu::TestSnippet> snippet = SnippetRegistry::instance()->createSnippet("snip::Stencil");
//ref<cvfu::TestSnippet> snippet = SnippetRegistry::instance()->createSnippet("snip::Stencil");
ref<cvfu::TestSnippet> snippet = SnippetRegistry::instance()->createSnippet("snip::TransparentWeightedAverage");
sl_snippetWnd = new Win32SnippetWindow;
sl_snippetWnd->create(hWnd, snippet.p());
SetFocus(sl_snippetWnd->windowHandle());

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -59,7 +59,7 @@ TEST(Base64Test, EncodeDecode)
size_t i;
for (i = 0; i < binaryDataSize; i++)
{
binaryData.set(i, static_cast<const ubyte>(i%256));
binaryData.set(i, static_cast<ubyte>(i%256));
}
// Encode binary data

View File

@@ -875,6 +875,6 @@ AxisAngleQuat AAQ_ARRAY[] =
INSTANTIATE_TEST_CASE_P(ParamInst, QuatTestAxisAngle, ::testing::ValuesIn(AAQ_ARRAY));
INSTANTIATE_TEST_SUITE_P(ParamInst, QuatTestAxisAngle, ::testing::ValuesIn(AAQ_ARRAY));

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -4,8 +4,10 @@ project(LibGuiQt_UnitTests)
find_package(OpenGL)
# Qt
if (CEE_USE_QT5)
if (CEE_USE_QT6)
find_package(Qt6 COMPONENTS REQUIRED Core Gui Widgets OpenGLWidgets)
set(QT_LIBRARIES Qt6::Core Qt6::Gui Qt6::Widgets Qt6::OpenGLWidgets )
elseif (CEE_USE_QT5)
find_package(Qt5 COMPONENTS REQUIRED Core Gui Widgets OpenGL)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets Qt5::OpenGL)
else()

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -91,7 +91,7 @@ TEST(OpenGLContextGroupTest, LifeCycle)
EXPECT_EQ(2, ctx2->refCount());
EXPECT_EQ(2, ctx3->refCount());
ctx1->shutdownContext();
grp->contextAboutToBeShutdown(ctx1.p());
EXPECT_EQ(1, ctx1->refCount());
EXPECT_TRUE(ctx1->group() == NULL);
EXPECT_FALSE(grp->containsContext(ctx1.p()));

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -38,7 +38,7 @@
#include "cvfBase.h"
#include "gtest/gtest.h"
#include "gtest/cvftestUtils.h"
#include <stdio.h>
@@ -54,7 +54,5 @@ int main(int argc, char **argv)
testing::InitGoogleTest(&argc, argv);
cvftest::TestDataDir::initializeInstance(cvftest::TestDataDir::DEFAULT_DEFINE_THEN_VIZ_FRAMEWORK, true);
return RUN_ALL_TESTS();
}

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -51,7 +51,7 @@ using namespace cvfu;
//--------------------------------------------------------------------------------------------------
TEST(ImageTgaTest, LoadUncompressed24bit)
{
String fullFileName = cvftest::TestDataDir::instance()->dataDir() + "TgaTestSuite/UTC24.TGA";
String fullFileName = cvftest::Utils::getTestDataDir() + "TgaTestSuite/UTC24.TGA";
cvf::Trace::show("FN: %s\n", fullFileName.toAscii().ptr());
ref<TextureImage> img = ImageTga::loadImage(fullFileName);
ASSERT_TRUE(img.notNull());
@@ -68,7 +68,7 @@ TEST(ImageTgaTest, LoadUncompressed24bit)
//--------------------------------------------------------------------------------------------------
TEST(ImageTgaTest, LoadCompressed24bit)
{
String fullFileName = cvftest::TestDataDir::instance()->dataDir() + "TgaTestSuite/CTC24.TGA";
String fullFileName = cvftest::Utils::getTestDataDir() + "TgaTestSuite/CTC24.TGA";
cvf::Trace::show("FN: %s\n", fullFileName.toAscii().ptr());
ref<TextureImage> img = ImageTga::loadImage(fullFileName);
ASSERT_TRUE(img.notNull());
@@ -85,7 +85,7 @@ TEST(ImageTgaTest, LoadCompressed24bit)
//--------------------------------------------------------------------------------------------------
TEST(ImageTgaTest, LoadUncompressed32bit)
{
String fullFileName = cvftest::TestDataDir::instance()->dataDir() + "TgaTestSuite/UTC32.TGA";
String fullFileName = cvftest::Utils::getTestDataDir() + "TgaTestSuite/UTC32.TGA";
ref<TextureImage> img = ImageTga::loadImage(fullFileName);
ASSERT_TRUE(img.notNull());
@@ -101,7 +101,7 @@ TEST(ImageTgaTest, LoadUncompressed32bit)
//--------------------------------------------------------------------------------------------------
TEST(ImageTgaTest, LoadCompressed32bit)
{
String fullFileName = cvftest::TestDataDir::instance()->dataDir() + "TgaTestSuite/CTC32.TGA";
String fullFileName = cvftest::Utils::getTestDataDir() + "TgaTestSuite/CTC32.TGA";
ref<TextureImage> img = ImageTga::loadImage(fullFileName);
ASSERT_TRUE(img.notNull());

View File

@@ -1,2 +0,0 @@
Sole purpose of this file is to have custom build rules to trigger copying of TBB DLLs

View File

@@ -461,7 +461,7 @@ void DepthPeelingFront::renderFrontToBackPeeling()
// 3. Final Pass
// ---------------------------------------------------------------------
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, m_openGLContext->defaultFramebufferObject());
glDrawBuffer(GL_BACK);
glDisable(GL_DEPTH_TEST);

Some files were not shown because too many files have changed in this diff Show More