TextureBuffer.hh 3.67 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 (ACGL_OPENGL_VERSION >= 31)
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