imagerepresentationgl.cpp 10.5 KB
Newer Older
1
2
3
4
// ================================================================================================
// 
// This file is part of the CAMPVis Software Framework.
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2013, all rights reserved,
6
7
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universität München
//      Boltzmannstr. 3, 85748 Garching b. München, Germany
10
// 
11
12
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
// 
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
25
26
27
28
29
30
31
32
33
34
35
36
37
// 
// ================================================================================================

#include "imagerepresentationgl.h"

#include "tgt/assert.h"
#include "tgt/shadermanager.h"
#include "tgt/textureunit.h"
#include "tgt/tgt_gl.h"

#include "core/datastructures/imagedata.h"

namespace campvis {

    const std::string ImageRepresentationGL::loggerCat_ = "CAMPVis.core.datastructures.ImageRepresentationGL";

38
39
40
41
42
43
44
45
46
47
48
49
    ImageRepresentationGL* ImageRepresentationGL::create(ImageData* parent, tgt::Texture* texture) {
        ImageRepresentationGL* toReturn = new ImageRepresentationGL(parent, texture);
        toReturn->addToParent();
        return toReturn;
    }

    ImageRepresentationGL* ImageRepresentationGL::create(ImageData* parent, const WeaklyTypedPointer& wtp) {
        ImageRepresentationGL* toReturn = new ImageRepresentationGL(parent, wtp);
        toReturn->addToParent();
        return toReturn;
    }

50
    ImageRepresentationGL::ImageRepresentationGL(ImageData* parent, tgt::Texture* texture)
51
        : GenericAbstractImageRepresentation<ImageRepresentationGL>(parent)
52
53
54
        , _texture(texture)
    {
        tgtAssert(texture != 0, "Given texture must not be 0.");
55
56
        tgtAssert(parent->getDimensionality() >= 3 || texture->getDimensions().z == 1, "Dimensionality of Parent and texture mismatch!");
        tgtAssert(parent->getDimensionality() >= 2 || texture->getDimensions().y == 1, "Dimensionality of Parent and texture mismatch!");
57
        tgtAssert(parent->getNumChannels() == texture->getNumChannels(), "Number of Channels of parent and texture mismatch!");
58
59
    }

60
    ImageRepresentationGL::ImageRepresentationGL(ImageData* parent, const WeaklyTypedPointer& wtp) 
61
        : GenericAbstractImageRepresentation<ImageRepresentationGL>(parent)
62
    {
63
        tgtAssert(wtp._numChannels == parent->getNumChannels(), "Number of Channels of parent and texture mismatch!");
64
65
66
67
68
69
70
        createTexture(wtp);
    }

    ImageRepresentationGL::~ImageRepresentationGL() {
        delete _texture;
    }

71
    ImageRepresentationGL* ImageRepresentationGL::clone(ImageData* newParent) const {
72
73
        GLubyte* data = _texture->downloadTextureToBuffer();
        WeaklyTypedPointer wtp(WeaklyTypedPointer::baseType(_texture->getDataType()), WeaklyTypedPointer::numChannels(_texture->getFormat()), data);
74
        ImageRepresentationGL* toReturn = ImageRepresentationGL::create(newParent, wtp);
75
76
77
78
79
80
81
        delete data;
        return toReturn;
    }

    void ImageRepresentationGL::createTexture(const WeaklyTypedPointer& wtp) {
        tgtAssert(wtp._pointer != 0, "Pointer to image data must not be 0!");

schultezub's avatar
schultezub committed
82
        _texture = new tgt::Texture(reinterpret_cast<GLubyte*>(wtp._pointer), getSize(), wtp.getGlFormat(), wtp.getGlInternalFormat(), wtp.getGlDataType(), tgt::Texture::LINEAR);
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
        setupAndUploadTexture(_texture, wtp.isInteger(), wtp.isSigned());

    }

    void ImageRepresentationGL::setupAndUploadTexture(tgt::Texture* texture, bool isInteger, bool isSigned) {
        // Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

        switch (getDimensionality()) {
            case 1:
                _texture->setType(GL_TEXTURE_1D);
                break;
            case 2:
                _texture->setType(GL_TEXTURE_2D);
                break;
            case 3:
                _texture->setType(GL_TEXTURE_3D);
                break;
            default:
                tgtAssert(false, "Unsupported dimensionality of image.");
                break;
        }

        tgt::TextureUnit tempUnit;
        tempUnit.activate();
        _texture->bind();

        // map signed integer types from [-1.0:1.0] to [0.0:1.0] in order to avoid clamping of negative values
        if (isInteger && isSigned) {
            glPixelTransferf(GL_RED_SCALE,   0.5f);
            glPixelTransferf(GL_GREEN_SCALE, 0.5f);
            glPixelTransferf(GL_BLUE_SCALE,  0.5f);
            glPixelTransferf(GL_ALPHA_SCALE, 0.5f);

            glPixelTransferf(GL_RED_BIAS,    0.5f);
            glPixelTransferf(GL_GREEN_BIAS,  0.5f);
            glPixelTransferf(GL_BLUE_BIAS,   0.5f);
            glPixelTransferf(GL_ALPHA_BIAS,  0.5f);

            //_mappingInformation.setRealWorldMapping(LinearMapping<float>(.5f, .5f));
        }

        _texture->uploadTexture();
126
        _texture->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
127
128

        if (isInteger && isSigned) {
129
130
131
132
133
134
135
136
137
138
            // restore default
            glPixelTransferf(GL_RED_SCALE,   1.0f);
            glPixelTransferf(GL_GREEN_SCALE, 1.0f);
            glPixelTransferf(GL_BLUE_SCALE,  1.0f);
            glPixelTransferf(GL_ALPHA_SCALE, 1.0f);

            glPixelTransferf(GL_RED_BIAS,    0.0f);
            glPixelTransferf(GL_GREEN_BIAS,  0.0f);
            glPixelTransferf(GL_BLUE_BIAS,   0.0f);
            glPixelTransferf(GL_ALPHA_BIAS,  0.0f);
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
        }

        // revoke ownership of local pixel data from the texture
        _texture->setPixelData(0);

        tgt::TextureUnit::setZeroUnit();
        LGL_ERROR;
    }

