ArrayBuffer.hh 8.11 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
#include <ACGL/ACGL.hh>

29
#include <ACGL/Base/Macros.hh>
Robert Menzel's avatar
Robert Menzel committed
30
31
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Tools.hh>
Robert Menzel's avatar
Robert Menzel committed
32
33
34

#include <string>
#include <vector>
Robert Menzel's avatar
Robert Menzel committed
35
#include <tr1/memory>
Robert Menzel's avatar
Robert Menzel committed
36
37

namespace ACGL{
Robert Menzel's avatar
Robert Menzel committed
38
namespace OpenGL{
Robert Menzel's avatar
Robert Menzel committed
39
40
41

class ArrayBuffer
{
42
    ACGL_NOT_COPYABLE(ArrayBuffer)
43

Robert Menzel's avatar
Robert Menzel committed
44
45
46
47
48
49
50
51
    // ==================================================================================================== \/
    // ============================================================================================ STRUCTS \/
    // ==================================================================================================== \/
public:
    //! Each attribute has a dimension (#components, e.g. normal with x/y/z => 3) and an offset in the stride (in bytes)
    struct Attribute
    {
        std::string name;
52
53
54
55
        GLenum      type;
        GLint       dimension;
        GLint       offset;
        GLboolean   normalized;
Robert Menzel's avatar
Robert Menzel committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    };

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

    // ========================================================================================================= \/
    // ============================================================================================ CONSTRUCTORS \/
    // ========================================================================================================= \/
public:
    ArrayBuffer(
        GLenum _usage = GL_STATIC_DRAW,
        GLenum _mode = GL_TRIANGLES)
71
    :   mObjectName(0),
Robert Menzel's avatar
Robert Menzel committed
72
73
74
75
76
77
        mUsage(_usage),
        mMode(_mode),
        mElements(0),
        mStride(0),
        mAttributes()
    {
78
        glGenBuffers(1, &mObjectName);
79
80
81
        if (openGLCriticalErrorOccured() ) {
            ACGL::Utils::error() << "could not generate array buffer!" << std::endl;
        }
Robert Menzel's avatar
Robert Menzel committed
82
83
84
85
    }

    virtual ~ArrayBuffer(void)
    {
86
        // buffer 0 will get ignored by OpenGL
87
        glDeleteBuffers(1, &mObjectName);
Robert Menzel's avatar
Robert Menzel committed
88
89
90
91
92
93
    }

    // ==================================================================================================== \/
    // ============================================================================================ GETTERS \/
    // ==================================================================================================== \/
public:
94
95
    inline       GLuint        operator()    (void) const { return mObjectName; }
    inline       GLuint        getObjectName (void) const { return mObjectName; }
Robert Menzel's avatar
Robert Menzel committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    inline       GLenum        getUsage      (void) const { return mUsage;      }
    inline       GLenum        getMode       (void) const { return mMode;       }
    inline       GLsizei       getElements   (void) const { return mElements;   }
    inline       GLsizei       getStride     (void) const { return mStride;     }
    inline const AttributeVec& getAttributes (void) const { return mAttributes; }

    // ==================================================================================================== \/
    // ============================================================================================ METHODS \/
    // ==================================================================================================== \/
public:
    int_t getAttributeIndexByName(const std::string& _nameInArray) const;

    inline void attachAttribute(
        const std::string& _name,
        GLenum _type,
111
112
        GLint _dimension,
        GLboolean _normalized = GL_FALSE)
Robert Menzel's avatar
Robert Menzel committed
113
114
115
116
117
    {
        Attribute attribute = {
            _name,
            _type,
            _dimension,
118
119
            mStride,
            _normalized};
Robert Menzel's avatar
Robert Menzel committed
120
        mStride += getGLTypeSize(_type) * _dimension;
Robert Menzel's avatar
Robert Menzel committed
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
        mAttributes.push_back(attribute);
    }

    inline void removeAttributes(void)
    {
        mStride = 0;
        mAttributes.clear();
    }

