summaryrefslogtreecommitdiff
path: root/include/SFML/Graphics/VertexBuffer.hpp
blob: b7a58bfe1670e8123cda6d48916300102b0e287e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////

#ifndef SFML_VERTEXBUFFER_HPP
#define SFML_VERTEXBUFFER_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/Export.hpp>
#include <SFML/Graphics/PrimitiveType.hpp>
#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Window/GlResource.hpp>


namespace sf
{
class RenderTarget;
class Vertex;

////////////////////////////////////////////////////////////
/// \brief Vertex buffer storage for one or more 2D primitives
///
////////////////////////////////////////////////////////////
class SFML_GRAPHICS_API VertexBuffer : public Drawable, private GlResource
{
public:

    ////////////////////////////////////////////////////////////
    /// \brief Usage specifiers
    ///
    /// If data is going to be updated once or more every frame,
    /// set the usage to Stream. If data is going to be set once
    /// and used for a long time without being modified, set the
    /// usage to Static. For everything else Dynamic should be a
    /// good compromise.
    ///
    ////////////////////////////////////////////////////////////
    enum Usage
    {
        Stream,  //!< Constantly changing data
        Dynamic, //!< Occasionally changing data
        Static   //!< Rarely changing data
    };

    ////////////////////////////////////////////////////////////
    /// \brief Default constructor
    ///
    /// Creates an empty vertex buffer.
    ///
    ////////////////////////////////////////////////////////////
    VertexBuffer();

    ////////////////////////////////////////////////////////////
    /// \brief Construct a VertexBuffer with a specific PrimitiveType
    ///
    /// Creates an empty vertex buffer and sets its primitive type to \p type.
    ///
    /// \param type Type of primitive
    ///
    ////////////////////////////////////////////////////////////
    explicit VertexBuffer(PrimitiveType type);

    ////////////////////////////////////////////////////////////
    /// \brief Construct a VertexBuffer with a specific usage specifier
    ///
    /// Creates an empty vertex buffer and sets its usage to \p usage.
    ///
    /// \param usage Usage specifier
    ///
    ////////////////////////////////////////////////////////////
    explicit VertexBuffer(Usage usage);

    ////////////////////////////////////////////////////////////
    /// \brief Construct a VertexBuffer with a specific PrimitiveType and usage specifier
    ///
    /// Creates an empty vertex buffer and sets its primitive type
    /// to \p type and usage to \p usage.
    ///
    /// \param type  Type of primitive
    /// \param usage Usage specifier
    ///
    ////////////////////////////////////////////////////////////
    VertexBuffer(PrimitiveType type, Usage usage);

    ////////////////////////////////////////////////////////////
    /// \brief Copy constructor
    ///
    /// \param copy instance to copy
    ///
    ////////////////////////////////////////////////////////////
    VertexBuffer(const VertexBuffer& copy);

    ////////////////////////////////////////////////////////////
    /// \brief Destructor
    ///
    ////////////////////////////////////////////////////////////
    ~VertexBuffer();

    ////////////////////////////////////////////////////////////
    /// \brief Create the vertex buffer
    ///
    /// Creates the vertex buffer and allocates enough graphics
    /// memory to hold \p vertexCount vertices. Any previously
    /// allocated memory is freed in the process.
    ///
    /// In order to deallocate previously allocated memory pass 0
    /// as \p vertexCount. Don't forget to recreate with a non-zero
    /// value when graphics memory should be allocated again.
    ///
    /// \param vertexCount Number of vertices worth of memory to allocate
    ///
    /// \return True if creation was successful
    ///
    ////////////////////////////////////////////////////////////
    bool create(std::size_t vertexCount);

    ////////////////////////////////////////////////////////////
    /// \brief Return the vertex count
    ///
    /// \return Number of vertices in the vertex buffer
    ///
    ////////////////////////////////////////////////////////////
    std::size_t getVertexCount() const;

    ////////////////////////////////////////////////////////////
    /// \brief Update the whole buffer from an array of vertices
    ///
    /// The \a vertex array is assumed to have the same size as
    /// the \a created buffer.
    ///
    /// No additional check is performed on the size of the vertex
    /// array, passing invalid arguments will lead to undefined
    /// behavior.
    ///
    /// This function does nothing if \a vertices is null or if the
    /// buffer was not previously created.
    ///
    /// \param vertices Array of vertices to copy to the buffer
    ///
    /// \return True if the update was successful
    ///
    ////////////////////////////////////////////////////////////
    bool update(const Vertex* vertices);

