tumvispainter.cpp 5.75 KB
Newer Older
schultezub's avatar
schultezub committed
1
#include "tumvispainter.h"
schultezub's avatar
schultezub committed
2

3
#include "tgt/assert.h"
schultezub's avatar
schultezub committed
4
#include "tgt/camera.h"
5
6
7
#include "tgt/qt/qtthreadedcanvas.h"
#include "tgt/qt/qtglcontext.h"
#include "tgt/qt/qtcontextmanager.h"
schultezub's avatar
schultezub committed
8
#include "tgt/quadrenderer.h"
schultezub's avatar
schultezub committed
9
10
#include "tgt/quadric.h"

schultezub's avatar
schultezub committed
11
#include "core/datastructures/imagedatarendertarget.h"
schultezub's avatar
schultezub committed
12
#include "core/pipeline/visualizationpipeline.h"
schultezub's avatar
schultezub committed
13

schultezub's avatar
schultezub committed
14
15
16
namespace TUMVis {
    const std::string TumVisPainter::loggerCat_ = "TUMVis.core.TumVisPainter";

17
18
19
    TumVisPainter::TumVisPainter(tgt::QtThreadedCanvas* canvas, VisualizationPipeline* pipeline)
        : Runnable()
        , tgt::Painter(canvas)
schultezub's avatar
schultezub committed
20
21
        , _pipeline(0)
        , _copyShader(0)
22
23
    {
        tgtAssert(getCanvas() != 0, "The given canvas must not be 0!");
24
        _dirty = true;
schultezub's avatar
schultezub committed
25
        setPipeline(pipeline);
schultezub's avatar
schultezub committed
26
27
    }

28
    TumVisPainter::~TumVisPainter() {
schultezub's avatar
schultezub committed
29

30
    }
schultezub's avatar
schultezub committed
31

32
33
34
35
    void TumVisPainter::stop() {
        // we need to execute run() one more time to ensure correct release of the OpenGL context
        _stopExecution = true;
        _renderCondition.notify_all();
36

37
38
        Runnable::stop();
    }
schultezub's avatar
schultezub committed
39

40
41
    void TumVisPainter::run() {
        std::unique_lock<tbb::mutex> lock(CtxtMgr.getGlMutex());
schultezub's avatar
schultezub committed
42

43
44
45
46
        while (! _stopExecution) {
            getCanvas()->getContext()->acquire();
            paint();
            getCanvas()->swap();
schultezub's avatar
schultezub committed
47

48
49
            while (!_stopExecution && !_dirty)
                _renderCondition.wait(lock);
schultezub's avatar
schultezub committed
50
51
        }

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
        // 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
67
            DataContainer::ScopedTypedData<ImageDataRenderTarget> image(_pipeline->getDataContainer(), _pipeline->getRenderTargetID());
68
69
70
71
72
73
74
75
76
77
78
            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
79
                image->bind(_copyShader, &colorUnit, &depthUnit);
80
81
82
83
84
85
86
87
88
89
90
91
92
93
                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);  
schultezub's avatar
schultezub committed
94
                //sphere.render();  
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

                /*
                // 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
114
        }
schultezub's avatar
schultezub committed
115
116
117
    }

    void TumVisPainter::sizeChanged(const tgt::ivec2& size) {
schultezub's avatar
schultezub committed
118
        _pipeline->setRenderTargetSize(size);
schultezub's avatar
schultezub committed
119
120
121
    }

    void TumVisPainter::init() {
schultezub's avatar
schultezub committed
122
123
124
        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
125
        }
schultezub's avatar
schultezub committed
126
127
        catch (tgt::Exception& e) {
            LERRORC("main.cpp", "Encountered tgt::Exception: " << e.what());
schultezub's avatar
schultezub committed
128
        }
schultezub's avatar
schultezub committed
129
    }
schultezub's avatar
schultezub committed
130

131
132
    void TumVisPainter::deinit() {
        ShdrMgr.dispose(_copyShader);
schultezub's avatar
schultezub committed
133
134
135
136
137
138
139

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

schultezub's avatar
schultezub committed
142
143
144
145
146
147
148
    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
149

schultezub's avatar
schultezub committed
150
        _pipeline = pipeline;
151
        _pipeline->s_renderTargetChanged.connect(this, &TumVisPainter::onRenderTargetChanged);
schultezub's avatar
schultezub committed
152
153
154
155
        _pipeline->setRenderTargetSize(getCanvas()->getSize());
        if (getCanvas()->getEventHandler() != 0)
            getCanvas()->getEventHandler()->addListenerToFront(_pipeline);
    }
schultezub's avatar
schultezub committed
156

157
    void TumVisPainter::onRenderTargetChanged() {
158
159
        // TODO:    What happens, if the mutex is still acquired?
        //          Will the render thread woken up as soon as it is released?
160
161
162
163
        if (!_stopExecution) {
            _dirty = true;
            _renderCondition.notify_all();
        }
schultezub's avatar
schultezub committed
164
    }
schultezub's avatar
schultezub committed
165

166
167
168
169
    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
170
}