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

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

Robert Menzel's avatar
Robert Menzel committed
10
/**
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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
26
27
 *
 ***************************************************************************************************************
Robert Menzel's avatar
Robert Menzel committed
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

Janis Born's avatar
Janis Born committed
68
69
70
class GeometryData;
ACGL_SMARTPOINTER_TYPEDEFS(GeometryData)

71
class ArrayBuffer : public Buffer
72
73
74
75
76
77
78
79
80
81
{
    // ==================================================================================================== \/
    // ============================================================================================ 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
82
        GLint       size;       // #elements per attribute, size in bytes would be: size*sizeof(type)
83
        GLuint      offset;     // offset in bytes into the array
Robert Menzel's avatar
Robert Menzel committed
84
        GLboolean   normalized; // int types can get normalzed to 0..1 / -1..1 by GL, useful e.g. for colors
85
        GLuint      divisor;    // vertex divisor for instancing, supported since OpenGL 3.3. Default is 0 (== off)
86
        GLboolean   isIntegerInShader; // should the data get read as vec or ivec ?
87
88
89
90
91
92
93
94
95
96
97
98
    };

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

    // ========================================================================================================= \/
    // ============================================================================================ CONSTRUCTORS \/
    // ========================================================================================================= \/
public:
Robert Menzel's avatar
Robert Menzel committed
99
    //! creates an ArrayBuffer with a new OpenGL Buffer object
100
    ArrayBuffer()
101
102
103
104
105
        : Buffer(GL_ARRAY_BUFFER),
        mStride(0),
        mAttributes()
    {}

Robert Menzel's avatar
Robert Menzel committed
106
    //! creates an ArrayBuffer with a pre-existing OpenGL Buffer
107
    ArrayBuffer( SharedBufferObject _pBuffer )
108
109
110
111
112
113
114
115
116
        : Buffer(_pBuffer, GL_ARRAY_BUFFER),
        mStride(0),
        mAttributes()
    {}

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

118
    //! elements is the number of vertices or instances (if the divisor is != 0):
119
    inline       GLsizei       getElements   (void) const { return (GLsizei) (mStride==0?0:(mSize/mStride)); }
Robert Menzel's avatar
Robert Menzel committed
120
121

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

    //! Returns the definitions of the attributes:
125
126
    inline const AttributeVec& getAttributes (void) const { return mAttributes; }

Robert Menzel's avatar
Robert Menzel committed
127
128
129
    //! Returns one attribute:
    inline Attribute getAttribute( uint_t i ) const { return mAttributes[i]; }

130
131
132
133
134
    // ==================================================================================================== \/
    // ============================================================================================ METHODS \/
    // ==================================================================================================== \/
public:
    //! Adds the attribute at the end of the existing attributes, stride gets computed automatically
135
    void defineAttribute(            const std::string& _name, GLenum _type, GLint _size, GLboolean _normalized = GL_FALSE, GLuint _divisor = 0);
136
    void defineIntegerAttribute(     const std::string& _name, GLenum _type, GLint _size, GLboolean _normalized = GL_FALSE, GLuint _divisor = 0);
137
138

    //! Adds the attribute at the end of the existing attributes, stride gets computed automatically
Robert Menzel's avatar
Robert Menzel committed
139
    //! + extra padding in bytes at the end
140
141
    void defineAttributeWithPadding(        const std::string& _name, GLenum _type, GLint _size, GLuint _padding, GLboolean _normalized = GL_FALSE, GLuint _divisor = 0);
    void defineIntegerAttributeWithPadding( const std::string& _name, GLenum _type, GLint _size, GLuint _padding, GLboolean _normalized = GL_FALSE, GLuint _divisor = 0);
142
143

    //! Adds an attribute defined by an offset: this way an attribute can get added at arbitrary
Robert Menzel's avatar
Robert Menzel committed
144
145
    //! 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...
146
147
    void defineAttributeWithOffset(        const std::string& _name, GLenum _type, GLint _size, GLuint _offset, GLboolean _normalized = GL_FALSE, GLuint _divisor = 0);
    void defineIntegerAttributeWithOffset( const std::string& _name, GLenum _type, GLint _size, GLuint _offset, GLboolean _normalized = GL_FALSE, GLuint _divisor = 0);
148
149

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

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

155
    //! Setting of the stride size explicitly is not needed if the attributes are defined correctly (with padding)
Robert Menzel's avatar
Robert Menzel committed
156
    inline void setStride( GLsizei _stride ) { mStride = _stride; }
157

Janis Born's avatar
Janis Born committed
158
159
160
    //! Sets all data (attributes, stride, size) to those specified in _geometryData. All previous data are overwritten.
    void setGeometryData( SharedGeometryData _geometryData );

161
162
163
164
165
166
167
    //! removes all attributes
    inline void removeAttributes(void)
    {
        mStride = 0;
        mAttributes.clear();
    }

168
    //! Set data for this buffer for a given number of elements (_elements*mStride == size in bytes)
169
170
171
172
173
    //! 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 );
    }

174
175
176
177
178
179
180
181
182
183
184
185
186
    //! 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
187
ACGL_SMARTPOINTER_TYPEDEFS(ArrayBuffer)
188
189


Robert Menzel's avatar
Robert Menzel committed
190
} // OpenGL
Robert Menzel's avatar
Robert Menzel committed
191
192
} // ACGL

193
#endif // ACGL_OPENGL_OBJECTS_ARRAYBUFFER_HH