Added QTMultiView test app based on cvfqt::OpenGLWidget

This commit is contained in:
Sigurd Pettersen 2024-01-12 17:40:28 +01:00
parent 71b1384b7f
commit 6b8dfd3f7b
9 changed files with 1713 additions and 0 deletions

View File

@ -81,6 +81,8 @@ if (CEE_BUILD_TEST_APPS)
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)

View File

@ -0,0 +1,53 @@
project(QtMultiView)
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)
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
QMVFactory.cpp
QMVFactory.h
QMVMain.cpp
QMVMainWindow.cpp
QMVMainWindow.h
QMVWidget.cpp
QMVWidget.h
)
# Headers that need MOCing
set(MOC_HEADER_FILES
QMVMainWindow.h
QMVWidget.h
)
if (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,349 @@
//##################################################################################################
//
// 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.h"
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVModelFactory::QMVModelFactory(bool useShaders, const cvf::OpenGLCapabilities& capabilities)
: m_useShaders(useShaders),
m_capabilities(capabilities)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Model> QMVModelFactory::createSphereAndBox()
{
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
{
cvf::GeometryBuilderDrawableGeo builder;
cvf::GeometryUtils::createSphere(2, 10, 10, &builder);
cvf::ref<cvf::Effect> eff = new cvf::Effect;
if (m_useShaders)
{
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));
}
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)
{
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));
}
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->updateBoundingBoxesRecursive();
return model;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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);
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);
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
cvf::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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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);
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);
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
cvf::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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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);
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);
cvf::ref<cvf::ModelBasicList> model = new cvf::ModelBasicList;
cvf::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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::ShaderProgram> QMVModelFactory::createProgramStandardHeadlightColor()
{
cvf::ShaderProgramGenerator gen("StandardHeadlightColor", cvf::ShaderSourceProvider::instance());
gen.configureStandardHeadlightColor();
cvf::ref<cvf::ShaderProgram> prog = gen.generate();
return prog;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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);
cvf::ref<cvf::ShaderProgram> prog = gen.generate();
return prog;
}
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVSceneFactory::QMVSceneFactory(QMVModelFactory* modelFactory)
: m_modelFactory(modelFactory)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Scene> QMVSceneFactory::createNumberedScene(int sceneNumber)
{
cvf::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());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Scene> QMVSceneFactory::createFromModel(cvf::Model* model)
{
cvf::ref<cvf::Scene> scene = new cvf::Scene;
if (model)
{
scene->addModel(model);
}
return scene;
}
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::RenderSequence> QMVRenderSequenceFactory::createFromScene(cvf::Scene* scene)
{
cvf::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);
}
}
cvf::ref<cvf::RenderSequence> renderSeq = new cvf::RenderSequence;
renderSeq->addRendering(rendering.p());
return renderSeq;
}

View File

@ -0,0 +1,96 @@
//##################################################################################################
//
// 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
//==================================================================================================
//
//
//
//==================================================================================================
class QMVModelFactory
{
public:
QMVModelFactory(bool useShaders, const cvf::OpenGLCapabilities& capabilities);
cvf::ref<cvf::Model> createSphereAndBox();
cvf::ref<cvf::Model> createSpheres();
cvf::ref<cvf::Model> createBoxes();
cvf::ref<cvf::Model> createTriangles();
private:
cvf::ref<cvf::ShaderProgram> createProgramStandardHeadlightColor();
cvf::ref<cvf::ShaderProgram> createProgramUnlit();
private:
bool m_useShaders;
cvf::OpenGLCapabilities m_capabilities;
};
//==================================================================================================
//
//
//
//==================================================================================================
class QMVSceneFactory
{
public:
QMVSceneFactory(QMVModelFactory* modelFactory);
cvf::ref<cvf::Scene> createNumberedScene(int sceneNumber);
cvf::ref<cvf::Scene> createFromModel(cvf::Model* model);
private:
QMVModelFactory* m_modelFactory;
};
//==================================================================================================
//
//
//
//==================================================================================================
class QMVRenderSequenceFactory
{
public:
cvf::ref<cvf::RenderSequence> createFromScene(cvf::Scene* model);
};

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.
//
//##################################################################################################
#include "cvfLibCore.h"
#include "QMVMainWindow.h"
#include <QApplication>
#include <clocale>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
// 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.show();
return app.exec();
}

View File

