ArrayBuffer.hh 8.23 KB
Newer Older
Robert Menzel's avatar
Robert Menzel committed
1
////////////////////////////////////////////////////////////////////////////////
Robert Menzel's avatar
Robert Menzel committed
2
// Copyright (c) 2011, 2012 Computer Graphics Group RWTH Aachen University    //
Robert Menzel's avatar
Robert Menzel committed
3 4 5
// All rights reserved.                                                       //
////////////////////////////////////////////////////////////////////////////////

6 7
#ifndef ACGL_OPENGL_OBJECTS_ARRAYBUFFER_HH
#define ACGL_OPENGL_OBJECTS_ARRAYBUFFER_HH
Robert Menzel's avatar
Robert Menzel committed
8

Robert Menzel's avatar
Robert Menzel committed
9
/**
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * An ArrayBuffer holds an array of per-vertex data. In its simplest form an
 * array of one attribute, for example the vertex position or texture-coordinate.
 * An ArrayBuffer however can also hold multiple attributes in an interleaved
 * way.
 *
 * An ArrayBuffer can be drawn directly or indexed in combination with an
 * ElementArrayBuffer.
 *
 * The combination of (multiple) attributes of (multiple) ArrayBuffers
 * and one (optional) ElementArrayBuffer is a VertexBufferObject or VertexArrayObject.
 *
 * Note: In some documents ArrayBuffers (and sometimes ElementArrayBuffers) are
 *       called VertexBufferObjects, VBOs. The original extension that introduced
 *       these two new buffer types was called ARB_vertex_buffer_object but the buffers
 *       itself are called ArrayBuffer and ElementArrayBuffer.
Robert Menzel's avatar
Robert Menzel committed
25 26
 *
 ***************************************************************************************************************
Robert Menzel's avatar
Robert Menzel committed
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
 * Attributes:
 *************
 *
 * _type is the GL type
 * _size the number of elements in this attribute (1..4)
 * _normalized is the attribute normalization for int types
 *
 * Want to add tightly packed attributes in order?
 *  -> use defineAttribute()
 *
 * Want to add attributes with individual padding in order?
 *  -> use defineAttributeWithPadding()
 *
 * Want to add attributes out-of-order?
 *  -> use defineAttributeWithOffset()
 *
 * The stride size gets always set to the minimal stride size that covers all defined attributes (/w padding).
 * All define methods can get mixed!
 *
 *
 * ab->defineAttribute(            "pos",       GL_FLOAT, 3    ); // stride: 12 bytes
 * ab->defineAttributeWithPadding( "color",     GL_CHAR,  3, 1 ); // stride: 12 + 3 + 1 = 16 bytes
 * ab->defineAttributeWithOffset(  "colorNorm", GL_CHAR,  3, 12, GL_TRUE ); // stride is still 16 as 12+3 <= 16!
 *
 **************************************************************************************************************/

Robert Menzel's avatar
Robert Menzel committed
53 54
#include <ACGL/ACGL.hh>

55
#include <ACGL/Base/Macros.hh>
Robert Menzel's avatar
Robert Menzel committed
56 57
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Tools.hh>
Robert Menzel's avatar
Robert Menzel committed
58 59 60 61

#include <string>
#include <vector>

62 63
#include <ACGL/OpenGL/Objects/Buffer.hh>

