visualizationpipeline.cpp 10.1 KB
Newer Older
1
2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
4
5
// 
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
8
9
//      Chair for Computer Aided Medical Procedures
//      Technische Universitt Mnchen
//      Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
schultezub's avatar
schultezub committed
10
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
// 
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// ================================================================================================

30
#include "visualizationpipeline.h"
schultezub's avatar
schultezub committed
31
#include "tgt/tgt_gl.h"
schultezub's avatar
schultezub committed
32
#include "tgt/glcanvas.h"
33
#include "tgt/glcontext.h"
34
#include "core/datastructures/imagerepresentationrendertarget.h"
35
#include "core/pipeline/visualizationprocessor.h"
36
37
#include "core/tools/job.h"
#include "core/tools/opengljobprocessor.h"
38
#include "core/tools/simplejobprocessor.h"
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
namespace {
    GLboolean getGlBool(GLenum param) {
        GLboolean toReturn;
        glGetBooleanv(param, &toReturn);
        return toReturn;
    };

    GLint getGlInt(GLenum param) {
        GLint toReturn;
        glGetIntegerv(param, &toReturn);
        return toReturn;
    };

    GLfloat getGlFloat(GLenum param) {
        GLfloat toReturn;
        glGetFloatv(param, &toReturn);
        return toReturn;
    }
}

schultezub's avatar
schultezub committed
60
61
namespace campvis {
    const std::string VisualizationPipeline::loggerCat_ = "CAMPVis.core.datastructures.VisualizationPipeline";
62

63
    VisualizationPipeline::VisualizationPipeline() 
schultezub's avatar
schultezub committed
64
        : AbstractPipeline()
schultezub's avatar
schultezub committed
65
        , tgt::EventListener()
66
        , _lqMode(false)
67
        , _ignoreCanvasSizeUpdate(false)
68
69
        , _canvasSize("CanvasSize", "Canvas Size", tgt::ivec2(128, 128), tgt::ivec2(1, 1), tgt::ivec2(4096, 4096))
        , _effectiveRenderTargetSize("EffectiveRenderTargetSize", "Render Target Size", tgt::ivec2(128, 128), tgt::ivec2(1, 1), tgt::ivec2(4096, 4096))
70
        , _renderTargetID("renderTargetID", "Render Target ID", "VisualizationPipeline.renderTarget", DataNameProperty::READ)
71
        , _canvas(0)
72
    {
schultezub's avatar
schultezub committed
73
        _data.s_dataAdded.connect(this, &VisualizationPipeline::onDataContainerDataAdded);
74
        addProperty(&_renderTargetID);
75
        addProperty(&_canvasSize);
76
        _renderTargetID.s_changed.connect<VisualizationPipeline>(this, &VisualizationPipeline::onPropertyChanged);
77
78
79
80
81
82
83
    }

    VisualizationPipeline::~VisualizationPipeline() {
    }

    void VisualizationPipeline::onEvent(tgt::Event* e) {
        // cycle through event handlers, ask each one if it handles the event and if so, execute it.
schultezub's avatar
schultezub committed
84
        for (std::vector<AbstractEventHandler*>::iterator it = _eventHandlers.begin(); it != _eventHandlers.end() && e->isAccepted(); ++it) {
85
86
87
88
            if ((*it)->accept(e)) {
                (*it)->execute(e);
            }
        }
schultezub's avatar
schultezub committed
89
90
91
92

        if (e->isAccepted()) {
            EventListener::onEvent(e);
        }
93
94
95
96
97
98
    }

    void VisualizationPipeline::init() {
        AbstractPipeline::init();
    }

99
    void VisualizationPipeline::deinit() {
100
101
102
        _data.s_dataAdded.disconnect(this);
        _renderTargetID.s_changed.disconnect(this);
	
103
104
105
        AbstractPipeline::deinit();
    }

schultezub's avatar
schultezub committed
106
    const tgt::ivec2& VisualizationPipeline::getRenderTargetSize() const {
107
        return _canvasSize.getValue();
108
109
110
    }

    void VisualizationPipeline::setRenderTargetSize(const tgt::ivec2& size) {
111
        if (_canvasSize.getValue() != size && !_ignoreCanvasSizeUpdate) {
112
            _canvasSize.setValue(size);
113
        }
114

115
        updateEffectiveRenderTargetSize();
schultezub's avatar
schultezub committed
116
    }
schultezub's avatar
schultezub committed
117

118
    void VisualizationPipeline::onDataContainerDataAdded(const std::string& name, const DataHandle& dh) {
schultezub's avatar
schultezub committed
119
120
        if (name == _renderTargetID.getValue()) {
            s_renderTargetChanged();
schultezub's avatar
schultezub committed
121
        }
122
123
    }

124
125
    const std::string& VisualizationPipeline::getRenderTargetID() const {
        return _renderTargetID.getValue();
126
127
    }

128
    void VisualizationPipeline::lockGLContextAndExecuteProcessor(AbstractProcessor* processor) {
129
        tgtAssert(_canvas != 0, "Set a valid canvas before calling this method!");
130
131
        GLJobProc.enqueueJob(
            _canvas, 
132
            makeJobOnHeap<VisualizationPipeline, AbstractProcessor*, bool>(this, &VisualizationPipeline::executeProcessor, processor, true),
133
            OpenGLJobProcessor::SerialJob);
134
135
    }

136
137
138
139
    void VisualizationPipeline::setCanvas(tgt::GLCanvas* canvas) {
        _canvas = canvas;
    }

140
141
142
    void VisualizationPipeline::onPropertyChanged(const AbstractProperty* prop) {
        if (prop == &_renderTargetID)
            s_renderTargetChanged();
143
144
145
        else if (prop == &_canvasSize && _canvas != 0 && !_ignoreCanvasSizeUpdate) {
            if (_canvasSize.getValue() != _canvas->getSize()) {
                _ignoreCanvasSizeUpdate = true;
146
                _canvas->setSize(_canvasSize.getValue());
147
148
                _ignoreCanvasSizeUpdate = false;
            }
149
        }
150
151
152
153
        else
            AbstractPipeline::onPropertyChanged(prop);
    }

schultezub's avatar
schultezub committed
154
155
156
157
158
    void VisualizationPipeline::addEventHandler(AbstractEventHandler* eventHandler) {
        tgtAssert(eventHandler != 0, "Event handler must not be 0.");
        _eventHandlers.push_back(eventHandler);
    }

159
160
161
162
163
164
165
166
167
168
169
170
    void VisualizationPipeline::enableLowQualityMode() {
        _lqMode = true;
        updateEffectiveRenderTargetSize();
    }

