VR-Vantage 2.5 API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
exampleEmbedded

This example shows how to create a your own QT application with a Main Window that has a VR-Vantage view embedded into it.

It also adds a dockable widget with a second embedded view (and its own independent observer). Finally, it adds some standard VR-Vantage GUI elements, including a File Menu, File Toolbar, and a dockable panel that can display the OSG scene graph.

Create and show the main application:

QApplication app(argc, argv);
mainWindow.showMaximized();

Run the application:

return app.exec();

The example application has a GUI derived from QMainWindow. This is a very common way of building QT applications.

The main window class owns some key VR-Vantage objects. It owns a DtDe (display engine) which is the core component for adding visualization to any application. It also owns a DtPluginManager which is responsible for loading all the VR-Vantage plug-ins.

The OpenGL graphics context needs to be owned and managed by the QT main window. We connect it the VR-Vantage display engine (and consequently OSG) via the DtOsgAdapterQtWidget. We use a second DtOsgAdapterWidget to embed the display engine into the dock widget.

The main window also owns a DtPage to display the scene graph tree;

as well as some QT widgets for menus and toolbars.

The real work begins in the constructor of the main window.

First, set up the display engine configuration and initializer.

{
DtDeConfiguration deConfig;
DtDeInitializer init;
std::string displayName = DtDisplayConfiguration::DefaultDisplayString;
displayName += " 1";
// Configure DtDeInitializer
init.setDeMode(DtDeInitializer::MasterMode);
init.setDisplayEngineName(displayName);

Create observer configurations for the main window and docked window and include them in the input driver configuration, and add the input driver configuration to the display engine initializer.

makVrv::DtObserverConfiguration observerConfig("Observer 1");

Create a window configuration for each window, specifying the observer for each.

Create, intialize, and provide the display configuration to the display engine.

Finally, create a plug-in manager, and then initialize and load the plug-ins.

Now we create the GUI. The interesting thing here is the DtQtIgTickerProvider. This provides us with a "ticker" that ticks the display engine as fast as the QT GUI will go. The rest of the function just sets up menus, toolbars, and the other things that would be part of this application.

During the call to preDisplayEngineInitialize(), we override the functionality set up by plug-ins. We want to create a DtEmbeddedOsgWindow that uses a DtOsgAdapterQtWidget for its graphic context and we do that by installing a new creator with the DtWindowFactory.

// Set the display window creator function to use the Adapter widget.
DtWindowFactory::instance(*myDe).setCreator(
DtWindowConfiguration::EmbeddedWindow,

We have to tell our application framework not to try and create a QApplication, which already exists. We also have to tell it not to create a main window, since that already exists too.

// Register the qApp with the DtQApplicationProvider.
DtQApplicationProvider::instance(*myDe).setQAppInstance(qApp);
// Register null with the DtDeMainWindowProvider so that no main window
// is ever created. This DtDe instance is embedded in a QMainWindow already.
DtDeMainWindowProvider::registerInstance(*myDe, NULL);

Finally, everything is all set up and we can initialize the display engine:

Building the Example

VR-Vantage includes pre-built versions of the example application. To build it yourself, follow the instructions at Building VR-Vantage Examples, Applications, and Plug-ins.

Running the Example

This example is an application. You can run it by running ./bin64/exampleEmbedded.exe (on Windows) or ./bin64/exampleEmbedded (on Linux). For more information about running examples, please see Running Applications and Examples.

Example Source Files


exampleEmbeddedMainWindow.h

/******************************************************************************
** Copyright (c) 2008 MAK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: exampleEmbeddedMainWindow.h,v $ $Revision: 1.4 $ $State: Exp $
******************************************************************************/
#ifndef exampleEmbeddedMainWindow_H
#define exampleEmbeddedMainWindow_H
// Include this header before any Qt header.
#include <vrvCore/DtDe.h>
#include <vrvCore/DtWindow.h>
#include <QtWidgets/QMainWindow>
#include <osg/Group>
#include <osg/Node>
class QAction;
class QMenu;
{
Q_OBJECT
public:
// The adapter widgets. These will become owned and
// deleted by MainWindow.
void buildGui();
public slots:
void open();
void closeFile();
protected:
virtual void closeEvent(QCloseEvent *event);
void createActions();
void createMenus();
protected:
};
{
public:
{
myWindow = window;
}
protected:
};
#endif

exampleEmbeddedMain.cxx

/******************************************************************************
** Copyright (c) 2008 MAK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: exampleEmbeddedMain.cxx,v $ $Revision: 1.3 $ $State: Exp $
******************************************************************************/
// Include this header before any Qt header.
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
//
// This example illustrates how to embed a DtOsgView into a preexisting
// application.
//
QApplication app(argc, argv);
mainWindow.showMaximized();
//
// Notice how the preexisting applications event loop wasn't changed.
//
return app.exec();
}

exampleEmbeddedMainWindow.cxx

/******************************************************************************
** Copyright (c) 2018 MAK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: exampleEmbeddedMainWindow.cxx,v $ $Revision: 1.13 $ $State: Exp $
******************************************************************************/
// Include this header before any Qt header.
#include <vrvOsg/vrvOsg.h>
#include <QtWidgets/QApplication>
#include <QtWidgets/QtWidgets>
#include <osg/Group>
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
using namespace makVrv;
, myPluginManager(0)
, myDe(0)
, myMainOSGWidget(0)
, myMiniOsgWidget(0)
{
createDisplayEngine();
buildGui();
preDisplayEngineInitialize();
initializeDisplayEngine();
postDisplayEngineInitialize();
}
{
// Delete the widget first. It's dtor unregisters it from the dialog
// manager which does a findInstance. Therefore, it has to be deleted
// before the DtDe is destroyed.
if (mySceneGraphTreeWidget)
{
mySceneGraphTreeWidget = 0;
}
if (myMainOSGWidget)
{
myMainOSGWidget = 0;
}
if (myMiniOsgWidget)
{
myMiniOsgWidget = 0;
}
delete myDe;
myDe = 0;
myPluginManager = 0;
}
{
// Pre initialize functions
}
{
std::string displayName = DtDisplayConfiguration::DefaultDisplayString;
displayName += " 1";
// Configure DtDeInitializer
init.setDeMode(DtDeInitializer::MasterMode);
init.setDisplayEngineName(displayName);
// Configure an observer for channel control
makVrv::DtObserverConfiguration observerConfig("Observer 1");
makVrv::DtObserverConfiguration observerConfig2("Observer 2");
inputConfig.observerConfigurations().add(observerConfig);
inputConfig.observerConfigurations().add(observerConfig2);
inputConfig.setOptionalParameter("windowDependent", "true");
init.setInputDriverConfiguration(inputConfig);
// Configure DtDeConfiguration
wName += " 1";
cName += " 1";
cc.setObserverName("Observer 1");
DtDisplayConfiguration dec(displayName);
wc.setWindowType(DtWindowConfiguration::EmbeddedWindow);
wc.channelConfigurations().add(cc);
wName2 += " 2";
DtWindowConfiguration wc2(wName2);
cName2 += " 2";
cc2.setObserverName("Observer 2");
wc2.setWindowType(DtWindowConfiguration::EmbeddedWindow);
wc2.channelConfigurations().add(cc2);
dec.windowConfigurations().add(wc);
dec.windowConfigurations().add(wc2);
deConfig.displayConfigurations().add(dec);
// Set helper pointer.
myDe = new DtDe();
myDe->setDeInitializer(init);
myDe->setDeConfiguration(deConfig);
//create the log once we get the DeInitializer since we need this as early as possible
myDe->createDebugLog(init.logFileName(), init.notifyLevel());
myPluginManager = new DtPluginManager(*myDe);
#ifndef _WIN32
// DI-Guy links in Qt 3, which is incompatible with Qt 4 based applications.
// The following code will exclude the DI-Guy plugin for Linux:
std::list<std::string> excludePlugins;
excludePlugins.push_back("../plugins/release/libvrvDiGuyPlugin.so");
myPluginManager->setExcludedPluginFiles(excludePlugins);
#endif
myPluginManager->initializePlugins();
}
{
// Set the display window creator function to use the Adapter widget.
DtWindowFactory::instance(*myDe).setCreator(
DtWindowConfiguration::EmbeddedWindow,
vrvOsg::init(*myDe);
// Register the qApp with the DtQApplicationProvider.
DtQApplicationProvider::instance(*myDe).setQAppInstance(qApp);
// Register null with the DtDeMainWindowProvider so that no main window
// is ever created. This DtDe instance is embedded in a QMainWindow already.
DtDeMainWindowProvider::registerInstance(*myDe, NULL);
}
{
// Create an IG ticker to tick during Qt's idle time.
DtQtDeTickerProvider& tickerProvider = DtQtDeTickerProvider::instance(*myDe);
tickerProvider.ticker(this);
// this needs an active Display to be hooked up properly
mySceneGraphTreeWidget = twc->create(this);
QDockWidget* dock = new QDockWidget(tr("Scene Tree"), this);
dock->setWidget(mySceneGraphTreeWidget);
addDockWidget(Qt::LeftDockWidgetArea, dock, Qt::Vertical);
setWindowTitle(tr("Embedded Example"));
setWindowIcon(QIcon(":/images/Mak-de.png"));
delete twc;
}
{
myDe->initialize();
}
{
}
{
event->accept();
}
{
DtEmbeddedOsgWindow* pWindow = 0;
DtOsgAdapterQtWidget* pAdapter = 0;
osg::GraphicsContext* sharedContext = 0;
if (de.display())
{
if (windows.size() > 0)
{
DtOsgWindow* osgView = dynamic_cast<DtOsgWindow*>(windows.front());
if (osgView)
{
sharedContext = osgView->graphicsContext();
}
}
}
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits();
traits->sharedContext = sharedContext;
const DtDeInitializer& deInit = de.deInitializer();
traits->doubleBuffer = deInit.doubleBuffer();
traits->vsync = deInit.vsync();
traits->depth = deInit.numDepthBits();
traits->stencil = deInit.numStencilBits();
traits->alpha = deInit.numAlphaBits();
unsigned short level = deInit.antiAliasingLevel();
if (level == 2 || level == 4 || level == 8 || level == 16 || level == 32)
{
traits->sampleBuffers = 1;
traits->samples = level;
}
else
{
traits->sampleBuffers = 0;
traits->samples = 0;
}
if (wc.name() == "Window 1")
{
// Set the main OSG widget as the central widget.
DtOsgAdapterQtWidgetCreator::instance(de).create(de, traits.get(),
DtOsgAdapterQtWidget::createFormatFromTraits(traits.get()), myWindow);
myWindow->setCentralWidget(myWindow->myMainOSGWidget);
}
else if (wc.name() == "Window 2")
{
DtOsgAdapterQtWidgetCreator::instance(de).create(de, traits.get(),
DtOsgAdapterQtWidget::createFormatFromTraits(traits.get()), myWindow);
QDockWidget* dockMini = new QDockWidget("Mini Widget", myWindow);
dockMini->setWidget(myWindow->myMiniOsgWidget);
myWindow->addDockWidget(Qt::LeftDockWidgetArea, dockMini, Qt::Vertical);
}
if (pAdapter)
{
pWindow = new DtEmbeddedOsgWindow(de, wc, pAdapter);
if (pWindow)
{
pAdapter->setView(pWindow);
}
}
return pWindow;
}
{
QString terrainDir = myDe->dePathConfiguration().dataPath().c_str();
terrainDir += "//Terrain";
QString filename =
DtStaticFileDialog::getOpenFileName(*myDe, this, tr("Open File"), terrainDir,
tr(
"All Readable Data Types (*.mtp *.mtd *.mtl *.gdb *medf *.dt0 *.dt1 *.dt2 *.dted *.flt *.c4b *.c7b *.c7l *.shp *.3ds *.osg *.lwo *.obj *.txp);;" \
"MAK Terrain Project (*.mtp *.mtd);;" \
"MAK Terrain Database (*.gdb);;" \
"MAK Stealth Legacy MTL (*.mtl);;" \
"MAK Encrypted Data Format (*.medf);;" \
"DTED (*.dt0 *.dt1 *.dt2 *.dted);;" \
"OpenFlight (*.flt);;" \
"CTDB Version 4 (*.c4b);;" \
"CTDB Version 7 (*.c7b);;" \
"CTDB Version 7L (*.c7l);;" \
"Shape Terrain Data (*.shp);;" \
"Terrapage (*.txp);;" \
"Other 3D Formats (*.3ds *.osg *.lwo *.obj);;" \
"All (*.*);;"
));
if (!filename.isEmpty())
{
QDir dir;
QString relativePath = dir.relativeFilePath(filename);
// Create a model definition.
std::string modelPath = relativePath.toStdString();
DtModelDefinition modelDef(modelPath);
modelDef.setParameter("filename", modelPath);
myDe->sharedState().addModelDefinition(modelDef);
// Add the model as a terrain patch
myDe->scene().terrain().addTerrainPatch(modelDef.name());
}
}
{
myDe->scene().resetScene();
}
{
myOpenAction = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
myOpenAction->setShortcut(tr("Ctrl+O"));
myOpenAction->setStatusTip(tr("Open an existing file"));
connect(myOpenAction, SIGNAL(triggered()), this, SLOT(open()));
myCloseAction = new QAction(QIcon(":/images/close.png"), tr("&Close"), this);
myCloseAction->setShortcut(tr("Ctrl+C"));
myCloseAction->setStatusTip(tr("Close the current file"));
connect(myCloseAction, SIGNAL(triggered()), this, SLOT(closeFile()));
myExitAction = new QAction(QIcon(":/images/exit.png"), tr("E&xit"), this);
//IF you want to quit using a key stroke
//exitAct->setShortcut(tr("Ctrl+Q"));
myExitAction->setStatusTip(tr("Exit the application"));
connect(myExitAction, SIGNAL(triggered()), this, SLOT(close()));
}
{
myFileMenu = this->menuBar()->addMenu(tr("&File"));
myFileMenu->addAction(myOpenAction);
myFileMenu->addAction(myCloseAction);
myFileMenu->addSeparator();
myFileMenu->addAction(myExitAction);
}
{
myFileToolBar = this->addToolBar(tr("File"));
myFileToolBar->addAction(myOpenAction);
myFileToolBar->addAction(myCloseAction);
}
{
this->statusBar()->showMessage(tr("Ready"));
}


Copyright © 2005-2019 VT MAK. All Rights Reserved (www.mak.com)