tumvispainter.cpp 7.46 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// ================================================================================================
// 
// This file is part of the TUMVis Visualization Framework.
// 
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
//      Christian Schulte zu Berge (christian.szb@in.tum.de)
//      Chair for Computer Aided Medical Procedures
//      Technische Universitt Mnchen
//      Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
// 
// 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.
// 
// ================================================================================================

schultezub's avatar
schultezub committed
29
#include "tumvispainter.h"
schultezub's avatar
schultezub committed
30

31
#include "tgt/assert.h"
schultezub's avatar
schultezub committed
32
#include "tgt/camera.h"
33
34
35
#include "tgt/qt/qtthreadedcanvas.h"
#include "tgt/qt/qtglcontext.h"
#include "tgt/qt/qtcontextmanager.h"
schultezub's avatar
schultezub committed
36
#include "tgt/quadrenderer.h"
schultezub's avatar
schultezub committed
37
38
#include "tgt/quadric.h"

schultezub's avatar
schultezub committed
39
#include "core/datastructures/imagedatarendertarget.h"
schultezub's avatar
schultezub committed
40
#include "core/pipeline/visualizationpipeline.h"
schultezub's avatar
schultezub committed
41

schultezub's avatar
schultezub committed
42
43
44
namespace TUMVis {
    const std::string TumVisPainter::loggerCat_ = "TUMVis.core.TumVisPainter";

45
46
47
    TumVisPainter::TumVisPainter(tgt::QtThreadedCanvas* canvas, VisualizationPipeline* pipeline)
        : Runnable()
        , tgt::Painter(canvas)
schultezub's avatar
schultezub committed
48
49
        , _pipeline(0)
        , _copyShader(0)
50
51
    {
        tgtAssert(getCanvas() != 0, "The given canvas must not be 0!");
52
        _dirty = true;
schultezub's avatar
schultezub committed
53
        setPipeline(pipeline);
schultezub's avatar
schultezub committed
54
55
    }

56
    TumVisPainter::~TumVisPainter() {
schultezub's avatar
schultezub committed
57

58
    }
schultezub's avatar
schultezub committed
59

60
61
62
63
    void TumVisPainter::stop() {
        // we need to execute run() one more time to ensure correct release of the OpenGL context
        _stopExecution = true;
        _renderCondition.notify_all();
64

65
66
        Runnable::stop();
    }
schultezub's avatar
schultezub committed
67

68
69
    void TumVisPainter::run() {
        std::unique_lock<tbb::mutex> lock(CtxtMgr.getGlMutex());
schultezub's avatar
schultezub committed
70

71
72
73
74
        while (! _stopExecution) {
            getCanvas()->getContext()->acquire();
            paint();
            getCanvas()->swap();
schultezub's avatar
schultezub committed
75

76
77
            while (!_stopExecution && !_dirty)
                _renderCondition.wait(lock);
schultezub's avatar
schultezub committed
78
79
        }

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
        // release OpenGL context, so that other threads can access it
        CtxtMgr.releaseCurrentContext();
    }

    void TumVisPainter::paint() {
        if (getCanvas() == 0)
            return;

        while (_dirty) {
            _dirty = false;

            const tgt::ivec2& size = getCanvas()->getSize();
            glViewport(0, 0, size.x, size.y);

            // try get Data
95
            DataContainer::ScopedTypedData<ImageDataRenderTarget> image(_pipeline->getDataContainer(), _pipeline->getRenderTargetID());
96
97
98
99
100
101
102
103
104
105
106
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            if (image != 0) {
                // activate shader
                _copyShader->activate();
                _copyShader->setIgnoreUniformLocationError(true);
                _copyShader->setUniform("_viewportSize", size);
                _copyShader->setUniform("_viewportSizeRCP", 1.f / tgt::vec2(size));
                _copyShader->setIgnoreUniformLocationError(false);

                // bind input textures
                tgt::TextureUnit colorUnit, depthUnit;
schultezub's avatar
schultezub committed
107
                image->bind(_copyShader, &colorUnit, &depthUnit);
108
109
110
111
112
113
114
115
116
117
118
119
120
121
                LGL_ERROR;

                // execute the shader
                tgt::QuadRenderer::renderQuad();
                _copyShader->deactivate();
                LGL_ERROR;
            }
            else {
                // TODO: render some nifty error texture
                //       so long, we do some dummy rendering
                tgt::Camera c(tgt::vec3(0.f,0.f,2.f)); 
                c.look();  
                glColor3f(1.f, 0.f, 0.f);  
                tgt::Sphere sphere(.5f, 64, 32);  
122
                sphere.render();
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

                /*
                // render error texture
                if (!errorTex_) {
                    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                    return;
                }
                glClear(GL_DEPTH_BUFFER_BIT);

                glActiveTexture(GL_TEXTURE0);
                errorTex_->bind();
                errorTex_->enable();

                glColor3f(1.f, 1.f, 1.f);
                renderQuad();

                errorTex_->disable();*/
            }
            LGL_ERROR;
schultezub's avatar
schultezub committed
142
        }
schultezub's avatar
schultezub committed
143
144
145
    }

