Browse Source

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.
pull/430/head
Vladimír Vondruš 6 years ago
parent
commit
32d49db402
  1. 23
      doc/changelog.dox
  2. 5
      doc/method-chaining.dox
  3. 8
      doc/opengl-mapping.dox
  4. 9
      doc/snippets/MagnumGL.cpp
  5. 79
      src/Magnum/GL/AbstractShaderProgram.cpp
  6. 188
      src/Magnum/GL/AbstractShaderProgram.h
  7. 2
      src/Magnum/GL/CMakeLists.txt
  8. 47
      src/Magnum/GL/Mesh.cpp
  9. 136
      src/Magnum/GL/Mesh.h
  10. 89
      src/Magnum/GL/MeshView.cpp
  11. 145
      src/Magnum/GL/MeshView.h
  12. 4
      src/Magnum/GL/Test/MeshTest.cpp
  13. 8
      src/Magnum/Shaders/DistanceFieldVector.h
  14. 8
      src/Magnum/Shaders/Flat.h
  15. 8
      src/Magnum/Shaders/MeshVisualizer.h
  16. 8
      src/Magnum/Shaders/Phong.h
  17. 8
      src/Magnum/Shaders/Vector.h
  18. 8
      src/Magnum/Shaders/VertexColor.h

23
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

5
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

8
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<Containers::Reference<MeshView>>)
@fn_gl{MultiDrawArrays}, \n @fn_gl{MultiDrawElements}, \n @fn_gl{MultiDrawElementsBaseVertex} | @ref GL::AbstractShaderProgram::draw(Containers::ArrayView<const Containers::Reference<MeshView>>)
@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

9
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 */

79
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<bool, std::string> 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<const Containers::Reference<MeshView>> 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<Containers::Reference<MeshView>> 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();

188
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
</li></ul>
</li>
<li>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
</ul>
@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<bool, std::string> 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<const Containers::Reference<MeshView>>),
* @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<const Containers::Reference<MeshView>>),
* @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<const Containers::Reference<MeshView>> meshes);
/**
* @overload
* @m_since_latest
*/
void draw(std::initializer_list<Containers::Reference<MeshView>> 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

2
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

47
src/Magnum/GL/Mesh.cpp

@ -29,7 +29,6 @@
#include <Corrade/Utility/Debug.h>
#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) {}

136
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<Containers::Reference<MeshView>>),
* @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);

89
src/Magnum/GL/MeshView.cpp

@ -36,33 +36,54 @@
namespace Magnum { namespace GL {
#ifdef MAGNUM_BUILD_DEPRECATED
void MeshView::draw(AbstractShaderProgram& shader, Containers::ArrayView<const Containers::Reference<MeshView>> 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<const Containers::Reference<MeshView>> 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<Containers::Reference<MeshView>> meshes) {
shader.draw(meshes);
}
#ifndef MAGNUM_TARGET_GLES
multiDrawImplementationDefault(meshes);
#else
Context::current().state().mesh->multiDrawImplementation(meshes);
void MeshView::draw(AbstractShaderProgram&& shader, std::initializer_list<Containers::Reference<MeshView>> meshes) {
shader.draw(meshes);
}
#endif
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, Containers::ArrayView<const Containers::Reference<MeshView>> meshes) {
draw(shader, Containers::arrayView(meshes));
#ifdef MAGNUM_BUILD_DEPRECATED
MeshView& MeshView::draw(AbstractShaderProgram& shader) {
shader.draw(*this);
return *this;
}
void MeshView::draw(AbstractShaderProgram& shader, std::initializer_list<Containers::Reference<MeshView>> meshes) {
draw(shader, Containers::arrayView(meshes));
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<const Containers::Reference<MeshView>> meshes) {
CORRADE_INTERNAL_ASSERT(meshes.size());
@ -147,40 +168,4 @@ void MeshView::multiDrawImplementationFallback(Containers::ArrayView<const Conta
}
#endif
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;
}
MeshView& MeshView::draw(AbstractShaderProgram& shader) {
CORRADE_ASSERT(_countSet, "GL::MeshView::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
_original.get().drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd);
#elif !defined(MAGNUM_TARGET_GLES2)
_original.get().drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd);
#else
_original.get().drawInternal(_count, _baseVertex, _instanceCount, _indexOffset);
#endif
return *this;
}
#ifndef MAGNUM_TARGET_GLES
MeshView& MeshView::draw(AbstractShaderProgram& shader, TransformFeedback& xfb, UnsignedInt stream) {
/* Nothing to draw, exit without touching any state */
if(!_instanceCount) return *this;
shader.use();
_original.get().drawInternal(xfb, stream, _instanceCount);
return *this;
}
#endif
}}

