datacontainerinspectorcanvas.cpp 9.87 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
29
30
31
32
// ================================================================================================
// 
// 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.
// 
// ================================================================================================

#include "datacontainerinspectorcanvas.h"

#include "tgt/assert.h"
#include "tgt/shadermanager.h"
33
34
#include "tgt/textureunit.h"

35
36
37
38
#include "core/datastructures/datacontainer.h"
#include "core/datastructures/datahandle.h"
#include "core/datastructures/imagedatarendertarget.h"
#include "core/datastructures/imagedatagl.h"
39
#include "core/datastructures/facegeometry.h"
40
#include "core/tools/job.h"
41
42
#include "core/tools/quadrenderer.h"

43
44
45
46
47
48
49
50
#include "application/gui/datacontainertreewidget.h"

namespace TUMVis {

    DataContainerInspectorCanvas::DataContainerInspectorCanvas(QWidget* parent /*= 0*/) 
        : tgt::QtThreadedCanvas("DataContainer Inspector", tgt::ivec2(640, 480), tgt::GLCanvas::RGBA_BUFFER, parent, true)
        , _dataContainer(0)
        , _paintShader(0)
51
52
53
54
55
56
57
        , _quad(0)
        , dimX_(0)
        , dimY_(0)
        , scaledWidth_(0)
        , scaledHeight_(0)
        , selected_(0)
        , fullscreen_(false)
58
    {
59
60
61
62
63
64
65
66
67
68

        makeCurrent();
        // Init GLEW for this context
        GLenum err = glewInit();
        if (err != GLEW_OK) {
            // Problem: glewInit failed, something is seriously wrong.
            tgtAssert(false, "glewInit failed");
            std::cerr << "glewInit failed, error: " << glewGetErrorString(err) << std::endl;
            exit(EXIT_FAILURE);
        }
69
70
71
72
73
74
75
    }

    DataContainerInspectorCanvas::~DataContainerInspectorCanvas() {

    }

    void DataContainerInspectorCanvas::init() {
76
77
78
79
        GLJobProc.registerContext(this);
        _paintShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector.frag", "", false);
        _paintShader->setAttributeLocation(0, "in_Position");
        _paintShader->setAttributeLocation(1, "in_TexCoords");
80

81
        // set this as painter to get notified when window size changes
82
        setPainter(this, false);
83
84
85
    }

    void DataContainerInspectorCanvas::deinit() {
86
87
88
89
90
        if (_dataContainer != 0) {
            _dataContainer->s_dataAdded.disconnect(this);
        }

        GLJobProc.deregisterContext(this);
91
        ShdrMgr.dispose(_paintShader);
92
        delete _quad;
93
94
95
96
97
98
99
100
101
    }

    void DataContainerInspectorCanvas::setDataContainer(DataContainer* dataContainer) {
        if (_dataContainer != 0) {
            _dataContainer->s_dataAdded.disconnect(this);
        }

        {
            tbb::mutex::scoped_lock lock(_localMutex);
102
            _dataContainer = dataContainer;
103
            if (_dataContainer != 0) {
104
                _handles = _dataContainer->getHandlesCopy();
105
            }
106
107
108
109
110
111
112
113
114
115
116
117
118
        }

        if (_dataContainer != 0) {
            _dataContainer->s_dataAdded.connect(this, &DataContainerInspectorCanvas::onDataContainerDataAdded);
        }

        invalidate();
    }

    QSize DataContainerInspectorCanvas::sizeHint() const {
        return QSize(640, 480);
    }

119
    void DataContainerInspectorCanvas::onDataContainerDataAdded(const std::string& name, const DataHandle& dh) {
120
121
122
123
        {
            tbb::mutex::scoped_lock lock(_localMutex);

            // check whether DataHandle is already existing
124
            std::map<std::string, DataHandle>::iterator lb = _handles.lower_bound(name);
125
            if (lb == _handles.end() || lb->first != name) {
126
                // not existant -> insert
127
                _handles.insert(std::make_pair(name, DataHandle(dh)));
128
129
            }
            else {
130
                // existant -> replace
131
                lb->second = DataHandle(dh);
132
133
134
135
136
137
138
139
140
141
            }
        }

        invalidate();
    }

