Added sf::VertexBuffer class.
This commit is contained in:
parent
fe39af4ec8
commit
61cdcd47ca
@ -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
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
@ -72,6 +72,8 @@ set(DRAWABLES_SRC
|
||||
${INCROOT}/Text.hpp
|
||||
${SRCROOT}/VertexArray.cpp
|
||||
${INCROOT}/VertexArray.hpp
|
||||
${SRCROOT}/VertexBuffer.cpp
|
||||
${INCROOT}/VertexBuffer.hpp
|
||||
)
|
||||
source_group("drawables" FILES ${DRAWABLES_SRC})
|
||||
|
||||
|
@ -53,6 +53,19 @@
|
||||
#define GLEXT_GL_CLAMP GL_CLAMP_TO_EDGE
|
||||
#define GLEXT_GL_CLAMP_TO_EDGE GL_CLAMP_TO_EDGE
|
||||
|
||||
// Core since 1.1
|
||||
// 1.1 does not support GL_STREAM_DRAW so we just define it to GL_DYNAMIC_DRAW
|
||||
#define GLEXT_vertex_buffer_object true
|
||||
#define GLEXT_GL_ARRAY_BUFFER GL_ARRAY_BUFFER
|
||||
#define GLEXT_GL_DYNAMIC_DRAW GL_DYNAMIC_DRAW
|
||||
#define GLEXT_GL_STATIC_DRAW GL_STATIC_DRAW
|
||||
#define GLEXT_GL_STREAM_DRAW GL_DYNAMIC_DRAW
|
||||
#define GLEXT_glBindBuffer glBindBuffer
|
||||
#define GLEXT_glBufferData glBufferData
|
||||
#define GLEXT_glBufferSubData glBufferSubData
|
||||
#define GLEXT_glDeleteBuffers glDeleteBuffers
|
||||
#define GLEXT_glGenBuffers glGenBuffers
|
||||
|
||||
// The following extensions are listed chronologically
|
||||
// Extension macro first, followed by tokens then
|
||||
// functions according to the corresponding specification
|
||||
@ -114,6 +127,9 @@
|
||||
// Core since 3.0
|
||||
#define GLEXT_framebuffer_blit false
|
||||
|
||||
// Core since 3.0 - NV_copy_buffer
|
||||
#define GLEXT_copy_buffer false
|
||||
|
||||
// Core since 3.0 - EXT_sRGB
|
||||
#ifdef GL_EXT_sRGB
|
||||
#define GLEXT_texture_sRGB GL_EXT_sRGB
|
||||
@ -168,6 +184,22 @@
|
||||
#define GLEXT_blend_func_separate sfogl_ext_EXT_blend_func_separate
|
||||
#define GLEXT_glBlendFuncSeparate glBlendFuncSeparateEXT
|
||||
|
||||
// Core since 1.5 - ARB_vertex_buffer_object
|
||||
#define GLEXT_vertex_buffer_object sfogl_ext_ARB_vertex_buffer_object
|
||||
#define GLEXT_GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB
|
||||
#define GLEXT_GL_DYNAMIC_DRAW GL_DYNAMIC_DRAW_ARB
|
||||
#define GLEXT_GL_READ_ONLY GL_READ_ONLY_ARB
|
||||
#define GLEXT_GL_STATIC_DRAW GL_STATIC_DRAW_ARB
|
||||
#define GLEXT_GL_STREAM_DRAW GL_STREAM_DRAW_ARB
|
||||
#define GLEXT_GL_WRITE_ONLY GL_WRITE_ONLY_ARB
|
||||
#define GLEXT_glBindBuffer glBindBufferARB
|
||||
#define GLEXT_glBufferData glBufferDataARB
|
||||
#define GLEXT_glBufferSubData glBufferSubDataARB
|
||||
#define GLEXT_glDeleteBuffers glDeleteBuffersARB
|
||||
#define GLEXT_glGenBuffers glGenBuffersARB
|
||||
#define GLEXT_glMapBuffer glMapBufferARB
|
||||
#define GLEXT_glUnmapBuffer glUnmapBufferARB
|
||||
|
||||
// Core since 2.0 - ARB_shading_language_100
|
||||
#define GLEXT_shading_language_100 sfogl_ext_ARB_shading_language_100
|
||||
|
||||
@ -254,6 +286,12 @@
|
||||
#define GLEXT_GL_DRAW_FRAMEBUFFER_BINDING GL_DRAW_FRAMEBUFFER_BINDING_EXT
|
||||
#define GLEXT_GL_READ_FRAMEBUFFER_BINDING GL_READ_FRAMEBUFFER_BINDING_EXT
|
||||
|
||||
// Core since 3.1 - ARB_copy_buffer
|
||||
#define GLEXT_copy_buffer sfogl_ext_ARB_copy_buffer
|
||||
#define GLEXT_GL_COPY_READ_BUFFER GL_COPY_READ_BUFFER
|
||||
#define GLEXT_GL_COPY_WRITE_BUFFER GL_COPY_WRITE_BUFFER
|
||||
#define GLEXT_glCopyBufferSubData glCopyBufferSubData
|
||||
|
||||
// Core since 3.2 - ARB_geometry_shader4
|
||||
#define GLEXT_geometry_shader4 sfogl_ext_ARB_geometry_shader4
|
||||
#define GLEXT_GL_GEOMETRY_SHADER GL_GEOMETRY_SHADER_ARB
|
||||
|
@ -7,6 +7,7 @@ EXT_blend_minmax
|
||||
EXT_blend_subtract
|
||||
ARB_multitexture
|
||||
EXT_blend_func_separate
|
||||
ARB_vertex_buffer_object
|
||||
ARB_shading_language_100
|
||||
ARB_shader_objects
|
||||
ARB_vertex_shader
|
||||
@ -16,4 +17,5 @@ EXT_blend_equation_separate
|
||||
EXT_texture_sRGB
|
||||
EXT_framebuffer_object
|
||||
EXT_framebuffer_blit
|
||||
ARB_copy_buffer
|
||||
ARB_geometry_shader4
|
||||
|
@ -39,6 +39,7 @@ int sfogl_ext_EXT_blend_minmax = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_blend_subtract = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_multitexture = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_blend_func_separate = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_vertex_buffer_object = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_shading_language_100 = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_shader_objects = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_vertex_shader = sfogl_LOAD_FAILED;
|
||||
@ -48,6 +49,7 @@ int sfogl_ext_EXT_blend_equation_separate = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_texture_sRGB = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_framebuffer_object = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_framebuffer_blit = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_copy_buffer = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_geometry_shader4 = sfogl_LOAD_FAILED;
|
||||
|
||||
void (GL_FUNCPTR *sf_ptrc_glBlendEquationEXT)(GLenum) = NULL;
|
||||
@ -254,6 +256,69 @@ static int Load_EXT_blend_func_separate()
|
||||
return numFailed;
|
||||
}
|
||||
|
||||
void (GL_FUNCPTR *sf_ptrc_glBindBufferARB)(GLenum, GLuint) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glBufferDataARB)(GLenum, GLsizeiptrARB, const void*, GLenum) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glBufferSubDataARB)(GLenum, GLintptrARB, GLsizeiptrARB, const void*) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glDeleteBuffersARB)(GLsizei, const GLuint*) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glGenBuffersARB)(GLsizei, GLuint*) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glGetBufferParameterivARB)(GLenum, GLenum, GLint*) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glGetBufferPointervARB)(GLenum, GLenum, void**) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glGetBufferSubDataARB)(GLenum, GLintptrARB, GLsizeiptrARB, void*) = NULL;
|
||||
GLboolean (GL_FUNCPTR *sf_ptrc_glIsBufferARB)(GLuint) = NULL;
|
||||
void* (GL_FUNCPTR *sf_ptrc_glMapBufferARB)(GLenum, GLenum) = NULL;
|
||||
GLboolean (GL_FUNCPTR *sf_ptrc_glUnmapBufferARB)(GLenum) = NULL;
|
||||
|
||||
static int Load_ARB_vertex_buffer_object()
|
||||
{
|
||||
int numFailed = 0;
|
||||
|
||||
sf_ptrc_glBindBufferARB = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLuint)>(glLoaderGetProcAddress("glBindBufferARB"));
|
||||
if (!sf_ptrc_glBindBufferARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glBufferDataARB = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLsizeiptrARB, const void*, GLenum)>(glLoaderGetProcAddress("glBufferDataARB"));
|
||||
if (!sf_ptrc_glBufferDataARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glBufferSubDataARB = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLintptrARB, GLsizeiptrARB, const void*)>(glLoaderGetProcAddress("glBufferSubDataARB"));
|
||||
if (!sf_ptrc_glBufferSubDataARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glDeleteBuffersARB = reinterpret_cast<void (GL_FUNCPTR *)(GLsizei, const GLuint*)>(glLoaderGetProcAddress("glDeleteBuffersARB"));
|
||||
if (!sf_ptrc_glDeleteBuffersARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glGenBuffersARB = reinterpret_cast<void (GL_FUNCPTR *)(GLsizei, GLuint*)>(glLoaderGetProcAddress("glGenBuffersARB"));
|
||||
if (!sf_ptrc_glGenBuffersARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glGetBufferParameterivARB = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLenum, GLint*)>(glLoaderGetProcAddress("glGetBufferParameterivARB"));
|
||||
if (!sf_ptrc_glGetBufferParameterivARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glGetBufferPointervARB = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLenum, void**)>(glLoaderGetProcAddress("glGetBufferPointervARB"));
|
||||
if (!sf_ptrc_glGetBufferPointervARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glGetBufferSubDataARB = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLintptrARB, GLsizeiptrARB, void*)>(glLoaderGetProcAddress("glGetBufferSubDataARB"));
|
||||
if (!sf_ptrc_glGetBufferSubDataARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glIsBufferARB = reinterpret_cast<GLboolean (GL_FUNCPTR *)(GLuint)>(glLoaderGetProcAddress("glIsBufferARB"));
|
||||
if (!sf_ptrc_glIsBufferARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glMapBufferARB = reinterpret_cast<void* (GL_FUNCPTR *)(GLenum, GLenum)>(glLoaderGetProcAddress("glMapBufferARB"));
|
||||
if (!sf_ptrc_glMapBufferARB)
|
||||
numFailed++;
|
||||
|
||||
sf_ptrc_glUnmapBufferARB = reinterpret_cast<GLboolean (GL_FUNCPTR *)(GLenum)>(glLoaderGetProcAddress("glUnmapBufferARB"));
|
||||
if (!sf_ptrc_glUnmapBufferARB)
|
||||
numFailed++;
|
||||
|
||||
return numFailed;
|
||||
}
|
||||
|
||||
void (GL_FUNCPTR *sf_ptrc_glAttachObjectARB)(GLhandleARB, GLhandleARB) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glCompileShaderARB)(GLhandleARB) = NULL;
|
||||
GLhandleARB (GL_FUNCPTR *sf_ptrc_glCreateProgramObjectARB)() = NULL;
|
||||
@ -814,6 +879,19 @@ static int Load_EXT_framebuffer_blit()
|
||||
return numFailed;
|
||||
}
|
||||
|
||||
void (GL_FUNCPTR *sf_ptrc_glCopyBufferSubData)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr) = NULL;
|
||||
|
||||
static int Load_ARB_copy_buffer()
|
||||
{
|
||||
int numFailed = 0;
|
||||
|
||||
sf_ptrc_glCopyBufferSubData = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr)>(glLoaderGetProcAddress("glCopyBufferSubData"));
|
||||
if (!sf_ptrc_glCopyBufferSubData)
|
||||
numFailed++;
|
||||
|
||||
return numFailed;
|
||||
}
|
||||
|
||||
void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureARB)(GLenum, GLenum, GLuint, GLint) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureFaceARB)(GLenum, GLenum, GLuint, GLint, GLenum) = NULL;
|
||||
void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureLayerARB)(GLenum, GLenum, GLuint, GLint, GLint) = NULL;
|
||||
@ -850,13 +928,14 @@ typedef struct sfogl_StrToExtMap_s
|
||||
PFN_LOADFUNCPOINTERS LoadExtension;
|
||||
} sfogl_StrToExtMap;
|
||||
|
||||
static sfogl_StrToExtMap ExtensionMap[16] = {
|
||||
static sfogl_StrToExtMap ExtensionMap[18] = {
|
||||
{"GL_SGIS_texture_edge_clamp", &sfogl_ext_SGIS_texture_edge_clamp, NULL},
|
||||
{"GL_EXT_texture_edge_clamp", &sfogl_ext_EXT_texture_edge_clamp, NULL},
|
||||
{"GL_EXT_blend_minmax", &sfogl_ext_EXT_blend_minmax, Load_EXT_blend_minmax},
|
||||
{"GL_EXT_blend_subtract", &sfogl_ext_EXT_blend_subtract, NULL},
|
||||
{"GL_ARB_multitexture", &sfogl_ext_ARB_multitexture, Load_ARB_multitexture},
|
||||
{"GL_EXT_blend_func_separate", &sfogl_ext_EXT_blend_func_separate, Load_EXT_blend_func_separate},
|
||||
{"GL_ARB_vertex_buffer_object", &sfogl_ext_ARB_vertex_buffer_object, Load_ARB_vertex_buffer_object},
|
||||
{"GL_ARB_shading_language_100", &sfogl_ext_ARB_shading_language_100, NULL},
|
||||
{"GL_ARB_shader_objects", &sfogl_ext_ARB_shader_objects, Load_ARB_shader_objects},
|
||||
{"GL_ARB_vertex_shader", &sfogl_ext_ARB_vertex_shader, Load_ARB_vertex_shader},
|
||||
@ -866,10 +945,11 @@ static sfogl_StrToExtMap ExtensionMap[16] = {
|
||||
{"GL_EXT_texture_sRGB", &sfogl_ext_EXT_texture_sRGB, NULL},
|
||||
{"GL_EXT_framebuffer_object", &sfogl_ext_EXT_framebuffer_object, Load_EXT_framebuffer_object},
|
||||
{"GL_EXT_framebuffer_blit", &sfogl_ext_EXT_framebuffer_blit, Load_EXT_framebuffer_blit},
|
||||
{"GL_ARB_copy_buffer", &sfogl_ext_ARB_copy_buffer, Load_ARB_copy_buffer},
|
||||
{"GL_ARB_geometry_shader4", &sfogl_ext_ARB_geometry_shader4, Load_ARB_geometry_shader4}
|
||||
};
|
||||
|
||||
static int g_extensionMapSize = 16;
|
||||
static int g_extensionMapSize = 18;
|
||||
|
||||
|
||||
static void ClearExtensionVars()
|
||||
@ -880,6 +960,7 @@ static void ClearExtensionVars()
|
||||
sfogl_ext_EXT_blend_subtract = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_multitexture = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_EXT_blend_func_separate = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_vertex_buffer_object = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_shading_language_100 = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_shader_objects = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_vertex_shader = sfogl_LOAD_FAILED;
|
||||
@ -889,6 +970,7 @@ static void ClearExtensionVars()
|
||||
sfogl_ext_EXT_texture_sRGB = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_EXT_framebuffer_object = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_EXT_framebuffer_blit = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_copy_buffer = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_geometry_shader4 = sfogl_LOAD_FAILED;
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,7 @@ extern int sfogl_ext_EXT_blend_minmax;
|
||||
extern int sfogl_ext_EXT_blend_subtract;
|
||||
extern int sfogl_ext_ARB_multitexture;
|
||||
extern int sfogl_ext_EXT_blend_func_separate;
|
||||
extern int sfogl_ext_ARB_vertex_buffer_object;
|
||||
extern int sfogl_ext_ARB_shading_language_100;
|
||||
extern int sfogl_ext_ARB_shader_objects;
|
||||
extern int sfogl_ext_ARB_vertex_shader;
|
||||
@ -185,6 +186,7 @@ extern int sfogl_ext_EXT_blend_equation_separate;
|
||||
extern int sfogl_ext_EXT_texture_sRGB;
|
||||
extern int sfogl_ext_EXT_framebuffer_object;
|
||||
extern int sfogl_ext_EXT_framebuffer_blit;
|
||||
extern int sfogl_ext_ARB_copy_buffer;
|
||||
extern int sfogl_ext_ARB_geometry_shader4;
|
||||
|
||||
#define GL_CLAMP_TO_EDGE_SGIS 0x812F
|
||||
@ -240,6 +242,38 @@ extern int sfogl_ext_ARB_geometry_shader4;
|
||||
#define GL_BLEND_SRC_ALPHA_EXT 0x80CB
|
||||
#define GL_BLEND_SRC_RGB_EXT 0x80C9
|
||||
|
||||
#define GL_ARRAY_BUFFER_ARB 0x8892
|
||||
#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
|
||||
#define GL_BUFFER_ACCESS_ARB 0x88BB
|
||||
#define GL_BUFFER_MAPPED_ARB 0x88BC
|
||||
#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
|
||||
#define GL_BUFFER_SIZE_ARB 0x8764
|
||||
#define GL_BUFFER_USAGE_ARB 0x8765
|
||||
#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
|
||||
#define GL_DYNAMIC_COPY_ARB 0x88EA
|
||||
#define GL_DYNAMIC_DRAW_ARB 0x88E8
|
||||
#define GL_DYNAMIC_READ_ARB 0x88E9
|
||||
#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
|
||||
#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
|
||||
#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
|
||||
#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
|
||||
#define GL_READ_ONLY_ARB 0x88B8
|
||||
#define GL_READ_WRITE_ARB 0x88BA
|
||||
#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
|
||||
#define GL_STATIC_COPY_ARB 0x88E6
|
||||
#define GL_STATIC_DRAW_ARB 0x88E4
|
||||
#define GL_STATIC_READ_ARB 0x88E5
|
||||
#define GL_STREAM_COPY_ARB 0x88E2
|
||||
#define GL_STREAM_DRAW_ARB 0x88E0
|
||||
#define GL_STREAM_READ_ARB 0x88E1
|
||||
#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
|
||||
#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
|
||||
#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
|
||||
#define GL_WRITE_ONLY_ARB 0x88B9
|
||||
|
||||
#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
|
||||
|
||||
#define GL_BOOL_ARB 0x8B56
|
||||
@ -385,6 +419,9 @@ extern int sfogl_ext_ARB_geometry_shader4;
|
||||
#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
|
||||
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
|
||||
|
||||
#define GL_COPY_READ_BUFFER 0x8F36
|
||||
#define GL_COPY_WRITE_BUFFER 0x8F37
|
||||
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
|
||||
@ -1022,6 +1059,32 @@ extern void (GL_FUNCPTR *sf_ptrc_glBlendFuncSeparateEXT)(GLenum, GLenum, GLenum,
|
||||
#define glBlendFuncSeparateEXT sf_ptrc_glBlendFuncSeparateEXT
|
||||
#endif // GL_EXT_blend_func_separate
|
||||
|
||||
#ifndef GL_ARB_vertex_buffer_object
|
||||
#define GL_ARB_vertex_buffer_object 1
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glBindBufferARB)(GLenum, GLuint);
|
||||
#define glBindBufferARB sf_ptrc_glBindBufferARB
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glBufferDataARB)(GLenum, GLsizeiptrARB, const void*, GLenum);
|
||||
#define glBufferDataARB sf_ptrc_glBufferDataARB
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glBufferSubDataARB)(GLenum, GLintptrARB, GLsizeiptrARB, const void*);
|
||||
#define glBufferSubDataARB sf_ptrc_glBufferSubDataARB
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glDeleteBuffersARB)(GLsizei, const GLuint*);
|
||||
#define glDeleteBuffersARB sf_ptrc_glDeleteBuffersARB
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glGenBuffersARB)(GLsizei, GLuint*);
|
||||
#define glGenBuffersARB sf_ptrc_glGenBuffersARB
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glGetBufferParameterivARB)(GLenum, GLenum, GLint*);
|
||||
#define glGetBufferParameterivARB sf_ptrc_glGetBufferParameterivARB
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glGetBufferPointervARB)(GLenum, GLenum, void**);
|
||||
#define glGetBufferPointervARB sf_ptrc_glGetBufferPointervARB
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glGetBufferSubDataARB)(GLenum, GLintptrARB, GLsizeiptrARB, void*);
|
||||
#define glGetBufferSubDataARB sf_ptrc_glGetBufferSubDataARB
|
||||
extern GLboolean (GL_FUNCPTR *sf_ptrc_glIsBufferARB)(GLuint);
|
||||
#define glIsBufferARB sf_ptrc_glIsBufferARB
|
||||
extern void* (GL_FUNCPTR *sf_ptrc_glMapBufferARB)(GLenum, GLenum);
|
||||
#define glMapBufferARB sf_ptrc_glMapBufferARB
|
||||
extern GLboolean (GL_FUNCPTR *sf_ptrc_glUnmapBufferARB)(GLenum);
|
||||
#define glUnmapBufferARB sf_ptrc_glUnmapBufferARB
|
||||
#endif // GL_ARB_vertex_buffer_object
|
||||
|
||||
|
||||
#ifndef GL_ARB_shader_objects
|
||||
#define GL_ARB_shader_objects 1
|
||||
@ -1254,6 +1317,12 @@ extern void (GL_FUNCPTR *sf_ptrc_glBlitFramebufferEXT)(GLint, GLint, GLint, GLin
|
||||
#define glBlitFramebufferEXT sf_ptrc_glBlitFramebufferEXT
|
||||
#endif // GL_EXT_framebuffer_blit
|
||||
|
||||
#ifndef GL_ARB_copy_buffer
|
||||
#define GL_ARB_copy_buffer 1
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glCopyBufferSubData)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr);
|
||||
#define glCopyBufferSubData sf_ptrc_glCopyBufferSubData
|
||||
#endif // GL_ARB_copy_buffer
|
||||
|
||||
#ifndef GL_ARB_geometry_shader4
|
||||
#define GL_ARB_geometry_shader4 1
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureARB)(GLenum, GLenum, GLuint, GLint);
|
||||
|
@ -30,10 +30,21 @@
|
||||
#include <SFML/Graphics/Shader.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/VertexArray.hpp>
|
||||
#include <SFML/Graphics/VertexBuffer.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
// GL_QUADS is unavailable on OpenGL ES, thus we need to define GL_QUADS ourselves
|
||||
#ifdef SFML_OPENGL_ES
|
||||
|
||||
#define GL_QUADS 0
|
||||
|
||||
#endif // SFML_OPENGL_ES
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -211,17 +222,13 @@ void RenderTarget::draw(const Vertex* vertices, std::size_t vertexCount,
|
||||
err() << "sf::Quads primitive type is not supported on OpenGL ES platforms, drawing skipped" << std::endl;
|
||||
return;
|
||||
}
|
||||
#define GL_QUADS 0
|
||||
#endif
|
||||
|
||||
if (setActive(true))
|
||||
{
|
||||
// First set the persistent OpenGL states if it's the very first call
|
||||
if (!m_cache.glStatesSet)
|
||||
resetGLStates();
|
||||
|
||||
// Check if the vertex count is low enough so that we can pre-transform them
|
||||
bool useVertexCache = (vertexCount <= StatesCache::VertexCacheSize);
|
||||
|
||||
if (useVertexCache)
|
||||
{
|
||||
// Pre-transform the vertices and store them into the vertex cache
|
||||
@ -232,32 +239,9 @@ void RenderTarget::draw(const Vertex* vertices, std::size_t vertexCount,
|
||||
vertex.color = vertices[i].color;
|
||||
vertex.texCoords = vertices[i].texCoords;
|
||||
}
|
||||
|
||||
// Since vertices are transformed, we must use an identity transform to render them
|
||||
if (!m_cache.useVertexCache)
|
||||
glCheck(glLoadIdentity());
|
||||
}
|
||||
else
|
||||
{
|
||||
applyTransform(states.transform);
|
||||
}
|
||||
|
||||
// Apply the view
|
||||
if (m_cache.viewChanged)
|
||||
applyCurrentView();
|
||||
|
||||
// Apply the blend mode
|
||||
if (states.blendMode != m_cache.lastBlendMode)
|
||||
applyBlendMode(states.blendMode);
|
||||
|
||||
// Apply the texture
|
||||
Uint64 textureId = states.texture ? states.texture->m_cacheId : 0;
|
||||
if (textureId != m_cache.lastTextureId)
|
||||
applyTexture(states.texture);
|
||||
|
||||
// Apply the shader
|
||||
if (states.shader)
|
||||
applyShader(states.shader);
|
||||
setupDraw(useVertexCache, states);
|
||||
|
||||
// Check if texture coordinates array is needed, and update client state accordingly
|
||||
bool enableTexCoordsArray = (states.texture || states.shader);
|
||||
@ -292,22 +276,8 @@ void RenderTarget::draw(const Vertex* vertices, std::size_t vertexCount,
|
||||
glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12));
|
||||
}
|
||||
|
||||
// Find the OpenGL primitive type
|
||||
static const GLenum modes[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS};
|
||||
GLenum mode = modes[type];
|
||||
|
||||
// Draw the primitives
|
||||
glCheck(glDrawArrays(mode, 0, static_cast<GLsizei>(vertexCount)));
|
||||
|
||||
// Unbind the shader, if any
|
||||
if (states.shader)
|
||||
applyShader(NULL);
|
||||
|
||||
// If the texture we used to draw belonged to a RenderTexture, then forcibly unbind that texture.
|
||||
// This prevents a bug where some drivers do not clear RenderTextures properly.
|
||||
if (states.texture && states.texture->m_fboAttachment)
|
||||
applyTexture(NULL);
|
||||
drawPrimitives(type, 0, vertexCount);
|
||||
cleanupDraw(states);
|
||||
|
||||
// Update the cache
|
||||
m_cache.useVertexCache = useVertexCache;
|
||||
@ -316,6 +286,73 @@ void RenderTarget::draw(const Vertex* vertices, std::size_t vertexCount,
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTarget::draw(const VertexBuffer& vertexBuffer, const RenderStates& states)
|
||||
{
|
||||
draw(vertexBuffer, 0, vertexBuffer.getVertexCount(), states);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTarget::draw(const VertexBuffer& vertexBuffer, std::size_t firstVertex,
|
||||
std::size_t vertexCount, const RenderStates& states)
|
||||
{
|
||||
// VertexBuffer not supported?
|
||||
if (!VertexBuffer::isAvailable())
|
||||
{
|
||||
err() << "sf::VertexBuffer is not available, drawing skipped" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (firstVertex > vertexBuffer.getVertexCount())
|
||||
return;
|
||||
|
||||
// Clamp vertexCount to something that makes sense
|
||||
vertexCount = std::min(vertexCount, vertexBuffer.getVertexCount() - firstVertex);
|
||||
|
||||
// Nothing to draw?
|
||||
if (!vertexCount || !vertexBuffer.getNativeHandle())
|
||||
return;
|
||||
|
||||
// GL_QUADS is unavailable on OpenGL ES
|
||||
#ifdef SFML_OPENGL_ES
|
||||
if (vertexBuffer.getPrimitiveType() == Quads)
|
||||
{
|
||||
err() << "sf::Quads primitive type is not supported on OpenGL ES platforms, drawing skipped" << std::endl;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (setActive(true))
|
||||
{
|
||||
setupDraw(false, states);
|
||||
|
||||
// Bind vertex buffer
|
||||
VertexBuffer::bind(&vertexBuffer);
|
||||
|
||||
// Always enable texture coordinates
|
||||
if (!m_cache.texCoordsArrayEnabled)
|
||||
glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
|
||||
glCheck(glVertexPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<const void*>(0)));
|
||||
glCheck(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), reinterpret_cast<const void*>(8)));
|
||||
glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<const void*>(12)));
|
||||
|
||||
drawPrimitives(vertexBuffer.getPrimitiveType(), firstVertex, vertexCount);
|
||||
|
||||
// Unbind vertex buffer
|
||||
VertexBuffer::bind(NULL);
|
||||
|
||||
cleanupDraw(states);
|
||||
|
||||
// Update the cache
|
||||
m_cache.useVertexCache = false;
|
||||
m_cache.texCoordsArrayEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTarget::pushGLStates()
|
||||
{
|
||||
@ -372,6 +409,7 @@ void RenderTarget::resetGLStates()
|
||||
{
|
||||
// Check here to make sure a context change does not happen after activate(true)
|
||||
bool shaderAvailable = Shader::isAvailable();
|
||||
bool vertexBufferAvailable = VertexBuffer::isAvailable();
|
||||
|
||||
// Workaround for states not being properly reset on
|
||||
// macOS unless a context switch really takes place
|
||||
@ -411,6 +449,9 @@ void RenderTarget::resetGLStates()
|
||||
if (shaderAvailable)
|
||||
applyShader(NULL);
|
||||
|
||||
if (vertexBufferAvailable)
|
||||
glCheck(VertexBuffer::bind(NULL));
|
||||
|
||||
m_cache.texCoordsArrayEnabled = true;
|
||||
|
||||
m_cache.useVertexCache = false;
|
||||
@ -527,6 +568,70 @@ void RenderTarget::applyShader(const Shader* shader)
|
||||
Shader::bind(shader);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTarget::setupDraw(bool useVertexCache, const RenderStates& states)
|
||||
{
|
||||
// First set the persistent OpenGL states if it's the very first call
|
||||
if (!m_cache.glStatesSet)
|
||||
resetGLStates();
|
||||
|
||||
if (useVertexCache)
|
||||
{
|
||||
// Since vertices are transformed, we must use an identity transform to render them
|
||||
if (!m_cache.useVertexCache)
|
||||
glCheck(glLoadIdentity());
|
||||
}
|
||||
else
|
||||
{
|
||||
applyTransform(states.transform);
|
||||
}
|
||||
|
||||
// Apply the view
|
||||
if (m_cache.viewChanged)
|
||||
applyCurrentView();
|
||||
|
||||
// Apply the blend mode
|
||||
if (states.blendMode != m_cache.lastBlendMode)
|
||||
applyBlendMode(states.blendMode);
|
||||
|
||||
// Apply the texture
|
||||
Uint64 textureId = states.texture ? states.texture->m_cacheId : 0;
|
||||
if (textureId != m_cache.lastTextureId)
|
||||
applyTexture(states.texture);
|
||||
|
||||
// Apply the shader
|
||||
if (states.shader)
|
||||
applyShader(states.shader);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTarget::drawPrimitives(PrimitiveType type, std::size_t firstVertex, std::size_t vertexCount)
|
||||
{
|
||||
// Find the OpenGL primitive type
|
||||
static const GLenum modes[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS};
|
||||
GLenum mode = modes[type];
|
||||
|
||||
// Draw the primitives
|
||||
glCheck(glDrawArrays(mode, firstVertex, static_cast<GLsizei>(vertexCount)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTarget::cleanupDraw(const RenderStates& states)
|
||||
{
|
||||
// Unbind the shader, if any
|
||||
if (states.shader)
|
||||
applyShader(NULL);
|
||||
|
||||
// If the texture we used to draw belonged to a RenderTexture, then forcibly unbind that texture.
|
||||
// This prevents a bug where some drivers do not clear RenderTextures properly.
|
||||
if (states.texture && states.texture->m_fboAttachment)
|
||||
applyTexture(NULL);
|
||||
}
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
|
363
src/SFML/Graphics/VertexBuffer.cpp
Normal file
363
src/SFML/Graphics/VertexBuffer.cpp
Normal file
@ -0,0 +1,363 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/VertexBuffer.hpp>
|
||||
#include <SFML/Graphics/RenderTarget.hpp>
|
||||
#include <SFML/Graphics/Vertex.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
#include <SFML/System/Mutex.hpp>
|
||||
#include <SFML/System/Lock.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
#include <cstring>
|
||||
|
||||
namespace
|
||||
{
|
||||
sf::Mutex isAvailableMutex;
|
||||
|
||||
GLenum usageToGlEnum(sf::VertexBuffer::Usage usage)
|
||||
{
|
||||
switch (usage)
|
||||
{
|
||||
case sf::VertexBuffer::Static: return GLEXT_GL_STATIC_DRAW;
|
||||
case sf::VertexBuffer::Dynamic: return GLEXT_GL_DYNAMIC_DRAW;
|
||||
default: return GLEXT_GL_STREAM_DRAW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
VertexBuffer::VertexBuffer() :
|
||||
m_buffer (0),
|
||||
m_size (0),
|
||||
m_primitiveType(Points),
|
||||
m_usage (Stream)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VertexBuffer::VertexBuffer(PrimitiveType type) :
|
||||
m_buffer (0),
|
||||
m_size (0),
|
||||
m_primitiveType(type),
|
||||
m_usage (Stream)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VertexBuffer::VertexBuffer(VertexBuffer::Usage usage) :
|
||||
m_buffer (0),
|
||||
m_size (0),
|
||||
m_primitiveType(Points),
|
||||
m_usage (usage)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VertexBuffer::VertexBuffer(PrimitiveType type, VertexBuffer::Usage usage) :
|
||||
m_buffer (0),
|
||||
m_size (0),
|
||||
m_primitiveType(type),
|
||||
m_usage (usage)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VertexBuffer::VertexBuffer(const VertexBuffer& copy) :
|
||||
m_buffer (0),
|
||||
m_size (0),
|
||||
m_primitiveType(copy.m_primitiveType),
|
||||
m_usage (copy.m_usage)
|
||||
{
|
||||
if (copy.m_buffer && copy.m_size)
|
||||
{
|
||||
if (!create(copy.m_size))
|
||||
{
|
||||
err() << "Could not create vertex buffer for copying" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!update(copy))
|
||||
err() << "Could not copy vertex buffer" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
if (m_buffer)
|
||||
{
|
||||
TransientContextLock contextLock;
|
||||
|
||||
glCheck(GLEXT_glDeleteBuffers(1, &m_buffer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VertexBuffer::create(std::size_t vertexCount)
|
||||
{
|
||||
if (!isAvailable())
|
||||
return false;
|
||||
|
||||
TransientContextLock contextLock;
|
||||
|
||||
if (!m_buffer)
|
||||
glCheck(GLEXT_glGenBuffers(1, &m_buffer));
|
||||
|
||||
if (!m_buffer)
|
||||
{
|
||||
err() << "Could not create vertex buffer, generation failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, m_buffer));
|
||||
glCheck(GLEXT_glBufferData(GLEXT_GL_ARRAY_BUFFER, sizeof(Vertex) * vertexCount, 0, usageToGlEnum(m_usage)));
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, 0));
|
||||
|
||||
m_size = vertexCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::size_t VertexBuffer::getVertexCount() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VertexBuffer::update(const Vertex* vertices)
|
||||
{
|
||||
return update(vertices, m_size, 0);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VertexBuffer::update(const Vertex* vertices, std::size_t vertexCount, unsigned int offset)
|
||||
{
|
||||
// Sanity checks
|
||||
if (!m_buffer)
|
||||
return false;
|
||||
|
||||
if (!vertices)
|
||||
return false;
|
||||
|
||||
if (offset && (offset + vertexCount > m_size))
|
||||
return false;
|
||||
|
||||
TransientContextLock contextLock;
|
||||
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, m_buffer));
|
||||
|
||||
// Check if we need to resize or orphan the buffer
|
||||
if (vertexCount >= m_size)
|
||||
{
|
||||
glCheck(GLEXT_glBufferData(GLEXT_GL_ARRAY_BUFFER, sizeof(Vertex) * vertexCount, 0, usageToGlEnum(m_usage)));
|
||||
|
||||
m_size = vertexCount;
|
||||
}
|
||||
|
||||
glCheck(GLEXT_glBufferSubData(GLEXT_GL_ARRAY_BUFFER, sizeof(Vertex) * offset, sizeof(Vertex) * vertexCount, vertices));
|
||||
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VertexBuffer::update(const VertexBuffer& vertexBuffer)
|
||||
{
|
||||
#ifdef SFML_OPENGL_ES
|
||||
|
||||
return false;
|
||||
|
||||
#else
|
||||
|
||||
if (!m_buffer || !vertexBuffer.m_buffer)
|
||||
return false;
|
||||
|
||||
TransientContextLock contextLock;
|
||||
|
||||
// Make sure that extensions are initialized
|
||||
sf::priv::ensureExtensionsInit();
|
||||
|
||||
if (GLEXT_copy_buffer)
|
||||
{
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_COPY_READ_BUFFER, vertexBuffer.m_buffer));
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_COPY_WRITE_BUFFER, m_buffer));
|
||||
|
||||
glCheck(GLEXT_glCopyBufferSubData(GLEXT_GL_COPY_READ_BUFFER, GLEXT_GL_COPY_WRITE_BUFFER, 0, 0, sizeof(Vertex) * vertexBuffer.m_size));
|
||||
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_COPY_WRITE_BUFFER, 0));
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_COPY_READ_BUFFER, 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, m_buffer));
|
||||
glCheck(GLEXT_glBufferData(GLEXT_GL_ARRAY_BUFFER, sizeof(Vertex) * vertexBuffer.m_size, 0, usageToGlEnum(m_usage)));
|
||||
|
||||
void* destination = 0;
|
||||
glCheck(destination = GLEXT_glMapBuffer(GLEXT_GL_ARRAY_BUFFER, GLEXT_GL_WRITE_ONLY));
|
||||
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, vertexBuffer.m_buffer));
|
||||
|
||||
void* source = 0;
|
||||
glCheck(source = GLEXT_glMapBuffer(GLEXT_GL_ARRAY_BUFFER, GLEXT_GL_READ_ONLY));
|
||||
|
||||
std::memcpy(destination, source, sizeof(Vertex) * vertexBuffer.m_size);
|
||||
|
||||
GLboolean sourceResult = GL_FALSE;
|
||||
glCheck(sourceResult = GLEXT_glUnmapBuffer(GLEXT_GL_ARRAY_BUFFER));
|
||||
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, m_buffer));
|
||||
|
||||
GLboolean destinationResult = GL_FALSE;
|
||||
glCheck(destinationResult = GLEXT_glUnmapBuffer(GLEXT_GL_ARRAY_BUFFER));
|
||||
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, 0));
|
||||
|
||||
if ((sourceResult == GL_FALSE) || (destinationResult == GL_FALSE))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
#endif // SFML_OPENGL_ES
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VertexBuffer& VertexBuffer::operator =(const VertexBuffer& right)
|
||||
{
|
||||
VertexBuffer temp(right);
|
||||
|
||||
swap(temp);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void VertexBuffer::swap(VertexBuffer& right)
|
||||
{
|
||||
std::swap(m_size, right.m_size);
|
||||
std::swap(m_buffer, right.m_buffer);
|
||||
std::swap(m_primitiveType, right.m_primitiveType);
|
||||
std::swap(m_usage, right.m_usage);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int VertexBuffer::getNativeHandle() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void VertexBuffer::bind(const VertexBuffer* vertexBuffer)
|
||||
{
|
||||
if (!isAvailable())
|
||||
return;
|
||||
|
||||
TransientContextLock lock;
|
||||
|
||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, vertexBuffer ? vertexBuffer->m_buffer : 0));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void VertexBuffer::setPrimitiveType(PrimitiveType type)
|
||||
{
|
||||
m_primitiveType = type;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
PrimitiveType VertexBuffer::getPrimitiveType() const
|
||||
{
|
||||
return m_primitiveType;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void VertexBuffer::setUsage(VertexBuffer::Usage usage)
|
||||
{
|
||||
m_usage = usage;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VertexBuffer::Usage VertexBuffer::getUsage() const
|
||||
{
|
||||
return m_usage;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VertexBuffer::isAvailable()
|
||||
{
|
||||
Lock lock(isAvailableMutex);
|
||||
|
||||
static bool checked = false;
|
||||
static bool available = false;
|
||||
|
||||
if (!checked)
|
||||
{
|
||||
checked = true;
|
||||
|
||||
TransientContextLock contextLock;
|
||||
|
||||
// Make sure that extensions are initialized
|
||||
sf::priv::ensureExtensionsInit();
|
||||
|
||||
available = GLEXT_vertex_buffer_object;
|
||||
}
|
||||
|
||||
return available;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void VertexBuffer::draw(RenderTarget& target, RenderStates states) const
|
||||
{
|
||||
if (m_buffer && m_size)
|
||||
target.draw(*this, 0, m_size, states);
|
||||
}
|
||||
|
||||
} // namespace sf
|
Loading…
Reference in New Issue
Block a user