145
src/Magnum/GL/MeshView.h

@ -52,55 +52,46 @@ bindings and attached buffers are reused from original mesh.
The same rules as in @ref Mesh apply, i.e. if the view has non-zero index
count, it is treated as indexed mesh, otherwise it is treated as non-indexed
mesh. If both index and vertex count is zero, the view is treated as empty and
no draw commands are issued when calling @ref draw().
no draw commands are issued when calling @ref AbstractShaderProgram::draw().
You must ensure that the original mesh remains available for whole view
lifetime.
*/
class MAGNUM_GL_EXPORT MeshView {
friend Implementation::MeshState;
public:
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @brief Draw multiple meshes at once
*
* In OpenGL ES, if @gl_extension{EXT,multi_draw_arrays} is not
* present, the functionality is emulated using sequence of
* @ref draw(AbstractShaderProgram&) 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(AbstractShaderProgram&), @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 baseVertex() is not `0`.
* @requires_gl Specifying base vertex for indexed meshes is not
* available in OpenGL ES or WebGL.
* @m_since_latest
* @m_deprecated_since_latest Use
* @ref AbstractShaderProgram::draw(Containers::ArrayView<const Containers::Reference<MeshView>>)
* instead.
*/
static void draw(AbstractShaderProgram& shader, Containers::ArrayView<const Containers::Reference<MeshView>> meshes);
CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") static void draw(AbstractShaderProgram& shader, Containers::ArrayView<const Containers::Reference<MeshView>> meshes);
/**
* @overload
* @m_since_latest
* @m_deprecated_since_latest Use
* @ref AbstractShaderProgram::draw(Containers::ArrayView<const Containers::Reference<MeshView>>)
* instead.
*/
static void draw(AbstractShaderProgram&& shader, Containers::ArrayView<const Containers::Reference<MeshView>> meshes);
CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") static void draw(AbstractShaderProgram&& shader, Containers::ArrayView<const Containers::Reference<MeshView>> meshes);
/** @overload */
static void draw(AbstractShaderProgram& shader, std::initializer_list<Containers::Reference<MeshView>> meshes);
/**
* @overload
* @m_deprecated_since_latest Use
* @ref AbstractShaderProgram::draw(std::initializer_list<Containers::Reference<MeshView>>)
* instead.
*/
CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") static void draw(AbstractShaderProgram& shader, std::initializer_list<Containers::Reference<MeshView>> meshes);
/** @overload */
static void draw(AbstractShaderProgram&& shader, std::initializer_list<Containers::Reference<MeshView>> meshes) {
draw(shader, meshes);
}
/**
* @overload
* @m_deprecated_since_latest Use
* @ref AbstractShaderProgram::draw(std::initializer_list<Containers::Reference<MeshView>>)
* instead.
*/
CORRADE_DEPRECATED("use AbstractShaderProgram::draw() instead") static void draw(AbstractShaderProgram&& shader, std::initializer_list<Containers::Reference<MeshView>> 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<Containers::Reference<MeshView>>),
* @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.
*/
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);
/**
* @overload
* @m_deprecated_since_latest Use
@ref AbstractShaderProgram::drawTransformFeedback() instead.
*/
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<const Containers::Reference<MeshView>> meshes);
#endif

4
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() {

8
src/Magnum/Shaders/DistanceFieldVector.h

@ -167,6 +167,14 @@ template<UnsignedInt dimensions> 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},

8
src/Magnum/Shaders/Flat.h

@ -334,6 +334,14 @@ template<UnsignedInt dimensions> 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},

8
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},

8
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},

8
src/Magnum/Shaders/Vector.h

@ -136,6 +136,14 @@ template<UnsignedInt dimensions> 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};

8
src/Magnum/Shaders/VertexColor.h

@ -145,6 +145,14 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColor: public
VertexColor<dimensions>& setTransformationProjectionMatrix(const MatrixTypeFor<dimensions, Float>& 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};
};

Loading…
Cancel
Save