    void DataContainerInspectorCanvas::paint() {
        tbb::mutex::scoped_lock lock(_localMutex);

        std::vector<const tgt::Texture*> textures;
142
143
        for (std::map<std::string, DataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
            if (const ImageDataGL* imgGL = dynamic_cast<const ImageDataGL*>(it->second.getData())) {
144
145
                if (imgGL->getDimensionality() == 2)
            	    textures.push_back(imgGL->getTexture());
146
            }
147
            else if (const ImageDataRenderTarget* imgRT = dynamic_cast<const ImageDataRenderTarget*>(it->second.getData())) {
148
                if (imgRT->getDimensionality() == 2) {
149
150
                    for (size_t i = 0; i < imgRT->getNumColorTextures(); ++i)
            	        textures.push_back(imgRT->getColorTexture(i));
151
152
                    textures.push_back(imgRT->getDepthTexture());
                }
153
154
155
156
157
            }
        }

        glPushAttrib(GL_ALL_ATTRIB_BITS);

158
        glViewport(0, 0, size_.x, size_.y);
159
160
161
162
        glClearColor(0.7f, 0.7f, 0.7f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);
        LGL_ERROR;

163
        if (textures.empty()) {
164
165
166
167
168
169
170
171
172
173
            glPopAttrib();
            return;
        }

        // update window title
        int memsize = 0;
        for (size_t i = 0; i < textures.size(); ++i) {
            memsize += textures[i]->getSizeOnGPU();
        }
        memsize /= 1024 * 1024;
174
        /*QString title = tr("DataContainer Inspector: %1 Textures (%2 mb)").arg(textures.size()).arg(memsize);
175
176
177
        if (parentWidget() && parentWidget()->parentWidget())
            parentWidget()->parentWidget()->setWindowTitle(title);
        else
178
            setWindowTitle(title);*/
179
180
181
182
183
184
185

        // update layout dimensions
        dimX_ = (int)ceil(sqrt((float)textures.size()));
        dimY_ = ceil((float)textures.size() / dimX_);

        scaledWidth_ = size_.x / dimX_;
        scaledHeight_ = size_.y / dimY_;
186
187
188
189
190
191
192
193
194
195
        createQuad(scaledWidth_, scaledHeight_);

        _paintShader->activate();

        tgt::mat4 projection = tgt::mat4::createOrtho(0, size_.x, 0, size_.y, -1, 1);
        _paintShader->setUniform("_projectionMatrix", projection);

        tgt::TextureUnit tu;
        tu.activate();
        _paintShader->setUniform("_texture._texture", tu.getUnitNumber());
196
197
198
199
200
201
202
203
204
205
206
207
208

        if (fullscreen_) {
            if(selected_ >= 0 && selected_ < (int)textures.size()) {
                paintTexture(textures[selected_]);
            }
        }
        else {
            for (int y = 0; y < dimY_; ++y) {
                for (int x = 0; x < dimX_; ++x) {
                    int index = (dimX_ * y) + x;
                    if (index >= static_cast<int>(textures.size()))
                        break;

209
210
                    tgt::mat4 translation = tgt::mat4::createTranslation(tgt::vec3(scaledWidth_ * x, scaledHeight_ * y, 0.f));
                    _paintShader->setUniform("_modelMatrix", translation);
211
212
213
214
215
                    paintTexture(textures[index]);
                }
            }
        }

216
        _paintShader->deactivate();
217
218
219
220
221
        LGL_ERROR;
        glPopAttrib();
    }

    void DataContainerInspectorCanvas::paintTexture(const tgt::Texture* texture) {
222
223
224
225
226
227
228
229
        texture->bind();

        _paintShader->setIgnoreUniformLocationError(true);
        _paintShader->setUniform("_texture._size", tgt::vec2(texture->getDimensions().xy()));
        _paintShader->setUniform("_texture._sizeRCP", tgt::vec2(1.f) / tgt::vec2(texture->getDimensions().xy()));
        _paintShader->setIgnoreUniformLocationError(false);

        _quad->render();
230
231
232
233
234
235
    }

    void DataContainerInspectorCanvas::invalidate() {
        GLJobProc.enqueueJob(this, new CallMemberFuncJob<DataContainerInspectorCanvas>(this, &DataContainerInspectorCanvas::paint), OpenGLJobProcessor::PaintJob);
    }

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
    void DataContainerInspectorCanvas::createQuad(float width, float height) {
        std::vector<tgt::vec3> vertices, texCorods;

        vertices.push_back(tgt::vec3( 0.f,  0.f, 0.f));
        vertices.push_back(tgt::vec3(width, 0.f, 0.f));
        vertices.push_back(tgt::vec3(width, height, 0.f));
        vertices.push_back(tgt::vec3( 0.f,  height, 0.f));
        texCorods.push_back(tgt::vec3(0.f, 1.f, 0.f));
        texCorods.push_back(tgt::vec3(1.f, 1.f, 0.f));
        texCorods.push_back(tgt::vec3(1.f, 0.f, 0.f));
        texCorods.push_back(tgt::vec3(0.f, 0.f, 0.f));

        delete _quad;
        _quad = new FaceGeometry(vertices, texCorods);
        _quad->createGLBuffers();
    }

253
254
255
256
    void DataContainerInspectorCanvas::sizeChanged(const tgt::ivec2&) {
        invalidate();
    }

257
}