ArrayBuffer.hh 8.21 KB
Newer Older
Robert Menzel's avatar
Robert Menzel committed
1
2
3
4
5
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University         //
// 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

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * 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
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
/***************************************************************************************************************
 * 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
54
55
#include <ACGL/ACGL.hh>

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

#include <string>
#include <vector>

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

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

68
class ArrayBuffer : public Buffer
69
70
71
72
73
74
75
76
77
78
{
    // ==================================================================================================== \/
    // ============================================================================================ 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
79
        GLint       size;       // #elements per attribute, size in bytes would be: size*sizeof(type)
80
        GLuint      offset;     // offset in bytes into the array
Robert Menzel's avatar
Robert Menzel committed
81
        GLboolean   normalized; // int types can get normalzed to 0..1 / -1..1 by GL, useful e.g. for colors
82
83
84
85
86
87
88
89
90
91
92
93
    };

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

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

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

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

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

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

    //! Returns the definitions of the attributes:
120
121
122
123
124
125
126
    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
127
    void defineAttribute(            const std::string& _name, GLenum _type, GLint _size, GLboolean _normalized = GL_FALSE);
128
129

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

    //! Adds an attribute defined by an offset: this way an attribute can get added at arbitrary
Robert Menzel's avatar
Robert Menzel committed
134
135
    //! 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
136
    void defineAttributeWithOffset(  const std::string& _name, GLenum _type, GLint _size, GLuint _offset, GLboolean _normalized = GL_FALSE);
137
138

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

141
142
143
    //! Returns the index of a named attribute
    int_t getAttributeIndexByName(const std::string& _nameInArray) const;

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

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

154
155
156
157
158
159
    //! 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 );
    }

160
161
162
163
164
165
166
167
168
169
170
171
172
    //! 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;
};

173
ACGL_SHARED_TYPEDEF(ArrayBuffer)
174
175


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

179
#endif // ACGL_OPENGL_OBJECTS_ARRAYBUFFER_HH