TextureBuffer.hh 3.69 KB
Newer Older
Robert Menzel's avatar
Robert Menzel committed
1
2
3
4
5
6
7
8
9
10
/***********************************************************************
 * Copyright 2011-2012 Computer Graphics Group RWTH Aachen University. *
 * All rights reserved.                                                *
 * Distributed under the terms of the MIT License (see LICENSE.TXT).   *
 **********************************************************************/

#ifndef ACGL_OPENGL_OBJECTS_TEXTUREBUFFER_HH
#define ACGL_OPENGL_OBJECTS_TEXTUREBUFFER_HH

/**
Janis Born's avatar
Janis Born committed
11
 * A Texture wraps the OpenGL texture buffer.
Robert Menzel's avatar
Robert Menzel committed
12
13
14
15
16
17
18
19
 *
 * TextureBuffers are 1D textures which store there data in a Buffer.
 * They are useful to access large chunks of data from within a shader.
 * Technically they are accessed as textures (uniform samplerBuffer) via texelFetch
 * with a 1D coordinate (int coordinate, so no filtering). This means they benefit from
 * texture caches.
 * Use these if the data doesn't fit into a UniformBufferObject.
 *
Janis Born's avatar
Janis Born committed
20
 * Data gets stored in the Buffer, no glTexImage calls are allowed!
Robert Menzel's avatar
Robert Menzel committed
21
22
23
24
25
26
27
28
 */

#include <ACGL/ACGL.hh>
#include <ACGL/Base/Macros.hh>
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Tools.hh>
#include <ACGL/OpenGL/Objects/Buffer.hh>

Janis Born's avatar
Janis Born committed
29
30
#include <cassert>

31
#if defined( ACGL_OPENGL_SUPPORTS_TEXTURE_BUFFER )
Robert Menzel's avatar
Robert Menzel committed
32
33
34
35
36
37
38
39
40

namespace ACGL{
namespace OpenGL{

class TextureBuffer : public Buffer
{
public:
    // create a new BufferObject with _reservedMemory space (in bytes!)
    TextureBuffer( GLenum _dataType, size_t _reservedMemory = 1 ) : Buffer(GL_TEXTURE_BUFFER) {
Robert Menzel's avatar
Robert Menzel committed
41
        mTextureObjectName = 0;
Robert Menzel's avatar
Robert Menzel committed
42
43
44
45
46
47
48
49
        glGenTextures(1, &mTextureObjectName);
        mDataType = _dataType;
        Buffer::setData( _reservedMemory );
        attachBufferToTexture();
    }

    // use an existing BufferObject
    TextureBuffer( GLenum _dataType, SharedBufferObject _pBuffer ) : Buffer(_pBuffer, GL_TEXTURE_BUFFER) {
Robert Menzel's avatar
Robert Menzel committed
50
        mTextureObjectName = 0;
Robert Menzel's avatar
Robert Menzel committed
51
52
53
54
55
56
57
58
59
60
61
62
63
        glGenTextures(1, &mTextureObjectName);
        mDataType = _dataType;
        attachBufferToTexture();
    }

    ~TextureBuffer() {
        setBufferObject( SharedBufferObject() ); // detach the Buffer
        glDeleteTextures(1, &mTextureObjectName);
    }

    //! the GL buffer can get changed at any time
    void setBufferObject( SharedBufferObject _pBuffer ) {
        Buffer::setBufferObject( _pBuffer );
Robert Menzel's avatar
Robert Menzel committed
64
        if (!_pBuffer) {
Robert Menzel's avatar
Robert Menzel committed
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
            // detach all buffers:
            glTexBuffer( GL_TEXTURE_BUFFER, mDataType, 0 );
        } else {
            attachBufferToTexture();
        }
    }

    //! Bind the texture part to access it from a shader
    void bindTexture(GLuint _textureUnit = 0) const {
        glActiveTexture(GL_TEXTURE0 + _textureUnit);
        glBindTexture(GL_TEXTURE_BUFFER, mTextureObjectName);
    }

    //! Bind the buffer part to change the data
    void bindBuffer() const {
        Buffer::bind();
    }

    inline GLuint  getTextureObjectName() const { return mTextureObjectName; }
    inline GLuint  getBufferObjectName()  const { return Buffer::getObjectName(); }

private:
    //! private to prevent it from being called -> it's not clear whether the texture or the buffer should get bound, call
    //! bindBuffer() or bindTexture() directly!
    void bind() {}

    void attachBufferToTexture() {
Robert Menzel's avatar
Robert Menzel committed
92
        if (!mBuffer) {
93
94
95
96
97
98
99
100
            // the buffer was in fact detached
            bindTexture();
            glTexBuffer( GL_TEXTURE_BUFFER, mDataType, 0 );
        } else {
            assert( Buffer::getSize() > 0 && "glTexBuffer will fail if the buffer is empty" );
            bindTexture();
            glTexBuffer( GL_TEXTURE_BUFFER, mDataType, Buffer::getObjectName() );
        }
Robert Menzel's avatar
Robert Menzel committed
101
102
103
104
105
106
107
108
109
110
111
112
113
114
    }

    GLenum mDataType;
    GLuint mTextureObjectName;
};
ACGL_SMARTPOINTER_TYPEDEFS(TextureBuffer)

} // namespace
} // namespace

#endif // OpenGL 3.0+


#endif // ACGL_OPENGL_OBJECTS_TEXTUREBUFFER_HH