From 52be3a44b15b20d468121c8d5b0d8593249d5946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 6 Jul 2015 15:22:21 +0200 Subject: [PATCH] Implemented EXT_geometry_shader AEP extension. --- doc/opengl-support.dox | 4 +- src/Magnum/Implementation/ShaderState.h | 14 ++--- src/Magnum/Platform/magnum-info.cpp | 27 ++++++---- src/Magnum/Shader.cpp | 71 +++++++++++++++++++++---- src/Magnum/Shader.h | 44 +++++++++------ 5 files changed, 118 insertions(+), 42 deletions(-) diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox index 75d7c9142..ce0d37d0d 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -92,7 +92,7 @@ GLSL 1.40 | done Extension | Status ------------------------------------------- | ------ GLSL 1.50 | done -@extension{ARB,geometry_shader4} | missing layered attachments +@extension{ARB,geometry_shader4} | missing layered attachments and some limit queries @extension{ARB,depth_clamp} | done @extension{ARB,draw_elements_base_vertex} | done @extension{ARB,fragment_coord_conventions} | done (shading language only) @@ -362,7 +362,7 @@ Extension | Status @es_extension{EXT,shader_integer_mix} | done (shading language only) @es_extension{EXT,copy_image} | | @es_extension{EXT,draw_buffers_indexed} | | -@es_extension{EXT,geometry_shader} | | +@es_extension{EXT,geometry_shader} | missing some ES-specific limit queries @es_extension{EXT,gpu_shader5} | done (shading language only) @es_extension{EXT,shader_io_blocks} | done (shading language only) @es_extension{EXT,tessellation_shader} | | diff --git a/src/Magnum/Implementation/ShaderState.h b/src/Magnum/Implementation/ShaderState.h index 993bfb28e..bd29d2295 100644 --- a/src/Magnum/Implementation/ShaderState.h +++ b/src/Magnum/Implementation/ShaderState.h @@ -35,10 +35,10 @@ struct ShaderState { explicit ShaderState(): maxVertexOutputComponents{}, maxFragmentInputComponents{}, #ifndef MAGNUM_TARGET_GLES - maxTessellationControlInputComponents{}, maxTessellationControlOutputComponents{}, maxTessellationControlTotalOutputComponents{}, maxTessellationEvaluationInputComponents{}, maxTessellationEvaluationOutputComponents{}, maxGeometryInputComponents{}, maxGeometryOutputComponents{}, maxGeometryTotalOutputComponents{}, + maxTessellationControlInputComponents{}, maxTessellationControlOutputComponents{}, maxTessellationControlTotalOutputComponents{}, maxTessellationEvaluationInputComponents{}, maxTessellationEvaluationOutputComponents{}, #endif #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - maxAtomicCounterBuffers{}, maxCombinedAtomicCounterBuffers{}, maxAtomicCounters{}, maxCombinedAtomicCounters{}, maxImageUniforms{}, maxCombinedImageUniforms{}, maxShaderStorageBlocks{}, maxCombinedShaderStorageBlocks{}, + maxGeometryInputComponents{}, maxGeometryOutputComponents{}, maxGeometryTotalOutputComponents{}, maxAtomicCounterBuffers{}, maxCombinedAtomicCounterBuffers{}, maxAtomicCounters{}, maxCombinedAtomicCounters{}, maxImageUniforms{}, maxCombinedImageUniforms{}, maxShaderStorageBlocks{}, maxCombinedShaderStorageBlocks{}, #endif maxTextureImageUnits{}, maxTextureImageUnitsCombined{}, #ifndef MAGNUM_TARGET_GLES2 @@ -54,7 +54,7 @@ struct ShaderState { #ifndef MAGNUM_TARGET_GLES StageCount = 6 #elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - StageCount = 3 + StageCount = 4 #else StageCount = 2 #endif @@ -67,12 +67,12 @@ struct ShaderState { maxTessellationControlOutputComponents, maxTessellationControlTotalOutputComponents, maxTessellationEvaluationInputComponents, - maxTessellationEvaluationOutputComponents, - maxGeometryInputComponents, - maxGeometryOutputComponents, - maxGeometryTotalOutputComponents; + maxTessellationEvaluationOutputComponents; #endif #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + GLint maxGeometryInputComponents, + maxGeometryOutputComponents, + maxGeometryTotalOutputComponents; GLint maxAtomicCounterBuffers[StageCount]; GLint maxCombinedAtomicCounterBuffers; GLint maxAtomicCounters[StageCount]; diff --git a/src/Magnum/Platform/magnum-info.cpp b/src/Magnum/Platform/magnum-info.cpp index b5f0c3338..12da3e5bd 100644 --- a/src/Magnum/Platform/magnum-info.cpp +++ b/src/Magnum/Platform/magnum-info.cpp @@ -320,9 +320,9 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifndef MAGNUM_TARGET_GLES _l(Shader::maxTextureImageUnits(Shader::Type::TessellationControl)) _l(Shader::maxTextureImageUnits(Shader::Type::TessellationEvaluation)) - _l(Shader::maxTextureImageUnits(Shader::Type::Geometry)) #endif #ifndef MAGNUM_TARGET_GLES2 + _l(Shader::maxTextureImageUnits(Shader::Type::Geometry)) _l(Shader::maxTextureImageUnits(Shader::Type::Compute)) #endif _l(Shader::maxTextureImageUnits(Shader::Type::Fragment)) @@ -331,9 +331,9 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifndef MAGNUM_TARGET_GLES _l(Shader::maxUniformComponents(Shader::Type::TessellationControl)) _l(Shader::maxUniformComponents(Shader::Type::TessellationEvaluation)) - _l(Shader::maxUniformComponents(Shader::Type::Geometry)) #endif #ifndef MAGNUM_TARGET_GLES2 + _l(Shader::maxUniformComponents(Shader::Type::Geometry)) _l(Shader::maxUniformComponents(Shader::Type::Compute)) #endif _l(Shader::maxUniformComponents(Shader::Type::Fragment)) @@ -383,9 +383,18 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat } #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #ifndef MAGNUM_TARGET_GLES - if(c->isExtensionSupported()) { + if(c->isExtensionSupported()) + #else + if(c->isExtensionSupported()) + #endif + { + #ifndef MAGNUM_TARGET_GLES _h(ARB::geometry_shader4) + #else + _h(EXT::geometry_shader) + #endif _l(Shader::maxGeometryInputComponents()) _l(Shader::maxGeometryOutputComponents()) @@ -407,8 +416,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifndef MAGNUM_TARGET_GLES _l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationControl)) _l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationEvaluation)) - _l(Shader::maxAtomicCounterBuffers(Shader::Type::Geometry)) #endif + _l(Shader::maxAtomicCounterBuffers(Shader::Type::Geometry)) _l(Shader::maxAtomicCounterBuffers(Shader::Type::Compute)) _l(Shader::maxAtomicCounterBuffers(Shader::Type::Fragment)) _l(Shader::maxCombinedAtomicCounterBuffers()) @@ -416,8 +425,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifndef MAGNUM_TARGET_GLES _l(Shader::maxAtomicCounters(Shader::Type::TessellationControl)) _l(Shader::maxAtomicCounters(Shader::Type::TessellationEvaluation)) - _l(Shader::maxAtomicCounters(Shader::Type::Geometry)) #endif + _l(Shader::maxAtomicCounters(Shader::Type::Geometry)) _l(Shader::maxAtomicCounters(Shader::Type::Compute)) _l(Shader::maxAtomicCounters(Shader::Type::Fragment)) _l(Shader::maxCombinedAtomicCounters()) @@ -436,8 +445,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifndef MAGNUM_TARGET_GLES _l(Shader::maxImageUniforms(Shader::Type::TessellationControl)) _l(Shader::maxImageUniforms(Shader::Type::TessellationEvaluation)) - _l(Shader::maxImageUniforms(Shader::Type::Geometry)) #endif + _l(Shader::maxImageUniforms(Shader::Type::Geometry)) _l(Shader::maxImageUniforms(Shader::Type::Compute)) _l(Shader::maxImageUniforms(Shader::Type::Fragment)) _l(Shader::maxCombinedImageUniforms()) @@ -460,8 +469,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifndef MAGNUM_TARGET_GLES _l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationControl)) _l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationEvaluation)) - _l(Shader::maxShaderStorageBlocks(Shader::Type::Geometry)) #endif + _l(Shader::maxShaderStorageBlocks(Shader::Type::Geometry)) _l(Shader::maxShaderStorageBlocks(Shader::Type::Compute)) _l(Shader::maxShaderStorageBlocks(Shader::Type::Fragment)) _l(Shader::maxCombinedShaderStorageBlocks()) @@ -570,8 +579,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifndef MAGNUM_TARGET_GLES _l(Shader::maxUniformBlocks(Shader::Type::TessellationControl)) _l(Shader::maxUniformBlocks(Shader::Type::TessellationEvaluation)) - _l(Shader::maxUniformBlocks(Shader::Type::Geometry)) #endif + _l(Shader::maxUniformBlocks(Shader::Type::Geometry)) _l(Shader::maxUniformBlocks(Shader::Type::Compute)) _l(Shader::maxUniformBlocks(Shader::Type::Fragment)) _l(Shader::maxCombinedUniformBlocks()) @@ -579,8 +588,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifndef MAGNUM_TARGET_GLES _l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationControl)) _l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationEvaluation)) - _l(Shader::maxCombinedUniformComponents(Shader::Type::Geometry)) #endif + _l(Shader::maxCombinedUniformComponents(Shader::Type::Geometry)) _l(Shader::maxCombinedUniformComponents(Shader::Type::Compute)) _l(Shader::maxCombinedUniformComponents(Shader::Type::Fragment)) _l(AbstractShaderProgram::maxUniformBlockSize()) diff --git a/src/Magnum/Shader.cpp b/src/Magnum/Shader.cpp index 25ea69547..a406ff2a9 100644 --- a/src/Magnum/Shader.cpp +++ b/src/Magnum/Shader.cpp @@ -60,8 +60,10 @@ namespace { std::string shaderName(const Shader::Type type) { switch(type) { case Shader::Type::Vertex: return "vertex"; - #ifndef MAGNUM_TARGET_GLES + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) case Shader::Type::Geometry: return "geometry"; + #endif + #ifndef MAGNUM_TARGET_GLES case Shader::Type::TessellationControl: return "tessellation control"; case Shader::Type::TessellationEvaluation: return "tessellation evaluation"; #endif @@ -80,9 +82,9 @@ UnsignedInt typeToIndex(const Shader::Type type) { case Shader::Type::Fragment: return 1; #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) case Shader::Type::Compute: return 2; + case Shader::Type::Geometry: return 3; #endif #ifndef MAGNUM_TARGET_GLES - case Shader::Type::Geometry: return 3; case Shader::Type::TessellationControl: return 4; case Shader::Type::TessellationEvaluation: return 5; #endif @@ -106,6 +108,9 @@ bool isTypeSupported(const Shader::Type type) { } #elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) bool isTypeSupported(const Shader::Type type) { + if(type == Shader::Type::Geometry && !Context::current()->isExtensionSupported()) + return false; + if(type == Shader::Type::Compute && !Context::current()->isVersionSupported(Version::GLES310)) return false; @@ -203,44 +208,76 @@ Int Shader::maxTessellationEvaluationOutputComponents() { return value; } +#endif +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) Int Shader::maxGeometryInputComponents() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) return 0; + #else + if(!Context::current()->isExtensionSupported()) + return 0; + #endif GLint& value = Context::current()->state().shader->maxGeometryInputComponents; /* Get the value, if not already cached */ /** @todo The extension has only `GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB`, this is supported since GL 3.2 (wtf?) */ - if(value == 0) - glGetIntegerv(GL_MAX_GEOMETRY_INPUT_COMPONENTS, &value); + if(value == 0) glGetIntegerv( + #ifndef MAGNUM_TARGET_GLES + GL_MAX_GEOMETRY_INPUT_COMPONENTS, + #else + GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT, + #endif + &value); return value; } Int Shader::maxGeometryOutputComponents() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) return 0; + #else + if(!Context::current()->isExtensionSupported()) + return 0; + #endif GLint& value = Context::current()->state().shader->maxGeometryOutputComponents; /* Get the value, if not already cached */ /** @todo The extension has only `GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB`, this is supported since GL 3.2 (wtf?) */ - if(value == 0) - glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &value); + if(value == 0) glGetIntegerv( + #ifndef MAGNUM_TARGET_GLES + GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, + #else + GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT, + #endif + &value); return value; } Int Shader::maxGeometryTotalOutputComponents() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) return 0; + #else + if(!Context::current()->isExtensionSupported()) + return 0; + #endif GLint& value = Context::current()->state().shader->maxGeometryTotalOutputComponents; /* Get the value, if not already cached */ - if(value == 0) - glGetIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &value); + if(value == 0) glGetIntegerv( + #ifndef MAGNUM_TARGET_GLES + GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, + #else + GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT, + #endif + &value); return value; } @@ -294,6 +331,8 @@ Int Shader::maxAtomicCounterBuffers(const Type type) { GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS, GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS + #else + GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT #endif }; if(value == 0) @@ -345,6 +384,8 @@ Int Shader::maxAtomicCounters(const Type type) { GL_MAX_GEOMETRY_ATOMIC_COUNTERS, GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, + #else + GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT #endif }; if(value == 0) @@ -396,6 +437,8 @@ Int Shader::maxImageUniforms(const Type type) { GL_MAX_GEOMETRY_IMAGE_UNIFORMS, GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS + #else + GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT #endif }; if(value == 0) @@ -447,6 +490,8 @@ Int Shader::maxShaderStorageBlocks(const Type type) { GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS + #else + GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT #endif }; if(value == 0) @@ -491,6 +536,8 @@ Int Shader::maxTextureImageUnits(const Type type) { GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS + #elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT #endif }; if(value == 0) @@ -532,6 +579,8 @@ Int Shader::maxUniformBlocks(const Type type) { GL_MAX_GEOMETRY_UNIFORM_BLOCKS, GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS + #elif !defined(MAGNUM_TARGET_WEBGL) + GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT #endif }; if(value == 0) @@ -575,6 +624,8 @@ Int Shader::maxUniformComponents(const Type type) { GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS + #elif !defined(MAGNUM_TARGET_WEBGL) + GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT #endif }; if(value == 0) @@ -618,6 +669,8 @@ Int Shader::maxCombinedUniformComponents(const Type type) { GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS, GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS + #elif !defined(MAGNUM_TARGET_WEBGL) + GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT, #endif }; if(value == 0) @@ -815,9 +868,9 @@ Debug operator<<(Debug debug, const Shader::Type value) { #ifndef MAGNUM_TARGET_GLES _c(TessellationControl) _c(TessellationEvaluation) - _c(Geometry) #endif #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + _c(Geometry) _c(Compute) #endif _c(Fragment) diff --git a/src/Magnum/Shader.h b/src/Magnum/Shader.h index 937536864..c51ceb2a0 100644 --- a/src/Magnum/Shader.h +++ b/src/Magnum/Shader.h @@ -83,17 +83,23 @@ class MAGNUM_EXPORT Shader: public AbstractObject { * or WebGL. */ TessellationEvaluation = GL_TESS_EVALUATION_SHADER, + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) /** * Geometry shader * @requires_gl32 Extension @extension{ARB,geometry_shader4} - * @requires_gl Geometry shaders are not available in OpenGL ES or - * WebGL. + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/ + * @es_extension{EXT,geometry_shader} + * @requires_gles Geometry shaders are not available in WebGL. */ + #ifndef MAGNUM_TARGET_GLES Geometry = GL_GEOMETRY_SHADER, + #else + Geometry = GL_GEOMETRY_SHADER_EXT, #endif - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) /** * Compute shader * @requires_gl43 Extension @extension{ARB,compute_shader} @@ -181,16 +187,20 @@ class MAGNUM_EXPORT Shader: public AbstractObject { * WebGL. */ static Int maxTessellationEvaluationOutputComponents(); + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) /** * @brief Max supported component count of geometry shader input vertex * * The result is cached, repeated queries don't result in repeated - * OpenGL calls. If extension @extension{ARB,geometry_shader4} (part of - * OpenGL 3.2) is not available, returns `0`. + * OpenGL calls. If neither @extension{ARB,geometry_shader4} (part of + * OpenGL 3.2) nor @es_extension{ANDROID,extension_pack_es31a}/ + * @es_extension{EXT,geometry_shader} ES extension is not available, + * returns `0`. * @see @fn_gl{Get} with @def_gl{MAX_GEOMETRY_INPUT_COMPONENTS} - * @requires_gl Geometry shaders are not available in OpenGL ES or - * WebGL. + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles Geometry shaders are not available in WebGL. */ static Int maxGeometryInputComponents(); @@ -198,11 +208,13 @@ class MAGNUM_EXPORT Shader: public AbstractObject { * @brief Max supported component count of geometry shader output vertex * * The result is cached, repeated queries don't result in repeated - * OpenGL calls. If extension @extension{ARB,geometry_shader4} (part of - * OpenGL 3.2) is not available, returns `0`. + * OpenGL calls. If neither @extension{ARB,geometry_shader4} (part of + * OpenGL 3.2) nor @es_extension{ANDROID,extension_pack_es31a}/ + * @es_extension{EXT,geometry_shader} ES extension is not available, + * returns `0`. * @see @fn_gl{Get} with @def_gl{MAX_GEOMETRY_OUTPUT_COMPONENTS} - * @requires_gl Geometry shaders are not available in OpenGL ES or - * WebGL. + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles Geometry shaders are not available in WebGL. */ static Int maxGeometryOutputComponents(); @@ -210,11 +222,13 @@ class MAGNUM_EXPORT Shader: public AbstractObject { * @brief Max supported component count of all geometry shader output vertices combined * * The result is cached, repeated queries don't result in repeated - * OpenGL calls. If extension @extension{ARB,geometry_shader4} (part of - * OpenGL 3.2) is not available, returns `0`. + * OpenGL calls. If neither @extension{ARB,geometry_shader4} (part of + * OpenGL 3.2) nor @es_extension{ANDROID,extension_pack_es31a}/ + * @es_extension{EXT,geometry_shader} ES extension is not available, + * returns `0`. * @see @fn_gl{Get} with @def_gl{MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS} - * @requires_gl Geometry shaders are not available in OpenGL ES or - * WebGL. + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles Geometry shaders are not available in WebGL. */ static Int maxGeometryTotalOutputComponents(); #endif