diff --git a/doc/changelog.dox b/doc/changelog.dox index 52d89fe16..5b9765be5 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -62,12 +62,14 @@ See also: @webgl_extension{WEBGL,debug_renderer_info} and @webgl_extension{WEBGL,debug_shaders} extensions, no implementation done yet -- Recognizing ANGLE GLES and WebGL multi-draw extensions: +- Recognizing ANGLE GLES and WebGL multi-draw extensions and using them in + @ref GL::AbstractShaderProgram::draw(Containers::ArrayView>): - @m_class{m-doc-external} [ANGLE_multi_draw](https://chromium.googlesource.com/angle/angle/+/master/extensions/ANGLE_multi_draw.txt) + - @webgl_extension{WEBGL,multi_draw} +- The following extensions are recognized but not used yet: - @m_class{m-doc-external} [ANGLE_base_vertex_base_instance](https://chromium.googlesource.com/angle/angle/+/master/extensions/ANGLE_base_vertex_base_instance.txt) - @gl_extension{EXT,draw_elements_base_vertex} - @gl_extension{OES,draw_elements_base_vertex} - - @webgl_extension{WEBGL,multi_draw} - @webgl_extension{WEBGL,draw_instanced_base_vertex_base_instance} - @webgl_extension{WEBGL,multi_draw_instanced_base_vertex_base_instance} - Added a @ref GL::AbstractTexture::target() getter to simplify interaction diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox index eaee12a1b..050e80605 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -449,7 +449,7 @@ Extension | Status @gl_extension2{ANGLE,texture_compression_dxt1,ANGLE_texture_compression_dxt} | done @gl_extension2{ANGLE,texture_compression_dxt3,ANGLE_texture_compression_dxt} | done @gl_extension2{ANGLE,texture_compression_dxt5,ANGLE_texture_compression_dxt} | done -@m_class{m-doc-external} [ANGLE_multi_draw](https://chromium.googlesource.com/angle/angle/+/master/extensions/ANGLE_multi_draw.txt) (unlisted) | | +@m_class{m-doc-external} [ANGLE_multi_draw](https://chromium.googlesource.com/angle/angle/+/master/extensions/ANGLE_multi_draw.txt) (unlisted) | done @m_class{m-doc-external} [ANGLE_base_vertex_base_instance](https://chromium.googlesource.com/angle/angle/+/master/extensions/ANGLE_base_vertex_base_instance.txt) (unlisted) | | @gl_extension{APPLE,texture_format_BGRA8888} | done @gl_extension{APPLE,clip_distance} | done @@ -571,10 +571,10 @@ Extension | Status @webgl_extension{WEBGL,compressed_texture_pvrtc} | done @webgl_extension{WEBGL,compressed_texture_astc} | done @webgl_extension{WEBGL,compressed_texture_s3tc_srgb} | done -@webgl_extension{WEBGL,multi_draw} | missing support in Emscripten +@webgl_extension{WEBGL,multi_draw} | done @webgl_extension{WEBGL,blend_equation_advanced_coherent} | done -@webgl_extension{WEBGL,draw_instanced_base_vertex_base_instance} | missing support in Emscripten -@webgl_extension{WEBGL,multi_draw_instanced_base_vertex_base_instance} | missing support in Emscripten +@webgl_extension{WEBGL,draw_instanced_base_vertex_base_instance} | | +@webgl_extension{WEBGL,multi_draw_instanced_base_vertex_base_instance} | | @section opengl-unsupported Unsupported OpenGL features diff --git a/src/Magnum/GL/AbstractShaderProgram.h b/src/Magnum/GL/AbstractShaderProgram.h index 804ddef34..7b3a24161 100644 --- a/src/Magnum/GL/AbstractShaderProgram.h +++ b/src/Magnum/GL/AbstractShaderProgram.h @@ -840,8 +840,10 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject { * @brief Draw multiple meshes at once * @m_since{2020,06} * - * In OpenGL ES, if @gl_extension{EXT,multi_draw_arrays} is not - * present, the functionality is emulated using a sequence of + * On OpenGL ES, if neither @gl_extension{EXT,multi_draw_arrays} nor + * @m_class{m-doc-external} [ANGLE_multi_draw](https://chromium.googlesource.com/angle/angle/+/master/extensions/ANGLE_multi_draw.txt) + * is present, and on WebGL if @webgl_extension{WEBGL,multi_draw} 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), diff --git a/src/Magnum/GL/Implementation/MeshState.cpp b/src/Magnum/GL/Implementation/MeshState.cpp index 955697e52..7901a6a8e 100644 --- a/src/Magnum/GL/Implementation/MeshState.cpp +++ b/src/Magnum/GL/Implementation/MeshState.cpp @@ -108,16 +108,43 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector()) { - extensions.push_back(Extensions::EXT::multi_draw_arrays::string()); + if(context.isExtensionSupported() || + context.isExtensionSupported()) + #else + if(context.isExtensionSupported()) + #endif + { + #ifndef MAGNUM_TARGET_WEBGL + if(context.isExtensionSupported()) { + extensions.push_back(Extensions::EXT::multi_draw_arrays::string()); + + multiDrawArraysImplementation = glMultiDrawArraysEXT; + multiDrawElementsImplementation = glMultiDrawElementsEXT; + } else if(context.isExtensionSupported()) { + extensions.push_back(Extensions::ANGLE::multi_draw::string()); + + multiDrawArraysImplementation = glMultiDrawArraysANGLE; + multiDrawElementsImplementation = glMultiDrawElementsANGLE; + } else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + #else + { + extensions.push_back(Extensions::WEBGL::multi_draw::string()); + + /* The WEBGL extension uses the same entrypoints as the ANGLE + extension it was based on */ + multiDrawArraysImplementation = glMultiDrawArraysANGLE; + multiDrawElementsImplementation = glMultiDrawElementsANGLE; + } + #endif multiDrawImplementation = &MeshView::multiDrawImplementationDefault; + } else multiDrawImplementation = &MeshView::multiDrawImplementationFallback; - #else - multiDrawImplementation = &MeshView::multiDrawImplementationFallback; - #endif #endif #ifdef MAGNUM_TARGET_GLES2 diff --git a/src/Magnum/GL/Implementation/MeshState.h b/src/Magnum/GL/Implementation/MeshState.h index 62544edc9..f512cc5bc 100644 --- a/src/Magnum/GL/Implementation/MeshState.h +++ b/src/Magnum/GL/Implementation/MeshState.h @@ -60,6 +60,8 @@ struct MeshState { #ifdef MAGNUM_TARGET_GLES void(*multiDrawImplementation)(Containers::ArrayView>); + void(APIENTRY *multiDrawArraysImplementation)(GLenum, const GLint*, const GLsizei*, GLsizei); + void(APIENTRY *multiDrawElementsImplementation)(GLenum, const GLsizei*, GLenum, const void* const*, GLsizei); #endif void(*bindVAOImplementation)(GLuint); diff --git a/src/Magnum/GL/MeshView.cpp b/src/Magnum/GL/MeshView.cpp index 76a5b42c3..0dddaff5c 100644 --- a/src/Magnum/GL/MeshView.cpp +++ b/src/Magnum/GL/MeshView.cpp @@ -84,7 +84,6 @@ MeshView& MeshView::draw(AbstractShaderProgram&& shader, TransformFeedback& xfb, #endif #endif -#ifndef MAGNUM_TARGET_WEBGL void MeshView::multiDrawImplementationDefault(Containers::ArrayView> meshes) { CORRADE_INTERNAL_ASSERT(meshes.size()); @@ -123,10 +122,11 @@ void MeshView::multiDrawImplementationDefault(Containers::ArrayView> meshes) { diff --git a/src/Magnum/GL/MeshView.h b/src/Magnum/GL/MeshView.h index 1cf344120..1ba06a250 100644 --- a/src/Magnum/GL/MeshView.h +++ b/src/Magnum/GL/MeshView.h @@ -257,9 +257,7 @@ class MAGNUM_GL_EXPORT MeshView { friend AbstractShaderProgram; friend Implementation::MeshState; - #ifndef MAGNUM_TARGET_WEBGL static MAGNUM_GL_LOCAL void multiDrawImplementationDefault(Containers::ArrayView> meshes); - #endif #ifdef MAGNUM_TARGET_GLES static MAGNUM_GL_LOCAL void multiDrawImplementationFallback(Containers::ArrayView> meshes); #endif diff --git a/src/Magnum/GL/Test/MeshGLTest.cpp b/src/Magnum/GL/Test/MeshGLTest.cpp index 2ecaac024..2bba4708b 100644 --- a/src/Magnum/GL/Test/MeshGLTest.cpp +++ b/src/Magnum/GL/Test/MeshGLTest.cpp @@ -3005,9 +3005,15 @@ template T MultiChecker::get(PixelFormat format, PixelType type) { #endif void MeshGLTest::multiDraw() { - #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL) - if(!Context::current().isExtensionSupported()) - Debug() << Extensions::EXT::multi_draw_arrays::string() << "not supported, using fallback implementation"; + #ifdef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_WEBGL + if(!Context::current().isExtensionSupported() && + !Context::current().isExtensionSupported()) + Debug{} << "Neither" << Extensions::EXT::multi_draw_arrays::string() << "nor" << Extensions::ANGLE::multi_draw::string() << "is supported, using fallback implementation"; + #else + if(!Context::current().isExtensionSupported()) + Debug{} << Extensions::WEBGL::multi_draw::string() << "is not supported, using fallback implementation"; + #endif #endif typedef Attribute<0, Float> Attribute; @@ -3042,9 +3048,15 @@ void MeshGLTest::multiDraw() { } void MeshGLTest::multiDrawIndexed() { - #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL) - if(!Context::current().isExtensionSupported()) - Debug() << Extensions::EXT::multi_draw_arrays::string() << "not supported, using fallback implementation"; + #ifdef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_WEBGL + if(!Context::current().isExtensionSupported() && + !Context::current().isExtensionSupported()) + Debug{} << "Neither" << Extensions::EXT::multi_draw_arrays::string() << "nor" << Extensions::ANGLE::multi_draw::string() << "is supported, using fallback implementation"; + #else + if(!Context::current().isExtensionSupported()) + Debug{} << Extensions::WEBGL::multi_draw::string() << "is not supported, using fallback implementation"; + #endif #endif Buffer vertices;