Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

Commit c32b41e0 authored by schultezub's avatar schultezub
Browse files

* introducing TumVisApplication for easy and straight-forward setup of...

 * introducing TumVisApplication for easy and straight-forward setup of pipelines, contexts, evaluators, etc.
 * VisualizationPipeline must not get its canvas during construction anymore

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@203 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent c96d2310
......@@ -18,20 +18,21 @@ FILE(GLOB TUMVIS_APPLICATION_HEADERS
# datastructures/
#)
#SET(TUMVIS_APPLICATION_HEADERS
# application/tumvispainter.h
#)
SET(TUMVIS_APPLICATION_TO_BE_MOCCED
tumvisapplication.h
)
#
# Qt related stuff:
#
FIND_PACKAGE(Qt4 ${TUMVIS_REQUIRED_QT_VERSION} REQUIRED QtCore QtGui QtOpenGL)
#QT4_WRAP_CPP(TUMVIS_APPLICATION_MOC ${TUMVIS_APPLICATION_HEADERS})
QT4_WRAP_CPP(TUMVIS_APPLICATION_MOC ${TUMVIS_APPLICATION_TO_BE_MOCCED})
LIST(APPEND TUMVIS_APPLICATION_SOURCES ${TUMVIS_APPLICATION_MOC})
INCLUDE(${QT_USE_FILE})
ADD_EXECUTABLE(tumvis-application
${TUMVIS_APPLICATION_SOURCES} ${TUMVIS_APPLICATION_HEADERS}
# ${TUMVIS_APPLICATION_MOC}
${TUMVIS_APPLICATION_MOC}
)
ADD_DEFINITIONS(${TUMVIS_DEFINITIONS} ${QT_DEFINITIONS})
INCLUDE_DIRECTORIES(${TUMVIS_INCLUDE_DIRECTORIES})
......
#include "tgt/camera.h"
#include "tgt/exception.h"
#include "tgt/shadermanager.h"
#include "tgt/qt/qtapplication.h"
#include "tgt/qt/qtcanvas.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tbb/include/tbb/task_scheduler_init.h"
#include "tbb/include/tbb/compat/thread"
#include "tumvispainter.h"
#include "core/pipeline/pipelineevaluator.h"
#include "application/tumvisapplication.h"
#include "modules/pipelines/slicevis.h"
using namespace TUMVis;
......@@ -25,69 +14,13 @@ PipelineEvaluator* pe;
* \param argv vector of arguments
* \return 0 if program exited successfully
**/
int main(int argc, char** argv) {
tgt::QtApplication* app = new tgt::QtApplication(argc, argv);
tgt::QtContextManager::init();
tgt::QtThreadedCanvas* renderCanvas = CtxtMgr.createContext("render", "TUMVis");
tgt::QtThreadedCanvas* sliceVisCanvas = CtxtMgr.createContext("sliceVis", "SliceVis");
tbb::task_scheduler_init init;
renderCanvas->getContext()->acquire();
app->addCanvas(renderCanvas);
app->init();
LogMgr.getConsoleLog()->addCat("", true);
LGL_ERROR;
if (argc > 0) {
// ugly hack
std::string programPath(argv[0]);
programPath = tgt::FileSystem::parentDir(tgt::FileSystem::parentDir(tgt::FileSystem::parentDir(programPath)));
ShdrMgr.addPath(programPath);
ShdrMgr.addPath(programPath + "/core/glsl");
}
LGL_ERROR;
tgt::Camera camera;
renderCanvas->setCamera(&camera);
try {
sliceVis = new SliceVis(sliceVisCanvas);
painter = new TumVisPainter(renderCanvas, sliceVis);
LGL_ERROR;
renderCanvas->setPainter(painter);
LGL_ERROR;
sliceVis->init();
LGL_ERROR;
}
catch (tgt::Exception& e) {
LERRORC("main.cpp", "Encountered tgt::Exception: " << e.what());
}
catch (std::exception& e) {
LERRORC("main.cpp", "Encountered std::exception: " << e.what());
}
// disconnect OpenGL context from this thread so that the other threads can acquire an OpenGL context.
CtxtMgr.releaseCurrentContext();
pe = new PipelineEvaluator(sliceVis);
pe->start();
painter->start();
app->run();
pe->stop();
painter->stop();
sliceVis->deinit();
painter->deinit();
tgt::deinitGL();
tgt::QtContextManager::deinit();
tgt::deinit();
int main(int argc, char** argv) {
TumVisApplication app(argc, argv);
app.addVisualizationPipeline("SliceVis", new SliceVis());
delete painter;
delete sliceVis;
delete app;
app.init();
int toReturn = app.run();
app.deinit();
return 0;
return toReturn;
}
#include "tumvisapplication.h"
#include "tgt/assert.h"
#include "tgt/exception.h"
#include "tgt/glcontext.h"
#include "tgt/shadermanager.h"
#include "tgt/qt/qtapplication.h"
#include "tgt/qt/qtthreadedcanvas.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tbb/include/tbb/compat/thread"
#include "application/tumvispainter.h"
#include "core/pipeline/abstractpipeline.h"
#include "core/pipeline/visualizationpipeline.h"
#include "core/pipeline/pipelineevaluator.h"
namespace TUMVis {
TumVisApplication::TumVisApplication(int argc, char** argv)
: QApplication(argc, argv)
, _localContext(0)
, _initialized(false)
, _argc(argc)
, _argv(argv)
{
tgt::QtContextManager::init();
}
TumVisApplication::~TumVisApplication() {
tgtAssert(_initialized == false, "Destructing initialized TumVisApplication, deinitialize first!");
// delete everything in the right order:
for (std::vector<PipelineEvaluator*>::iterator it = _pipelineEvaluators.begin(); it != _pipelineEvaluators.end(); ++it) {
delete *it;
}
for (std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
delete it->second;
}
for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
delete *it;
}
}
void TumVisApplication::init() {
tgtAssert(_initialized == false, "Tried to initialize TumVisApplication twice.");
// Init TGT
tgt::InitFeature::Features featureset = tgt::InitFeature::ALL;
tgt::init(featureset);
LogMgr.getConsoleLog()->addCat("", true);
// create a local OpenGL context and init GL
_localContext = CtxtMgr.createContext("AppContext", "", tgt::ivec2(16, 16));
tgtAssert(_localContext != 0, "Could not create local OpenGL context");
tgt::initGL(featureset);
LGL_ERROR;
if (_argc > 0) {
// ugly hack
std::string programPath(_argv[0]);
programPath = tgt::FileSystem::parentDir(tgt::FileSystem::parentDir(tgt::FileSystem::parentDir(programPath)));
ShdrMgr.addPath(programPath);
ShdrMgr.addPath(programPath + "/core/glsl");
}
// init pipeline first
for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
(*it)->init();
}
// Now init painters:
for (std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
it->second->init();
}
_initialized = true;
}
void TumVisApplication::deinit() {
tgtAssert(_initialized, "Tried to deinitialize uninitialized TumVisApplication.");
// Deinit pipeline first
for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
(*it)->deinit();
}
// Now deinit painters:
for (std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
it->second->deinit();
}
// deinit OpenGL and tgt
tgt::deinitGL();
tgt::QtContextManager::deinit();
tgt::deinit();
_initialized = false;
}
int TumVisApplication::run() {
tgtAssert(_initialized, "Tried to run uninitialized TumVisApplication.");
// disconnect OpenGL context from this thread so that the other threads can acquire an OpenGL context.
CtxtMgr.releaseCurrentContext();
// Start evaluator/render threads
for (std::vector<PipelineEvaluator*>::iterator it = _pipelineEvaluators.begin(); it != _pipelineEvaluators.end(); ++it) {
(*it)->start();
}
for (std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
it->second->start();
}
// Start QApplication
int toReturn = QApplication::exec();
// QApplication has returned -> Stop evaluator/render threads
for (std::vector<PipelineEvaluator*>::iterator it = _pipelineEvaluators.begin(); it != _pipelineEvaluators.end(); ++it) {
(*it)->stop();
}
for (std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
it->second->stop();
}
return toReturn;
}
void TumVisApplication::addPipeline(AbstractPipeline* pipeline) {
tgtAssert(pipeline != 0, "Pipeline must not be 0.");
_pipelines.push_back(pipeline);
PipelineEvaluator* pe = new PipelineEvaluator(pipeline);
_pipelineEvaluators.push_back(pe);
}
void TumVisApplication::addVisualizationPipeline(const std::string& name, VisualizationPipeline* vp) {
tgtAssert(vp != 0, "Pipeline must not be 0.");
// TODO: is there a more leightweight method to create a context for the pipeline (just performing off-screen rendering)?
tgt::QtThreadedCanvas* evaluationContext = CtxtMgr.createContext(name + "_eval", "", tgt::ivec2(512, 512));
vp->setCanvas(evaluationContext);
addPipeline(vp);
// create canvas and painter for the VisPipeline and connect all together
tgt::QtThreadedCanvas* canvas = CtxtMgr.createContext(name, "TUMVis", tgt::ivec2(512, 512));
canvas->init();
TumVisPainter* painter = new TumVisPainter(canvas, vp);
canvas->setPainter(painter, false);
CtxtMgr.releaseCurrentContext();
_visualizations.push_back(std::make_pair(vp, painter));
}
}
\ No newline at end of file
#ifndef TUMVISAPPLICATION_H__
#define TUMVISAPPLICATION_H__
#include <QApplication>
#include <utility>
#include <vector>
namespace tgt {
class QtThreadedCanvas;
}
namespace TUMVis {
class AbstractPipeline;
class PipelineEvaluator;
class TumVisPainter;
class VisualizationPipeline;
/**
* The TumVisApplication class wraps Pipelines, Evaluators and Painters all together and takes
* care about correctly handling all those instances.
*
* Intended usage is:
* 1) Create your TumVisApplication
* 2) Add Pipelines and Visualizations as needed
* 3) call init()
* 4) call run()
* 5) call deinit()
* 6) You can now safely destroy your TumVisApplication
*/
class TumVisApplication : QApplication {
public:
/**
* Creates a new TumVisApplication.
* \param argc number of passed arguments
* \param argv vector of arguments
*/
TumVisApplication(int argc, char** argv);
/**
* Destructor, make sure to call deinit() first.
*/
~TumVisApplication();
/**
* Initializes tgt, OpenGL, and all pipelines, evaluators and painters.
* Make sure to have everything setup before calling init().
*/
void init();
/**
* Deinitializes tgt, OpenGL, and all pipelines, evaluators and painters.
*/
void deinit();
/**
* Adds a pipeline which doesn't need visualization (OpenGL) support.
* Each pipeline will automatically get its own evaluator.
*
* \note If you want to add a pipeline that needs a valid OpenGL context, use
* addVisualizationPipeline() instead.
* \param pipeline Pipeline to add, must not need OpenGL support.
*/
void addPipeline(AbstractPipeline* pipeline);
/**
* Adds a visualization pipeline (i.e. a pipeline that needs a OpenGL context).
* For each added pipeline, two OpenGL contexts will be created (one for the evaluation,
* one for the rendering).
*
* \note You do \emph not need to call addPipeline.
* \param name Name of the OpenGL context to create for the pipeline.
* \param vp VisualizationPipeline to add.
*/
void addVisualizationPipeline(const std::string& name, VisualizationPipeline* vp);
/**
* Runs the actual application.
* Make sure to call init() before.
* \return 0 on success.
*/
int run();
private:
/// All pipelines (incuding VisualizationPipelines)
std::vector<AbstractPipeline*> _pipelines;
/// All pipeline evaluators
std::vector<PipelineEvaluator*> _pipelineEvaluators;
/// All visualisations (i.e. VisualizationPipelines with their corresponding painters/canvases)
std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> > _visualizations;
/// A local OpenGL context used for initialization
tgt::QtThreadedCanvas* _localContext;
/// Flag, whether TumVisApplication was correctly initialized
bool _initialized;
int _argc;
char** _argv;
};
}
#endif // TUMVISAPPLICATION_H__
......@@ -65,7 +65,6 @@ namespace TUMVis {
// try get Data
DataContainer::ScopedTypedData<ImageDataRenderTarget> image(_pipeline->getDataContainer(), _pipeline->getRenderTargetID());
//const ImageDataRenderTarget* image = _pipeline->getRenderTarget();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (image != 0) {
// activate shader
......
#ifndef TUMVISPAINTER_H__
#define TUMVISPAINTER_H__
#include "sigslot/sigslot.h"
#include "tbb/include/tbb/atomic.h"
#include "tbb/include/tbb/compat/condition_variable"
......@@ -91,3 +94,5 @@ namespace TUMVis {
};
}
#endif // TUMVISPAINTER_H__
......@@ -8,14 +8,13 @@
namespace TUMVis {
const std::string VisualizationPipeline::loggerCat_ = "TUMVis.core.datastructures.VisualizationPipeline";
VisualizationPipeline::VisualizationPipeline(tgt::GLCanvas* canvas)
VisualizationPipeline::VisualizationPipeline()
: AbstractPipeline()
, tgt::EventListener()
, _renderTargetSize("canvasSize", "Canvas Size", tgt::ivec2(128, 128))
, _renderTargetID("renderTargetID", "Render Target ID", "VisualizationPipeline.renderTarget")
, _canvas(canvas)
, _canvas(0)
{
tgtAssert(canvas != 0, "Canvas must not be 0.");
_data.s_dataAdded.connect(this, &VisualizationPipeline::onDataContainerDataAdded);
}
......@@ -41,11 +40,13 @@ namespace TUMVis {
}
void VisualizationPipeline::init() {
tgtAssert(_canvas != 0, "Set a valid canvas before calling this method!");
tgt::GLContextScopedLock lock(_canvas->getContext());
AbstractPipeline::init();
}
void VisualizationPipeline::deinit() {
tgtAssert(_canvas != 0, "Set a valid canvas before calling this method!");
tgt::GLContextScopedLock lock(_canvas->getContext());
AbstractPipeline::deinit();
}
......@@ -69,9 +70,14 @@ namespace TUMVis {
}
void VisualizationPipeline::lockGLContextAndExecuteProcessor(AbstractProcessor& processor) {
tgtAssert(_canvas != 0, "Set a valid canvas before calling this method!");
tgt::GLContextScopedLock lock(_canvas->getContext());
executeProcessor(processor);
glFlush(); // TODO: is glFlush enough or do we need a glFinish here?
}
void VisualizationPipeline::setCanvas(tgt::GLCanvas* canvas) {
_canvas = canvas;
}
}
......@@ -23,9 +23,8 @@ namespace TUMVis {
public:
/**
* Creates a VisualizationPipeline.
* \param canvas Canvas hosting the OpenGL context for this pipeline.
*/
VisualizationPipeline(tgt::GLCanvas* canvas);
VisualizationPipeline();
/**
* Virtual Destructor
......@@ -35,6 +34,7 @@ namespace TUMVis {
/**
* Initializes the OpenGL context of the pipeline and its processors.
* Pipeline must have a valid canvas set before calling this method.
* \note When overwriting this method, make sure to call the base class version first.
*/
virtual void init();
......@@ -47,6 +47,7 @@ namespace TUMVis {
/**
* Execute this pipeline.
* Pipeline must have a valid canvas set before calling this method.
**/
virtual void execute() = 0;
......@@ -63,6 +64,12 @@ namespace TUMVis {
*/
PropertyCollection& getPropertyCollection();
/**
* Sets the Canvas hosting the OpenGL context for this pipeline.
* \param canvas Canvas hosting the OpenGL context for this pipeline
*/
void setCanvas(tgt::GLCanvas* canvas);
/**
* Sets the size of the render target
* \param size New viewport dimensions
......
......@@ -22,6 +22,7 @@ namespace tgt {
{
tgtAssert(_contexts.find(key) == _contexts.end(), "A context with the same key already exists!");
tbb::mutex::scoped_lock lock(_glMutex);
QtThreadedCanvas* toReturn = new QtThreadedCanvas(title, size, buffers, parent, shared, f, name);
_contexts.insert(std::make_pair(key, toReturn));
......
......@@ -5,8 +5,8 @@
namespace TUMVis {
SliceVis::SliceVis(tgt::GLCanvas* canvas)
: VisualizationPipeline(canvas)
SliceVis::SliceVis()
: VisualizationPipeline()
, _imageReader()
, _sliceExtractor(_renderTargetSize)
, _wheelHandler(&_sliceExtractor._sliceNumber)
......
......@@ -14,7 +14,7 @@ namespace TUMVis {
* Creates a VisualizationPipeline.
* \param canvas Canvas hosting the OpenGL context for this pipeline.
*/
SliceVis(tgt::GLCanvas* canvas);
SliceVis();
/**
* Virtual Destructor
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment