imagedatarendertarget.cpp 5.85 KB
Newer Older
schultezub's avatar
schultezub committed
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "imagedatarendertarget.h"

#include "tgt/assert.h"
#include "tgt/gpucapabilities.h"
#include "tgt/logmanager.h"
#include "tgt/shadermanager.h"
#include "tgt/tgt_gl.h"

namespace TUMVis {

    const std::string ImageDataRenderTarget::loggerCat_ = "TUMVis.core.datastructures.ImageDataRenderTarget";

    ImageDataRenderTarget::ImageDataRenderTarget(const tgt::svec3& size, GLint internalFormatColor /*= GL_RGBA8*/, GLint internalFormatDepth /*= GL_DEPTH_COMPONENT24*/)
        : ImageData(2, size)
        , _colorTexture(0)
        , _depthTexture(0)
        , _fbo(0)
    {
        tgtAssert(size.z == 1, "RenderTargets are only two-dimensional, expected size.z == 1.");

        initRenderTarget(internalFormatColor, internalFormatDepth);

        tgtAssert(_colorTexture != 0, "Color texture is 0, something went terribly wrong...");
        tgtAssert(_depthTexture != 0, "Depth texture is 0, something went terribly wrong...");
        tgtAssert(_fbo != 0, "Framebuffer object is 0, something went terribly wrong...");
    }

    ImageDataRenderTarget::~ImageDataRenderTarget() {
        delete _fbo;
        delete _colorTexture;
        delete _depthTexture;
    }

    void ImageDataRenderTarget::initRenderTarget(GLint internalFormatColor, GLint internalFormatDepth) {
        if (!GpuCaps.isNpotSupported() && !GpuCaps.areTextureRectanglesSupported()) {
            LWARNING("Neither non-power-of-two textures nor texture rectangles seem to be supported!");
        }

        switch(internalFormatColor) {
            case GL_RGB:
                _colorTexture = new tgt::Texture(0, _size, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
                break;
            case GL_RGBA:
                _colorTexture = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
                break;
            case GL_RGBA16:
                _colorTexture = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA16, GL_UNSIGNED_SHORT, tgt::Texture::LINEAR);
                break;
            case GL_RGB16F_ARB:
                _colorTexture = new tgt::Texture(0, _size, GL_RGB, GL_RGB16F_ARB, GL_FLOAT, tgt::Texture::LINEAR);
                break;
            case GL_RGBA16F_ARB:
                _colorTexture = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA16F_ARB, GL_FLOAT, tgt::Texture::LINEAR);
                break;
            case GL_RGBA32F_ARB:
                _colorTexture = new tgt::Texture(0, _size, GL_RGBA, GL_RGBA32F_ARB, GL_FLOAT, tgt::Texture::LINEAR);
                break;
            default:
                LERROR("Unknown internal format!");
        }
        _colorTexture->uploadTexture();
        _colorTexture->setWrapping(tgt::Texture::CLAMP_TO_EDGE);

        switch(internalFormatDepth) {
        case GL_DEPTH_COMPONENT16:
            _depthTexture = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_FLOAT, tgt::Texture::LINEAR);
            break;
        case GL_DEPTH_COMPONENT24:
            _depthTexture = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);
            break;
        case GL_DEPTH_COMPONENT32:
            _depthTexture = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32, GL_FLOAT, tgt::Texture::LINEAR);
            break;
#ifdef GL_DEPTH_COMPONENT32F
        case GL_DEPTH_COMPONENT32F:
            _depthTexture = new tgt::Texture(0, _size, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32F, GL_FLOAT, tgt::Texture::LINEAR);
            break;
#endif
        default:
            LERROR("Unknown internal depth format!");
        }
        _depthTexture->uploadTexture();
        _depthTexture->setWrapping(tgt::Texture::CLAMP_TO_EDGE);

        _fbo = new tgt::FramebufferObject();
        if (!_fbo) {
            LERROR("Failed to initialize framebuffer object!");
            return;
        }
        _fbo->activate();

        _fbo->attachTexture(_colorTexture);
        _fbo->isComplete();
        _fbo->attachTexture(_depthTexture, GL_DEPTH_ATTACHMENT_EXT);
        _fbo->isComplete();

        _fbo->deactivate();
    }

    void ImageDataRenderTarget::activate() {
        _fbo->activate();
        glViewport(0, 0, _size.x, _size.y);
    }

    void ImageDataRenderTarget::deactivate() {
        _fbo->deactivate();
    }

    void ImageDataRenderTarget::bindColorTexture() const {
        _colorTexture->bind();
    }

    void ImageDataRenderTarget::bindColorTexture(GLint texUnit) const {
        glActiveTexture(texUnit);
        _colorTexture->bind();
    }

    void ImageDataRenderTarget::bindDepthTexture() const {
        _depthTexture->bind();
    }

    void ImageDataRenderTarget::bindDepthTexture(GLint texUnit) const {
        glActiveTexture(texUnit);
        _depthTexture->bind();
    }

    void ImageDataRenderTarget::bind(tgt::Shader* shader, GLint colorTexUnit /*= GL_TEXTURE0*/, GLint depthTexUnit /*= GL_TEXTURE1*/, const std::string& colorTexUniform /*= "_colorTexture"*/, const std::string& depthTexUniform /*= "_depthTexture"*/, const std::string& textureParametersUniform /*= "_textureParameters"*/) const {
        bindColorTexture(colorTexUnit);
        bindDepthTexture(depthTexUnit);
        shader->setUniform(colorTexUniform, 0);
        shader->setUniform(depthTexUniform, 1);
        shader->setUniform(textureParametersUniform + "._size", tgt::vec2(_size.xy()));
        shader->setUniform(textureParametersUniform + "._sizeRCP", tgt::vec2(1.f) / tgt::vec2(_size.xy()));
    }

    ImageDataRenderTarget* ImageDataRenderTarget::clone() const {
        tgtAssert(false, "To be implemented!");
        return 0;
    }

    ImageDataRenderTarget* ImageDataRenderTarget::getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const {
        tgtAssert(false, "To be implemented!");
        return 0;
    }

}