Browse Source

First-class WebGL support, part 10: reduced mesh functionality.

Actually properly supporting ANGLE_instanced_arrays. Emscripten
currently has the functions without the ANGLE suffix. Only causes linker
warnings when not used, need to fill a bugreport and fix properly.
pull/107/head
Vladimír Vondruš 11 years ago
parent
commit
cab484050b
  1. 24
      src/Magnum/Implementation/MeshState.cpp
  2. 4
      src/Magnum/Implementation/MeshState.h
  3. 51
      src/Magnum/Mesh.cpp
  4. 93
      src/Magnum/Mesh.h
  5. 6
      src/Magnum/MeshView.cpp
  6. 12
      src/Magnum/MeshView.h

24
src/Magnum/Implementation/MeshState.cpp

@ -105,12 +105,16 @@ MeshState::MeshState(Context& context, std::vector<std::string>& extensions): cu
#endif
#ifdef MAGNUM_TARGET_GLES
#ifndef MAGNUM_TARGET_WEBGL
/* Multi draw implementation on ES */
if(context.isExtensionSupported<Extensions::GL::EXT::multi_draw_arrays>()) {
extensions.push_back(Extensions::GL::EXT::multi_draw_arrays::string());
multiDrawImplementation = &MeshView::multiDrawImplementationDefault;
} else multiDrawImplementation = &MeshView::multiDrawImplementationFallback;
#else
multiDrawImplementation = &MeshView::multiDrawImplementationFallback;
#endif
#endif
#ifdef MAGNUM_TARGET_GLES2
@ -120,8 +124,9 @@ MeshState::MeshState(Context& context, std::vector<std::string>& extensions): cu
drawArraysInstancedImplementation = &Mesh::drawArraysInstancedImplementationANGLE;
drawElementsInstancedImplementation = &Mesh::drawElementsInstancedImplementationANGLE;
} else if(context.isExtensionSupported<Extensions::GL::EXT::draw_instanced>()) {
}
#ifndef MAGNUM_TARGET_WEBGL
else if(context.isExtensionSupported<Extensions::GL::EXT::draw_instanced>()) {
extensions.push_back(Extensions::GL::EXT::draw_instanced::string());
drawArraysInstancedImplementation = &Mesh::drawArraysInstancedImplementationEXT;
@ -132,8 +137,9 @@ MeshState::MeshState(Context& context, std::vector<std::string>& extensions): cu
drawArraysInstancedImplementation = &Mesh::drawArraysInstancedImplementationNV;
drawElementsInstancedImplementation = &Mesh::drawElementsInstancedImplementationNV;
} else {
}
#endif
else {
drawArraysInstancedImplementation = nullptr;
drawElementsInstancedImplementation = nullptr;
}
@ -152,8 +158,9 @@ MeshState::MeshState(Context& context, std::vector<std::string>& extensions): cu
/* Extension added above */
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationANGLE;
} else if(context.isExtensionSupported<Extensions::GL::EXT::instanced_arrays>()) {
}
#ifndef MAGNUM_TARGET_WEBGL
else if(context.isExtensionSupported<Extensions::GL::EXT::instanced_arrays>()) {
extensions.push_back(Extensions::GL::EXT::instanced_arrays::string());
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationEXT;
@ -162,8 +169,9 @@ MeshState::MeshState(Context& context, std::vector<std::string>& extensions): cu
extensions.push_back(Extensions::GL::NV::instanced_arrays::string());
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationNV;
} else vertexAttribDivisorImplementation = nullptr;
}
#endif
else vertexAttribDivisorImplementation = nullptr;
#endif
}

4
src/Magnum/Implementation/MeshState.h

@ -64,7 +64,11 @@ struct MeshState {
GLuint currentVAO;
#ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_WEBGL
GLint64 maxElementIndex;
#else
GLint maxElementIndex;
#endif
GLint maxElementsIndices, maxElementsVertices;
#endif
};

51
src/Magnum/Mesh.cpp

