From 32d49db4028eccde901869e480bf1c9c275ccbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 12 Mar 2020 12:38:35 +0100 Subject: [PATCH] GL: mesh.draw(shader) -> shader.draw(mesh). As usual, the old APIs are still present, but marked as deprecated. Existing code is not updated yet to ensure I didn't break anything with this. This way it's much more intuitive and makes the code shorter and nicer in many cases. Shaders are now also able to hide irrelevant draw/dispatch APIs to avoid accidents. --- doc/changelog.dox | 23 +-- doc/method-chaining.dox | 5 +- doc/opengl-mapping.dox | 8 +- doc/snippets/MagnumGL.cpp | 9 ++ src/Magnum/GL/AbstractShaderProgram.cpp | 79 ++++++++++ src/Magnum/GL/AbstractShaderProgram.h | 188 ++++++++++++++++++++++- src/Magnum/GL/CMakeLists.txt | 2 +- src/Magnum/GL/Mesh.cpp | 47 +++--- src/Magnum/GL/Mesh.h | 136 +++++----------- src/Magnum/GL/MeshView.cpp | 91 +++++------ src/Magnum/GL/MeshView.h | 145 +++++++---------- src/Magnum/GL/Test/MeshTest.cpp | 4 +- src/Magnum/Shaders/DistanceFieldVector.h | 8 + src/Magnum/Shaders/Flat.h | 8 + src/Magnum/Shaders/MeshVisualizer.h | 8 + src/Magnum/Shaders/Phong.h | 8 + src/Magnum/Shaders/Vector.h | 8 + src/Magnum/Shaders/VertexColor.h | 8 + 18 files changed, 505 insertions(+), 280 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 0df47ac2c..52fceea4b 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -227,10 +227,11 @@ See also: @subsubsection changelog-latest-changes-gl GL library - Added @ref GL::AbstractTexture::bind(), - @ref GL::AbstractTexture::bindImages() and @ref GL::MeshView::draw() - overloads taking a @ref Corrade::Containers::ArrayView instead of - @ref std::initializer_list in order to allow passing runtime-sized lists - (see also [mosra/magnum#403](https://github.com/mosra/magnum/pull/403)) + @ref GL::AbstractTexture::bindImages() and + @ref GL::AbstractShaderProgram::draw() overloads taking a + @ref Corrade::Containers::ArrayView instead of @ref std::initializer_list + in order to allow passing runtime-sized lists (see also + [mosra/magnum#403](https://github.com/mosra/magnum/pull/403)) - Added an ability to remove a buffer from a @ref GL::BufferTexture using @ref GL::BufferTexture::resetBuffer() "resetBuffer()" @@ -392,6 +393,10 @@ See also: @subsection changelog-latest-deprecated Deprecated APIs +- @cpp GL::Mesh::draw() @ce and @cpp GL::MeshView::draw() @ce are deprecated + in favor of @ref GL::AbstractShaderProgram::draw() and + @ref GL::AbstractShaderProgram::drawTransformFeedback(), as the API makes + much more sense to have on a shader and not on a mesh - @cpp GL::Attribute::DataType::HalfFloat @ce, @cpp GL::DynamicAttribute::DataType::HalfFloat @ce and @cpp GL::PixelType::HalfFloat @ce is deprecated in favor of @@ -1806,9 +1811,9 @@ Released 2018-10-23, tagged as @ref GL::Mesh::setIndexBuffer() can now take ownership of a passed @ref GL::Buffer to simplify resource management on user side. See @ref GL-Mesh-buffer-ownership for more information. -- @ref GL::Mesh::draw() and @ref GL::MeshView::draw() now return a reference - to self to make method-chained draws (for example using a different shader) - possible as well +- @cpp GL::Mesh::draw() @ce and @cpp GL::MeshView::draw() @ce now return a + reference to self to make method-chained draws (for example using a + different shader) possible as well - The @ref GL::BufferUsage parameter in @ref GL::Buffer::setData() is now optional, defaults to @ref GL::BufferUsage::StaticDraw @@ -3237,8 +3242,8 @@ a high-level overview. - Removed deprecated `Mesh*::set*{Range,Count}()` functions, use @ref GL::Mesh::setCount() "Mesh*::setCount()" and @ref GL::MeshView::setIndexRange() "MeshView::setIndexRange()" instead -- Removed deprecated parameterless @ref GL::Mesh::draw() "Mesh*::draw()" - overload, use the one with explicit shader parameter instead +- Removed deprecated parameterless @cpp GL::Mesh::draw() @ce overload, use + the one with explicit shader parameter instead - Removed deprecated `Context::Flag::Robustness` enum value, use @ref GL::Context::Flag::RobustAccess "Context::Flag::RobustAccess" instead - Removed deprecated `Texture::Target` enum, use dedicated diff --git a/doc/method-chaining.dox b/doc/method-chaining.dox index dbd9f3288..58fc6a1e3 100644 --- a/doc/method-chaining.dox +++ b/doc/method-chaining.dox @@ -56,8 +56,9 @@ configured in one run, reducing count of bind calls from 9 to 3. @snippet MagnumGL.cpp method-chaining-texture-chained Method chaining is not used on non-configuring functions, such as -@ref GL::Framebuffer::clear() or @ref GL::Mesh::draw(), as these won't be -commonly used in conjunction with other functions anyway. +@ref GL::Framebuffer::clear() or @ref GL::AbstractShaderProgram::draw(), as +their desired use is commonly as a last step in the chain, after everything +else. Method chaining is also used in @ref SceneGraph and other libraries and in some cases it allows you to just "configure and forget" without even saving the diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index c606102f7..f46e876f4 100644 --- a/doc/opengl-mapping.dox +++ b/doc/opengl-mapping.dox @@ -138,10 +138,10 @@ OpenGL function | Matching API @fn_gl{DispatchCompute} | @ref GL::AbstractShaderProgram::dispatchCompute() @fn_gl_extension{DispatchComputeGroupSize,ARB,compute_variable_group_size} | | @fn_gl{DispatchComputeIndirect} | | -@fn_gl{DrawArrays}, \n @fn_gl{DrawArraysInstanced}, \n @fn_gl{DrawArraysInstancedBaseInstance}, \n @fn_gl{DrawElements}, \n @fn_gl{DrawRangeElements}, \n @fn_gl{DrawElementsBaseVertex}, \n @fn_gl{DrawRangeElementsBaseVertex}, \n @fn_gl{DrawElementsInstanced}, \n @fn_gl{DrawElementsInstancedBaseInstance}, \n @fn_gl{DrawElementsInstancedBaseVertex}, \n @fn_gl{DrawElementsInstancedBaseVertexBaseInstance} | @ref GL::Mesh::draw(AbstractShaderProgram&), \n @ref GL::MeshView::draw(AbstractShaderProgram&) +@fn_gl{DrawArrays}, \n @fn_gl{DrawArraysInstanced}, \n @fn_gl{DrawArraysInstancedBaseInstance}, \n @fn_gl{DrawElements}, \n @fn_gl{DrawRangeElements}, \n @fn_gl{DrawElementsBaseVertex}, \n @fn_gl{DrawRangeElementsBaseVertex}, \n @fn_gl{DrawElementsInstanced}, \n @fn_gl{DrawElementsInstancedBaseInstance}, \n @fn_gl{DrawElementsInstancedBaseVertex}, \n @fn_gl{DrawElementsInstancedBaseVertexBaseInstance} | @ref GL::AbstractShaderProgram::drawTransformFeedback() @fn_gl{DrawArraysIndirect}, \n @fn_gl{DrawElementsIndirect}, \n @fn_gl{MultiDrawArraysIndirect}, \n @fn_gl{MultiDrawElementsIndirect} | | @fn_gl{DrawBuffer}, \n `glNamedFramebufferDrawBuffer()`, \n @fn_gl{DrawBuffers}, \n `glNamedFramebufferDrawBuffers()` | @ref GL::DefaultFramebuffer::mapForDraw(), \n @ref GL::Framebuffer::mapForDraw() -@fn_gl{DrawTransformFeedback}, \n @fn_gl{DrawTransformFeedbackInstanced}, \n @fn_gl{DrawTransformFeedbackStream}, \n @fn_gl{DrawTransformFeedbackStreamInstanced} | @ref GL::Mesh::draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt), \n @ref GL::MeshView::draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt) +@fn_gl{DrawTransformFeedback}, \n @fn_gl{DrawTransformFeedbackInstanced}, \n @fn_gl{DrawTransformFeedbackStream}, \n @fn_gl{DrawTransformFeedbackStreamInstanced} | @ref GL::AbstractShaderProgram::drawTransformFeedback() @subsection opengl-mapping-functions-e E @@ -292,7 +292,7 @@ OpenGL function | Matching API @fn_gl{MapBuffer}, \n `glMapNamedBuffer()`, \n @fn_gl{MapBufferRange}, \n `glMapNamedBufferRange()`, \n @fn_gl{UnmapBuffer}, \n `glUnmapNamedBuffer()` | @ref GL::Buffer::map(), @ref GL::Buffer::unmap() @fn_gl{MemoryBarrier}, \n `glMemoryBarrierByRegion()` | @ref GL::Renderer::setMemoryBarrier(), \n @ref GL::Renderer::setMemoryBarrierByRegion() @fn_gl{MinSampleShading} | @ref GL::Renderer::setMinSampleShading() -@fn_gl{MultiDrawArrays}, \n @fn_gl{MultiDrawElements}, \n @fn_gl{MultiDrawElementsBaseVertex} | @ref GL::MeshView::draw(AbstractShaderProgram&, std::initializer_list>) +@fn_gl{MultiDrawArrays}, \n @fn_gl{MultiDrawElements}, \n @fn_gl{MultiDrawElementsBaseVertex} | @ref GL::AbstractShaderProgram::draw(Containers::ArrayView>) @fn_gl{MultiDrawArraysIndirectCount}, \n @fn_gl{MultiDrawElementsIndirectCount} | | @subsection opengl-mapping-functions-o O @@ -394,7 +394,7 @@ OpenGL function | Matching API @fn_gl_extension{UniformHandle,ARB,bindless_texture}, \n @fn_gl_extension{ProgramUniformHandle,ARB,bindless_texture} | | @fn_gl{UniformBlockBinding} | @ref GL::AbstractShaderProgram::setUniformBlockBinding() @fn_gl{UniformSubroutines} | | -@fn_gl{UseProgram} | @ref GL::Mesh::draw(), @ref GL::MeshView::draw() +@fn_gl{UseProgram} | @ref GL::AbstractShaderProgram::draw(), \n @ref GL::AbstractShaderProgram::drawTransformFeedback(), \n @ref GL::AbstractShaderProgram::dispatchCompute() @fn_gl{UseProgramStages} | | @subsection opengl-mapping-functions-v V diff --git a/doc/snippets/MagnumGL.cpp b/doc/snippets/MagnumGL.cpp index 3dfb6f426..88a169114 100644 --- a/doc/snippets/MagnumGL.cpp +++ b/doc/snippets/MagnumGL.cpp @@ -268,6 +268,15 @@ enum: UnsignedInt { }; /* [AbstractShaderProgram-output-attributes] */ +#if !defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL) +/* [AbstractShaderProgram-hide-irrelevant] */ +private: + using GL::AbstractShaderProgram::drawTransformFeedback; + using GL::AbstractShaderProgram::dispatchCompute; +/* [AbstractShaderProgram-hide-irrelevant] */ +public: +#endif + /* [AbstractShaderProgram-constructor] */ explicit MyShader() { /* Load shader sources */ diff --git a/src/Magnum/GL/AbstractShaderProgram.cpp b/src/Magnum/GL/AbstractShaderProgram.cpp index 78c87788d..e7f8676e3 100644 --- a/src/Magnum/GL/AbstractShaderProgram.cpp +++ b/src/Magnum/GL/AbstractShaderProgram.cpp @@ -31,10 +31,15 @@ #include "Magnum/GL/Context.h" #include "Magnum/GL/Extensions.h" +#include "Magnum/GL/Mesh.h" +#include "Magnum/GL/MeshView.h" #include "Magnum/GL/Shader.h" #ifndef MAGNUM_TARGET_WEBGL #include "Magnum/GL/Implementation/DebugState.h" #endif +#ifdef MAGNUM_TARGET_GLES +#include "Magnum/GL/Implementation/MeshState.h" +#endif #include "Magnum/GL/Implementation/ShaderProgramState.h" #include "Magnum/GL/Implementation/State.h" #include "Magnum/Math/RectangularMatrix.h" @@ -333,6 +338,80 @@ std::pair AbstractShaderProgram::validate() { return {success, std::move(message)}; } +void AbstractShaderProgram::draw(Mesh& mesh) { + CORRADE_ASSERT(mesh._countSet, "GL::AbstractShaderProgram::draw(): Mesh::setCount() was never called, probably a mistake?", ); + + /* Nothing to draw, exit without touching any state */ + if(!mesh._count || !mesh._instanceCount) return; + + use(); + + #ifndef MAGNUM_TARGET_GLES + mesh.drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._baseInstance, mesh._indexOffset, mesh._indexStart, mesh._indexEnd); + #elif !defined(MAGNUM_TARGET_GLES2) + mesh.drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._indexOffset, mesh._indexStart, mesh._indexEnd); + #else + mesh.drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._indexOffset); + #endif +} + +void AbstractShaderProgram::draw(MeshView& mesh) { + CORRADE_ASSERT(mesh._countSet, "GL::AbstractShaderProgram::draw(): MeshView::setCount() was never called, probably a mistake?", ); + + /* Nothing to draw, exit without touching any state */ + if(!mesh._count || !mesh._instanceCount) return; + + use(); + + #ifndef MAGNUM_TARGET_GLES + mesh._original->drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._baseInstance, mesh._indexOffset, mesh._indexStart, mesh._indexEnd); + #elif !defined(MAGNUM_TARGET_GLES2) + mesh._original->drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._indexOffset, mesh._indexStart, mesh._indexEnd); + #else + mesh._original->drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._indexOffset); + #endif +} + +void AbstractShaderProgram::draw(Containers::ArrayView> meshes) { + if(meshes.empty()) return; + + use(); + + #ifndef CORRADE_NO_ASSERT + const Mesh* original = &meshes.begin()->get()._original.get(); + for(MeshView& mesh: meshes) + CORRADE_ASSERT(&mesh._original.get() == original, "GL::AbstractShaderProgram::draw(): all meshes must be views of the same original mesh", ); + #endif + + #ifndef MAGNUM_TARGET_GLES + MeshView::multiDrawImplementationDefault(meshes); + #else + Context::current().state().mesh->multiDrawImplementation(meshes); + #endif +} + +void AbstractShaderProgram::draw(std::initializer_list> meshes) { + draw(Containers::arrayView(meshes)); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::drawTransformFeedback(Mesh& mesh, TransformFeedback& xfb, UnsignedInt stream) { + /* Nothing to draw, exit without touching any state */ + if(!mesh._instanceCount) return; + + use(); + mesh.drawInternal(xfb, stream, mesh._instanceCount); +} + +void AbstractShaderProgram::drawTransformFeedback(MeshView& mesh, TransformFeedback& xfb, UnsignedInt stream) { + /* Nothing to draw, exit without touching any state */ + if(!mesh._instanceCount) return; + + use(); + mesh._original->drawInternal(xfb, stream, mesh._instanceCount); +} +#endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) void AbstractShaderProgram::dispatchCompute(const Vector3ui& workgroupCount) { use(); diff --git a/src/Magnum/GL/AbstractShaderProgram.h b/src/Magnum/GL/AbstractShaderProgram.h index 2218d5667..0b56733bd 100644 --- a/src/Magnum/GL/AbstractShaderProgram.h +++ b/src/Magnum/GL/AbstractShaderProgram.h @@ -86,7 +86,14 @@ functions and properties: and similar, possibly with overloads based on desired use cases, e.g.: @snippet MagnumGL.cpp AbstractShaderProgram-xfb - + +
  • And optionally, **hiding irrelevant draw/dispatch functions** to prevent + users from accidentally calling @ref draw() on compute shaders, + @ref drawTransformFeedback() on shaders that don't have transform feedback + or @ref dispatchCompute() on shaders that aren't compute. For example: + + @snippet MagnumGL.cpp AbstractShaderProgram-hide-irrelevant + @subsection GL-AbstractShaderProgram-attribute-location Binding attribute and fragment data location @@ -345,7 +352,7 @@ class, configure attribute binding in meshes (see @ref GL-Mesh-configuration "Me for more information) and map shader outputs to framebuffer attachments if needed (see @ref GL-Framebuffer-usage "Framebuffer documentation" for more information). In each draw event set all required shader parameters, bind -specific framebuffer (if needed) and then call @ref Mesh::draw(). Example: +specific framebuffer (if needed) and then call @ref draw(). Example: @snippet MagnumGL.cpp AbstractShaderProgram-rendering @@ -419,8 +426,6 @@ comes in handy. @todo `GL_NUM_{PROGRAM,SHADER}_BINARY_FORMATS` + `GL_{PROGRAM,SHADER}_BINARY_FORMATS` (vector), (@gl_extension{ARB,ES2_compatibility}) */ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject { - friend Mesh; - friend MeshView; #ifndef MAGNUM_TARGET_GLES2 friend TransformFeedback; #endif @@ -729,6 +734,181 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject { */ std::pair validate(); + /** + * @brief Draw a mesh + * @param mesh Mesh to draw + * @m_since_latest + * + * Expects that @p mesh is compatible with this shader and is fully set + * up. If its vertex/index count or instance count is @cpp 0 @ce, no + * draw commands are issued. See also + * @ref GL-AbstractShaderProgram-rendering-workflow "class documentation" + * for more information. If @gl_extension{ARB,vertex_array_object} (part + * of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, @gl_extension{OES,vertex_array_object} + * in OpenGL ES 2.0 or @webgl_extension{OES,vertex_array_object} in + * WebGL 1.0 is available, the associated vertex array object is bound + * instead of setting up the mesh from scratch. + * @see @ref Mesh::setCount(), @ref Mesh::setInstanceCount(), + * @ref draw(MeshView&), + * @ref draw(Containers::ArrayView>), + * @ref drawTransformFeedback(), + * @fn_gl_keyword{UseProgram}, @fn_gl_keyword{EnableVertexAttribArray}, + * @fn_gl{BindBuffer}, @fn_gl_keyword{VertexAttribPointer}, + * @fn_gl_keyword{DisableVertexAttribArray} or @fn_gl_keyword{BindVertexArray}, + * @fn_gl_keyword{DrawArrays}/@fn_gl_keyword{DrawArraysInstanced}/ + * @fn_gl_keyword{DrawArraysInstancedBaseInstance} or @fn_gl_keyword{DrawElements}/ + * @fn_gl_keyword{DrawRangeElements}/@fn_gl_keyword{DrawElementsBaseVertex}/ + * @fn_gl_keyword{DrawRangeElementsBaseVertex}/@fn_gl_keyword{DrawElementsInstanced}/ + * @fn_gl_keyword{DrawElementsInstancedBaseInstance}/ + * @fn_gl_keyword{DrawElementsInstancedBaseVertex}/ + * @fn_gl_keyword{DrawElementsInstancedBaseVertexBaseInstance} + * @requires_gl32 Extension @gl_extension{ARB,draw_elements_base_vertex} + * if the mesh is indexed and @ref Mesh::baseVertex() is not `0`. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} if + * @ref Mesh::instanceCount() is more than `1`. + * @requires_gl42 Extension @gl_extension{ARB,base_instance} if + * @ref Mesh::baseInstance() is not `0`. + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays}, + * @gl_extension{EXT,draw_instanced}, + * @gl_extension{NV,instanced_arrays}, + * @gl_extension{NV,draw_instanced} in OpenGL ES 2.0 if + * @ref Mesh::instanceCount() is more than `1`. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0 if @ref Mesh::instanceCount() is more than `1`. + * @requires_gl Specifying base vertex for indexed meshes is not + * available in OpenGL ES or WebGL. + */ + void draw(Mesh& mesh); + + /** + * @overload + * @m_since_latest + */ + void draw(Mesh&& mesh) { draw(mesh); } + + /** + * @brief Draw a mesh view + * @m_since_latest + * + * See @ref draw(Mesh&) for more information. + * @see @ref draw(Containers::ArrayView>), + * @ref drawTransformFeedback() + * @requires_gl32 Extension @gl_extension{ARB,draw_elements_base_vertex} + * if the mesh is indexed and @ref MeshView::baseVertex() is not + * `0`. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} if + * @ref MeshView::instanceCount() is more than `1`. + * @requires_gl42 Extension @gl_extension{ARB,base_instance} if + * @ref MeshView::baseInstance() is not `0`. + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays}, + * @gl_extension{EXT,draw_instanced}, + * @gl_extension{NV,instanced_arrays}, + * @gl_extension{NV,draw_instanced} in OpenGL ES 2.0 if + * @ref MeshView::instanceCount() is more than `1`. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0 if @ref MeshView::instanceCount() is more than + * `1` + * @requires_gl Specifying base vertex for indexed meshes is not + * available in OpenGL ES or WebGL. + */ + void draw(MeshView& mesh); + + /** + * @overload + * @m_since_latest + */ + void draw(MeshView&& mesh) { draw(mesh); } + + /** + * @brief Draw multiple meshes at once + * @m_since_latest + * + * In OpenGL ES, if @gl_extension{EXT,multi_draw_arrays} is not + * present, the functionality is emulated using a sequence of + * @ref draw(MeshView&) calls. + * + * If @gl_extension{ARB,vertex_array_object} (part of OpenGL 3.0), + * OpenGL ES 3.0, WebGL 2.0, @gl_extension{OES,vertex_array_object} in + * OpenGL ES 2.0 or @webgl_extension{OES,vertex_array_object} in WebGL + * 1.0 is available, the associated vertex array object is bound + * instead of setting up the mesh from scratch. + * @attention All meshes must be views of the same original mesh and + * must not be instanced. + * @see @ref draw(MeshView&), @fn_gl{UseProgram}, + * @fn_gl_keyword{EnableVertexAttribArray}, @fn_gl{BindBuffer}, + * @fn_gl_keyword{VertexAttribPointer}, @fn_gl_keyword{DisableVertexAttribArray} + * or @fn_gl{BindVertexArray}, @fn_gl_keyword{MultiDrawArrays} or + * @fn_gl_keyword{MultiDrawElements}/@fn_gl_keyword{MultiDrawElementsBaseVertex} + * @requires_gl32 Extension @gl_extension{ARB,draw_elements_base_vertex} + * if the mesh is indexed and @ref MeshView::baseVertex() is not + * `0` + * @requires_gl Specifying base vertex for indexed meshes is not + * available in OpenGL ES or WebGL. + */ + void draw(Containers::ArrayView> meshes); + + /** + * @overload + * @m_since_latest + */ + void draw(std::initializer_list> meshes); + + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Draw a mesh with vertices coming out of transform feedback + * @param mesh Mesh to draw + * @param xfb Transform feedback to use for vertex count + * @param stream Transform feedback stream ID + * @m_since_latest + * + * Expects that @p mesh is compatible with this shader, is fully set up + * and that the output buffer(s) from @p xfb are used as vertex buffers + * in the mesh. Everything set by @ref Mesh::setCount(), + * @ref Mesh::setBaseInstance(), @ref Mesh::setBaseVertex() and + * @ref Mesh::setIndexBuffer() is ignored, the mesh is drawn as + * non-indexed and the vertex count is taken from the @p xfb object. If + * @p stream is @cpp 0 @ce, non-stream draw command is used. If + * @gl_extension{ARB,vertex_array_object} (part of OpenGL 3.0) is + * available, the associated vertex array object is bound instead of + * setting up the mesh from scratch. + * @see @ref Mesh::setInstanceCount(), @ref draw(Mesh&), + * @ref drawTransformFeedback(MeshView&, TransformFeedback&, UnsignedInt), + * @fn_gl_keyword{UseProgram}, @fn_gl_keyword{EnableVertexAttribArray}, + * @fn_gl{BindBuffer}, @fn_gl_keyword{VertexAttribPointer}, + * @fn_gl_keyword{DisableVertexAttribArray} or @fn_gl_keyword{BindVertexArray}, + * @fn_gl_keyword{DrawTransformFeedback}/@fn_gl_keyword{DrawTransformFeedbackInstanced} or + * @fn_gl_keyword{DrawTransformFeedbackStream}/@fn_gl_keyword{DrawTransformFeedbackStreamInstanced} + * @requires_gl40 Extension @gl_extension{ARB,transform_feedback2} + * @requires_gl40 Extension @gl_extension{ARB,transform_feedback3} if + * @p stream is not `0` + * @requires_gl42 Extension @gl_extension{ARB,transform_feedback_instanced} + * if @ref Mesh::instanceCount() is more than `1` + */ + void drawTransformFeedback(Mesh& mesh, TransformFeedback& xfb, UnsignedInt stream = 0); + + /** + * @brief Draw a mesh view with vertices coming out of transform feedback + * @m_since_latest + * + * Everything set by @ref MeshView::setCount(), + * @ref MeshView::setBaseInstance(), @ref MeshView::setBaseVertex(), + * @ref MeshView::setIndexRange() and @ref Mesh::setIndexBuffer() is + * ignored, the mesh is drawn as non-indexed and the vertex count is + * taken from the @p xfb object. See + * @ref drawTransformFeedback(Mesh&, TransformFeedback&, UnsignedInt) + * for more information. + * @see @ref draw(Mesh&) + * @requires_gl40 Extension @gl_extension{ARB,transform_feedback2} + * @requires_gl40 Extension @gl_extension{ARB,transform_feedback3} if + * @p stream is not `0` + * @requires_gl42 Extension @gl_extension{ARB,transform_feedback_instanced} + * if @ref MeshView::instanceCount() is more than `1` + */ + void drawTransformFeedback(MeshView& mesh, TransformFeedback& xfb, UnsignedInt stream = 0); + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) /** * @brief Dispatch compute diff --git a/src/Magnum/GL/CMakeLists.txt b/src/Magnum/GL/CMakeLists.txt index fdaec99fc..c412fe9de 100644 --- a/src/Magnum/GL/CMakeLists.txt +++ b/src/Magnum/GL/CMakeLists.txt @@ -26,7 +26,6 @@ set(MagnumGL_SRCS AbstractObject.cpp AbstractQuery.cpp - AbstractShaderProgram.cpp Buffer.cpp Context.cpp DefaultFramebuffer.cpp @@ -54,6 +53,7 @@ set(MagnumGL_SRCS set(MagnumGL_GracefulAssert_SRCS AbstractFramebuffer.cpp + AbstractShaderProgram.cpp AbstractTexture.cpp Attribute.cpp CubeMapTexture.cpp diff --git a/src/Magnum/GL/Mesh.cpp b/src/Magnum/GL/Mesh.cpp index d26778434..3090da9e3 100644 --- a/src/Magnum/GL/Mesh.cpp +++ b/src/Magnum/GL/Mesh.cpp @@ -29,7 +29,6 @@ #include #include "Magnum/Mesh.h" -#include "Magnum/GL/AbstractShaderProgram.h" #include "Magnum/GL/Buffer.h" #include "Magnum/GL/Context.h" #include "Magnum/GL/Extensions.h" @@ -43,6 +42,10 @@ #include "Magnum/GL/Implementation/MeshState.h" #include "Magnum/GL/Implementation/State.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include "Magnum/GL/AbstractShaderProgram.h" +#endif + namespace Magnum { namespace GL { namespace { @@ -397,25 +400,6 @@ Mesh& Mesh::setIndexBuffer(Buffer& buffer, const GLintptr offset, const MeshInde return *this; } -Mesh& Mesh::draw(AbstractShaderProgram& shader) { - CORRADE_ASSERT(_countSet, "GL::Mesh::draw(): setCount() was never called, probably a mistake?", *this); - - /* Nothing to draw, exit without touching any state */ - if(!_count || !_instanceCount) return *this; - - shader.use(); - - #ifndef MAGNUM_TARGET_GLES - drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd); - #elif !defined(MAGNUM_TARGET_GLES2) - drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd); - #else - drawInternal(_count, _baseVertex, _instanceCount, _indexOffset); - #endif - - return *this; -} - #ifndef MAGNUM_TARGET_GLES void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, UnsignedInt baseInstance, GLintptr indexOffset, Int indexStart, Int indexEnd) #elif !defined(MAGNUM_TARGET_GLES2) @@ -554,16 +538,31 @@ void Mesh::drawInternal(TransformFeedback& xfb, const UnsignedInt stream, const (this->*state.unbindImplementation)(); } +#endif + +#ifdef MAGNUM_BUILD_DEPRECATED +Mesh& Mesh::draw(AbstractShaderProgram& shader) { + shader.draw(*this); + return *this; +} +Mesh& Mesh::draw(AbstractShaderProgram&& shader) { + shader.draw(*this); + return *this; +} + +#ifndef MAGNUM_TARGET_GLES Mesh& Mesh::draw(AbstractShaderProgram& shader, TransformFeedback& xfb, UnsignedInt stream) { - /* Nothing to draw, exit without touching any state */ - if(!_instanceCount) return *this; + shader.drawTransformFeedback(*this, xfb, stream); + return *this; +} - shader.use(); - drawInternal(xfb, stream, _instanceCount); +Mesh& Mesh::draw(AbstractShaderProgram&& shader, TransformFeedback& xfb, UnsignedInt stream) { + shader.drawTransformFeedback(*this, xfb, stream); return *this; } #endif +#endif void Mesh::bindVAOImplementationDefault(GLuint) {} diff --git a/src/Magnum/GL/Mesh.h b/src/Magnum/GL/Mesh.h index 9b953f094..b97e794d1 100644 --- a/src/Magnum/GL/Mesh.h +++ b/src/Magnum/GL/Mesh.h @@ -227,7 +227,7 @@ for use with stock shaders. ownership to the mesh. If vertex/index count or instance count is zero, the mesh is empty and no draw -commands are issued when calling @ref draw(). +commands are issued when calling @ref AbstractShaderProgram::draw(). @subsection GL-Mesh-configuration-example Example mesh configuration @@ -289,7 +289,7 @@ getting only a moved-out instance. For example: Basic workflow is: bind specific framebuffer for drawing (if needed), set up respective shader (see @ref GL-AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation" -for more infromation) and call @ref Mesh::draw(). +for more infromation) and call @ref AbstractShaderProgram::draw(). @section GL-Mesh-webgl-restrictions WebGL restrictions @@ -302,8 +302,8 @@ If @gl_extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, @gl_extension{OES,vertex_array_object} in OpenGL ES 2.0 or @webgl_extension{OES,vertex_array_object} in WebGL 1.0 is supported, VAOs are used instead of binding the buffers and specifying vertex attribute pointers -in each @ref draw() call. The engine tracks currently bound VAO and currently -active shader program to avoid unnecessary calls to @fn_gl_keyword{BindVertexArray} +in each @ref AbstractShaderProgram::draw() call. The engine tracks currently +bound VAO and currently active shader program to avoid unnecessary calls to @fn_gl_keyword{BindVertexArray} and @fn_gl_keyword{UseProgram}. Mesh limits and implementation-defined values (such as @ref maxElementIndex()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. @@ -315,12 +315,9 @@ documentation of @ref addVertexBuffer() for more information. If index range is specified in @ref setIndexBuffer(), range-based version of drawing commands are used on desktop OpenGL and OpenGL ES 3.0. See also -@ref draw() for more information. +@ref AbstractShaderProgram::draw() for more information. */ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { - friend MeshView; - friend Implementation::MeshState; - public: /** * @brief Max vertex attribute stride @@ -582,8 +579,8 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * * If the mesh is indexed, the value is treated as index count, * otherwise the value is vertex count. If set to @cpp 0 @ce, no draw - * commands are issued when calling @ref draw(AbstractShaderProgram&). - * Ignored when calling @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). + * commands are issued when calling @ref AbstractShaderProgram::draw(). + * Ignored when calling @ref AbstractShaderProgram::drawTransformFeedback(). * * @attention To prevent nothing being rendered by accident, this * function has to be always called, even to just set the count to @@ -606,8 +603,8 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * * Sets number of vertices of which the vertex buffer will be offset * when drawing. Ignored when calling - * @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). - * Default is @cpp 0 @ce. + * @ref AbstractShaderProgram::drawTransformFeedback(). Default is + * @cpp 0 @ce. * @see @ref setCount(), @ref setBaseInstance() * @requires_gl32 Extension @gl_extension{ARB,draw_elements_base_vertex} * for indexed meshes @@ -627,16 +624,16 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * @return Reference to self (for method chaining) * * If set to @cpp 1 @ce, non-instanced draw commands are issued when - * calling @ref draw(AbstractShaderProgram&) or - * @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). + * calling @ref AbstractShaderProgram::draw() or + * @ref AbstractShaderProgram::drawTransformFeedback(). * If set to @cpp 0 @ce, no draw commands are issued at all. Default is * @cpp 1 @ce. * @see @ref setBaseInstance(), @ref setCount(), * @ref addVertexBufferInstanced() * @requires_gl31 Extension @gl_extension{ARB,draw_instanced} if using - * @ref draw(AbstractShaderProgram&) + * @ref AbstractShaderProgram::draw() * @requires_gl42 Extension @gl_extension{ARB,transform_feedback_instanced} - * if using @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt) + * if using @ref AbstractShaderProgram::drawTransformFeedback() * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, * @gl_extension{EXT,instanced_arrays}, * @gl_extension{EXT,draw_instanced}, @@ -658,7 +655,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * @brief Set base instance * @return Reference to self (for method chaining) * - * Ignored when calling @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). + * Ignored when calling @ref AbstractShaderProgram::drawTransformFeedback(). * Default is @cpp 0 @ce. * @see @ref setInstanceCount(), @ref setBaseVertex() * @requires_gl42 Extension @gl_extension{ARB,base_instance} @@ -895,8 +892,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * ES 2.0 or @webgl_extension{OES,vertex_array_object} in WebGL 1.0 is * available, the vertex array object is used to hold the parameters. * - * Ignored when calling @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). - * + * Ignored when calling @ref AbstractShaderProgram::drawTransformFeedback(). * @see @ref maxElementIndex(), @ref maxElementsIndices(), * @ref maxElementsVertices(), @ref setCount(), @ref isIndexed(), * @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} or @@ -957,93 +953,43 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { return setIndexBuffer(std::move(buffer), offset, meshIndexType(type), 0, 0); } /**< @overload */ + #ifdef MAGNUM_BUILD_DEPRECATED /** * @brief Draw the mesh - * @param shader Shader to use for drawing - * @return Reference to self (for method chaining) - * - * Expects that the shader is compatible with this mesh and is fully - * set up. If vertex/index count or instance count is `0`, no draw - * commands are issued. See also - * @ref GL-AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation" - * for more information. If @gl_extension{ARB,vertex_array_object} (part - * of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, @gl_extension{OES,vertex_array_object} - * in OpenGL ES 2.0 or @webgl_extension{OES,vertex_array_object} in - * WebGL 1.0 is available, the associated vertex array object is bound - * instead of setting up the mesh from scratch. - * @see @ref setCount(), @ref setInstanceCount(), - * @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt), - * @ref MeshView::draw(AbstractShaderProgram&), - * @ref MeshView::draw(AbstractShaderProgram&, std::initializer_list>), - * @fn_gl_keyword{UseProgram}, @fn_gl_keyword{EnableVertexAttribArray}, - * @fn_gl{BindBuffer}, @fn_gl_keyword{VertexAttribPointer}, - * @fn_gl_keyword{DisableVertexAttribArray} or @fn_gl_keyword{BindVertexArray}, - * @fn_gl_keyword{DrawArrays}/@fn_gl_keyword{DrawArraysInstanced}/ - * @fn_gl_keyword{DrawArraysInstancedBaseInstance} or @fn_gl_keyword{DrawElements}/ - * @fn_gl_keyword{DrawRangeElements}/@fn_gl_keyword{DrawElementsBaseVertex}/ - * @fn_gl_keyword{DrawRangeElementsBaseVertex}/@fn_gl_keyword{DrawElementsInstanced}/ - * @fn_gl_keyword{DrawElementsInstancedBaseInstance}/ - * @fn_gl_keyword{DrawElementsInstancedBaseVertex}/ - * @fn_gl_keyword{DrawElementsInstancedBaseVertexBaseInstance} - * @requires_gl32 Extension @gl_extension{ARB,draw_elements_base_vertex} - * if the mesh is indexed and @ref baseVertex() is not `0`. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} if - * @ref instanceCount() is more than `1`. - * @requires_gl42 Extension @gl_extension{ARB,base_instance} if - * @ref baseInstance() is not `0`. - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays}, - * @gl_extension{EXT,draw_instanced}, - * @gl_extension{NV,instanced_arrays}, - * @gl_extension{NV,draw_instanced} in OpenGL ES 2.0 if - * @ref instanceCount() is more than `1`. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0 if @ref instanceCount() is more than `1`. - * @requires_gl Specifying base vertex for indexed meshes is not - * available in OpenGL ES or WebGL. + * @m_deprecated_since_latest Use @ref AbstractShaderProgram::draw() + * instead. */ - Mesh& draw(AbstractShaderProgram& shader); - Mesh& draw(AbstractShaderProgram&& shader) { - return draw(shader); - } /**< @overload */ + CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") Mesh& draw(AbstractShaderProgram& shader); + + /** + * @overload + * @m_deprecated_since_latest Use @ref AbstractShaderProgram::draw() + * instead. + */ + CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") Mesh& draw(AbstractShaderProgram&& shader); #ifndef MAGNUM_TARGET_GLES /** * @brief Draw the mesh with vertices coming out of transform feedback - * @param shader Shader to use for drawing - * @param xfb Transform feedback to use for vertex count - * @param stream Transform feedback stream ID - * @return Reference to self (for method chaining) - * - * Expects that the @p shader is compatible with this mesh, is fully - * set up and that the output buffer(s) from @p xfb are used as vertex - * buffers in this mesh. Everything set by @ref setCount(), - * @ref setBaseInstance(), @ref setBaseVertex() and @ref setIndexBuffer() - * is ignored, the mesh is drawn as non-indexed and the vertex count is - * taken from the @p xfb object. If @p stream is @cpp 0 @ce, non-stream - * draw command is used. If @gl_extension{ARB,vertex_array_object} (part - * of OpenGL 3.0) is available, the associated vertex array object is - * bound instead of setting up the mesh from scratch. - * @see @ref setInstanceCount(), @ref draw(AbstractShaderProgram&), - * @ref MeshView::draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt), - * @fn_gl_keyword{UseProgram}, @fn_gl_keyword{EnableVertexAttribArray}, - * @fn_gl{BindBuffer}, @fn_gl_keyword{VertexAttribPointer}, - * @fn_gl_keyword{DisableVertexAttribArray} or @fn_gl_keyword{BindVertexArray}, - * @fn_gl_keyword{DrawTransformFeedback}/@fn_gl_keyword{DrawTransformFeedbackInstanced} or - * @fn_gl_keyword{DrawTransformFeedbackStream}/@fn_gl_keyword{DrawTransformFeedbackStreamInstanced} - * @requires_gl40 Extension @gl_extension{ARB,transform_feedback2} - * @requires_gl40 Extension @gl_extension{ARB,transform_feedback3} if - * @p stream is not `0` - * @requires_gl42 Extension @gl_extension{ARB,transform_feedback_instanced} - * if @ref instanceCount() is more than `1`. + * @m_deprecated_since_latest Use + * @ref AbstractShaderProgram::drawTransformFeedback() instead. */ - Mesh& draw(AbstractShaderProgram& shader, TransformFeedback& xfb, UnsignedInt stream = 0); - Mesh& draw(AbstractShaderProgram&& shader, TransformFeedback& xfb, UnsignedInt stream = 0) { - return draw(shader, xfb, stream); - } /**< @overload */ + CORRADE_DEPRECATED("use AbstractShaderProgram::drawTransformFeedback() instead") Mesh& draw(AbstractShaderProgram& shader, TransformFeedback& xfb, UnsignedInt stream = 0); + + /** + * @overload + * @m_deprecated_since_latest Use + * @ref AbstractShaderProgram::drawTransformFeedback() instead. + */ + CORRADE_DEPRECATED("use AbstractShaderProgram::drawTransformFeedback() instead") Mesh& draw(AbstractShaderProgram&& shader, TransformFeedback& xfb, UnsignedInt stream = 0); + #endif #endif private: + friend AbstractShaderProgram; + friend MeshView; + friend Implementation::MeshState; + struct MAGNUM_GL_LOCAL AttributeLayout; explicit Mesh(GLuint id, MeshPrimitive primitive, ObjectFlags flags); diff --git a/src/Magnum/GL/MeshView.cpp b/src/Magnum/GL/MeshView.cpp index 42e9fa8c9..872bd2c3b 100644 --- a/src/Magnum/GL/MeshView.cpp +++ b/src/Magnum/GL/MeshView.cpp @@ -36,33 +36,54 @@ namespace Magnum { namespace GL { +#ifdef MAGNUM_BUILD_DEPRECATED void MeshView::draw(AbstractShaderProgram& shader, Containers::ArrayView> meshes) { - /* Why std::initializer_list doesn't have empty()? */ - if(!meshes.size()) return; + shader.draw(meshes); +} - shader.use(); +void MeshView::draw(AbstractShaderProgram&& shader, Containers::ArrayView> meshes) { + shader.draw(meshes); +} - #ifndef CORRADE_NO_ASSERT - const Mesh* original = &meshes.begin()->get()._original.get(); - for(MeshView& mesh: meshes) - CORRADE_ASSERT(&mesh._original.get() == original, "GL::MeshView::draw(): all meshes must be views of the same original mesh", ); - #endif +void MeshView::draw(AbstractShaderProgram& shader, std::initializer_list> meshes) { + shader.draw(meshes); +} - #ifndef MAGNUM_TARGET_GLES - multiDrawImplementationDefault(meshes); - #else - Context::current().state().mesh->multiDrawImplementation(meshes); - #endif +void MeshView::draw(AbstractShaderProgram&& shader, std::initializer_list> meshes) { + shader.draw(meshes); } +#endif -void MeshView::draw(AbstractShaderProgram&& shader, Containers::ArrayView> meshes) { - draw(shader, Containers::arrayView(meshes)); +MeshView& MeshView::setIndexRange(Int first) { + CORRADE_ASSERT(_original.get()._indexBuffer.id(), "MeshView::setIndexRange(): mesh is not indexed", *this); + _indexOffset = _original.get()._indexOffset + first*_original.get().indexTypeSize(); + return *this; } -void MeshView::draw(AbstractShaderProgram& shader, std::initializer_list> meshes) { - draw(shader, Containers::arrayView(meshes)); +#ifdef MAGNUM_BUILD_DEPRECATED +MeshView& MeshView::draw(AbstractShaderProgram& shader) { + shader.draw(*this); + return *this; } +MeshView& MeshView::draw(AbstractShaderProgram&& shader) { + shader.draw(*this); + return *this; +} + +#ifndef MAGNUM_TARGET_GLES +MeshView& MeshView::draw(AbstractShaderProgram& shader, TransformFeedback& xfb, UnsignedInt stream) { + shader.drawTransformFeedback(*this, xfb, stream); + return *this; +} + +MeshView& MeshView::draw(AbstractShaderProgram&& shader, TransformFeedback& xfb, UnsignedInt stream) { + shader.drawTransformFeedback(*this, xfb, stream); + return *this; +} +#endif +#endif + #ifndef MAGNUM_TARGET_WEBGL void MeshView::multiDrawImplementationDefault(Containers::ArrayView> meshes) { CORRADE_INTERNAL_ASSERT(meshes.size()); @@ -147,40 +168,4 @@ void MeshView::multiDrawImplementationFallback(Containers::ArrayView>) + * instead. */ - static void draw(AbstractShaderProgram& shader, Containers::ArrayView> meshes); + CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") static void draw(AbstractShaderProgram& shader, Containers::ArrayView> meshes); /** * @overload - * @m_since_latest + * @m_deprecated_since_latest Use + * @ref AbstractShaderProgram::draw(Containers::ArrayView>) + * instead. */ - static void draw(AbstractShaderProgram&& shader, Containers::ArrayView> meshes); + CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") static void draw(AbstractShaderProgram&& shader, Containers::ArrayView> meshes); - /** @overload */ - static void draw(AbstractShaderProgram& shader, std::initializer_list> meshes); + /** + * @overload + * @m_deprecated_since_latest Use + * @ref AbstractShaderProgram::draw(std::initializer_list>) + * instead. + */ + CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") static void draw(AbstractShaderProgram& shader, std::initializer_list> meshes); - /** @overload */ - static void draw(AbstractShaderProgram&& shader, std::initializer_list> meshes) { - draw(shader, meshes); - } + /** + * @overload + * @m_deprecated_since_latest Use + * @ref AbstractShaderProgram::draw(std::initializer_list>) + * instead. + */ + CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") static void draw(AbstractShaderProgram&& shader, std::initializer_list> meshes); + #endif /** * @brief Constructor @@ -131,8 +122,7 @@ class MAGNUM_GL_EXPORT MeshView { * @brief Set vertex/index count * @return Reference to self (for method chaining) * - * Ignored when calling @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). - * + * Ignored when calling @ref AbstractShaderProgram::drawTransformFeedback(). * @attention To prevent nothing being rendered by accident, this * function has to be always called, even to just set the count to * @cpp 0 @ce. @@ -151,8 +141,9 @@ class MAGNUM_GL_EXPORT MeshView { * @return Reference to self (for method chaining) * * Sets number of vertices of which the vertex buffer will be offset - * when drawing. Ignored when calling @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). - * Default is @cpp 0 @ce. + * when drawing. Ignored when calling + * @ref AbstractShaderProgram::drawTransformFeedback(). Default is + * @cpp 0 @ce. * @requires_gl32 Extension @gl_extension{ARB,draw_elements_base_vertex} * for indexed meshes * @requires_gles32 Base vertex cannot be specified for indexed meshes @@ -175,7 +166,7 @@ class MAGNUM_GL_EXPORT MeshView { * acccessed. On OpenGL ES 2.0 this function behaves the same as * @ref setIndexRange(Int), as index range functionality is not * available there. Ignored when calling - * @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). + * @ref AbstractShaderProgram::drawTransformFeedback(). * * Expects that the original mesh is indexed. * @see @ref setCount(), @ref mesh(), @ref Mesh::isIndexed() @@ -190,7 +181,7 @@ class MAGNUM_GL_EXPORT MeshView { * * Prefer to use @ref setIndexRange(Int, UnsignedInt, UnsignedInt) for * better performance. Ignored when calling - * @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). + * @ref AbstractShaderProgram::drawTransformFeedback(). * * Expects that the original mesh is indexed. * @see @ref setCount(), @ref mesh(), @ref Mesh::isIndexed() @@ -206,9 +197,9 @@ class MAGNUM_GL_EXPORT MeshView { * * Default is @cpp 1 @ce. * @requires_gl31 Extension @gl_extension{ARB,draw_instanced} if using - * @ref draw(AbstractShaderProgram&) + * @ref AbstractShaderProgram::draw() * @requires_gl42 Extension @gl_extension{ARB,transform_feedback_instanced} - * if using @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt) + * if using @ref AbstractShaderProgram::drawTransformFeedback() * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, * @gl_extension{EXT,instanced_arrays}, * @gl_extension{EXT,draw_instanced}, @@ -230,7 +221,7 @@ class MAGNUM_GL_EXPORT MeshView { * @brief Set base instance * @return Reference to self (for method chaining) * - * Ignored when calling @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). + * Ignored when calling @ref AbstractShaderProgram::drawTransformFeedback(). * Default is @cpp 0 @ce. * @requires_gl42 Extension @gl_extension{ARB,base_instance} * @requires_gl Base instance cannot be specified in OpenGL ES or @@ -242,60 +233,42 @@ class MAGNUM_GL_EXPORT MeshView { } #endif + #ifdef MAGNUM_BUILD_DEPRECATED /** * @brief Draw the mesh - * @return Reference to self (for method chaining) - * - * See @ref Mesh::draw(AbstractShaderProgram&) for more information. - * @see @ref draw(AbstractShaderProgram&, std::initializer_list>), - * @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt) - * @requires_gl32 Extension @gl_extension{ARB,draw_elements_base_vertex} - * if the mesh is indexed and @ref baseVertex() is not `0`. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} if - * @ref instanceCount() is more than `1`. - * @requires_gl42 Extension @gl_extension{ARB,base_instance} if - * @ref baseInstance() is not `0`. - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays}, - * @gl_extension{EXT,draw_instanced}, - * @gl_extension{NV,instanced_arrays}, - * @gl_extension{NV,draw_instanced} in OpenGL ES 2.0 if - * @ref instanceCount() is more than `1`. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0 if @ref instanceCount() is more than `1`. - * @requires_gl Specifying base vertex for indexed meshes is not - * available in OpenGL ES or WebGL. + * @m_deprecated_since_latest Use @ref AbstractShaderProgram::draw() + * instead. */ - MeshView& draw(AbstractShaderProgram& shader); - MeshView& draw(AbstractShaderProgram&& shader) { - return draw(shader); - } /**< @overload */ + CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") MeshView& draw(AbstractShaderProgram& shader); + + /** + * @overload + * @m_deprecated_since_latest Use @ref AbstractShaderProgram::draw() + * instead. + */ + CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") MeshView& draw(AbstractShaderProgram&& shader); #ifndef MAGNUM_TARGET_GLES /** * @brief Draw the mesh with vertices coming out of transform feedback - * @return Reference to self (for method chaining) - * - * Everything set by @ref setCount(), @ref setBaseInstance(), - * @ref setBaseVertex(), @ref setIndexRange() and @ref Mesh::setIndexBuffer() - * is ignored, the mesh is drawn as non-indexed and the vertex count is - * taken from the @p xfb object. See - * @ref Mesh::draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt) - * for more information. - * @see @ref draw(AbstractShaderProgram&) - * @requires_gl40 Extension @gl_extension{ARB,transform_feedback2} - * @requires_gl40 Extension @gl_extension{ARB,transform_feedback3} if - * @p stream is not `0` - * @requires_gl42 Extension @gl_extension{ARB,transform_feedback_instanced} - * if @ref instanceCount() is more than `1`. + * @m_deprecated_since_latest Use + * @ref AbstractShaderProgram::drawTransformFeedback() instead. + */ + CORRADE_DEPRECATED("use AbstractShaderProgram::drawTransformFeedback() instead") MeshView& draw(AbstractShaderProgram& shader, TransformFeedback& xfb, UnsignedInt stream = 0); + + /** + * @overload + * @m_deprecated_since_latest Use + @ref AbstractShaderProgram::drawTransformFeedback() instead. */ - MeshView& draw(AbstractShaderProgram& shader, TransformFeedback& xfb, UnsignedInt stream = 0); - MeshView& draw(AbstractShaderProgram&& shader, TransformFeedback& xfb, UnsignedInt stream = 0) { - return draw(shader, xfb, stream); - } /**< @overload */ + CORRADE_DEPRECATED("use AbstractShaderProgram::drawTransformFeedback() instead") MeshView& draw(AbstractShaderProgram&& shader, TransformFeedback& xfb, UnsignedInt stream = 0); + #endif #endif private: + friend AbstractShaderProgram; + friend Implementation::MeshState; + #ifndef MAGNUM_TARGET_WEBGL static MAGNUM_GL_LOCAL void multiDrawImplementationDefault(Containers::ArrayView> meshes); #endif diff --git a/src/Magnum/GL/Test/MeshTest.cpp b/src/Magnum/GL/Test/MeshTest.cpp index 9569b6fcb..b4f5fc7eb 100644 --- a/src/Magnum/GL/Test/MeshTest.cpp +++ b/src/Magnum/GL/Test/MeshTest.cpp @@ -136,7 +136,7 @@ void MeshTest::drawCountNotSet() { mesh.draw(Shader{NoCreate}); CORRADE_COMPARE(out.str(), - "GL::Mesh::draw(): setCount() was never called, probably a mistake?\n"); + "GL::AbstractShaderProgram::draw(): Mesh::setCount() was never called, probably a mistake?\n"); } void MeshTest::drawViewCountNotSet() { @@ -148,7 +148,7 @@ void MeshTest::drawViewCountNotSet() { view.draw(Shader{NoCreate}); CORRADE_COMPARE(out.str(), - "GL::MeshView::draw(): setCount() was never called, probably a mistake?\n"); + "GL::AbstractShaderProgram::draw(): MeshView::setCount() was never called, probably a mistake?\n"); } void MeshTest::mapPrimitive() { diff --git a/src/Magnum/Shaders/DistanceFieldVector.h b/src/Magnum/Shaders/DistanceFieldVector.h index dbb8a7b71..3330dc7b8 100644 --- a/src/Magnum/Shaders/DistanceFieldVector.h +++ b/src/Magnum/Shaders/DistanceFieldVector.h @@ -167,6 +167,14 @@ template class MAGNUM_SHADERS_EXPORT DistanceFieldVector #endif private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + Int _transformationProjectionMatrixUniform{0}, _colorUniform{1}, _outlineColorUniform{2}, diff --git a/src/Magnum/Shaders/Flat.h b/src/Magnum/Shaders/Flat.h index e1514d641..38a1a87f0 100644 --- a/src/Magnum/Shaders/Flat.h +++ b/src/Magnum/Shaders/Flat.h @@ -334,6 +334,14 @@ template class MAGNUM_SHADERS_EXPORT Flat: public GL::Ab #endif private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + Flags _flags; Int _transformationProjectionMatrixUniform{0}, _colorUniform{1}, diff --git a/src/Magnum/Shaders/MeshVisualizer.h b/src/Magnum/Shaders/MeshVisualizer.h index 5af656268..b6645c953 100644 --- a/src/Magnum/Shaders/MeshVisualizer.h +++ b/src/Magnum/Shaders/MeshVisualizer.h @@ -252,6 +252,14 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer: public GL::AbstractShaderProgram { MeshVisualizer& setSmoothness(Float smoothness); private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + Flags _flags; Int _transformationProjectionMatrixUniform{0}, _colorUniform{1}, diff --git a/src/Magnum/Shaders/Phong.h b/src/Magnum/Shaders/Phong.h index cc7f9262e..5ee92ef8a 100644 --- a/src/Magnum/Shaders/Phong.h +++ b/src/Magnum/Shaders/Phong.h @@ -554,6 +554,14 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram { } private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + Flags _flags; UnsignedInt _lightCount; Int _transformationMatrixUniform{0}, diff --git a/src/Magnum/Shaders/Vector.h b/src/Magnum/Shaders/Vector.h index cd63656f1..91a82ec22 100644 --- a/src/Magnum/Shaders/Vector.h +++ b/src/Magnum/Shaders/Vector.h @@ -136,6 +136,14 @@ template class MAGNUM_SHADERS_EXPORT Vector: public Abst #endif private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + Int _transformationProjectionMatrixUniform{0}, _backgroundColorUniform{1}, _colorUniform{2}; diff --git a/src/Magnum/Shaders/VertexColor.h b/src/Magnum/Shaders/VertexColor.h index 92e17206b..e206a84a5 100644 --- a/src/Magnum/Shaders/VertexColor.h +++ b/src/Magnum/Shaders/VertexColor.h @@ -145,6 +145,14 @@ template class MAGNUM_SHADERS_EXPORT VertexColor: public VertexColor& setTransformationProjectionMatrix(const MatrixTypeFor& matrix); private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + Int _transformationProjectionMatrixUniform{0}; };