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