From 5b54b0721001840ea8cec730c38a2ece165993a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 25 May 2013 15:17:44 +0200 Subject: [PATCH] Added Buffer::size(), Buffer::data() and Buffer::subData() queries. --- src/Buffer.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++ src/Buffer.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index eeb26b659..025cbc0bc 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -24,6 +24,7 @@ #include "Buffer.h" +#include #include #include "Context.h" @@ -36,6 +37,8 @@ namespace Magnum { #ifndef MAGNUM_TARGET_GLES2 Buffer::CopyImplementation Buffer::copyImplementation = &Buffer::copyImplementationDefault; #endif +Buffer::GetParameterImplementation Buffer::getParameterImplementation = &Buffer::getParameterImplementationDefault; +Buffer::GetSubDataImplementation Buffer::getSubDataImplementation = &Buffer::getSubDataImplementationDefault; Buffer::DataImplementation Buffer::dataImplementation = &Buffer::dataImplementationDefault; Buffer::SubDataImplementation Buffer::subDataImplementation = &Buffer::subDataImplementationDefault; Buffer::InvalidateImplementation Buffer::invalidateImplementation = &Buffer::invalidateImplementationNoOp; @@ -53,6 +56,8 @@ void Buffer::initializeContextBasedFunctionality(Context* context) { Debug() << "Buffer: using" << Extensions::GL::EXT::direct_state_access::string() << "features"; copyImplementation = &Buffer::copyImplementationDSA; + getParameterImplementation = &Buffer::getParameterImplementationDSA; + getSubDataImplementation = &Buffer::getSubDataImplementationDSA; dataImplementation = &Buffer::dataImplementationDSA; subDataImplementation = &Buffer::subDataImplementationDSA; mapImplementation = &Buffer::mapImplementationDSA; @@ -111,6 +116,26 @@ Buffer::Target Buffer::bindInternal(Target hint) { return hint; } +Int Buffer::size() { + /** + * @todo there is something like glGetBufferParameteri64v in 3.2 (I + * couldn't find any matching extension, though) + */ + GLint size; + (this->*getParameterImplementation)(GL_BUFFER_SIZE, &size); + return size; +} + +Containers::Array Buffer::data() { + return subData(0, size()); +} + +Containers::Array Buffer::subData(const GLintptr offset, const GLsizeiptr size) { + Containers::Array data(size); + if(size) (this->*getSubDataImplementation)(offset, size, data); + return std::move(data); +} + #ifndef MAGNUM_TARGET_GLES2 void Buffer::copyImplementationDefault(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { glCopyBufferSubData(static_cast(read->bindInternal(Target::CopyRead)), static_cast(write->bindInternal(Target::CopyWrite)), readOffset, writeOffset, size); @@ -123,6 +148,26 @@ void Buffer::copyImplementationDSA(Buffer* read, Buffer* write, GLintptr readOff #endif #endif +void Buffer::getParameterImplementationDefault(const GLenum value, GLint* const data) { + glGetBufferParameteriv(GLenum(bindInternal(_targetHint)), value, data); +} + +#ifndef MAGNUM_TARGET_GLES +void Buffer::getParameterImplementationDSA(const GLenum value, GLint* const data) { + glGetNamedBufferParameterivEXT(_id, value, data); +} +#endif + +void Buffer::getSubDataImplementationDefault(const GLintptr offset, const GLsizeiptr size, GLvoid* const data) { + glGetBufferSubData(GLenum(bindInternal(_targetHint)), offset, size, data); +} + +#ifndef MAGNUM_TARGET_GLES +void Buffer::getSubDataImplementationDSA(const GLintptr offset, const GLsizeiptr size, GLvoid* const data) { + glGetNamedBufferSubDataEXT(_id, offset, size, data); +} +#endif + void Buffer::dataImplementationDefault(GLsizeiptr size, const GLvoid* data, Buffer::Usage usage) { glBufferData(static_cast(bindInternal(_targetHint)), size, data, static_cast(usage)); } diff --git a/src/Buffer.h b/src/Buffer.h index c73a4e64f..600b9c076 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "Magnum.h" @@ -519,6 +520,44 @@ class MAGNUM_EXPORT Buffer { */ inline void bind(Target target) { bind(target, _id); } + /** + * @brief Buffer size + * + * If @extension{EXT,direct_state_access} is not available and the + * buffer is not already bound somewhere, it is bound to hinted target + * before the operation. + * @see @fn_gl{BindBuffer} and @fn_gl{GetBufferParameter} or + * @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access} + * with @def_gl{BUFFER_SIZE} + */ + Int size(); + + /** + * @brief Buffer data + * + * Returns data of whole buffer. If @extension{EXT,direct_state_access} + * is not available and the buffer is not already bound somewhere, it + * is bound to hinted target before the operation. + * @see size(), subData(), setData(), @fn_gl{BindBuffer} and @fn_gl{GetBufferParameter} or + * @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access} + * with @def_gl{BUFFER_SIZE}, @fn_gl{GetBufferSubData} or + * @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access} + */ + Containers::Array data(); + + /** + * @brief Buffer subdata + * @param offset Offset in the buffer + * @param size Data size + * + * Returns data of given buffer portion. If @extension{EXT,direct_state_access} + * is not available and the buffer is not already bound somewhere, it + * is bound to hinted target before the operation. + * @see size(), data(), setSubData(), @fn_gl{BindBuffer} and @fn_gl{GetBufferSubData} + * or @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access} + */ + Containers::Array subData(GLintptr offset, GLsizeiptr size); + /** * @brief Set buffer data * @param size Data size @@ -746,6 +785,20 @@ class MAGNUM_EXPORT Buffer { static CopyImplementation copyImplementation; #endif + typedef void(Buffer::*GetParameterImplementation)(GLenum, GLint*); + void MAGNUM_LOCAL getParameterImplementationDefault(GLenum value, GLint* data); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL getParameterImplementationDSA(GLenum value, GLint* data); + #endif + static MAGNUM_LOCAL GetParameterImplementation getParameterImplementation; + + typedef void(Buffer::*GetSubDataImplementation)(GLintptr, GLsizeiptr, GLvoid*); + void MAGNUM_LOCAL getSubDataImplementationDefault(GLintptr offset, GLsizeiptr size, GLvoid* data); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL getSubDataImplementationDSA(GLintptr offset, GLsizeiptr size, GLvoid* data); + #endif + static MAGNUM_LOCAL GetSubDataImplementation getSubDataImplementation; + typedef void(Buffer::*DataImplementation)(GLsizeiptr, const GLvoid*, Usage); void MAGNUM_LOCAL dataImplementationDefault(GLsizeiptr size, const GLvoid* data, Usage usage); #ifndef MAGNUM_TARGET_GLES