Added sf::VertexBuffer class.
This commit is contained in:
parent
fe39af4ec8
commit
61cdcd47ca
10 changed files with 1165 additions and 47 deletions
|
@ -54,6 +54,7 @@
|
|||
#include <SFML/Graphics/Transformable.hpp>
|
||||
#include <SFML/Graphics/Vertex.hpp>
|
||||
#include <SFML/Graphics/VertexArray.hpp>
|
||||
#include <SFML/Graphics/VertexBuffer.hpp>
|
||||
#include <SFML/Graphics/View.hpp>
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
namespace sf
|
||||
{
|
||||
class Drawable;
|
||||
class VertexBuffer;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Base class for all render targets (window, texture, ...)
|
||||
|
@ -247,6 +248,26 @@ public:
|
|||
void draw(const Vertex* vertices, std::size_t vertexCount,
|
||||
PrimitiveType type, const RenderStates& states = RenderStates::Default);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Draw primitives defined by a vertex buffer
|
||||
///
|
||||
/// \param vertexBuffer Vertex buffer
|
||||
/// \param states Render states to use for drawing
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void draw(const VertexBuffer& vertexBuffer, const RenderStates& states = RenderStates::Default);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Draw primitives defined by a vertex buffer
|
||||
///
|
||||
/// \param vertexBuffer Vertex buffer
|
||||
/// \param firstVertex Index of the first vertex to render
|
||||
/// \param vertexCount Number of vertices to render
|
||||
/// \param states Render states to use for drawing
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void draw(const VertexBuffer& vertexBuffer, std::size_t firstVertex, std::size_t vertexCount, const RenderStates& states = RenderStates::Default);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the size of the rendering region of the target
|
||||
///
|
||||
|
@ -402,6 +423,33 @@ private:
|
|||
////////////////////////////////////////////////////////////
|
||||
void applyShader(const Shader* shader);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Setup environment for drawing
|
||||
///
|
||||
/// \param useVertexCache Are we going to use the vertex cache?
|
||||
/// \param states Render states to use for drawing
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void setupDraw(bool useVertexCache, const RenderStates& states);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Draw the primitives
|
||||
///
|
||||
/// \param type Type of primitives to draw
|
||||
/// \param firstVertex Index of the first vertex to use when drawing
|
||||
/// \param vertexCount Number of vertices to use when drawing
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void drawPrimitives(PrimitiveType type, std::size_t firstVertex, std::size_t vertexCount);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Clean up environment after drawing
|
||||
///
|
||||
/// \param states Render states used for drawing
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void cleanupDraw(const RenderStates& states);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Render states cache
|
||||
///
|
||||
|
|
408
include/SFML/Graphics/VertexBuffer.hpp
Normal file
408
include/SFML/Graphics/VertexBuffer.hpp
Normal file
|
@ -0,0 +1,408 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2017 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
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
Loading…
Add table
Add a link
Reference in a new issue