    ////////////////////////////////////////////////////////////
    /// \brief Update a part of the buffer from an array of vertices
    ///
    /// \p offset is specified as the number of vertices to skip
    /// from the beginning of the buffer.
    ///
    /// If \p offset is 0 and \p vertexCount is equal to the size of
    /// the currently created buffer, its whole contents are replaced.
    ///
    /// If \p offset is 0 and \p vertexCount is greater than the
    /// size of the currently created buffer, a new buffer is created
    /// containing the vertex data.
    ///
    /// If \p offset is 0 and \p vertexCount is less than the size of
    /// the currently created buffer, only the corresponding region
    /// is updated.
    ///
    /// If \p offset is not 0 and \p offset + \p vertexCount is greater
    /// than the size of the currently created buffer, the update fails.
    ///
    /// No additional check is performed on the size of the vertex
    /// array, passing invalid arguments will lead to undefined
    /// behavior.
    ///
    /// \param vertices    Array of vertices to copy to the buffer
    /// \param vertexCount Number of vertices to copy
    /// \param offset      Offset in the buffer to copy to
    ///
    /// \return True if the update was successful
    ///
    ////////////////////////////////////////////////////////////
    bool update(const Vertex* vertices, std::size_t vertexCount, unsigned int offset);

    ////////////////////////////////////////////////////////////
    /// \brief Copy the contents of another buffer into this buffer
    ///
    /// \param vertexBuffer Vertex buffer whose contents to copy into this vertex buffer
    ///
    /// \return True if the copy was successful
    ///
    ////////////////////////////////////////////////////////////
    bool update(const VertexBuffer& vertexBuffer);

    ////////////////////////////////////////////////////////////
    /// \brief Overload of assignment operator
    ///
    /// \param right Instance to assign
    ///
    /// \return Reference to self
    ///
    ////////////////////////////////////////////////////////////
    VertexBuffer& operator =(const VertexBuffer& right);

    ////////////////////////////////////////////////////////////
    /// \brief Swap the contents of this vertex buffer with those of another
    ///
    /// \param right Instance to swap with
    ///
    ////////////////////////////////////////////////////////////
    void swap(VertexBuffer& right);

    ////////////////////////////////////////////////////////////
    /// \brief Get the underlying OpenGL handle of the vertex buffer.
    ///
    /// You shouldn't need to use this function, unless you have
    /// very specific stuff to implement that SFML doesn't support,
    /// or implement a temporary workaround until a bug is fixed.
    ///
    /// \return OpenGL handle of the vertex buffer or 0 if not yet created
    ///
    ////////////////////////////////////////////////////////////
    unsigned int getNativeHandle() const;

    ////////////////////////////////////////////////////////////
    /// \brief Set the type of primitives to draw
    ///
    /// This function defines how the vertices must be interpreted
    /// when it's time to draw them.
    ///
    /// The default primitive type is sf::Points.
    ///
    /// \param type Type of primitive
    ///
    ////////////////////////////////////////////////////////////
    void setPrimitiveType(PrimitiveType type);

    ////////////////////////////////////////////////////////////
    /// \brief Get the type of primitives drawn by the vertex buffer
    ///
    /// \return Primitive type
    ///
    ////////////////////////////////////////////////////////////
    PrimitiveType getPrimitiveType() const;

    ////////////////////////////////////////////////////////////
    /// \brief Set the usage specifier of this vertex buffer
    ///
    /// This function provides a hint about how this vertex buffer is
    /// going to be used in terms of data update frequency.
    ///
    /// After changing the usage specifier, the vertex buffer has
    /// to be updated with new data for the usage specifier to
    /// take effect.
    ///
    /// The default primitive type is sf::VertexBuffer::Stream.
    ///
    /// \param usage Usage specifier
    ///
    ////////////////////////////////////////////////////////////
    void setUsage(Usage usage);

    ////////////////////////////////////////////////////////////
    /// \brief Get the usage specifier of this vertex buffer
    ///
    /// \return Usage specifier
    ///
    ////////////////////////////////////////////////////////////
    Usage getUsage() const;