@ -46,17 +46,32 @@ Int Mesh::maxVertexAttributes() { return AbstractShaderProgram::maxVertexAttribu
#endif
#ifndef MAGNUM_TARGET_GLES2
Long Mesh::maxElementIndex() {
#ifndef MAGNUM_TARGET_WEBGL
Long Mesh::maxElementIndex()
#else
Int Mesh::maxElementIndex()
#endif
{
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::ES3_compatibility>())
return 0xFFFFFFFFl;
#endif
GLint64& value = Context::current()->state().mesh->maxElementIndex;
#ifndef MAGNUM_TARGET_WEBGL
GLint64& value =
#else
GLint& value =
#endif
Context::current()->state().mesh->maxElementIndex;
/* Get the value, if not already cached */
if(value == 0)
if(value == 0) {
#ifndef MAGNUM_TARGET_WEBGL
glGetInteger64v(GL_MAX_ELEMENT_INDEX, &value);
#else
glGetIntegerv(GL_MAX_ELEMENT_INDEX, &value);
#endif
}
return value;
}
@ -341,7 +356,7 @@ void Mesh::bindVAO() {
_created = true;
#ifndef MAGNUM_TARGET_GLES2
glBindVertexArray(current = _id);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#elif !defined(CORRADE_TARGET_NACL)
glBindVertexArrayOES(current = _id);
#else
CORRADE_ASSERT_UNREACHABLE();
@ -357,7 +372,7 @@ void Mesh::createImplementationDefault() {
void Mesh::createImplementationVAO() {
#ifndef MAGNUM_TARGET_GLES2
glGenVertexArrays(1, &_id);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#elif !defined(CORRADE_TARGET_NACL)
glGenVertexArraysOES(1, &_id);
#else
CORRADE_ASSERT_UNREACHABLE();
@ -378,7 +393,7 @@ void Mesh::destroyImplementationDefault() {}
void Mesh::destroyImplementationVAO() {
#ifndef MAGNUM_TARGET_GLES2
glDeleteVertexArrays(1, &_id);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#elif !defined(CORRADE_TARGET_NACL)
glDeleteVertexArraysOES(1, &_id);
#else
CORRADE_ASSERT_UNREACHABLE();
@ -503,7 +518,7 @@ void Mesh::vertexAttribDivisorImplementationDSAEXT(const GLuint index, const GLu
}
#elif defined(MAGNUM_TARGET_GLES2)
void Mesh::vertexAttribDivisorImplementationANGLE(const GLuint index, const GLuint divisor) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glVertexAttribDivisorANGLE(index, divisor);
#else
static_cast<void>(index);
@ -511,8 +526,9 @@ void Mesh::vertexAttribDivisorImplementationANGLE(const GLuint index, const GLui
CORRADE_ASSERT_UNREACHABLE();
#endif
}
#ifndef MAGNUM_TARGET_WEBGL
void Mesh::vertexAttribDivisorImplementationEXT(const GLuint index, const GLuint divisor) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glVertexAttribDivisorEXT(index, divisor);
#else
static_cast<void>(index);
@ -521,7 +537,7 @@ void Mesh::vertexAttribDivisorImplementationEXT(const GLuint index, const GLuint
#endif
}
void Mesh::vertexAttribDivisorImplementationNV(const GLuint index, const GLuint divisor) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glVertexAttribDivisorNV(index, divisor);
#else
static_cast<void>(index);
@ -530,6 +546,7 @@ void Mesh::vertexAttribDivisorImplementationNV(const GLuint index, const GLuint
#endif
}
#endif
#endif
void Mesh::bindIndexBufferImplementationDefault(Buffer&) {}
@ -585,7 +602,7 @@ void Mesh::unbindImplementationVAO() {}
#ifdef MAGNUM_TARGET_GLES2
void Mesh::drawArraysInstancedImplementationANGLE(const GLint baseVertex, const GLsizei count, const GLsizei instanceCount) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glDrawArraysInstancedANGLE(GLenum(_primitive), baseVertex, count, instanceCount);
#else
static_cast<void>(baseVertex);
@ -595,8 +612,9 @@ void Mesh::drawArraysInstancedImplementationANGLE(const GLint baseVertex, const
#endif
}
#ifndef MAGNUM_TARGET_WEBGL
void Mesh::drawArraysInstancedImplementationEXT(const GLint baseVertex, const GLsizei count, const GLsizei instanceCount) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glDrawArraysInstancedEXT(GLenum(_primitive), baseVertex, count, instanceCount);
#else
static_cast<void>(baseVertex);
@ -607,7 +625,7 @@ void Mesh::drawArraysInstancedImplementationEXT(const GLint baseVertex, const GL
}
void Mesh::drawArraysInstancedImplementationNV(const GLint baseVertex, const GLsizei count, const GLsizei instanceCount) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glDrawArraysInstancedNV(GLenum(_primitive), baseVertex, count, instanceCount);
#else
static_cast<void>(baseVertex);
@ -616,9 +634,10 @@ void Mesh::drawArraysInstancedImplementationNV(const GLint baseVertex, const GLs
CORRADE_ASSERT_UNREACHABLE();
#endif
}
#endif
void Mesh::drawElementsInstancedImplementationANGLE(const GLsizei count, const GLintptr indexOffset, const GLsizei instanceCount) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glDrawElementsInstancedANGLE(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexOffset), instanceCount);
#else
static_cast<void>(count);
@ -628,8 +647,9 @@ void Mesh::drawElementsInstancedImplementationANGLE(const GLsizei count, const G
#endif
}
#ifndef MAGNUM_TARGET_WEBGL
void Mesh::drawElementsInstancedImplementationEXT(const GLsizei count, const GLintptr indexOffset, const GLsizei instanceCount) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glDrawElementsInstancedEXT(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexOffset), instanceCount);
#else
static_cast<void>(count);
@ -640,7 +660,7 @@ void Mesh::drawElementsInstancedImplementationEXT(const GLsizei count, const GLi
}
void Mesh::drawElementsInstancedImplementationNV(const GLsizei count, const GLintptr indexOffset, const GLsizei instanceCount) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glDrawElementsInstancedNV(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexOffset), instanceCount);
#else
static_cast<void>(count);
@ -650,6 +670,7 @@ void Mesh::drawElementsInstancedImplementationNV(const GLsizei count, const GLin
#endif
}
#endif
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug operator<<(Debug debug, MeshPrimitive value) {

93
src/Magnum/Mesh.h

@ -70,14 +70,14 @@ enum class MeshPrimitive: GLenum {
/**
* Line strip with adjacency information.
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gl Geometry shaders are not available in OpenGL ES.
* @requires_gl Geometry shaders are not available in OpenGL ES or WebGL.
*/
LineStripAdjacency = GL_LINE_STRIP_ADJACENCY,
/**
* Lines with adjacency information.
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gl Geometry shaders are not available in OpenGL ES.
* @requires_gl Geometry shaders are not available in OpenGL ES or WebGL.
*/
LinesAdjacency = GL_LINES_ADJACENCY,
#endif
@ -101,21 +101,22 @@ enum class MeshPrimitive: GLenum {
/**
* Triangle strip with adjacency information.
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gl Geometry shaders are not available in OpenGL ES.
* @requires_gl Geometry shaders are not available in OpenGL ES or WebGL.
*/
TriangleStripAdjacency = GL_TRIANGLE_STRIP_ADJACENCY,
/**
* Triangles with adjacency information.
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gl Geometry shaders are not available in OpenGL ES.
* @requires_gl Geometry shaders are not available in OpenGL ES or WebGL.
*/
TrianglesAdjacency = GL_TRIANGLES_ADJACENCY,
/**
* Patches.
* @requires_gl40 Extension @extension{ARB,tessellation_shader}
* @requires_gl Tessellation shaders are not available in OpenGL ES.
* @requires_gl Tessellation shaders are not available in OpenGL ES or
* WebGL.
*/
Patches = GL_PATCHES
#endif
@ -321,8 +322,9 @@ layout, see @ref addVertexBuffer() documentation for details.
@anchor Mesh-performance-optimization
## Performance optimizations
If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL ES 3.0 or
@es_extension{OES,vertex_array_object} on OpenGL ES 2.0 is supported, VAOs are
If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL ES 3.0,
WebGL 2.0, @es_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{BindVertexArray} and
@ -330,10 +332,10 @@ active shader program to avoid unnecessary calls to @fn_gl{BindVertexArray} and
@ref maxElementIndex()) are cached, so repeated queries don't result in
repeated @fn_gl{Get} calls.
If extension @extension{EXT,direct_state_access} and VAOs are available,
DSA functions are used for specifying attribute locations to avoid unnecessary
calls to @fn_gl{BindBuffer} and @fn_gl{BindVertexArray}. See documentation of
@ref addVertexBuffer() for more information.
If @extension{EXT,direct_state_access} desktop extension and VAOs are
available, DSA functions are used for specifying attribute locations to avoid
unnecessary calls to @fn_gl{BindBuffer} and @fn_gl{BindVertexArray}. See
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
@ -356,7 +358,9 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
/**
* Unsigned int
* @requires_gles30 Extension @es_extension{OES,element_index_uint}
* in OpenGL ES 2.0
* in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{OES,element_index_uint}
* in WebGL 1.0.
*/
UnsignedInt = GL_UNSIGNED_INT
};
@ -379,9 +383,15 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* value (@f$ 2^32 - 1 @f$).
* @see @ref setIndexBuffer(), @fn_gl{Get} with @def_gl{MAX_ELEMENT_INDEX}
* @requires_gles30 No upper limit is specified for index values in
* OpenGL ES 2.0
* OpenGL ES 2.0.
* @requires_webgl20 No upper limit is specified for index values in
* WebGL 1.0.
*/
#ifndef MAGNUM_TARGET_WEBGL
static Long maxElementIndex();
#else
static Int maxElementIndex();
#endif
/**
* @brief Max recommended index count
@ -391,6 +401,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @see @ref setIndexBuffer(), @fn_gl{Get} with @def_gl{MAX_ELEMENTS_INDICES}
* @requires_gles30 Ranged element draw is not supported in OpenGL ES
* 2.0.
* @requires_webgl20 Ranged element draw is not supported in WebGL 1.0.
*/
static Int maxElementsIndices();
@ -402,6 +413,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @see @ref setIndexBuffer(), @fn_gl{Get} with @def_gl{MAX_ELEMENTS_VERTICES}
* @requires_gles30 Ranged element draw is not supported in OpenGL ES
* 2.0.
* @requires_webgl20 Ranged element draw is not supported in WebGL 1.0.
*/
static Int maxElementsVertices();
#endif
@ -418,9 +430,10 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @param primitive Primitive type
*
* If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
* ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
* ES 3.0, WebGL 2.0, @es_extension{OES,vertex_array_object} in OpenGL
* ES 2.0 or @webgl_extension{OES,vertex_array_object} in WebGL 1.0 is
* available, vertex array object is created. If @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) is not supported, the vertex array object is
* (part of OpenGL 4.5) is not available, the vertex array object is
* created on first use.
* @see @ref setPrimitive(), @ref setCount(), @fn_gl{CreateVertexArrays},
* eventually @fn_gl{GenVertexArrays}
@ -437,7 +450,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @brief Destructor
*
* If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
* ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
* ES 3.0, WebGL 2.0, @es_extension{OES,vertex_array_object} in OpenGL
* ES 2.0 or @webgl_extension{OES,vertex_array_object} in WebGL 1.0 is
* available, associated vertex array object is deleted.
* @see @fn_gl{DeleteVertexArrays}
*/
@ -453,8 +467,9 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @brief OpenGL mesh ID
*
* If neither @extension{ARB,vertex_array_object} (part of OpenGL 3.0)
* nor OpenGL ES 3.0 nor @es_extension{OES,vertex_array_object} in
* OpenGL ES 2.0 is available, returns `0`.
* nor OpenGL ES 3.0 / WebGL 2.0 nor @es_extension{OES,vertex_array_object}
* in OpenGL ES 2.0 / @webgl_extension{OES,vertex_array_object} in
* WebGL 1.0 is available, returns `0`.
*/
GLuint id() const { return _id; }
@ -553,7 +568,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @requires_gl32 Extension @extension{ARB,draw_elements_base_vertex}
* for indexed meshes
* @requires_gl Base vertex cannot be specified for indexed meshes in
* OpenGL ES.
* OpenGL ES or WebGL.
*/
Mesh& setBaseVertex(Int baseVertex) {
_baseVertex = baseVertex;
@ -609,6 +624,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @requires_gles30 Extension @es_extension{ANGLE,instanced_arrays},
* @es_extension2{EXT,draw_instanced,draw_instanced} or
* @es_extension{NV,draw_instanced} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays}
* in WebGL 1.0.
*/
Mesh& setInstanceCount(Int count) {
_instanceCount = count;
@ -626,7 +643,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* Default is `0`.
* @see @ref setInstanceCount(), @ref setBaseVertex()
* @requires_gl42 Extension @extension{ARB,base_instance}
* @requires_gl Base instance cannot be specified in OpenGL ES.
* @requires_gl Base instance cannot be specified in OpenGL ES or
* WebGL.
*/
Mesh& setBaseInstance(UnsignedInt baseInstance) {
_baseInstance = baseInstance;
@ -682,25 +700,25 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @endcode
*
* If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
* ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
* ES 3.0, WebGL 2.0, @es_extension{OES,vertex_array_object} in OpenGL
* 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.
*
* @attention The buffer passed as parameter is not managed by the
* mesh, you must ensure it will exist for whole lifetime of the
* mesh and delete it afterwards.
*
* @attention In @ref MAGNUM_TARGET_WEBGL "WebGL" the data must be
* properly aligned (e.g. all float data must start at addresses
* divisible by four). Also the maximum stride of attribute data
* must be at most 255 bytes. This is not required anywhere else,
* but doing so may have performance benefits.
*
* @see @ref addVertexBufferInstanced(), @ref setPrimitive(),
* @ref setCount(), @fn_gl{BindVertexArray},
* @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer},
* @fn_gl{VertexAttribPointer} or
* @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access},
* @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access}
* @requires_gles In WebGL the data must be properly aligned (e.g. all
* float data must start at addresses divisible by four). Also the
* maximum stride of attribute data must be at most 255 bytes.
* This is not required anywhere else, but doing so may have
* performance benefits.
*/
template<class ...T> inline Mesh& addVertexBuffer(Buffer& buffer, GLintptr offset, const T&... attributes) {
addVertexBufferInternal(buffer, offset, strideOfInterleaved(attributes...), 0, attributes...);
@ -717,7 +735,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @ref addVertexBuffer().
*
* If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
* ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
* ES 3.0, WebGL 2.0, @es_extension{OES,vertex_array_object} in OpenGL
* 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.
*
* @see @ref setPrimitive(), @ref setCount(), @ref setInstanceCount(),
@ -732,6 +751,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @requires_gles30 Extension @es_extension{ANGLE,instanced_arrays},
* @es_extension{EXT,instanced_arrays} or
* @es_extension{NV,instanced_arrays} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays}
* in WebGL 1.0.
*/
template<class ...T> inline Mesh& addVertexBufferInstanced(Buffer& buffer, UnsignedInt divisor, GLintptr offset, const T&... attributes) {
addVertexBufferInternal(buffer, offset, strideOfInterleaved(attributes...), divisor, attributes...);
@ -756,7 +777,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* functionality is not available there.
*
* If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
* ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
* ES 3.0, WebGL 2.0, @es_extension{OES,vertex_array_object} in OpenGL
* 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.
*
* @see @ref maxElementIndex(), @ref maxElementsIndices(),
@ -789,9 +811,10 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* commands are issued. See also
* @ref AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation"
* for more information. If @extension{ARB,vertex_array_object} (part
* of OpenGL 3.0), OpenGL ES 3.0 or @es_extension{OES,vertex_array_object}
* in OpenGL ES 2.0 is available, the associated vertex array object is
* bound instead of setting up the mesh from scratch.
* of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, @es_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 MeshView::draw(AbstractShaderProgram&),
* @ref MeshView::draw(AbstractShaderProgram&, std::initializer_list<std::reference_wrapper<MeshView>>),
@ -985,9 +1008,11 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
void MAGNUM_LOCAL vertexAttribDivisorImplementationDSAEXT(GLuint index, GLuint divisor);
#elif defined(MAGNUM_TARGET_GLES2)
void MAGNUM_LOCAL vertexAttribDivisorImplementationANGLE(GLuint index, GLuint divisor);
#ifndef MAGNUM_TARGET_WEBGL
void MAGNUM_LOCAL vertexAttribDivisorImplementationEXT(GLuint index, GLuint divisor);
void MAGNUM_LOCAL vertexAttribDivisorImplementationNV(GLuint index, GLuint divisor);
#endif
#endif
void MAGNUM_LOCAL bindIndexBufferImplementationDefault(Buffer&);
void MAGNUM_LOCAL bindIndexBufferImplementationVAO(Buffer& buffer);
@ -1000,13 +1025,17 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
#ifdef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL drawArraysInstancedImplementationANGLE(GLint baseVertex, GLsizei count, GLsizei instanceCount);
#ifndef MAGNUM_TARGET_WEBGL
void MAGNUM_LOCAL drawArraysInstancedImplementationEXT(GLint baseVertex, GLsizei count, GLsizei instanceCount);
void MAGNUM_LOCAL drawArraysInstancedImplementationNV(GLint baseVertex, GLsizei count, GLsizei instanceCount);
#endif
void MAGNUM_LOCAL drawElementsInstancedImplementationANGLE(GLsizei count, GLintptr indexOffset, GLsizei instanceCount);
#ifndef MAGNUM_TARGET_WEBGL
void MAGNUM_LOCAL drawElementsInstancedImplementationEXT(GLsizei count, GLintptr indexOffset, GLsizei instanceCount);
void MAGNUM_LOCAL drawElementsInstancedImplementationNV(GLsizei count, GLintptr indexOffset, GLsizei instanceCount);
#endif
#endif
GLuint _id;
bool _created; /* see createIfNotAlready() for details */

6
src/Magnum/MeshView.cpp

@ -56,6 +56,7 @@ void MeshView::draw(AbstractShaderProgram& shader, std::initializer_list<std::re
#endif
}
#ifndef MAGNUM_TARGET_WEBGL
void MeshView::multiDrawImplementationDefault(std::initializer_list<std::reference_wrapper<MeshView>> meshes) {
CORRADE_INTERNAL_ASSERT(meshes.size());
@ -95,7 +96,7 @@ void MeshView::multiDrawImplementationDefault(std::initializer_list<std::referen
if(!original._indexBuffer) {
#ifndef MAGNUM_TARGET_GLES
glMultiDrawArrays(GLenum(original._primitive), baseVertex, count, meshes.size());
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#elif !defined(CORRADE_TARGET_NACL)
glMultiDrawArraysEXT(GLenum(original._primitive), baseVertex, count, meshes.size());
#else
CORRADE_ASSERT_UNREACHABLE();
@ -114,7 +115,7 @@ void MeshView::multiDrawImplementationDefault(std::initializer_list<std::referen
{
#ifndef MAGNUM_TARGET_GLES
glMultiDrawElements(GLenum(original._primitive), count, GLenum(original._indexType), indices, meshes.size());
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#elif !defined(CORRADE_TARGET_NACL)
glMultiDrawElementsEXT(GLenum(original._primitive), count, GLenum(original._indexType), indices, meshes.size());
#else
CORRADE_ASSERT_UNREACHABLE();
@ -124,6 +125,7 @@ void MeshView::multiDrawImplementationDefault(std::initializer_list<std::referen
(original.*state.unbindImplementation)();
}
#endif
#ifdef MAGNUM_TARGET_GLES
void MeshView::multiDrawImplementationFallback(std::initializer_list<std::reference_wrapper<MeshView>> meshes) {

12
src/Magnum/MeshView.h

@ -72,7 +72,8 @@ class MAGNUM_EXPORT MeshView {
* @ref draw(AbstractShaderProgram&) calls.
*
* If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
* ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
* ES 3.0, WebGL 2.0, @es_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
@ -128,7 +129,7 @@ class MAGNUM_EXPORT MeshView {
* @requires_gl32 Extension @extension{ARB,draw_elements_base_vertex}
* for indexed meshes
* @requires_gl Base vertex cannot be specified for indexed meshes in
* OpenGL ES.
* OpenGL ES or WebGL.
*/
MeshView& setBaseVertex(Int baseVertex) {
_baseVertex = baseVertex;
@ -217,6 +218,8 @@ class MAGNUM_EXPORT MeshView {
* @requires_gles30 Extension @es_extension{ANGLE,instanced_arrays},
* @es_extension2{EXT,draw_instanced,draw_instanced} or
* @es_extension{NV,draw_instanced} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays}
* in WebGL 1.0.
*/
MeshView& setInstanceCount(Int count) {
_instanceCount = count;
@ -233,7 +236,8 @@ class MAGNUM_EXPORT MeshView {
*
* Default is `0`.
* @requires_gl42 Extension @extension{ARB,base_instance}
* @requires_gl Base instance cannot be specified in OpenGL ES.
* @requires_gl Base instance cannot be specified in OpenGL ES or
* WebGL.
*/
MeshView& setBaseInstance(UnsignedInt baseInstance) {
_baseInstance = baseInstance;
@ -259,7 +263,9 @@ class MAGNUM_EXPORT MeshView {
#endif
private:
#ifndef MAGNUM_TARGET_WEBGL
static MAGNUM_LOCAL void multiDrawImplementationDefault(std::initializer_list<std::reference_wrapper<MeshView>> meshes);
#endif
static MAGNUM_LOCAL void multiDrawImplementationFallback(std::initializer_list<std::reference_wrapper<MeshView>> meshes);
std::reference_wrapper<Mesh> _original;

Loading…
Cancel
Save