Robert Menzel's avatar
Robert Menzel committed
64
namespace ACGL{
Robert Menzel's avatar
Robert Menzel committed
65
namespace OpenGL{
Robert Menzel's avatar
Robert Menzel committed
66

67
class ArrayBuffer : public Buffer
68 69 70 71 72 73 74 75 76 77
{
    // ==================================================================================================== \/
    // ============================================================================================ STRUCTS \/
    // ==================================================================================================== \/
public:
    //! Each attribute has a size (#components, e.g. normal with x/y/z => 3) and an offset in the stride (in bytes)
    struct Attribute
    {
        std::string name;       // human readable name, can be used to match the attribute to shader programs
        GLenum      type;       // GL_FLOAT, GL_UNSIGNED_BYTE etc.
Robert Menzel's avatar
Robert Menzel committed
78
        GLint       size;       // #elements per attribute, size in bytes would be: size*sizeof(type)
79
        GLuint      offset;     // offset in bytes into the array
Robert Menzel's avatar
Robert Menzel committed
80
        GLboolean   normalized; // int types can get normalzed to 0..1 / -1..1 by GL, useful e.g. for colors
81 82 83 84 85 86 87 88 89 90 91 92
    };

    // ===================================================================================================== \/
    // ============================================================================================ TYPEDEFS \/
    // ===================================================================================================== \/
public:
    typedef std::vector< Attribute > AttributeVec;

    // ========================================================================================================= \/
    // ============================================================================================ CONSTRUCTORS \/
    // ========================================================================================================= \/
public:
Robert Menzel's avatar
Robert Menzel committed
93
    //! creates an ArrayBuffer with a new OpenGL Buffer object
94
    ArrayBuffer()
95 96 97 98 99
        : Buffer(GL_ARRAY_BUFFER),
        mStride(0),
        mAttributes()
    {}

Robert Menzel's avatar
Robert Menzel committed
100
    //! creates an ArrayBuffer with a pre-existing OpenGL Buffer
101
    ArrayBuffer( SharedBufferObject _pBuffer )
102 103 104 105 106 107 108 109 110
        : Buffer(_pBuffer, GL_ARRAY_BUFFER),
        mStride(0),
        mAttributes()
    {}

    // ==================================================================================================== \/
    // ============================================================================================ GETTERS \/
    // ==================================================================================================== \/
public:
Robert Menzel's avatar
Robert Menzel committed
111

Robert Menzel's avatar
Robert Menzel committed
112
    //! elements is the number of vertices (unless this AB should get interpreted in a strange way):
Robert Menzel's avatar
Robert Menzel committed
113
    inline       GLsizei       getElements   (void) const { return (GLsizei) (mSize/mStride); }
Robert Menzel's avatar
Robert Menzel committed
114 115

    //! size in bytes of all attributes that make up one element (vertex):
116
    inline       GLsizei       getStride     (void) const { return mStride;     }
Robert Menzel's avatar
Robert Menzel committed
117 118

    //! Returns the definitions of the attributes:
119 120 121 122 123 124 125
    inline const AttributeVec& getAttributes (void) const { return mAttributes; }

    // ==================================================================================================== \/
    // ============================================================================================ METHODS \/
    // ==================================================================================================== \/
public:
    //! Adds the attribute at the end of the existing attributes, stride gets computed automatically
Robert Menzel's avatar
Robert Menzel committed
126
    void defineAttribute(            const std::string& _name, GLenum _type, GLint _size, GLboolean _normalized = GL_FALSE);
127 128

    //! Adds the attribute at the end of the existing attributes, stride gets computed automatically
Robert Menzel's avatar
Robert Menzel committed
129
    //! + extra padding in bytes at the end
Robert Menzel's avatar
Robert Menzel committed
130
    void defineAttributeWithPadding( const std::string& _name, GLenum _type, GLint _size, GLuint _padding, GLboolean _normalized = GL_FALSE);
131 132

    //! Adds an attribute defined by an offset: this way an attribute can get added at arbitrary
Robert Menzel's avatar
Robert Menzel committed
133 134
    //! locations in the stride. If it's added at the end, the stride gets resized. This way attributes can even
    //! overlap, hope you know what you're doing...
Robert Menzel's avatar
Robert Menzel committed
135
    void defineAttributeWithOffset(  const std::string& _name, GLenum _type, GLint _size, GLuint _offset, GLboolean _normalized = GL_FALSE);
136 137

    //! Takes care of a valid stride size and adds the attribute
Robert Menzel's avatar
Robert Menzel committed
138
    void defineAttribute( const Attribute &_attribute );
139

140
    //! Returns the index of a named attribute
Robert Menzel's avatar
Robert Menzel committed
141
    int32_t getAttributeIndexByName(const std::string& _nameInArray) const;
142

143
    //! Setting of the stride size explicitly is not needed if the attributes are defined correctly (with padding)
Robert Menzel's avatar
Robert Menzel committed
144
    inline void setStride( GLsizei _stride ) { mStride = _stride; }
145 146 147 148 149 150 151 152

    //! removes all attributes
    inline void removeAttributes(void)
    {
        mStride = 0;
        mAttributes.clear();
    }

153 154 155 156 157 158
    //! Set data for this buffer for a given number of elements
    //! Use only after all attributes have been defined
    inline void setDataElements( uint_t _elements, const GLvoid *_pData = NULL, GLenum _usage = GL_STATIC_DRAW ) {
        setData( mTarget, _elements * mStride, _pData, _usage );
    }

159 160 161 162 163 164 165 166 167 168 169 170 171
    //! Overloaded from the base class to _prevent_ redefining of the binding target! (see Buffer)
    inline void setTarget( GLenum ) {
        ACGL::Utils::error() << "DON'T redefine the target binding point of an ArrayBuffer" << std::endl;
    }

    // =================================================================================================== \/
    // ============================================================================================ FIELDS \/
    // =================================================================================================== \/
protected:
    GLsizei      mStride;
    AttributeVec mAttributes;
};

Robert Menzel's avatar
Robert Menzel committed
172
ACGL_SMARTPOINTER_TYPEDEFS(ArrayBuffer)
173 174


Robert Menzel's avatar
Robert Menzel committed
175
} // OpenGL
Robert Menzel's avatar
Robert Menzel committed
176 177
} // ACGL

178
#endif // ACGL_OPENGL_OBJECTS_ARRAYBUFFER_HH