@ -0,0 +1,681 @@
//##################################################################################################
//
// 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.h"
#include "QMVWidget.h"
#include "QMVFactory.h"
#include <QTimer>
#include <QFrame>
#include <QHBoxLayout>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QStatusBar>
#include <QLabel>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVMainWindow::QMVMainWindow()
{
memset(m_vizWidgets, 0, sizeof(m_vizWidgets));
QFrame* mainFrame = new QFrame;
QGridLayout* frameLayout = new QGridLayout;
mainFrame->setLayout(frameLayout);
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_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()));
widgetsMenu->addAction(m_createWidgetsAsFloatingDialogsAction);
widgetsMenu->addSeparator();
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");
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("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("All Widgets Show Different Scene", this, SLOT(slotAllWidgetsDifferentScene()));
scenesMenu->addSeparator();
scenesMenu->addAction("Clear Scene", this, SLOT(slotClearScene()));
QMenu* renderingMenu = menuBar()->addMenu("&Rendering");
renderingMenu->addAction("Use Buffer Objects", this, SLOT(slotUseBufferObjects()));
renderingMenu->addAction("Use Client Vertex Arrays", this, SLOT(slotUseClientVertexArrays()));
QMenu* testMenu = menuBar()->addMenu("&Test");
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, false);
QTimer* timer = new QTimer;
connect(timer, SIGNAL(timeout()), SLOT(slotUpdateStatusbar()));
timer->start(250);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMVMainWindow::~QMVMainWindow()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int QMVMainWindow::vizWidgetCount()
{
int count = 0;
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i])
{
count++;
}
}
return count;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::createVizWidgets(int numWidgets, bool recycleScenes)
{
CVF_ASSERT(numWidgets <= MAX_NUM_WIDGETS);
cvf::Collection<cvf::Scene> sceneCollection;
if (recycleScenes)
{
gatherAllScenes(&sceneCollection);
}
deleteAllVizWidgets();
// 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();
QWidget* parentWidget = centralWidget();
// The context group that all the contexts end up in
CVF_ASSERT(m_contextGroup.notNull());
CVF_ASSERT(m_contextGroup->contextCount() == 0);
int i;
for (i = 0; i < numWidgets; i++)
{
QMVWidget* newWidget = NULL;
if (createAsDialogs)
{
newWidget = new QMVWidget(m_contextGroup.p(), i, parentWidget, Qt::Dialog);
newWidget->resize(600, 400);
newWidget->show();
}
else
{
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);
}
}
m_vizWidgets[i] = newWidget;
}
if (recycleScenes)
{
spreadScenesAcrossVizWidgets(&sceneCollection);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::deleteOrReleaseOpenGLResourcesInAllVizWidgets()
{
// Will be set to one of the OpenGL contexts so we can use it in final evict call
cvf::OpenGLContext* someOglContext = NULL;
// 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++)
{
QMVWidget* vizWidget = m_vizWidgets[i];
if (vizWidget)
{
vizWidget->makeCurrent();
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::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);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::deleteAllVizWidgets()
{
QWidget* parentWidget = centralWidget();
QLayout* layout = parentWidget->layout();
// Should not be needed, but left for experimentation
//deleteOrReleaseOpenGLResourcesInAllVizWidgets();
//deleteAllOpenGLResourcesInResourceManager();
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::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;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::setSceneInAllVizWidgets(cvf::Scene* scene)
{
QMVRenderSequenceFactory factory;
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
cvf::ref<cvf::RenderSequence> renderSeq = factory.createFromScene(scene);
m_vizWidgets[i]->setRenderSequence(renderSeq.p());
}
}
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::spreadScenesAcrossVizWidgets(cvf::Collection<cvf::Scene>* sceneCollection)
{
QMVRenderSequenceFactory factory;
cvf::uint i;
for (i = 0; i < static_cast<cvf::uint>(MAX_NUM_WIDGETS); i++)
{
QMVWidget* vizWidget = m_vizWidgets[i];
if (vizWidget)
{
cvf::Scene* scene = (sceneCollection->size() > i) ? sceneCollection->at(i) : NULL;
if (scene)
{
cvf::ref<cvf::RenderSequence> renderSeq = factory.createFromScene(scene);
vizWidget->setRenderSequence(renderSeq.p());
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::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::redrawAllVizWidgets()
{
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
m_vizWidgets[i]->update();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::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::closeEvent(QCloseEvent*)
{
// Should not be needed any more, but left for experimentation
//deleteOrReleaseOpenGLResourcesInAllVizWidgets();
//deleteAllOpenGLResourcesInResourceManager();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotConfigNumVizWidgets()
{
QObject* senderAct = sender();
bool recycleScenes = m_recycleScenesInWidgetConfigAction->isChecked();
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()
{
// 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);
cvf::ref<cvf::Model> model = modelFactory.createSphereAndBox();
cvf::ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotCreateSpheresScene()
{
// 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);
cvf::ref<cvf::Model> model = modelFactory.createSpheres();
cvf::ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotCreateBoxesScene()
{
// 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);
cvf::ref<cvf::Model> model = modelFactory.createBoxes();
cvf::ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotCreateTrianglesScene()
{
// 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);
cvf::ref<cvf::Model> model = modelFactory.createTriangles();
cvf::ref<cvf::Scene> scene = sceneFactory.createFromModel(model.p());
setSceneInAllVizWidgets(scene.p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotAllWidgetsDifferentScene()
{
// 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;
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
cvf::ref<cvf::Scene> scene = sceneFactory.createNumberedScene(i);
cvf::ref<cvf::RenderSequence> renderSeq = renderSeqFactory.createFromScene(scene.p());
m_vizWidgets[i]->setRenderSequence(renderSeq.p());
}
}
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotClearScene()
{
int i;
for (i = 0; i < MAX_NUM_WIDGETS; i++)
{
if (m_vizWidgets[i] != NULL)
{
m_vizWidgets[i]->setRenderSequence(NULL);
}
}
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotUseBufferObjects()
{
setRenderModeInAllModels(cvf::DrawableGeo::BUFFER_OBJECT);
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotUseClientVertexArrays()
{
setRenderModeInAllModels(cvf::DrawableGeo::VERTEX_ARRAY);
redrawAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotDeleteAllResourcesInResourceManager()
{
deleteAllOpenGLResourcesInResourceManager();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::slotDeleteOrReleaseOpenGLResourcesInAllVizWidgets()
{
deleteOrReleaseOpenGLResourcesInAllVizWidgets();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVMainWindow::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* vizWidget = m_vizWidgets[i];
if (vizWidget)
{
cvf::RenderSequence* renderSeq = vizWidget->renderSequence();
if (renderSeq)
{
cvf::PerformanceInfo pi = renderSeq->performanceInfo();
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

@ -0,0 +1,119 @@
//##################################################################################################
//
// 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 <QMainWindow>
#include <QPointer>
class QMVWidget;
namespace cvf {
class Scene;
class OpenGLResourceManager;
class OpenGLContextGroup;
}
//==================================================================================================
//
//
//
//==================================================================================================
class QMVMainWindow : public QMainWindow
{
Q_OBJECT
public:
QMVMainWindow();
~QMVMainWindow();
private:
int vizWidgetCount();
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:
virtual void closeEvent(QCloseEvent* pCE);
private slots:
void slotConfigNumVizWidgets();
void slotDeleteFirstVizWidget();
void slotDeleteSecondVizWidget();
void slotCreateSphereAndBoxScene();
void slotCreateSpheresScene();
void slotCreateBoxesScene();
void slotCreateTrianglesScene();
void slotAllWidgetsDifferentScene();
void slotClearScene();
void slotUseBufferObjects();
void slotUseClientVertexArrays();
void slotDeleteAllResourcesInResourceManager();
void slotDeleteOrReleaseOpenGLResourcesInAllVizWidgets();
void slotUpdateStatusbar();
private:
static const int MAX_NUM_WIDGETS = 4;
cvf::ref<cvf::OpenGLContextGroup> m_contextGroup;
QPointer<QMVWidget> m_vizWidgets[MAX_NUM_WIDGETS];
QAction* m_createWidgetsAsFloatingDialogsAction;
QAction* m_recycleScenesInWidgetConfigAction;
QAction* m_configNumWidgets1Action;
QAction* m_configNumWidgets2Action;
QAction* m_configNumWidgets4Action;
QAction* m_configNumWidgetsNoneAction;
QAction* m_useShadersAction;
};

View File

@ -0,0 +1,255 @@
//##################################################################################################
//
// 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.h"
#include <QMouseEvent>
#include <QOpenGLFunctions>
#include <QPainter>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget::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::renderSequence()
{
return m_renderSequence.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OpenGLContext* QMVWidget::cvfOpenGLContext()
{
return cvfqt::OpenGLWidget::cvfOpenGLContext();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget::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());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget::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
{
// Reddish background for empty widgets
QOpenGLFunctions* funcs = context()->functions();
funcs->glClearColor(0.9f, 0.5f, 0.5f, 1.0f);
funcs->glClear(GL_COLOR_BUFFER_BIT);
}
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));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Camera* QMVWidget::currentCamera()
{
if (m_renderSequence.notNull())
{
cvf::Rendering* rendering = m_renderSequence->firstRendering();
if (rendering)
{
return rendering->camera();
}
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void QMVWidget::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 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();
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 QMVWidget::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 "cvfRenderSequence.h"
#include "cvfManipulatorTrackball.h"
#include "cvfqtOpenGLWidget.h"
//==================================================================================================
//
//
//
//==================================================================================================
class QMVWidget : public cvfqt::OpenGLWidget
{
Q_OBJECT
public:
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();
cvf::Camera* currentCamera();
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
private:
int m_indexOfWidget;
int m_paintCount;
cvf::ref<cvf::ManipulatorTrackball> m_trackball;
cvf::ref<cvf::RenderSequence> m_renderSequence;
};