    void VisualizationPipeline::disableLowQualityMode() {
        _lqMode = false;
        updateEffectiveRenderTargetSize();
    }

    void VisualizationPipeline::updateEffectiveRenderTargetSize() {
        if (_lqMode)
171
            _effectiveRenderTargetSize.setValue(_canvasSize.getValue() / 2);
172
        else
173
            _effectiveRenderTargetSize.setValue(_canvasSize.getValue());
174
175
    }

176
177
178
179
180
181
182
183
184
185
    void VisualizationPipeline::onProcessorInvalidated(AbstractProcessor* processor) {
        if (_canvas == 0)
            return;

        tbb::concurrent_hash_map<AbstractProcessor*, bool>::const_accessor a;
        if (_isVisProcessorMap.find(a, processor)) {
            if (a->second) {
                // is VisualizationProcessor
                GLJobProc.enqueueJob(
                    _canvas, 
186
                    makeJobOnHeap<VisualizationPipeline, AbstractProcessor*>(this, &VisualizationPipeline::executeProcessorAndCheckOpenGLState, processor), 
187
188
189
                    OpenGLJobProcessor::SerialJob);
            }
            else {
190
                SimpleJobProc.enqueueJob(makeJob<VisualizationPipeline, AbstractProcessor*, bool>(this, &VisualizationPipeline::executeProcessor, processor, false));
191
192
193
194
195
196
197
198
199
200
201
202
            }
        }
        else {
            tgtAssert(false, "Could not find processor in processor map.");
            LWARNING("Caught invalidation of a non-registered processor!");
        }
    }

    void VisualizationPipeline::addProcessor(AbstractProcessor* processor) {
        _isVisProcessorMap.insert(std::make_pair(processor, (dynamic_cast<VisualizationProcessor*>(processor) != 0)));
        AbstractPipeline::addProcessor(processor);
    }
203
204
    
    void VisualizationPipeline::executeProcessorAndCheckOpenGLState(AbstractProcessor* processor) {
205
        AbstractPipeline::executeProcessor(processor, true);
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

#ifdef CAMPVIS_DEBUG
//         tgtAssert(getGlBool(GL_DEPTH_TEST) == false, "Invalid OpenGL state after processor execution, GL_DEPTH_TEST != false.");
//         tgtAssert(getGlBool(GL_SCISSOR_TEST) == false, "Invalid OpenGL state after processor execution, GL_SCISSOR_TEST != false.");
// 
//         tgtAssert(getGlInt(GL_CULL_FACE_MODE) == GL_BACK, "Invalid OpenGL state after processor execution, GL_CULL_FACE_MODE != GL_BACk.");
//         tgtAssert(getGlInt(GL_DEPTH_FUNC) == GL_LESS, "Invalid OpenGL state after processor execution, GL_DEPTH_FUNC != GL_LESS.");
// 
//         tgtAssert(getGlFloat(GL_DEPTH_CLEAR_VALUE) == 1.f, "Invalid OpenGL state after processor execution, GL_DEPTH_CLEAR_VALUE != 1.f.");
// 
//         tgtAssert(getGlFloat(GL_RED_SCALE) == 1.f, "Invalid OpenGL state after processor execution, GL_RED_SCALE != 1.f.");
//         tgtAssert(getGlFloat(GL_GREEN_SCALE) == 1.f, "Invalid OpenGL state after processor execution, GL_GREEN_SCALE != 1.f.");
//         tgtAssert(getGlFloat(GL_BLUE_SCALE) == 1.f, "Invalid OpenGL state after processor execution, GL_BLUE_SCALE != 1.f.");
//         tgtAssert(getGlFloat(GL_ALPHA_SCALE) == 1.f, "Invalid OpenGL state after processor execution, GL_ALPHA_SCALE != 1.f.");
// 
//         tgtAssert(getGlFloat(GL_RED_BIAS) == 0.f, "Invalid OpenGL state after processor execution, GL_RED_BIAS != 0.f.");
//         tgtAssert(getGlFloat(GL_GREEN_BIAS) == 0.f, "Invalid OpenGL state after processor execution, GL_GREEN_BIAS != 0.f.");
//         tgtAssert(getGlFloat(GL_BLUE_BIAS) == 0.f, "Invalid OpenGL state after processor execution, GL_BLUE_BIAS != 0.f.");
//         tgtAssert(getGlFloat(GL_ALPHA_BIAS) == 0.f, "Invalid OpenGL state after processor execution, GL_ALPHA_BIAS != 0.f.");
#endif
    }
227

228
}