    void ImageRepresentationGL::bind() const {
        _texture->bind();
    }

    void ImageRepresentationGL::bind(const tgt::TextureUnit& texUnit) const {
        texUnit.activate();
        _texture->bind();
    }

157
    void ImageRepresentationGL::bind(tgt::Shader* shader, const tgt::TextureUnit& texUnit, const std::string& texUniform /*= "_texture"*/, const std::string& texParamsUniform) const {
158
159
160
161
162
163
164
165
166
167
        bind(texUnit);
        bool tmp = shader->getIgnoreUniformLocationError();
        shader->setIgnoreUniformLocationError(true);

        switch (getDimensionality()) {
            case 1:
                LERROR("Setting um 1D texture uniforms currently not implemented - you probably wanna do that yourself...");
                break;

            case 2:
168
169
170
171
                shader->setUniform(texUniform, texUnit.getUnitNumber());
                shader->setUniform(texParamsUniform + "._size", tgt::vec2(getSize().xy()));
                shader->setUniform(texParamsUniform + "._sizeRCP", tgt::vec2(1.f) / tgt::vec2(getSize().xy()));
                shader->setUniform(texParamsUniform + "._numChannels", static_cast<int>(_parent->getNumChannels()));
172
173
174
                break;

            case 3:
175
176
177
178
179
180
181
                shader->setUniform(texUniform, texUnit.getUnitNumber());
                shader->setUniform(texParamsUniform + "._size", tgt::vec3(getSize()));
                shader->setUniform(texParamsUniform + "._sizeRCP", tgt::vec3(1.f) / tgt::vec3(getSize()));
                shader->setUniform(texParamsUniform + "._numChannels", static_cast<int>(_parent->getNumChannels()));
                shader->setUniform(texParamsUniform + "._voxelSize", _parent->getMappingInformation().getVoxelSize());
                shader->setUniform(texParamsUniform + "._voxelSizeRCP", tgt::vec3(1.f) / _parent->getMappingInformation().getVoxelSize());
                shader->setUniform(texParamsUniform + "._textureToWorldMatrix", _parent->getMappingInformation().getTextureToWorldMatrix());
182
                shader->setUniform(texParamsUniform + "._worldToTextureMatrix", _parent->getMappingInformation().getWorldToTextureMatrix());
183
                shader->setUniform(texParamsUniform + "._realWorldMapping", tgt::vec2(_parent->getMappingInformation().getRealWorldMapping()._shift, _parent->getMappingInformation().getRealWorldMapping()._scale));
184
185
186
187
188
189
190
                break;

            default:
                tgtAssert(false, "Should not reach this!");
                break;
        }
        shader->setIgnoreUniformLocationError(tmp);
191
        LGL_ERROR;
192
193
    }

194
195
196
    void ImageRepresentationGL::downloadTexture() const {
        _texture->downloadTexture();
    }
197

198
    const tgt::Texture* ImageRepresentationGL::getTexture() const {
199

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
        return _texture;
    }

    size_t ImageRepresentationGL::getLocalMemoryFootprint() const {
        size_t sum = 0;
        if (_texture != 0) {
            sum += sizeof(tgt::Texture);
            if (_texture->getPixelData() != 0) {
                sum += _texture->getBpp() + _texture->getArraySize();
            }
        }

        return sizeof(*this) + sum;
    }

    size_t ImageRepresentationGL::getVideoMemoryFootprint() const {
        return _texture->getSizeOnGPU();
    }

219
220
221
222
223
224
225
    const WeaklyTypedPointer ImageRepresentationGL::getWeaklyTypedPointer() const {
        if (_texture->getPixelData() == 0) {
            _texture->downloadTexture();
        }
        return WeaklyTypedPointer(WeaklyTypedPointer::baseType(_texture->getDataType()), _texture->getNumChannels(), _texture->getPixelData());
    }

226
227
228
229
    void ImageRepresentationGL::unbind() const {
        _texture->unbind();
    }

230
231
232
233
234
    const WeaklyTypedPointer ImageRepresentationGL::getWeaklyTypedPointerCopy() const {
        void* ptr = _texture->downloadTextureToBuffer(_texture->getFormat(), _texture->getDataType());
        return WeaklyTypedPointer(WeaklyTypedPointer::baseType(_texture->getDataType()), _texture->getNumChannels(), ptr);
    }

235
236
237
238
    const WeaklyTypedPointer ImageRepresentationGL::getWeaklyTypedPointerConvert(GLenum dataType) const {
        void* ptr = _texture->downloadTextureToBuffer(_texture->getFormat(), dataType);
        return WeaklyTypedPointer(WeaklyTypedPointer::baseType(dataType), _texture->getNumChannels(), ptr);
    }
239

240
}