diff --git a/doc/changelog.dox b/doc/changelog.dox index d2e4f04cd..4ef5b3e33 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -69,6 +69,8 @@ See also: fixes crashes on Apple macOS when attempting to modify a @ref GL::Buffer when a @ref GL::BufferTexture is bound. See @ref opengl-workarounds for more information. +- New @ref GL::Buffer::Buffer(Containers::ArrayView, BufferUsage) + constructor for directly creating buffers filled with data. @subsubsection changelog-latest-new-math Math library diff --git a/doc/snippets/MagnumGL.cpp b/doc/snippets/MagnumGL.cpp index 7137b9217..b6533726b 100644 --- a/doc/snippets/MagnumGL.cpp +++ b/doc/snippets/MagnumGL.cpp @@ -425,7 +425,9 @@ GL::BufferImage2D image = framebuffer.read(framebuffer.viewport(), GL::Buffer buffer; /* [Buffer-setdata] */ Containers::ArrayView data; -buffer.setData(data, GL::BufferUsage::StaticDraw); +buffer.setData(data); + +GL::Buffer buffer2{data}; // or construct & fill in a single step /* [Buffer-setdata] */ } @@ -433,11 +435,11 @@ buffer.setData(data, GL::BufferUsage::StaticDraw); GL::Buffer buffer; /* [Buffer-setdata-stl] */ std::vector data; -buffer.setData(data, GL::BufferUsage::StaticDraw); +buffer.setData(data); /* [Buffer-setdata-stl] */ /* [Buffer-setdata-allocate] */ -buffer.setData({nullptr, 200*sizeof(Vector3)}, GL::BufferUsage::StaticDraw); +buffer.setData({nullptr, 200*sizeof(Vector3)}); /* [Buffer-setdata-allocate] */ } diff --git a/src/Magnum/GL/Buffer.h b/src/Magnum/GL/Buffer.h index 3fc6bab3b..0eb5fdfc8 100644 --- a/src/Magnum/GL/Buffer.h +++ b/src/Magnum/GL/Buffer.h @@ -145,9 +145,10 @@ data updates. @section GL-Buffer-data-updating Data updating -Default way to set or update buffer data with @ref setData() or @ref setSubData() -is to use @ref Corrade::Containers::ArrayView. See its documentation for -more information about automatic conversions etc. +Default way to set or update buffer data with @ref setData(), @ref setSubData() +or the shorthand @ref Buffer() constructor is to use +@ref Corrade::Containers::ArrayView. See its documentation for more information +about automatic conversions etc. @snippet MagnumGL.cpp Buffer-setdata @@ -784,6 +785,42 @@ class MAGNUM_GL_EXPORT Buffer: public AbstractObject { */ explicit Buffer(NoCreateT) noexcept; + /** + * @brief Construct and directly fill with data + * @param targetHint Target hint, see @ref setTargetHint() for more + * information + * @param data Data + * @param usage Buffer usage + * @m_since_latest + * + * Equivalent to constructing via @ref Buffer(TargetHint) and then + * calling @ref setData(). + */ + explicit Buffer(TargetHint targetHint, Containers::ArrayView data, BufferUsage usage = BufferUsage::StaticDraw): Buffer{targetHint} { + setData(data, usage); + } + + /** + * @overload + * @m_since_latest + */ + template explicit Buffer(TargetHint targetHint, std::initializer_list data, BufferUsage usage = BufferUsage::StaticDraw): Buffer{targetHint, Containers::arrayView(data), usage} {} + + /** + * @overload + * @m_since_latest + * + * Equivalent to calling @ref Buffer(TargetHint, Containers::ArrayView, BufferUsage) + * with @ref TargetHint::Array. Unlike with + * @ref Buffer(TargetHint, std::initializer_list, BufferUsage) an + * @ref std::initializer_list overload isn't provided in this case as + * it would cause a lot of undesired implicit conversions when using + * the `{}`-style construction. Use the above overload or the + * @ref Corrade::Containers::arrayView(std::initializer_list) helper + * instead. + */ + explicit Buffer(Containers::ArrayView data, BufferUsage usage = BufferUsage::StaticDraw): Buffer{TargetHint::Array, data, usage} {} + /** @brief Copying is not allowed */ Buffer(const Buffer&) = delete; diff --git a/src/Magnum/GL/Test/BufferGLTest.cpp b/src/Magnum/GL/Test/BufferGLTest.cpp index 1bf02aa0f..1d53b2ded 100644 --- a/src/Magnum/GL/Test/BufferGLTest.cpp +++ b/src/Magnum/GL/Test/BufferGLTest.cpp @@ -41,6 +41,7 @@ struct BufferGLTest: OpenGLTester { explicit BufferGLTest(); void construct(); + void constructFromData(); void constructMove(); void wrap(); @@ -67,6 +68,7 @@ struct BufferGLTest: OpenGLTester { BufferGLTest::BufferGLTest() { addTests({&BufferGLTest::construct, + &BufferGLTest::constructFromData, &BufferGLTest::constructMove, &BufferGLTest::wrap, @@ -104,6 +106,36 @@ void BufferGLTest::construct() { MAGNUM_VERIFY_NO_GL_ERROR(); } +void BufferGLTest::constructFromData() { + constexpr Int data[] = {2, 7, 5, 13, 25}; + + Buffer a{Buffer::TargetHint::ElementArray, data}; + Buffer b{Buffer::TargetHint::ElementArray, {2, 7, 5, 13, 25}}; + Buffer c{data}; + Buffer d{{nullptr, 5*4}}; /* This should work too for reserving memory */ + + MAGNUM_VERIFY_NO_GL_ERROR(); + + CORRADE_COMPARE(a.size(), 5*4); + CORRADE_COMPARE(b.size(), 5*4); + CORRADE_COMPARE(c.size(), 5*4); + CORRADE_COMPARE(d.size(), 5*4); + + /** @todo How to verify the contents in ES? */ + #ifndef MAGNUM_TARGET_GLES + CORRADE_COMPARE_AS(Containers::arrayCast(a.data()), + Containers::arrayView(data), + TestSuite::Compare::Container); + CORRADE_COMPARE_AS(Containers::arrayCast(b.data()), + Containers::arrayView(data), + TestSuite::Compare::Container); + CORRADE_COMPARE_AS(Containers::arrayCast(c.data()), + Containers::arrayView(data), + TestSuite::Compare::Container); + /* d's data is undefined, not testing */ + #endif +} + void BufferGLTest::constructMove() { Buffer a; const Int id = a.id();