# ifndef Magnum_Buffer_h
# define Magnum_Buffer_h
/*
This file is part of Magnum .
Copyright © 2010 , 2011 , 2012 , 2013 , 2014 , 2015
Vladimír Vondruš < mosra @ centrum . cz >
Permission is hereby granted , free of charge , to any person obtaining a
copy of this software and associated documentation files ( the " Software " ) ,
to deal in the Software without restriction , including without limitation
the rights to use , copy , modify , merge , publish , distribute , sublicense ,
and / or sell copies of the Software , and to permit persons to whom the
Software is furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE .
*/
/** @file
* @ brief Class @ ref Magnum : : Buffer , enum @ ref Magnum : : BufferUsage
*/
# include <cstddef>
# include <array>
# include <vector>
# include <Corrade/Containers/Array.h>
# include <Corrade/Containers/EnumSet.h>
# include <Corrade/Utility/Assert.h>
# include "Magnum/AbstractObject.h"
# include "Magnum/Magnum.h"
# ifdef MAGNUM_BUILD_DEPRECATED
# include <Corrade/Utility/Macros.h>
# endif
namespace Magnum {
/**
@ brief Buffer usage
@ see @ ref Buffer , @ ref Buffer : : setData ( Containers : : ArrayReference < const void > , BufferUsage )
*/
enum class BufferUsage : GLenum {
/** Set once by the application and used infrequently for drawing. */
StreamDraw = GL_STREAM_DRAW ,
# ifndef MAGNUM_TARGET_GLES2
/**
* Set once as output from an OpenGL command and used infequently for
* drawing .
* @ requires_gles30 Only @ ref BufferUsage : : StreamDraw is available in
* OpenGL ES 2.0 .
* @ requires_webgl20 Only @ ref BufferUsage : : StreamDraw is available in
* WebGL 1.0 .
*/
StreamRead = GL_STREAM_READ ,
/**
* Set once as output from an OpenGL command and used infrequently for
* drawing or copying to other buffers .
* @ requires_gles30 Only @ ref BufferUsage : : StreamDraw is available in
* OpenGL ES 2.0 .
* @ requires_webgl20 Only @ ref BufferUsage : : StreamDraw is available in
* WebGL 1.0 .
*/
StreamCopy = GL_STREAM_COPY ,
# endif
/** Set once by the application and used frequently for drawing. */
StaticDraw = GL_STATIC_DRAW ,
# ifndef MAGNUM_TARGET_GLES2
/**
* Set once as output from an OpenGL command and queried many times by the
* application .
* @ requires_gles30 Only @ ref BufferUsage : : StaticDraw is available in
* OpenGL ES 2.0 .
* @ requires_webgl20 Only @ ref BufferUsage : : StaticDraw is available in
* WebGL 1.0 .
*/
StaticRead = GL_STATIC_READ ,
/**
* Set once as output from an OpenGL command and used frequently for
* drawing or copying to other buffers .
* @ requires_gles30 Only @ ref BufferUsage : : StaticDraw is available in
* OpenGL ES 2.0 .
* @ requires_webgl20 Only @ ref BufferUsage : : StaticDraw is available in
* WebGL 1.0 .
*/
StaticCopy = GL_STATIC_COPY ,
# endif
/**
* Updated frequently by the application and used frequently for drawing or
* copying to other images .
*/
DynamicDraw = GL_DYNAMIC_DRAW ,
# ifndef MAGNUM_TARGET_GLES2
/**
* Updated frequently as output from OpenGL command and queried many times
* from the application .
* @ requires_gles30 Only @ ref BufferUsage : : DynamicDraw is available in
* OpenGL ES 2.0 .
* @ requires_webgl20 Only @ ref BufferUsage : : DynamicDraw is available in
* WebGL 1.0 .
*/
DynamicRead = GL_DYNAMIC_READ ,
/**
* Updated frequently as output from OpenGL command and used frequently for
* drawing or copying to other images .
* @ requires_gles30 Only @ ref BufferUsage : : DynamicDraw is available in
* OpenGL ES 2.0 .
* @ requires_webgl20 Only @ ref BufferUsage : : DynamicDraw is available in
* WebGL 1.0 .
*/
DynamicCopy = GL_DYNAMIC_COPY
# endif
} ;
namespace Implementation { struct BufferState ; }
/**
@ brief Buffer
Encapsulates one OpenGL buffer object and provides functions for convenient
data updates .
# # Data updating
Default way to set or update buffer data with @ ref setData ( ) or @ ref setSubData ( )
is to use @ ref Corrade : : Containers : : ArrayReference . See its documentation for
more information about automatic conversions etc .
@ code
Containers : : ArrayReference < Vector3 > data ;
buffer . setData ( data , BufferUsage : : StaticDraw ) ;
@ endcode
There is also overload for array - like containers from STL , such as ` std : : vector `
or ` std : : array ` :
@ code
std : : vector < Vector3 > data ;
buffer . setData ( data , BufferUsage : : StaticDraw ) ;
@ endcode
@ anchor Buffer - data - mapping
# # Memory mapping
Buffer data can be also updated asynchronously . First you need to allocate
the buffer to desired size by passing ` nullptr ` to @ ref setData ( ) , e . g . :
@ code
buffer . setData ( { nullptr , 200 * sizeof ( Vector3 ) } , BufferUsage : : StaticDraw ) ;
@ endcode
Then you can map the buffer to client memory and operate with the memory
directly . After you are done with the operation , call @ ref unmap ( ) to unmap the
buffer again .
@ code
Vector3 * data = buffer . map < Vector3 > ( 0 , 200 * sizeof ( Vector3 ) , Buffer : : MapFlag : : Write | Buffer : : MapFlag : : InvalidateBuffer ) ;
for ( std : : size_t i = 0 ; i ! = 200 ; + + i )
data [ i ] = . . . ;
CORRADE_INTERNAL_ASSERT_OUTPUT ( buffer . unmap ( ) ) ;
@ endcode
If you are updating only a few discrete portions of the buffer , you can use
@ ref MapFlag : : FlushExplicit and @ ref flushMappedRange ( ) to reduce number of
memory operations performed by OpenGL on unmapping . Example :
@ code
Vector3 * data = buffer . map < Vector3 > ( 0 , 200 * sizeof ( Vector3 ) , Buffer : : MapFlag : : Write | Buffer : : MapFlag : : FlushExplicit ) ;
for ( std : : size_t i : { 7 , 27 , 56 , 128 } ) {
data [ i ] = . . . ;
buffer . flushMappedRange ( i * sizeof ( Vector3 ) , sizeof ( Vector3 ) ) ;
}
CORRADE_INTERNAL_ASSERT_OUTPUT ( buffer . unmap ( ) ) ;
@ endcode
# # WebGL and NaCl restrictions
Buffers in @ ref MAGNUM_TARGET_WEBGL " WebGL " and @ ref CORRADE_TARGET_NACL " NaCl "
need to be bound only to one unique target , i . e . , @ ref Buffer bound to
@ ref Buffer : : Target : : Array cannot be later rebound to
@ ref Buffer : : Target : : ElementArray . However , Magnum by default uses any
sufficient target when binding the buffer internally ( e . g . for setting data ) .
To avoid GL errors , set target hint to desired target , either in constructor or
using @ ref Buffer : : setTargetHint ( ) :
@ code
Buffer vertices { Buffer : : Target : : Array } ;
Buffer indices { Buffer : : Target : : ElementArray } ;
@ endcode
To ease up the development , @ ref Mesh checks proper target hint when adding
vertex and index buffers in both WebGL and NaCl .
# # Performance optimizations
The engine tracks currently bound buffers to avoid unnecessary calls to
@ fn_gl { BindBuffer } . If the buffer is already bound to some target , functions
@ ref copy ( ) , @ ref setData ( ) , @ ref setSubData ( ) , @ ref map ( ) , @ ref flushMappedRange ( )
and @ ref unmap ( ) use that target instead of binding the buffer to some specific
target . You can also use @ ref setTargetHint ( ) to possibly reduce unnecessary
rebinding . Buffer limits and implementation - defined values ( such as
@ ref maxUniformBindings ( ) ) are cached , so repeated queries don ' t result in
repeated @ fn_gl { Get } calls .
If either @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 ) or
@ extension { EXT , direct_state_access } desktop extension is available , functions
@ ref copy ( ) , @ ref size ( ) , @ ref data ( ) , @ ref subData ( ) , @ ref setData ( ) ,
@ ref setSubData ( ) , @ ref map ( ) , @ ref flushMappedRange ( ) and @ ref unmap ( ) use DSA
functions to avoid unnecessary calls to @ fn_gl { BindBuffer } . See their
respective documentation for more information .
You can use functions @ ref invalidateData ( ) and @ ref invalidateSubData ( ) if you
don ' t need buffer data anymore to avoid unnecessary memory operations performed
by OpenGL in order to preserve the data . If running on OpenGL ES or extension
@ extension { ARB , invalidate_subdata } ( part of OpenGL 4.3 ) is not available , these
functions do nothing .
*/
class MAGNUM_EXPORT Buffer : public AbstractObject {
friend Implementation : : BufferState ;
public :
/**
* @ brief Buffer target
*
* @ see @ ref Buffer ( ) , @ ref setTargetHint ( )
*/
enum class TargetHint : GLenum {
/** Used for storing vertex attributes. */
Array = GL_ARRAY_BUFFER ,
# ifndef MAGNUM_TARGET_GLES2
# ifndef MAGNUM_TARGET_WEBGL
/**
* Used for storing atomic counters .
* @ requires_gl42 Extension @ extension { ARB , shader_atomic_counters }
* @ requires_gles31 Atomic counters are not available in OpenGL ES
* 3.0 and older .
* @ requires_gles Atomic counters are not available in WebGL .
*/
AtomicCounter = GL_ATOMIC_COUNTER_BUFFER ,
# endif
/**
* Source for copies . See @ ref copy ( ) .
* @ requires_gl31 Extension @ extension { ARB , copy_buffer }
* @ requires_gles30 Buffer copying is not available in OpenGL ES
* 2.0 .
* @ requires_webgl20 Buffer copying is not available in WebGL 1.0 .
*/
CopyRead = GL_COPY_READ_BUFFER ,
/**
* Target for copies . See @ ref copy ( ) .
* @ requires_gl31 Extension @ extension { ARB , copy_buffer }
* @ requires_gles30 Buffer copying is not available in OpenGL ES
* 2.0 .
* @ requires_webgl20 Buffer copying is not available in WebGL 1.0 .
*/
CopyWrite = GL_COPY_WRITE_BUFFER ,
# ifndef MAGNUM_TARGET_WEBGL
/**
* Indirect compute dispatch commands .
* @ requires_gl43 Extension @ extension { ARB , compute_shader }
* @ requires_gles31 Compute shaders are not available in OpenGL ES
* 3.0 and older .
* @ requires_gles Compute shaders are not available in WebGL .
*/
DispatchIndirect = GL_DISPATCH_INDIRECT_BUFFER ,
/**
* Used for supplying arguments for indirect drawing .
* @ requires_gl40 Extension @ extension { ARB , draw_indirect }
* @ requires_gles31 Indirect drawing is not available in OpenGL ES
* 3.0 and older .
* @ requires_gles Indirect drawing is not available in WebGL .
*/
DrawIndirect = GL_DRAW_INDIRECT_BUFFER ,
# endif
# endif
/** Used for storing vertex indices. */
ElementArray = GL_ELEMENT_ARRAY_BUFFER ,
# ifndef MAGNUM_TARGET_GLES2
/**
* Target for pixel pack operations .
* @ requires_gles30 Pixel buffer objects are not available in
* OpenGL ES 2.0 .
* @ requires_webgl20 Pixel buffer objects are not available in
* WebGL 1.0 .
*/
PixelPack = GL_PIXEL_PACK_BUFFER ,
/**
* Source for texture update operations .
* @ requires_gles30 Pixel buffer objects are not available in
* OpenGL ES 2.0 .
* @ requires_webgl20 Pixel buffer objects are not available in
* WebGL 1.0 .
*/
PixelUnpack = GL_PIXEL_UNPACK_BUFFER ,
# ifndef MAGNUM_TARGET_WEBGL
/**
* Used for shader storage .
* @ requires_gl43 Extension @ extension { ARB , shader_storage_buffer_object }
* @ requires_gles31 Shader storage is not available in OpenGL ES
* 3.0 and older .
* @ requires_gles Shader storage is not available in WebGL .
*/
ShaderStorage = GL_SHADER_STORAGE_BUFFER ,
# endif
# endif
# ifndef MAGNUM_TARGET_GLES
/**
* Source for texel fetches . See @ ref BufferTexture .
* @ requires_gl31 Extension @ extension { ARB , texture_buffer_object }
* @ requires_gl Texture buffers are not available in OpenGL ES or
* WebGL .
*/
Texture = GL_TEXTURE_BUFFER ,
# endif
# ifndef MAGNUM_TARGET_GLES2
/**
* Target for transform feedback .
* @ requires_gl30 Extension @ extension { EXT , transform_feedback }
* @ requires_gles30 Transform feedback is not available in OpenGL
* ES 2.0 .
* @ requires_webgl20 Transform feedback is not available in WebGL
* 1.0 .
*/
TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER ,
/**
* Used for storing uniforms .
* @ requires_gl31 Extension @ extension { ARB , uniform_buffer_object }
* @ requires_gles30 Uniform buffers are not available in OpenGL ES
* 2.0 .
* @ requires_webgl20 Uniform buffers are not available in WebGL
* 1.0 .
*/
Uniform = GL_UNIFORM_BUFFER
# endif
} ;
# if !defined(MAGNUM_TARGET_GLES2) || defined(MAGNUM_BUILD_DEPRECATED)
/**
* @ brief Buffer binding target
*
* @ see @ ref bind ( ) , @ ref unbind ( )
*/
enum class Target : GLenum {
# ifdef MAGNUM_BUILD_DEPRECATED
/**
* @ copydoc TargetHint : : Array
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : Array instead .
*/
Array = GL_ARRAY_BUFFER ,
# endif
# if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* Atomic counter binding
* @ requires_gl42 Extension @ extension { ARB , shader_atomic_counters }
* @ requires_gles31 Atomic counters are not available in OpenGL ES
* 3.0 and older .
* @ requires_gles Atomic counters are not available in WebGL .
*/
AtomicCounter = GL_ATOMIC_COUNTER_BUFFER ,
# endif
# ifdef MAGNUM_BUILD_DEPRECATED
# ifndef MAGNUM_TARGET_GLES2
/**
* @ copydoc TargetHint : : CopyRead
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : CopyRead instead .
*/
CopyRead = GL_COPY_READ_BUFFER ,
/**
* @ copydoc TargetHint : : CopyWrite
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : CopyWrite instead .
*/
CopyWrite = GL_COPY_WRITE_BUFFER ,
# endif
# if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* @ copydoc TargetHint : : DispatchIndirect
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : DispatchIndirect instead .
*/
DispatchIndirect = GL_DISPATCH_INDIRECT_BUFFER ,
/**
* @ copydoc TargetHint : : DrawIndirect
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : DrawIndirect instead .
*/
DrawIndirect = GL_DRAW_INDIRECT_BUFFER ,
# endif
/**
* @ copydoc TargetHint : : ElementArray
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : ElementArray instead .
*/
ElementArray = GL_ELEMENT_ARRAY_BUFFER ,
# ifndef MAGNUM_TARGET_GLES2
/**
* @ copydoc TargetHint : : PixelPack
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : PixelPack instead .
*/
PixelPack = GL_PIXEL_PACK_BUFFER ,
/**
* @ copydoc TargetHint : : PixelUnpack
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : PixelUnpack instead .
*/
PixelUnpack = GL_PIXEL_UNPACK_BUFFER ,
# endif
# endif
# if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* Shader storage binding
* @ requires_gl43 Extension @ extension { ARB , shader_storage_buffer_object }
* @ requires_gles31 Shader storage is not available in OpenGL ES
* 3.0 and older .
* @ requires_gles Shader storage is not available in WebGL .
*/
ShaderStorage = GL_SHADER_STORAGE_BUFFER ,
# endif
# if defined(MAGNUM_BUILD_DEPRECATED) && !defined(MAGNUM_TARGET_GLES)
/**
* @ copydoc TargetHint : : Texture
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : Texture instead .
*/
Texture = GL_TEXTURE_BUFFER ,
# endif
# if defined(MAGNUM_BUILD_DEPRECATED) && !defined(MAGNUM_TARGET_GLES2)
/**
* @ copydoc TargetHint : : TransformFeedback
* @ deprecated For @ ref setTargetHint ( ) only , use
* @ ref TargetHint : : TransformFeedback instead .
*/
TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER ,
# endif
# ifndef MAGNUM_TARGET_GLES2
/**
* Uniform binding
* @ requires_gl31 Extension @ extension { ARB , uniform_buffer_object }
* @ requires_gles30 Uniform buffers are not available in OpenGL ES
* 2.0 .
* @ requires_webgl20 Uniform buffers are not available in WebGL
* 1.0 .
*/
Uniform = GL_UNIFORM_BUFFER
# endif
} ;
# endif
# ifdef MAGNUM_BUILD_DEPRECATED
/**
* @ copybrief BufferUsage
* @ deprecated Use @ ref BufferUsage instead .
*/
typedef CORRADE_DEPRECATED ( " use BufferUsage instead " ) BufferUsage Usage ;
# endif
# ifndef MAGNUM_TARGET_WEBGL
/**
* @ brief Memory mapping access
*
* @ see @ ref map ( MapAccess ) , @ ref mapSub ( )
* @ requires_es_extension Extension @ es_extension { OES , mapbuffer } or
* @ es_extension { CHROMIUM , map_sub }
* @ requires_gles Buffer mapping is not available in WebGL .
* @ deprecated_gl Prefer to use @ ref map ( GLintptr , GLsizeiptr , MapFlags )
* instead , as it has more complete set of features .
*/
enum class MapAccess : GLenum {
# ifndef MAGNUM_TARGET_GLES
/**
* Map buffer for reading only .
* @ requires_gl Only @ ref MapAccess : : WriteOnly is available in
* OpenGL ES .
*/
ReadOnly = GL_READ_ONLY ,
# endif
/** Map buffer for writing only. */
# ifdef MAGNUM_TARGET_GLES
WriteOnly = GL_WRITE_ONLY_OES
# else
WriteOnly = GL_WRITE_ONLY ,
/**
* Map buffer for both reading and writing .
* @ requires_gl Only @ ref MapAccess : : WriteOnly is available in
* OpenGL ES .
*/
ReadWrite = GL_READ_WRITE
# endif
} ;
/**
* @ brief Memory mapping flag
*
* @ see @ ref MapFlags , @ ref map ( GLintptr , GLsizeiptr , MapFlags )
* @ requires_gl30 Extension @ extension { ARB , map_buffer_range }
* @ requires_gles30 Extension @ es_extension { EXT , map_buffer_range } in
* OpenGL ES 2.0 .
* @ requires_gles Buffer mapping is not available in WebGL .
*/
enum class MapFlag : GLbitfield {
/** Map buffer for reading. */
# ifndef MAGNUM_TARGET_GLES2
Read = GL_MAP_READ_BIT ,
# else
Read = GL_MAP_READ_BIT_EXT ,
# endif
/** Map buffer for writing. */
# ifndef MAGNUM_TARGET_GLES2
Write = GL_MAP_WRITE_BIT ,
# else
Write = GL_MAP_WRITE_BIT_EXT ,
# endif
/**
* Previous contents of the entire buffer may be discarded . May not
* be used in combination with @ ref MapFlag : : Read .
* @ see @ ref invalidateData ( )
*/
# ifndef MAGNUM_TARGET_GLES2
InvalidateBuffer = GL_MAP_INVALIDATE_BUFFER_BIT ,
# else
InvalidateBuffer = GL_MAP_INVALIDATE_BUFFER_BIT_EXT ,
# endif
/**
* Previous contents of mapped range may be discarded . May not be
* used in combination with @ ref MapFlag : : Read .
* @ see @ ref invalidateSubData ( )
*/
# ifndef MAGNUM_TARGET_GLES2
InvalidateRange = GL_MAP_INVALIDATE_RANGE_BIT ,
# else
InvalidateRange = GL_MAP_INVALIDATE_RANGE_BIT_EXT ,
# endif
/**
* Only one or more discrete subranges of the mapping will be
* modified . See @ ref flushMappedRange ( ) for more information . May
* only be used in conjuction with @ ref MapFlag : : Write .
*/
# ifndef MAGNUM_TARGET_GLES2
FlushExplicit = GL_MAP_FLUSH_EXPLICIT_BIT ,
# else
FlushExplicit = GL_MAP_FLUSH_EXPLICIT_BIT_EXT ,
# endif
/**
* No pending operations on the buffer should be synchronized
* before mapping .
*/
# ifndef MAGNUM_TARGET_GLES2
Unsynchronized = GL_MAP_UNSYNCHRONIZED_BIT
# else
Unsynchronized = GL_MAP_UNSYNCHRONIZED_BIT_EXT
# endif
} ;
/**
* @ brief Memory mapping flags
*
* @ see @ ref map ( GLintptr , GLsizeiptr , MapFlags )
* @ requires_gl30 Extension @ extension { ARB , map_buffer_range }
* @ requires_gles30 Extension @ es_extension { EXT , map_buffer_range } in
* OpenGL ES 2.0 .
* @ requires_gles Buffer mapping is not available in WebGL .
*/
typedef Containers : : EnumSet < MapFlag > MapFlags ;
# endif
# ifndef MAGNUM_TARGET_GLES
/**
* @ brief Minimal supported mapping alignment
*
* The result is cached , repeated queries don ' t result in repeated
* OpenGL calls . If extension @ extension { ARB , map_buffer_alignment }
* ( part of OpenGL 4.2 ) is not available , returns ` 1 ` .
* @ see @ ref map ( ) , @ fn_gl { Get } with @ def_gl { MIN_MAP_BUFFER_ALIGNMENT }
* @ requires_gl No minimal value is specified for OpenGL ES . Buffer
* mapping is not available in WebGL .
*/
static Int minMapAlignment ( ) ;
# endif
# ifndef MAGNUM_TARGET_GLES2
# ifndef MAGNUM_TARGET_WEBGL
/**
* @ brief Max supported atomic counter buffer binding count
*
* The result is cached , repeated queries don ' t result in repeated
* OpenGL calls . If neither extension @ extension { ARB , shader_atomic_counters }
* ( part of OpenGL 4.2 ) nor OpenGL ES 3.1 is available , returns ` 0 ` .
* @ see @ ref bind ( ) , @ ref unbind ( ) , @ fn_gl { Get } with
* @ def_gl { MAX_ATOMIC_COUNTER_BUFFER_BINDINGS }
* @ requires_gles30 Not defined in OpenGL ES 2.0 .
* @ requires_gles Atomic counters are not available in WebGL .
*/
static Int maxAtomicCounterBindings ( ) ;
/**
* @ brief Max supported shader storage buffer binding count
*
* The result is cached , repeated queries don ' t result in repeated
* OpenGL calls . If neither extension @ extension { ARB , shader_storage_buffer_object }
* ( part of OpenGL 4.3 ) nor OpenGL ES 3.1 is available , returns ` 0 ` .
* @ see @ ref bind ( ) , @ ref unbind ( ) , @ fn_gl { Get } with
* @ def_gl { MAX_SHADER_STORAGE_BUFFER_BINDINGS }
* @ requires_gles30 Not defined in OpenGL ES 2.0 .
* @ requires_gles Shader storage is not available in WebGL .
*/
static Int maxShaderStorageBindings ( ) ;
# endif
/**
* @ brief Alignment of uniform buffer binding offset
*
* The result is cached , repeated queries don ' t result in repeated
* OpenGL calls . If extension @ extension { ARB , uniform_buffer_object }
* ( part of OpenGL 3.1 ) is not available , returns ` 1 ` .
* @ see @ ref bind ( ) , @ fn_gl { Get } with @ def_gl { UNIFORM_BUFFER_OFFSET_ALIGNMENT }
* @ requires_gles30 Uniform buffers are not available in OpenGL ES 2.0 .
* @ requires_webgl20 Uniform buffers are not available in WebGL 1.0 .
*/
static Int uniformOffsetAlignment ( ) ;
# ifndef MAGNUM_TARGET_WEBGL
/**
* @ brief Alignment of shader storage buffer binding offset
*
* The result is cached , repeated queries don ' t result in repeated
* OpenGL calls . If neither extension @ extension { ARB , shader_storage_buffer_object }
* ( part of OpenGL 4.3 ) nor OpenGL ES 3.1 is available , returns ` 1 ` .
* @ see @ ref bind ( ) , @ fn_gl { Get } with @ def_gl { SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT }
* @ requires_gles30 Not defined in OpenGL ES 2.0 .
* @ requires_gles Shader storage is not available in WebGL .
*/
static Int shaderStorageOffsetAlignment ( ) ;
# endif
/**
* @ brief Max supported uniform buffer binding count
*
* The result is cached , repeated queries don ' t result in repeated
* OpenGL calls . If extension @ extension { ARB , uniform_buffer_object }
* ( part of OpenGL 3.1 ) is not available , returns ` 0 ` .
* @ see @ ref bind ( ) , @ ref unbind ( ) , @ fn_gl { Get } with
* @ def_gl { MAX_UNIFORM_BUFFER_BINDINGS }
* @ requires_gles30 Uniform buffers are not available in OpenGL ES 2.0 .
* @ requires_webgl20 Uniform buffers are not available in WebGL 1.0 .
*/
static Int maxUniformBindings ( ) ;
/**
* @ brief Unbind any buffer from given indexed target
*
* The @ p index parameter must respect limits for given @ p target .
* @ note This function is meant to be used only internally from
* @ ref AbstractShaderProgram subclasses . See its documentation
* for more information .
* @ see @ ref bind ( ) , @ ref maxAtomicCounterBindings ( ) ,
* @ ref maxShaderStorageBindings ( ) , @ ref maxUniformBindings ( ) ,
* @ fn_gl { BindBufferBase }
* @ requires_gl30 No form of indexed buffer binding is available in
* OpenGL 2.1 , see particular @ ref Target values for
* version / extension requirements .
* @ requires_gles30 No form of indexed buffer binding is available in
* OpenGL ES 2.0 , see particular @ ref Target values for version
* requirements .
* @ requires_webgl20 No form of indexed buffer binding is available in
* WebGL 1.0 , see particular @ ref Target values for version
* requirements .
*/
static void unbind ( Target target , UnsignedInt index ) ;
/**
* @ brief Unbind given range of indexed targets
*
* Unbinds all buffers in given target in range @ f $ [ firstIndex ; firstIndex + count ] @ f $ .
* The range of indices must respect limits for given @ p target . If
* @ extension { ARB , multi_bind } ( part of OpenGL 4.4 ) is not available ,
* the feature is emulated with sequence of @ ref unbind ( Target , UnsignedInt )
* calls .
* @ note This function is meant to be used only internally from
* @ ref AbstractShaderProgram subclasses . See its documentation
* for more information .
* @ see @ ref unbind ( Target , UnsignedInt ) , @ ref maxAtomicCounterBindings ( ) ,
* @ ref maxShaderStorageBindings ( ) , @ ref maxUniformBindings ( ) ,
* @ fn_gl { BindBuffersBase } or @ fn_gl { BindBufferBase }
* @ requires_gl30 No form of indexed buffer binding is available in
* OpenGL 2.1 , see particular @ ref Target values for
* version / extension requirements .
* @ requires_gles30 No form of indexed buffer binding is available in
* OpenGL ES 2.0 , see particular @ ref Target values for version
* requirements .
* @ requires_webgl20 No form of indexed buffer binding is available in
* WebGL 1.0 , see particular @ ref Target values for version
* requirements .
*/
static void unbind ( Target target , UnsignedInt firstIndex , std : : size_t count ) ;
/**
* @ brief Bind ranges of buffers to given range of indexed targets
*
* Binds first buffer in the list to @ p firstIndex , second to
* ` firstIndex + 1 ` etc . Second parameter is offset , third is size . If
* any buffer is ` nullptr ` , given indexed target is unbound . The range
* of indices must respect limits for given @ p target . The offsets must
* respect alignment , which is 4 bytes for @ ref Target : : AtomicCounter
* and implementation - defined for other targets . All the buffers must
* have allocated data store . If @ extension { ARB , multi_bind } ( part of
* OpenGL 4.4 ) is not available , the feature is emulated with sequence
* of @ ref bind ( Target , UnsignedInt , GLintptr , GLsizeiptr ) /
* @ ref unbind ( Target , UnsignedInt ) calls .
* @ note This function is meant to be used only internally from
* @ ref AbstractShaderProgram subclasses . See its documentation
* for more information .
* @ see @ ref bind ( Target , UnsignedInt , GLintptr , GLsizeiptr ) ,
* @ ref maxAtomicCounterBindings ( ) , @ ref maxShaderStorageBindings ( ) ,
* @ ref maxUniformBindings ( ) , @ ref shaderStorageOffsetAlignment ( ) ,
* @ ref uniformOffsetAlignment ( ) , @ ref TransformFeedback : : attachBuffers ( ) ,
* @ fn_gl { BindBuffersRange } or @ fn_gl { BindBufferRange }
* @ requires_gl30 No form of indexed buffer binding is available in
* OpenGL 2.1 , see particular @ ref Target values for
* version / extension requirements .
* @ requires_gles30 No form of indexed buffer binding is available in
* OpenGL ES 2.0 , see particular @ ref Target values for version
* requirements .
* @ requires_webgl20 No form of indexed buffer binding is available in
* WebGL 1.0 , see particular @ ref Target values for version
* requirements .
*/
static void bind ( Target target , UnsignedInt firstIndex , std : : initializer_list < std : : tuple < Buffer * , GLintptr , GLsizeiptr > > buffers ) ;
/**
* @ brief Bind buffers to given range of indexed targets
*
* Binds first buffer in the list to @ p firstIndex , second to
* ` firstIndex + 1 ` etc . If any buffer is ` nullptr ` , given indexed
* target is unbound . The range of indices must respect limits for
* given @ p target . All the buffers must have allocated data store . If
* @ extension { ARB , multi_bind } ( part of OpenGL 4.4 ) is not available ,
* the feature is emulated with sequence of @ ref bind ( Target , UnsignedInt )
* / @ ref unbind ( Target , UnsignedInt ) calls .
* @ note This function is meant to be used only internally from
* @ ref AbstractShaderProgram subclasses . See its documentation
* for more information .
* @ see @ ref bind ( Target , UnsignedInt ) , @ ref maxAtomicCounterBindings ( ) ,
* @ ref maxShaderStorageBindings ( ) , @ ref maxUniformBindings ( ) ,
* @ ref TransformFeedback : : attachBuffers ( ) , @ fn_gl { BindBuffersBase }
* or @ fn_gl { BindBufferBase }
* @ requires_gl30 No form of indexed buffer binding is available in
* OpenGL 2.1 , see particular @ ref Target values for
* version / extension requirements .
* @ requires_gles30 No form of indexed buffer binding is available in
* OpenGL ES 2.0 , see particular @ ref Target values for version
* requirements .
* @ requires_webgl20 No form of indexed buffer binding is available in
* WebGL 1.0 , see particular @ ref Target values for version
* requirements .
*/
static void bind ( Target target , UnsignedInt firstIndex , std : : initializer_list < Buffer * > buffers ) ;
/**
* @ brief Copy one buffer to another
* @ param read Buffer from which to read
* @ param write Buffer to which to copy
* @ param readOffset Offset in the read buffer
* @ param writeOffset Offset in the write buffer
* @ param size Data size
*
* If neither @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 )
* nor @ extension { EXT , direct_state_access } desktop extension is
* available , @ p read buffer is bound for reading and @ p write buffer
* is bound for writing before the copy is performed ( if not already ) .
* @ see @ fn_gl2 { CopyNamedBufferSubData , CopyBufferSubData } ,
* @ fn_gl_extension { NamedCopyBufferSubData , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { CopyBufferSubData }
* @ requires_gl31 Extension @ extension { ARB , copy_buffer }
* @ requires_gles30 Buffer copying is not available in OpenGL ES 2.0 .
* @ requires_webgl20 Buffer copying is not available in WebGL 1.0 .
*/
static void copy ( Buffer & read , Buffer & write , GLintptr readOffset , GLintptr writeOffset , GLsizeiptr size ) ;
# endif
/**
* @ brief Wrap existing OpenGL buffer object
* @ param id OpenGL buffer ID
* @ param targetHint Target hint , see @ ref setTargetHint ( ) for more
* information
* @ param flags Object creation flags
*
* The @ p id is expected to be of an existing OpenGL buffer object .
* Unlike buffer created using constructor , the OpenGL object is by
* default not deleted on destruction , use @ p flags for different
* behavior .
* @ see @ ref release ( )
*/
static Buffer wrap ( GLuint id , TargetHint targetHint = TargetHint : : Array , ObjectFlags flags = { } ) {
return Buffer { id , targetHint , flags } ;
}
/** @overload */
static Buffer wrap ( GLuint id , ObjectFlags flags ) {
return Buffer ( id , TargetHint : : Array , flags ) ;
}
/**
* @ brief Constructor
* @ param targetHint Target hint , see @ ref setTargetHint ( ) for more
* information
*
* Creates new OpenGL buffer object . If @ extension { ARB , direct_state_access }
* ( part of OpenGL 4.5 ) is not available , the buffer is created on
* first use .
* @ see @ ref wrap ( ) , @ fn_gl { CreateBuffers } , eventually
* @ fn_gl { GenBuffers }
*/
explicit Buffer ( TargetHint targetHint = TargetHint : : Array ) ;
# ifdef MAGNUM_BUILD_DEPRECATED
/**
* @ copybrief Buffer ( TargetHint )
* @ deprecated Use @ ref Buffer ( TargetHint ) instead .
*/
CORRADE_DEPRECATED ( " use Buffer(TargetHint) instead " ) explicit Buffer ( Target targetHint ) : Buffer { static_cast < TargetHint > ( targetHint ) } { }
# endif
/** @brief Copying is not allowed */
Buffer ( const Buffer & ) = delete ;
/** @brief Move constructor */
Buffer ( Buffer & & other ) noexcept ;
/**
* @ brief Destructor
*
* Deletes associated OpenGL buffer object .
* @ see @ ref wrap ( ) , @ ref release ( ) , @ fn_gl { DeleteBuffers }
*/
~ Buffer ( ) ;
/** @brief Copying is not allowed */
Buffer & operator = ( const Buffer & ) = delete ;
/** @brief Move assignment */
Buffer & operator = ( Buffer & & other ) noexcept ;
/** @brief OpenGL buffer ID */
GLuint id ( ) const { return _id ; }
/**
* @ brief Release OpenGL object
*
* Releases ownership of OpenGL buffer object and returns its ID so it
* is not deleted on destruction . The internal state is then equivalent
* to moved - from state .
* @ see @ ref wrap ( )
*/
GLuint release ( ) ;
# ifndef MAGNUM_TARGET_WEBGL
/**
* @ brief Buffer label
*
* The result is * not * cached , repeated queries will result in repeated
* OpenGL calls . If OpenGL 4.3 is not supported and neither
* @ extension { KHR , debug } nor @ extension2 { EXT , debug_label } desktop or ES
* extension is available , this function returns empty string .
* @ see @ fn_gl { GetObjectLabel } with @ def_gl { BUFFER } or
* @ fn_gl_extension2 { GetObjectLabel , EXT , debug_label } with
* @ def_gl { BUFFER_OBJECT_EXT }
* @ requires_gles Debug output is not available in WebGL .
*/
std : : string label ( ) ;
/**
* @ brief Set buffer label
* @ return Reference to self ( for method chaining )
*
* Default is empty string . If OpenGL 4.3 is not supported and neither
* @ extension { KHR , debug } nor @ extension2 { EXT , debug_label } desktop or ES
* extension is available , this function does nothing .
* @ see @ ref maxLabelLength ( ) , @ fn_gl { ObjectLabel } with @ def_gl { BUFFER }
* or @ fn_gl_extension2 { LabelObject , EXT , debug_label } with
* @ def_gl { BUFFER_OBJECT_EXT }
* @ requires_gles Debug output is not available in WebGL .
*/
Buffer & setLabel ( const std : : string & label ) {
return setLabelInternal ( { label . data ( ) , label . size ( ) } ) ;
}
/** @overload */
template < std : : size_t size > Buffer & setLabel ( const char ( & label ) [ size ] ) {
return setLabelInternal ( { label , size - 1 } ) ;
}
# endif
/** @brief Target hint */
TargetHint targetHint ( ) const { return _targetHint ; }
/**
* @ brief Set target hint
* @ return Reference to self ( for method chaining )
*
* If neither @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 )
* nor @ extension { EXT , direct_state_access } desktop extension is
* available , the buffer needs to be internally bound to some target
* before any operation . You can specify target which will always be
* used when binding the buffer internally , possibly saving some calls
* to @ fn_gl { BindBuffer } . Default target hint is @ ref Target : : Array .
* @ see @ ref setData ( ) , @ ref setSubData ( )
* @ todo Target : : ElementArray cannot be used when no VAO is bound -
* http : //www.opengl.org/wiki/Vertex_Specification#Index_buffers
* . . . damned GL state
*/
Buffer & setTargetHint ( TargetHint hint ) {
_targetHint = hint ;
return * this ;
}
# ifdef MAGNUM_BUILD_DEPRECATED
/**
* @ copybrief setTargetHint ( TargetHint )
* @ deprecated Use @ ref setTargetHint ( TargetHint ) instead .
*/
CORRADE_DEPRECATED ( " use setTargetHint(TargetHint) instead " ) Buffer & setTargetHint ( Target hint ) {
return setTargetHint ( static_cast < TargetHint > ( hint ) ) ;
}
# endif
# ifndef MAGNUM_TARGET_GLES2
/**
* @ brief Bind buffer range to given binding index
*
* The @ p index parameter must respect limits for given @ p target . The
* @ p offset parameter must respect alignment , which is 4 bytes for
* @ ref Target : : AtomicCounter and implementation - defined for other
* targets . The buffer must have allocated data store .
* @ note This function is meant to be used only internally from
* @ ref AbstractShaderProgram subclasses . See its documentation
* for more information .
* @ see @ ref bind ( Target , UnsignedInt , std : : initializer_list < std : : tuple < Buffer * , GLintptr , GLsizeiptr > > ) ,
* @ ref maxAtomicCounterBindings ( ) , @ ref maxShaderStorageBindings ( ) ,
* @ ref maxUniformBindings ( ) , @ ref shaderStorageOffsetAlignment ( ) ,
* @ ref uniformOffsetAlignment ( ) , @ ref TransformFeedback : : attachBuffer ( ) ,
* @ fn_gl { BindBufferRange }
* @ requires_gl30 No form of indexed buffer binding is available in
* OpenGL 2.1 , see particular @ ref Target values for
* version / extension requirements .
* @ requires_gles30 No form of indexed buffer binding is available in
* OpenGL ES 2.0 , see particular @ ref Target values for version
* requirements .
* @ requires_webgl20 No form of indexed buffer binding is available in
* WebGL 1.0 , see particular @ ref Target values for version
* requirements .
* @ todo State tracking for indexed binding
*/
Buffer & bind ( Target target , UnsignedInt index , GLintptr offset , GLsizeiptr size ) ;
/**
* @ brief Bind buffer to given binding index
*
* The @ p index parameter must respect limits for given @ p target . The
* buffer must have allocated data store .
* @ note This function is meant to be used only internally from
* @ ref AbstractShaderProgram subclasses . See its documentation
* for more information .
* @ see @ ref bind ( Target , UnsignedInt , std : : initializer_list < Buffer * > ) ,
* @ ref maxAtomicCounterBindings ( ) , @ ref maxShaderStorageBindings ( ) ,
* @ ref maxUniformBindings ( ) , @ ref TransformFeedback : : attachBuffer ( ) ,
* @ fn_gl { BindBufferBase }
* @ requires_gl30 No form of indexed buffer binding is available in
* OpenGL 2.1 , see particular @ ref Target values for
* version / extension requirements .
* @ requires_gles30 No form of indexed buffer binding is available in
* OpenGL ES 2.0 , see particular @ ref Target values for version
* requirements .
* @ requires_webgl20 No form of indexed buffer binding is available in
* WebGL 1.0 , see particular @ ref Target values for version
* requirements .
*/
Buffer & bind ( Target target , UnsignedInt index ) ;
# endif
/**
* @ brief Buffer size
*
* If neither @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 )
* nor @ extension { EXT , direct_state_access } desktop extension is
* available , the buffer is bound to hinted target before the operation
* ( if not already ) .
* @ see @ ref setTargetHint ( ) , @ fn_gl2 { GetNamedBufferParameter , GetBufferParameter } ,
* @ fn_gl_extension { GetNamedBufferParameter , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { GetBufferParameter }
*/
Int size ( ) ;
# ifndef MAGNUM_TARGET_GLES
/**
* @ brief Buffer data
*
* Returns data of whole buffer . If neither @ extension { ARB , direct_state_access }
* ( part of OpenGL 4.5 ) nor @ extension { EXT , direct_state_access } is
* available , the buffer is bound to hinted target before the operation
* ( if not already ) .
* @ see @ ref size ( ) , @ ref subData ( ) , @ ref setData ( ) , @ ref setTargetHint ( ) ,
* @ fn_gl2 { GetNamedBufferParameter , GetBufferParameter } ,
* @ fn_gl_extension { GetNamedBufferParameter , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { GetBufferParameter }
* with @ def_gl { BUFFER_SIZE } , then @ fn_gl2 { GetNamedBufferSubData , GetBufferSubData } ,
* @ fn_gl_extension { GetNamedBufferSubData , EXT , direct_state_access } ,
* eventually @ fn_gl { GetBufferSubData }
* @ requires_gl Buffer data queries are not available in OpenGL ES and
* WebGL . Use @ ref map ( ) in OpenGL ES instead .
*/
template < class T = char > Containers : : Array < T > data ( ) ;
/**
* @ brief Buffer subdata
* @ param offset Byte offset in the buffer
* @ param size Data size ( count of @ p T values )
*
* Returns data of given buffer portion . If neither
* @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 ) nor
* @ extension { EXT , direct_state_access } is available , the buffer is
* bound to hinted target before the operation ( if not already ) .
* @ see @ ref size ( ) , @ ref data ( ) , @ ref setSubData ( ) , @ ref setTargetHint ( ) ,
* @ fn_gl2 { GetNamedBufferSubData , GetBufferSubData } ,
* @ fn_gl_extension { GetNamedBufferSubData , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { GetBufferSubData }
* @ requires_gl Buffer data queries are not available in OpenGL ES and
* WebGL . Use @ ref map ( ) in OpenGL ES instead .
*/
template < class T = char > Containers : : Array < T > subData ( GLintptr offset , GLsizeiptr size ) ;
# endif
/**
* @ brief Set buffer data
* @ param data Data
* @ param usage Buffer usage
* @ return Reference to self ( for method chaining )
*
* If neither @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 )
* nor @ extension { EXT , direct_state_access } desktop extension is
* available , the buffer is bound to hinted target before the operation
* ( if not already ) .
* @ see @ ref setTargetHint ( ) , @ fn_gl2 { NamedBufferData , BufferData } ,
* @ fn_gl_extension { NamedBufferData , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { BufferData }
*/
Buffer & setData ( Containers : : ArrayReference < const void > data , BufferUsage usage ) ;
/** @overload */
template < class T > Buffer & setData ( const std : : vector < T > & data , BufferUsage usage ) {
setData ( { data . data ( ) , data . size ( ) } , usage ) ;
return * this ;
}
/** @overload */
template < std : : size_t size , class T > Buffer & setData ( const std : : array < T , size > & data , BufferUsage usage ) {
setData ( { data . data ( ) , data . size ( ) } , usage ) ;
return * this ;
}
/**
* @ brief Set buffer subdata
* @ param offset Offset in the buffer
* @ param data Data
* @ return Reference to self ( for method chaining )
*
* If neither @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 )
* nor @ extension { EXT , direct_state_access } desktop extension is
* available , the buffer is bound to hinted target before the operation
* ( if not already ) .
* @ see @ ref setTargetHint ( ) , @ fn_gl2 { NamedBufferSubData , BufferSubData } ,
* @ fn_gl_extension { NamedBufferSubData , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { BufferSubData }
*/
Buffer & setSubData ( GLintptr offset , Containers : : ArrayReference < const void > data ) ;
/** @overload */
template < class T > Buffer & setSubData ( GLintptr offset , const std : : vector < T > & data ) {
setSubData ( offset , { data . data ( ) , data . size ( ) } ) ;
return * this ;
}
/** @overload */
template < std : : size_t size , class T > Buffer & setSubData ( GLintptr offset , const std : : array < T , size > & data ) {
setSubData ( offset , { data . data ( ) , data . size ( ) } ) ;
return * this ;
}
/**
* @ brief Invalidate buffer data
* @ return Reference to self ( for method chaining )
*
* If running on OpenGL ES or extension @ extension { ARB , invalidate_subdata }
* ( part of OpenGL 4.3 ) is not available , this function does nothing .
* @ see @ ref MapFlag : : InvalidateBuffer , @ fn_gl { InvalidateBufferData }
*/
Buffer & invalidateData ( ) ;
/**
* @ brief Invalidate buffer subdata
* @ param offset Offset into the buffer
* @ param length Length of the invalidated range
* @ return Reference to self ( for method chaining )
*
* If running on OpenGL ES or extension @ extension { ARB , invalidate_subdata }
* ( part of OpenGL 4.3 ) is not available , this function does nothing .
* @ see @ ref MapFlag : : InvalidateRange , @ fn_gl { InvalidateBufferData }
*/
Buffer & invalidateSubData ( GLintptr offset , GLsizeiptr length ) ;
# ifndef MAGNUM_TARGET_WEBGL
/**
* @ brief Map buffer to client memory
* @ param access Access
* @ return Pointer to buffer data
*
* If neither @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 )
* nor @ extension { EXT , direct_state_access } desktop extension is
* available , the buffer is bound to hinted target before the operation
* ( if not already ) .
* @ see @ ref minMapAlignment ( ) , @ ref unmap ( ) , @ ref setTargetHint ( ) ,
* @ fn_gl2 { MapNamedBuffer , MapBuffer } ,
* @ fn_gl_extension { MapNamedBuffer , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { MapBuffer }
* @ requires_es_extension Extension @ es_extension { OES , mapbuffer } in
* OpenGL ES 2.0 , use @ ref map ( GLintptr , GLsizeiptr , MapFlags ) in
* OpenGL ES 3.0 instead .
* @ requires_gles Buffer mapping is not available in WebGL .
* @ deprecated_gl Prefer to use @ ref map ( GLintptr , GLsizeiptr , MapFlags )
* instead , as it has more complete set of features .
*/
void * map ( MapAccess access ) ;
/** @overload */
template < class T > T * map ( MapAccess access ) {
return static_cast < T * > ( map ( access ) ) ;
}
# ifdef CORRADE_TARGET_NACL
/**
* @ brief Map portion of buffer to client memory
* @ param offset Offset into the buffer
* @ param length Length of the mapped memory
* @ param access Access
* @ return Pointer to buffer data
*
* The buffer is bound to hinted target before the operation ( if not
* already ) .
* @ see @ ref unmapSub ( ) , @ ref setTargetHint ( ) ,
* @ fn_gl_extension { MapBufferSubData , CHROMIUM , map_sub }
* @ requires_gles20 Available only in NaCl build . Use
* @ ref map ( GLintptr , GLsizeiptr , MapFlags ) elsewhere .
* @ requires_es_extension Extension @ es_extension { CHROMIUM , map_sub }
* @ requires_gles Buffer mapping is not available in WebGL .
* @ deprecated_gl Prefer to use @ ref map ( GLintptr , GLsizeiptr , MapFlags )
* instead , as it has more complete set of features .
*/
void * mapSub ( GLintptr offset , GLsizeiptr length , MapAccess access ) ;
/** @overload */
template < class T > T * mapSub ( GLintptr offset , GLsizeiptr length , MapAccess access ) {
return static_cast < T * > ( mapSub ( offset , length , access ) ) ;
}
# endif
/**
* @ brief Map buffer to client memory
* @ param offset Offset into the buffer
* @ param length Length of the mapped memory
* @ param flags Flags . At least @ ref MapFlag : : Read or
* @ ref MapFlag : : Write must be specified .
* @ return Pointer to buffer data
*
* If neither @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 )
* nor @ extension { EXT , direct_state_access } desktop extension is
* available , the buffer is bound to hinted target before the operation
* ( if not already ) .
* @ see @ ref minMapAlignment ( ) , @ ref flushMappedRange ( ) , @ ref unmap ( ) ,
* @ ref map ( MapAccess ) , @ ref setTargetHint ( ) ,
* @ fn_gl2 { MapNamedBufferRange , MapBufferRange } ,
* @ fn_gl_extension { MapNamedBufferRange , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { MapBufferRange }
* @ requires_gl30 Extension @ extension { ARB , map_buffer_range }
* @ requires_gles30 Extension @ es_extension { EXT , map_buffer_range } in
* OpenGL ES 2.0 .
* @ requires_gles Buffer mapping is not available in WebGL .
*/
void * map ( GLintptr offset , GLsizeiptr length , MapFlags flags ) ;
/** @overload */
template < class T > T * map ( GLintptr offset , GLsizeiptr length , MapFlags flags ) {
return static_cast < T * > ( map ( offset , length , flags ) ) ;
}
/**
* @ brief Flush mapped range
* @ param offset Offset relative to start of mapped range
* @ param length Length of the flushed memory
* @ return Reference to self ( for method chaining )
*
* Flushes specified subsection of mapped range . Use only if you called
* @ ref map ( ) with @ ref MapFlag : : FlushExplicit flag . See
* @ ref Buffer - data - mapping " class documentation " for usage example .
*
* If neither @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 )
* nor @ extension { EXT , direct_state_access } desktop extension is
* available , the buffer is bound to hinted target before the operation
* ( if not already ) .
* @ see @ ref setTargetHint ( ) , @ fn_gl2 { FlushMappedNamedBufferRange , FlushMappedBufferRange } ,
* @ fn_gl_extension { FlushMappedNamedBufferRange , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { FlushMappedBufferRange }
* @ requires_gl30 Extension @ extension { ARB , map_buffer_range }
* @ requires_gles30 Extension @ es_extension { EXT , map_buffer_range } in
* OpenGL ES 2.0 .
* @ requires_gles Buffer mapping is not available in WebGL .
*/
Buffer & flushMappedRange ( GLintptr offset , GLsizeiptr length ) ;
/**
* @ brief Unmap buffer
* @ return ` False ` if the data have become corrupt during the time
* the buffer was mapped ( e . g . after screen was resized ) , ` true `
* otherwise .
*
* Unmaps buffer previously mapped with @ ref map ( ) , invalidating the
* pointer returned by these functions . If neither
* @ extension { ARB , direct_state_access } ( part of OpenGL 4.5 ) nor
* @ extension { EXT , direct_state_access } desktop extension is available ,
* the buffer is bound to hinted target before the operation ( if not
* already ) .
* @ see @ ref setTargetHint ( ) , @ fn_gl2 { UnmapNamedBuffer , UnmapBuffer } ,
* @ fn_gl_extension { UnmapNamedBuffer , EXT , direct_state_access } ,
* eventually @ fn_gl { BindBuffer } and @ fn_gl { UnmapBuffer }
* @ requires_gles30 Extension @ es_extension { OES , mapbuffer } in OpenGL
* ES 2.0 .
* @ requires_gles Buffer mapping is not available in WebGL .
*/
bool unmap ( ) ;
# ifdef CORRADE_TARGET_NACL
/**
* @ brief Unmap portion of buffer
*
* Unmaps portion of buffer previously mapped with @ ref mapSub ( ) ,
* invalidating the pointer returned by the function .
* @ see @ fn_gl_extension { UnmapBufferSubData , CHROMIUM , map_sub }
* @ requires_gles20 Available only in NaCl build . Use
* @ ref map ( GLintptr , GLsizeiptr , MapFlags ) elsewhere .
* @ requires_es_extension Extension @ es_extension { CHROMIUM , map_sub }
* @ requires_gles Buffer mapping is not available in WebGL .
*/
void unmapSub ( ) ;
# endif
# endif
# ifdef DOXYGEN_GENERATING_OUTPUT
private :
# endif
/* There should be no need to use these from user code. Also it's a bit
unfortunate to have the parameter typed as TargetHint while in this
case it is no hint at all , but it allows to have cleaner public
binding API ( just with short Target name ) */
static void unbindInternal ( TargetHint target ) { bindInternal ( target , nullptr ) ; }
void bindInternal ( TargetHint target ) { bindInternal ( target , this ) ; }
private :
static void bindInternal ( TargetHint hint , Buffer * buffer ) ;
TargetHint MAGNUM_LOCAL bindSomewhereInternal ( TargetHint hint ) ;
# ifndef MAGNUM_TARGET_GLES2
static void MAGNUM_LOCAL bindImplementationFallback ( Target target , GLuint firstIndex , Containers : : ArrayReference < Buffer * const > buffers ) ;
# ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL bindImplementationMulti ( Target target , GLuint firstIndex , Containers : : ArrayReference < Buffer * const > buffers ) ;
# endif
static void MAGNUM_LOCAL bindImplementationFallback ( Target target , GLuint firstIndex , Containers : : ArrayReference < const std : : tuple < Buffer * , GLintptr , GLsizeiptr > > buffers ) ;
# ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL bindImplementationMulti ( Target target , GLuint firstIndex , Containers : : ArrayReference < const std : : tuple < Buffer * , GLintptr , GLsizeiptr > > buffers ) ;
# endif
static void MAGNUM_LOCAL copyImplementationDefault ( Buffer & read , Buffer & write , GLintptr readOffset , GLintptr writeOffset , GLsizeiptr size ) ;
# ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL copyImplementationDSA ( Buffer & read , Buffer & write , GLintptr readOffset , GLintptr writeOffset , GLsizeiptr size ) ;
static void MAGNUM_LOCAL copyImplementationDSAEXT ( Buffer & read , Buffer & write , GLintptr readOffset , GLintptr writeOffset , GLsizeiptr size ) ;
# endif
# endif
explicit Buffer ( GLuint id , TargetHint targetHint , ObjectFlags flags ) noexcept : _id { id } , _targetHint { targetHint } , _flags { flags } { }
void MAGNUM_LOCAL createImplementationDefault ( ) ;
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL createImplementationDSA ( ) ;
# endif
void MAGNUM_LOCAL createIfNotAlready ( ) ;
# ifndef MAGNUM_TARGET_WEBGL
Buffer & setLabelInternal ( Containers : : ArrayReference < const char > label ) ;
# endif
# ifndef MAGNUM_TARGET_GLES
void subDataInternal ( GLintptr offset , GLsizeiptr size , GLvoid * data ) ;
# endif
void MAGNUM_LOCAL getParameterImplementationDefault ( GLenum value , GLint * data ) ;
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL getParameterImplementationDSA ( GLenum value , GLint * data ) ;
void MAGNUM_LOCAL getParameterImplementationDSAEXT ( GLenum value , GLint * data ) ;
# endif
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL getSubDataImplementationDefault ( GLintptr offset , GLsizeiptr size , GLvoid * data ) ;
void MAGNUM_LOCAL getSubDataImplementationDSA ( GLintptr offset , GLsizeiptr size , GLvoid * data ) ;
void MAGNUM_LOCAL getSubDataImplementationDSAEXT ( GLintptr offset , GLsizeiptr size , GLvoid * data ) ;
# endif
void MAGNUM_LOCAL dataImplementationDefault ( GLsizeiptr size , const GLvoid * data , BufferUsage usage ) ;
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL dataImplementationDSA ( GLsizeiptr size , const GLvoid * data , BufferUsage usage ) ;
void MAGNUM_LOCAL dataImplementationDSAEXT ( GLsizeiptr size , const GLvoid * data , BufferUsage usage ) ;
# endif
void MAGNUM_LOCAL subDataImplementationDefault ( GLintptr offset , GLsizeiptr size , const GLvoid * data ) ;
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL subDataImplementationDSA ( GLintptr offset , GLsizeiptr size , const GLvoid * data ) ;
void MAGNUM_LOCAL subDataImplementationDSAEXT ( GLintptr offset , GLsizeiptr size , const GLvoid * data ) ;
# endif
void MAGNUM_LOCAL invalidateImplementationNoOp ( ) ;
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL invalidateImplementationARB ( ) ;
# endif
void MAGNUM_LOCAL invalidateSubImplementationNoOp ( GLintptr offset , GLsizeiptr length ) ;
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL invalidateSubImplementationARB ( GLintptr offset , GLsizeiptr length ) ;
# endif
# ifndef MAGNUM_TARGET_WEBGL
void MAGNUM_LOCAL * mapImplementationDefault ( MapAccess access ) ;
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL * mapImplementationDSA ( MapAccess access ) ;
void MAGNUM_LOCAL * mapImplementationDSAEXT ( MapAccess access ) ;
# endif
void MAGNUM_LOCAL * mapRangeImplementationDefault ( GLintptr offset , GLsizeiptr length , MapFlags access ) ;
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL * mapRangeImplementationDSA ( GLintptr offset , GLsizeiptr length , MapFlags access ) ;
void MAGNUM_LOCAL * mapRangeImplementationDSAEXT ( GLintptr offset , GLsizeiptr length , MapFlags access ) ;
# endif
void MAGNUM_LOCAL flushMappedRangeImplementationDefault ( GLintptr offset , GLsizeiptr length ) ;
# ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL flushMappedRangeImplementationDSA ( GLintptr offset , GLsizeiptr length ) ;
void MAGNUM_LOCAL flushMappedRangeImplementationDSAEXT ( GLintptr offset , GLsizeiptr length ) ;
# endif
bool MAGNUM_LOCAL unmapImplementationDefault ( ) ;
# ifndef MAGNUM_TARGET_GLES
bool MAGNUM_LOCAL unmapImplementationDSA ( ) ;
bool MAGNUM_LOCAL unmapImplementationDSAEXT ( ) ;
# endif
# endif
GLuint _id ;
TargetHint _targetHint ;
# ifdef CORRADE_TARGET_NACL
void * _mappedBuffer ;
# endif
ObjectFlags _flags ;
} ;
# ifndef MAGNUM_TARGET_WEBGL
CORRADE_ENUMSET_OPERATORS ( Buffer : : MapFlags )
# endif
/** @debugoperatorclassenum{Magnum::Buffer,Magnum::Buffer::TargetHint} */
Debug MAGNUM_EXPORT operator < < ( Debug debug , Buffer : : TargetHint value ) ;
# if !defined(MAGNUM_TARGET_GLES2) || defined(MAGNUM_BUILD_DEPRECATED)
/** @debugoperatorclassenum{Magnum::Buffer,Magnum::Buffer::Target} */
Debug MAGNUM_EXPORT operator < < ( Debug debug , Buffer : : Target value ) ;
# endif
inline Buffer : : Buffer ( Buffer & & other ) noexcept : _id { other . _id } , _targetHint { other . _targetHint } ,
# ifdef CORRADE_TARGET_NACL
_mappedBuffer { other . _mappedBuffer } ,
# endif
_flags { other . _flags }
{
other . _id = 0 ;
# ifdef CORRADE_TARGET_NACL
other . _mappedBuffer = nullptr ;
# endif
}
inline Buffer & Buffer : : operator = ( Buffer & & other ) noexcept {
using std : : swap ;
swap ( _id , other . _id ) ;
swap ( _targetHint , other . _targetHint ) ;
# ifdef CORRADE_TARGET_NACL
swap ( _mappedBuffer , other . _mappedBuffer ) ;
# endif
swap ( _flags , other . _flags ) ;
return * this ;
}
inline GLuint Buffer : : release ( ) {
const GLuint id = _id ;
_id = 0 ;
return id ;
}
# ifndef MAGNUM_TARGET_GLES
template < class T > Containers : : Array < T > inline Buffer : : data ( ) {
const Int bufferSize = size ( ) ;
CORRADE_ASSERT ( bufferSize % sizeof ( T ) = = 0 , " Buffer::data(): the buffer size is " < < bufferSize < < " bytes, which can't be expressed as array of types with size " < < sizeof ( T ) , nullptr ) ;
return subData < T > ( 0 , bufferSize / sizeof ( T ) ) ;
}
template < class T > Containers : : Array < T > inline Buffer : : subData ( const GLintptr offset , const GLsizeiptr size ) {
Containers : : Array < T > data ( size ) ;
if ( size ) subDataInternal ( offset , size * sizeof ( T ) , data ) ;
return data ;
}
# endif
}
# endif