campvispainter.cpp 7.34 KB
Newer Older
1 2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Visualization Framework.
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
// 
// 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 "campvispainter.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"
36

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"
41 42
#include "core/tools/job.h"
#include "core/tools/opengljobprocessor.h"
43
#include "core/tools/quadrenderer.h"
schultezub's avatar
schultezub committed
44

schultezub's avatar
schultezub committed
45 46
namespace campvis {
    const std::string TumVisPainter::loggerCat_ = "CAMPVis.core.TumVisPainter";
schultezub's avatar
schultezub committed
47

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

59
    TumVisPainter::~TumVisPainter() {
schultezub's avatar
schultezub committed
60

61
    }
schultezub's avatar
schultezub committed
62

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

68 69
        Runnable::stop();
    }
schultezub's avatar
schultezub committed
70

71 72
    void TumVisPainter::run() {
        std::unique_lock<tbb::mutex> lock(CtxtMgr.getGlMutex());
schultezub's avatar
schultezub committed
73

74
        while (! _stopExecution) {
75 76

            /*getCanvas()->getContext()->acquire();
77
            paint();
78
            getCanvas()->swap();*/
schultezub's avatar
schultezub committed
79

80
            //while (!_stopExecution)
81
                _renderCondition.wait(lock);
schultezub's avatar
schultezub committed
82 83
        }

84 85 86 87 88 89 90 91
        // release OpenGL context, so that other threads can access it
        CtxtMgr.releaseCurrentContext();
    }

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

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
        const tgt::ivec2& size = getCanvas()->getSize();
        glViewport(0, 0, size.x, size.y);

        // try get Data
        DataContainer::ScopedTypedData<ImageDataRenderTarget> image(_pipeline->getDataContainer(), _pipeline->getRenderTargetID());
        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;
            image->bind(_copyShader, &colorUnit, &depthUnit);
109
            LGL_ERROR;
110 111

            // execute the shader
112 113 114
            _copyShader->setAttributeLocation(0, "in_Position");
            _copyShader->setAttributeLocation(1, "in_TexCoords");
            QuadRdr.renderQuad();
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
            _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);  
            sphere.render();

            /*
            // 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();*/
schultezub's avatar
schultezub committed
143
        }
144
        LGL_ERROR;
145 146

        getCanvas()->swap();
schultezub's avatar
schultezub committed
147 148 149
    }

    void TumVisPainter::sizeChanged(const tgt::ivec2& size) {
schultezub's avatar
schultezub committed
150
        _pipeline->setRenderTargetSize(size);
schultezub's avatar
schultezub committed
151 152 153
    }

    void TumVisPainter::init() {
schultezub's avatar
schultezub committed
154 155 156
        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
157
        }
schultezub's avatar
schultezub committed
158 159
        catch (tgt::Exception& e) {
            LERRORC("main.cpp", "Encountered tgt::Exception: " << e.what());
schultezub's avatar
schultezub committed
160
        }
schultezub's avatar
schultezub committed
161
    }
schultezub's avatar
schultezub committed
162

163 164
    void TumVisPainter::deinit() {
        ShdrMgr.dispose(_copyShader);
schultezub's avatar
schultezub committed
165 166 167 168 169 170 171

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

schultezub's avatar
schultezub committed
174 175 176 177 178 179 180
    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
181

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

189
    void TumVisPainter::onRenderTargetChanged() {
190
        GLJobProc.enqueueJob(getCanvas(), new CallMemberFuncJob<TumVisPainter>(this, &TumVisPainter::paint), OpenGLJobProcessor::PaintJob);
schultezub's avatar
schultezub committed
191
    }
schultezub's avatar
schultezub committed
192

193 194 195 196
    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
197
}