    ////////////////////////////////////////////////////////////
    /// \brief Bind a vertex buffer for rendering
    ///
    /// This function is not part of the graphics API, it mustn't be
    /// used when drawing SFML entities. It must be used only if you
    /// mix sf::VertexBuffer with OpenGL code.
    ///
    /// \code
    /// sf::VertexBuffer vb1, vb2;
    /// ...
    /// sf::VertexBuffer::bind(&vb1);
    /// // draw OpenGL stuff that use vb1...
    /// sf::VertexBuffer::bind(&vb2);
    /// // draw OpenGL stuff that use vb2...
    /// sf::VertexBuffer::bind(NULL);
    /// // draw OpenGL stuff that use no vertex buffer...
    /// \endcode
    ///
    /// \param vertexBuffer Pointer to the vertex buffer to bind, can be null to use no vertex buffer
    ///
    ////////////////////////////////////////////////////////////
    static void bind(const VertexBuffer* vertexBuffer);

    ////////////////////////////////////////////////////////////
    /// \brief Tell whether or not the system supports vertex buffers
    ///
    /// This function should always be called before using
    /// the vertex buffer features. If it returns false, then
    /// any attempt to use sf::VertexBuffer will fail.
    ///
    /// \return True if vertex buffers are supported, false otherwise
    ///
    ////////////////////////////////////////////////////////////
    static bool isAvailable();

private:

    ////////////////////////////////////////////////////////////
    /// \brief Draw the vertex buffer to a render target
    ///
    /// \param target Render target to draw to
    /// \param states Current render states
    ///
    ////////////////////////////////////////////////////////////
    virtual void draw(RenderTarget& target, RenderStates states) const;

private:

    ////////////////////////////////////////////////////////////
    // Member data
    ////////////////////////////////////////////////////////////
    unsigned int  m_buffer;        //!< Internal buffer identifier
    std::size_t   m_size;          //!< Size in Vertexes of the currently allocated buffer
    PrimitiveType m_primitiveType; //!< Type of primitives to draw
    Usage         m_usage;         //!< How this vertex buffer is to be used
};

} // namespace sf


#endif // SFML_VERTEXBUFFER_HPP


////////////////////////////////////////////////////////////
/// \class sf::VertexBuffer
/// \ingroup graphics
///
/// sf::VertexBuffer is a simple wrapper around a dynamic
/// buffer of vertices and a primitives type.
///
/// Unlike sf::VertexArray, the vertex data is stored in
/// graphics memory.
///
/// In situations where a large amount of vertex data would
/// have to be transferred from system memory to graphics memory
/// every frame, using sf::VertexBuffer can help. By using a
/// sf::VertexBuffer, data that has not been changed between frames
/// does not have to be re-transferred from system to graphics
/// memory as would be the case with sf::VertexArray. If data transfer
/// is a bottleneck, this can lead to performance gains.
///
/// Using sf::VertexBuffer, the user also has the ability to only modify
/// a portion of the buffer in graphics memory. This way, a large buffer
/// can be allocated at the start of the application and only the
/// applicable portions of it need to be updated during the course of
/// the application. This allows the user to take full control of data
/// transfers between system and graphics memory if they need to.
///
/// In special cases, the user can make use of multiple threads to update
/// vertex data in multiple distinct regions of the buffer simultaneously.
/// This might make sense when e.g. the position of multiple objects has to
/// be recalculated very frequently. The computation load can be spread
/// across multiple threads as long as there are no other data dependencies.
///
/// Simultaneous updates to the vertex buffer are not guaranteed to be
/// carried out by the driver in any specific order. Updating the same
/// region of the buffer from multiple threads will not cause undefined
/// behaviour, however the final state of the buffer will be unpredictable.
///
/// Simultaneous updates of distinct non-overlapping regions of the buffer
/// are also not guaranteed to complete in a specific order. However, in
/// this case the user can make sure to synchronize the writer threads at
/// well-defined points in their code. The driver will make sure that all
/// pending data transfers complete before the vertex buffer is sourced
/// by the rendering pipeline.
///
/// It inherits sf::Drawable, but unlike other drawables it
/// is not transformable.
///
/// Example:
/// \code
/// sf::Vertex vertices[15];
/// ...
/// sf::VertexBuffer triangles(sf::Triangles);
/// triangles.create(15);
/// triangles.update(vertices);
/// ...
/// window.draw(triangles);
/// \endcode
///
/// \see sf::Vertex, sf::VertexArray
///
////////////////////////////////////////////////////////////