tumvisapplication.cpp 7.17 KB
Newer Older
1
2
3
4
5
#include "tumvisapplication.h"

#include "tgt/assert.h"
#include "tgt/exception.h"
#include "tgt/glcontext.h"
6
#include "tgt/gpucapabilities.h"
7
8
9
10
11
12
13
#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"
14
#include "application/gui/mainwindow.h"
15
16
17
18
19
20
#include "core/pipeline/abstractpipeline.h"
#include "core/pipeline/visualizationpipeline.h"
#include "core/pipeline/pipelineevaluator.h"

namespace TUMVis {

21
22
    const std::string TumVisApplication::loggerCat_ = "TUMVis.application.TumVisApplication";

23
24
25
    TumVisApplication::TumVisApplication(int argc, char** argv) 
        : QApplication(argc, argv)
        , _localContext(0)
26
        , _mainWindow(0)
27
28
29
30
        , _initialized(false)
        , _argc(argc)
        , _argv(argv)
    {
31
32
        // Make Xlib and GLX thread safe under X11
        QApplication::setAttribute(Qt::AA_X11InitThreads);
33

34
35
        _mainWindow = new MainWindow(this);
        tgt::QtContextManager::init();
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    }

    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;
        }

52
        // TODO: _mainWindow is a Qt pointer and does not need to be deleted - right?
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    }

    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;

69
70
71
72
73
74
75
76
        // ensure matching OpenGL specs
        if (GpuCaps.getGlVersion() < tgt::GpuCapabilities::GlVersion::TGT_GL_VERSION_3_0) {
            LERROR("Your system does not support OpenGL 3.0, which is mandatory. TUMVis will probably not work as intendet.");
        }
        if (GpuCaps.getShaderVersion() < tgt::GpuCapabilities::GlVersion::SHADER_VERSION_130) {
            LERROR("Your system does not support GLSL Shader Version 1.30, which is mandatory. TUMVis will probably not work as intendet.");
        }

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
        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();

125
126
        _mainWindow->show();

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
        // 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) {
150
        tgtAssert(_initialized == false, "Adding pipelines after initialization is currently not supported.");
151
152
153
154
155
        tgtAssert(pipeline != 0, "Pipeline must not be 0.");
        _pipelines.push_back(pipeline);

        PipelineEvaluator* pe = new PipelineEvaluator(pipeline);
        _pipelineEvaluators.push_back(pe);
156
157

        s_PipelinesChanged();
158
159
160
    }

    void TumVisApplication::addVisualizationPipeline(const std::string& name, VisualizationPipeline* vp) {
161
        tgtAssert(_initialized == false, "Adding pipelines after initialization is currently not supported.");
162
163
164
165
166
167
168
169
170
171
172
        tgtAssert(vp != 0, "Pipeline must not be 0.");

        // 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));
173
174
175
176
177

        // 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);
178
179
180
    }

}