Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

campvispainter.cpp 6.38 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-2014, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
//      Chair for Computer Aided Medical Procedures
8 9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
schultezub's avatar
schultezub committed
11
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
12
// 
13 14 15 16
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
17
// 
18 19 20 21
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
22 23 24
// 
// ================================================================================================

schultezub's avatar
schultezub committed
25
#include "campvispainter.h"
schultezub's avatar
schultezub committed
26

27 28 29 30 31 32 33
#include "cgt/assert.h"
#include "cgt/camera.h"
#include "cgt/glcontextmanager.h"
#include "cgt/shadermanager.h"
#include "cgt/texture.h"
#include "cgt/textureunit.h"
#include "cgt/qt/qtthreadedcanvas.h"
34

schultezub's avatar
schultezub committed
35

36
#include "core/datastructures/imagedata.h"
37
#include "core/datastructures/renderdata.h"
38
#include "core/datastructures/imagerepresentationgl.h"
39
#include "core/pipeline/abstractpipeline.h"
40
#include "core/tools/quadrenderer.h"
schultezub's avatar
schultezub committed
41

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

45 46
    CampVisPainter::CampVisPainter(cgt::GLCanvas* canvas, AbstractPipeline* pipeline)
        : cgt::Painter(canvas)
47 48 49
        , _pipeline(nullptr)
        , _copyShader(nullptr)
        , _errorTexture(nullptr)
50
    {
51
        cgtAssert(getCanvas() != nullptr, "The given canvas must not be 0!");
schultezub's avatar
schultezub committed
52
        setPipeline(pipeline);
schultezub's avatar
schultezub committed
53 54
    }

55
    CampVisPainter::~CampVisPainter() {
schultezub's avatar
schultezub committed
56

57
    }
schultezub's avatar
schultezub committed
58

59
    void CampVisPainter::paint() {
60
        if (getCanvas() == nullptr)
61 62
            return;

63 64 65 66 67
        if (_copyShader == nullptr) {
            LERROR("Shader not initialized!");
            return;
        }

68
        const cgt::ivec2& size = getCanvas()->getSize();
69 70 71
        glViewport(0, 0, size.x, size.y);

        // try get Data
72 73 74 75 76 77 78 79
        DataHandle dh = _pipeline->getDataContainer().getData(_pipeline->getRenderTargetID());
        const RenderData* rd = nullptr;
        const ImageRepresentationGL* repGL = nullptr;
        if (dh.getData() != nullptr) {
            rd = dynamic_cast<const RenderData*>(dh.getData());
            repGL = dynamic_cast<const ImageRepresentationGL*>(dh.getData());
        }

80
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
81 82 83

        // activate the shader
        _copyShader->activate();
84
        cgt::Shader::IgnoreUniformLocationErrorGuard guard(_copyShader);
85 86

        // render whatever there is to render
87
        if (rd != nullptr || (repGL != nullptr && repGL->getDimensionality() == 2)) {
88
            _copyShader->setUniform("_viewMatrix", cgt::mat4::identity);
89 90

            // bind input textures
91
            cgt::TextureUnit colorUnit;
92 93 94 95
            if (rd)
                rd->bindColorTexture(_copyShader, colorUnit);
            else if (repGL)
                repGL->bind(_copyShader, colorUnit);
96 97

            // execute the shader
98
            QuadRdr.renderQuad();
99 100 101 102
        }
        // if there is nothing to render, render the error texture
        else if (_errorTexture != nullptr) {
            float ratioRatio = static_cast<float>(size.y) / size.x;
103
            cgt::mat4 viewMatrix = (ratioRatio > 1) ? cgt::mat4::createScale(cgt::vec3(1.f, 1.f / ratioRatio, 1.f)) : cgt::mat4::createScale(cgt::vec3(ratioRatio, 1.f, 1.f));
104 105 106
            _copyShader->setUniform("_viewMatrix", viewMatrix);

            // bind input textures
107
            cgt::TextureUnit colorUnit;
108 109 110 111 112 113
            colorUnit.activate();
            _errorTexture->bind();
            _copyShader->setUniform("_colorTexture", colorUnit.getUnitNumber());

            // execute the shader
            QuadRdr.renderQuad();
114 115
        }
        else {
116
            LERROR("Nothing to render but could not load error texture either.");
schultezub's avatar
schultezub committed
117
        }
118 119

        _copyShader->deactivate();
120
        LGL_ERROR;
121 122

        getCanvas()->swap();
schultezub's avatar
schultezub committed
123 124
    }

125
    void CampVisPainter::sizeChanged(const cgt::ivec2& size) {
schultezub's avatar
schultezub committed
126
        _pipeline->setRenderTargetSize(size);
schultezub's avatar
schultezub committed
127 128
    }

129
    void CampVisPainter::init() {
schultezub's avatar
schultezub committed
130
        try {
131
            _copyShader = ShdrMgr.load("core/glsl/passthrough.vert", "core/glsl/copyimage.frag", "");
132 133
            _copyShader->setAttributeLocation(0, "in_Position");
            _copyShader->setAttributeLocation(1, "in_TexCoords");
schultezub's avatar
schultezub committed
134
        }
135 136
        catch (cgt::Exception& e) {
            LFATAL("Encountered cgt::Exception: " << e.what());
schultezub's avatar
schultezub committed
137
        }
schultezub's avatar
schultezub committed
138
    }
schultezub's avatar
schultezub committed
139

140
    void CampVisPainter::deinit() {
141
        ShdrMgr.dispose(_copyShader);
schultezub's avatar
schultezub committed
142

143 144
        if (_pipeline != nullptr) {
            if (getCanvas()->getEventHandler() != nullptr)
145
                getCanvas()->getEventHandler()->removeEventListener(_pipeline);
146
            _pipeline = nullptr;
schultezub's avatar
schultezub committed
147
        }
148 149
    }

150
    void CampVisPainter::setPipeline(AbstractPipeline* pipeline) {
151
        cgtAssert(pipeline != nullptr, "The given pipeline must not be 0.");
152 153 154

        if (_pipeline != nullptr) {
            if (getCanvas()->getEventHandler() != nullptr)
155
                getCanvas()->getEventHandler()->removeEventListener(_pipeline);
schultezub's avatar
schultezub committed
156
        }
schultezub's avatar
schultezub committed
157

schultezub's avatar
schultezub committed
158 159
        _pipeline = pipeline;
        _pipeline->setRenderTargetSize(getCanvas()->getSize());
160
        if (getCanvas()->getEventHandler() != nullptr)
161
            getCanvas()->getEventHandler()->addEventListenerToFront(_pipeline);
schultezub's avatar
schultezub committed
162
    }
schultezub's avatar
schultezub committed
163

164
    void CampVisPainter::repaint() {
165
        // do nothing, as the painting is entirely managed by the pipeline.
166 167
    }

168 169
    void CampVisPainter::setCanvas(cgt::GLCanvas* canvas) {
        cgtAssert(dynamic_cast<cgt::QtThreadedCanvas*>(canvas) != nullptr, "Canvas must be of type QtThreadedCanvas!");
170 171
        Painter::setCanvas(canvas);
    }
172

173
    void CampVisPainter::setErrorTexture(cgt::Texture* texture) {
174 175 176
        _errorTexture = texture;
    }

177
}