    void TumVisPainter::sizeChanged(const tgt::ivec2& size) {
schultezub's avatar
schultezub committed
146
        _pipeline->setRenderTargetSize(size);
schultezub's avatar
schultezub committed
147
148
149
    }

    void TumVisPainter::init() {
schultezub's avatar
schultezub committed
150
151
152
        try {
            // TODO:    Remove hardcoded paths, and use ShdrMgr.addPath() at some central location
            _copyShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "core/glsl/copyimage.frag", "", false);
schultezub's avatar
schultezub committed
153
        }
schultezub's avatar
schultezub committed
154
155
        catch (tgt::Exception& e) {
            LERRORC("main.cpp", "Encountered tgt::Exception: " << e.what());
schultezub's avatar
schultezub committed
156
        }
schultezub's avatar
schultezub committed
157
    }
schultezub's avatar
schultezub committed
158

159
160
    void TumVisPainter::deinit() {
        ShdrMgr.dispose(_copyShader);
schultezub's avatar
schultezub committed
161
162
163
164
165
166
167

        if (_pipeline != 0) {
            _pipeline->s_renderTargetChanged.disconnect(this);
            if (getCanvas()->getEventHandler() != 0)
                getCanvas()->getEventHandler()->removeListener(_pipeline);
            _pipeline = 0;
        }
168
169
    }

schultezub's avatar
schultezub committed
170
171
172
173
174
175
176
    void TumVisPainter::setPipeline(VisualizationPipeline* pipeline) {
        tgtAssert(pipeline != 0, "The given pipeline must not be 0.");
        if (_pipeline != 0) {
            _pipeline->s_renderTargetChanged.disconnect(this);
            if (getCanvas()->getEventHandler() != 0)
                getCanvas()->getEventHandler()->removeListener(_pipeline);
        }
schultezub's avatar
schultezub committed
177

schultezub's avatar
schultezub committed
178
        _pipeline = pipeline;
179
        _pipeline->s_renderTargetChanged.connect(this, &TumVisPainter::onRenderTargetChanged);
schultezub's avatar
schultezub committed
180
181
182
183
        _pipeline->setRenderTargetSize(getCanvas()->getSize());
        if (getCanvas()->getEventHandler() != 0)
            getCanvas()->getEventHandler()->addListenerToFront(_pipeline);
    }
schultezub's avatar
schultezub committed
184

185
    void TumVisPainter::onRenderTargetChanged() {
186
187
        // TODO:    What happens, if the mutex is still acquired?
        //          Will the render thread woken up as soon as it is released?
188
189
190
191
        if (!_stopExecution) {
            _dirty = true;
            _renderCondition.notify_all();
        }
schultezub's avatar
schultezub committed
192
    }
schultezub's avatar
schultezub committed
193

194
195
196
197
    void TumVisPainter::setCanvas(tgt::GLCanvas* canvas) {
        tgtAssert(dynamic_cast<tgt::QtThreadedCanvas*>(canvas) != 0, "Canvas must be of type QtThreadedCanvas!");
        Painter::setCanvas(canvas);
    }
schultezub's avatar
schultezub committed
198
}