    // ===================================================================================================== \/
    // ============================================================================================ WRAPPERS \/
    // ===================================================================================================== \/
public:
    void render(void) const;

    void draw(void) const
    {
        glDrawArrays(mMode, 0, mElements);
139
        openGLRareError();
Robert Menzel's avatar
Robert Menzel committed
140
141
    }

142
143
144
    void draw(GLint _first, GLsizei _count) const
    {
        glDrawArrays(mMode, _first, _count);
145
        openGLRareError();
146
147
    }

Robert Menzel's avatar
Robert Menzel committed
148
149
150
    //! Bind this buffer
    inline void bind(void) const
    {
151
        glBindBuffer(GL_ARRAY_BUFFER, mObjectName);
152
        openGLRareError();
Robert Menzel's avatar
Robert Menzel committed
153
154
    }

155
    inline void setAttributePointer(AttributeVec::size_type _indexInArray, GLuint _indexInShader) const
Robert Menzel's avatar
Robert Menzel committed
156
157
158
159
160
    {
        glVertexAttribPointer(
            _indexInShader,
            mAttributes[_indexInArray].dimension,
            mAttributes[_indexInArray].type,
161
            mAttributes[_indexInArray].normalized,
Robert Menzel's avatar
Robert Menzel committed
162
163
            mStride,
            reinterpret_cast<GLvoid*>(mAttributes[_indexInArray].offset));
164
        openGLRareError();
Robert Menzel's avatar
Robert Menzel committed
165
166
    }

167
    inline bool setAttributePointer(const std::string& _nameInArray, GLuint _indexInShader) const
Robert Menzel's avatar
Robert Menzel committed
168
169
170
171
172
    {
        int_t index = getAttributeIndexByName(_nameInArray);
        if(index == -1)
            return false;

173
        setAttributePointer(index, _indexInShader);
Robert Menzel's avatar
Robert Menzel committed
174
        return true;
175
    }    
Robert Menzel's avatar
Robert Menzel committed
176

177
178
179
180
181
182
    //! Set data for this buffer and change its size, usage and mode
    inline void setData(
        const GLvoid* _pData,
        GLsizei       _elements,
        GLenum        _usage,
        GLenum        _mode)
Robert Menzel's avatar
Robert Menzel committed
183
    {
184
185
186
        mUsage = _usage;
        mMode  = _mode;
        setData( _pData, _elements );
Robert Menzel's avatar
Robert Menzel committed
187
188
189
    }

    //! Set data for this buffer and change its size
190
191
    inline void setData(
        const GLvoid* _pData,
192
        GLsizei       _elements)
193
194
    {
        mElements = _elements;
195
        setData( _pData );
196
197
    }

198
199
200
    //! Set data for this buffer
    //! Note: The function is not const, because it changes the corresponding GPU data
    inline void setData(const GLvoid* _pData)
Robert Menzel's avatar
Robert Menzel committed
201
    {
202
        glBindBuffer(GL_ARRAY_BUFFER, mObjectName);
Robert Menzel's avatar
Robert Menzel committed
203
204
205
206
207
208
209
210
211
212
213
        glBufferData(
            GL_ARRAY_BUFFER,
            mStride * mElements,
            _pData,
            mUsage);
    }

    // =================================================================================================== \/
    // ============================================================================================ FIELDS \/
    // =================================================================================================== \/
protected:
214
    GLuint       mObjectName;
Robert Menzel's avatar
Robert Menzel committed
215
216
217
218
219
220
221
    GLenum       mUsage;
    GLenum       mMode;
    GLsizei      mElements;
    GLsizei      mStride;
    AttributeVec mAttributes;
};

222
ACGL_SHARED_TYPEDEF(ArrayBuffer)
Robert Menzel's avatar
Robert Menzel committed
223
224

} // OpenGL
Robert Menzel's avatar
Robert Menzel committed
225
226
} // ACGL

227
#endif // ACGL_OPENGL_OBJECTS_ARRAYBUFFER_HH