Browse Source

GL: implemente ANGLE_provoking_vertex and ANGLE_polygon_mode on ES.

No WebGL support yet as Emscripten doesn't have the required
entrypoints.
pull/638/head
Vladimír Vondruš 2 years ago
parent
commit
89bb568f23
  1. 4
      doc/opengl-support.dox
  2. 14
      src/Magnum/GL/Implementation/RendererState.cpp
  3. 3
      src/Magnum/GL/Implementation/RendererState.h
  4. 11
      src/Magnum/GL/Renderer.cpp
  5. 33
      src/Magnum/GL/Renderer.h
  6. 22
      src/Magnum/GL/Test/RendererGLTest.cpp

4
doc/opengl-support.dox

@ -452,8 +452,8 @@ Extension | Status
@gl_extension2{ANGLE,texture_compression_dxt5,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) | done @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) | 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) | done
@m_class{m-doc-external} [ANGLE_provoking_vertex](https://chromium.googlesource.com/angle/angle/+/main/extensions/ANGLE_provoking_vertex.txt) (unlisted) | | @m_class{m-doc-external} [ANGLE_provoking_vertex](https://chromium.googlesource.com/angle/angle/+/main/extensions/ANGLE_provoking_vertex.txt) (unlisted) | done
@m_class{m-doc-external} [ANGLE_polygon_mode](https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/ANGLE_polygon_mode.txt) (unlisted) | | @m_class{m-doc-external} [ANGLE_polygon_mode](https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/ANGLE_polygon_mode.txt) (unlisted) | done
@m_class{m-doc-external} [ANGLE_stencil_texturing](https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/ANGLE_stencil_texturing.txt) (unlisted) | | @m_class{m-doc-external} [ANGLE_stencil_texturing](https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/ANGLE_stencil_texturing.txt) (unlisted) | |
@gl_extension{APPLE,texture_format_BGRA8888} | done @gl_extension{APPLE,texture_format_BGRA8888} | done
@gl_extension{APPLE,clip_distance} | done @gl_extension{APPLE,clip_distance} | done

14
src/Magnum/GL/Implementation/RendererState.cpp

@ -206,6 +206,20 @@ RendererState::RendererState(Context& context, ContextState& contextState, Conta
#endif #endif
#endif #endif
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
if(context.isExtensionSupported<Extensions::NV::polygon_mode>()) {
extensions[Extensions::NV::polygon_mode::Index] =
Extensions::NV::polygon_mode::string();
polygonModeImplementation = glPolygonModeNV;
} else if(context.isExtensionSupported<Extensions::ANGLE::polygon_mode>()) {
extensions[Extensions::ANGLE::polygon_mode::Index] =
Extensions::ANGLE::polygon_mode::string();
polygonModeImplementation = glPolygonModeANGLE;
} else {
polygonModeImplementation = nullptr;
}
#endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/* On compatibility profile we need to explicitly enable GL_POINT_SPRITE /* On compatibility profile we need to explicitly enable GL_POINT_SPRITE
in order to have gl_PointCoord working (on NVidia at least, Mesa behaves in order to have gl_PointCoord working (on NVidia at least, Mesa behaves

3
src/Magnum/GL/Implementation/RendererState.h

@ -59,6 +59,9 @@ struct RendererState {
void(APIENTRY *blendFuncSeparateiImplementation)(GLuint, GLenum, GLenum, GLenum, GLenum); void(APIENTRY *blendFuncSeparateiImplementation)(GLuint, GLenum, GLenum, GLenum, GLenum);
void(APIENTRY *colorMaskiImplementation)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean); void(APIENTRY *colorMaskiImplementation)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean);
#endif #endif
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
void(APIENTRY *polygonModeImplementation)(GLenum, GLenum);
#endif
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
GLenum(APIENTRY *graphicsResetStatusImplementation)(); GLenum(APIENTRY *graphicsResetStatusImplementation)();

11
src/Magnum/GL/Renderer.cpp

@ -126,9 +126,14 @@ void Renderer::setFaceCullingMode(const PolygonFacing mode) {
glCullFace(GLenum(mode)); glCullFace(GLenum(mode));
} }
#ifndef MAGNUM_TARGET_GLES #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void Renderer::setProvokingVertex(const ProvokingVertex mode) { void Renderer::setProvokingVertex(const ProvokingVertex mode) {
glProvokingVertex(GLenum(mode)); #ifndef MAGNUM_TARGET_GLES
glProvokingVertex
#else
glProvokingVertexANGLE
#endif
(GLenum(mode));
} }
#endif #endif
@ -137,7 +142,7 @@ void Renderer::setPolygonMode(const PolygonMode mode) {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
glPolygonMode glPolygonMode
#else #else
glPolygonModeNV Context::current().state().renderer.polygonModeImplementation
#endif #endif
(GL_FRONT_AND_BACK, GLenum(mode)); (GL_FRONT_AND_BACK, GLenum(mode));
} }

33
src/Magnum/GL/Renderer.h

@ -411,6 +411,7 @@ class MAGNUM_GL_EXPORT Renderer {
* @see @ref Feature::PolygonOffsetFill, @ref Feature::PolygonOffsetPoint, * @see @ref Feature::PolygonOffsetFill, @ref Feature::PolygonOffsetPoint,
* @ref setPolygonOffset() * @ref setPolygonOffset()
* @requires_es_extension Extension @gl_extension{NV,polygon_offset} * @requires_es_extension Extension @gl_extension{NV,polygon_offset}
* or @m_class{m-doc-external} [ANGLE_polygon_mode](https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/ANGLE_polygon_mode.txt)
* @requires_gles Only @ref Feature::PolygonOffsetFill is available * @requires_gles Only @ref Feature::PolygonOffsetFill is available
* in WebGL. * in WebGL.
*/ */
@ -796,7 +797,7 @@ class MAGNUM_GL_EXPORT Renderer {
*/ */
static void setFaceCullingMode(PolygonFacing mode); static void setFaceCullingMode(PolygonFacing mode);
#ifndef MAGNUM_TARGET_GLES #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/** /**
* @brief Provoking vertex * @brief Provoking vertex
* *
@ -804,15 +805,27 @@ class MAGNUM_GL_EXPORT Renderer {
* @m_enum_values_as_keywords * @m_enum_values_as_keywords
* @requires_gl32 Extension @gl_extension{ARB,provoking_vertex}. Older * @requires_gl32 Extension @gl_extension{ARB,provoking_vertex}. Older
* versions behave always like @ref ProvokingVertex::LastVertexConvention. * versions behave always like @ref ProvokingVertex::LastVertexConvention.
* @requires_gl OpenGL ES and WebGL behave always like * @requires_es_extension OpenGL ES 3.0 and extension
* @m_class{m-doc-external} [ANGLE_provoking_vertex](https://chromium.googlesource.com/angle/angle/+/main/extensions/ANGLE_provoking_vertex.txt).
* Without the extension behaves always like
* @ref ProvokingVertex::LastVertexConvention.
* @requires_gles WebGL behaves always like
* @ref ProvokingVertex::LastVertexConvention. * @ref ProvokingVertex::LastVertexConvention.
*/ */
enum class ProvokingVertex: GLenum { enum class ProvokingVertex: GLenum {
/** Use first vertex of each polygon. */ /** Use first vertex of each polygon. */
#ifndef MAGNUM_TARGET_GLES
FirstVertexConvention = GL_FIRST_VERTEX_CONVENTION, FirstVertexConvention = GL_FIRST_VERTEX_CONVENTION,
#else
FirstVertexConvention = GL_FIRST_VERTEX_CONVENTION_ANGLE,
#endif
/** Use last vertex of each polygon (default). */ /** Use last vertex of each polygon (default). */
#ifndef MAGNUM_TARGET_GLES
LastVertexConvention = GL_LAST_VERTEX_CONVENTION LastVertexConvention = GL_LAST_VERTEX_CONVENTION
#else
LastVertexConvention = GL_LAST_VERTEX_CONVENTION_ANGLE
#endif
}; };
/** /**
@ -822,7 +835,9 @@ class MAGNUM_GL_EXPORT Renderer {
* @see @fn_gl_keyword{ProvokingVertex} * @see @fn_gl_keyword{ProvokingVertex}
* @requires_gl32 Extension @gl_extension{ARB,provoking_vertex}. Older * @requires_gl32 Extension @gl_extension{ARB,provoking_vertex}. Older
* versions behave always like the default. * versions behave always like the default.
* @requires_gl OpenGL ES and WebGL behave always like the default. * @requires_es_extension OpenGL ES 3.0 and extension
* @m_class{m-doc-external} [ANGLE_provoking_vertex](https://chromium.googlesource.com/angle/angle/+/main/extensions/ANGLE_provoking_vertex.txt)
* @requires_gles WebGL behaves always like the default.
*/ */
static void setProvokingVertex(ProvokingVertex mode); static void setProvokingVertex(ProvokingVertex mode);
#endif #endif
@ -833,11 +848,12 @@ class MAGNUM_GL_EXPORT Renderer {
* *
* @see @ref setPolygonMode() * @see @ref setPolygonMode()
* @m_enum_values_as_keywords * @m_enum_values_as_keywords
* @requires_es_extension Extension @gl_extension{NV,polygon_mode}. * @requires_es_extension Extension @gl_extension{NV,polygon_mode} or
* @m_class{m-doc-external} [ANGLE_polygon_mode](https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/ANGLE_polygon_mode.txt).
* Otherwise behaves always like @ref PolygonMode::Fill. See * Otherwise behaves always like @ref PolygonMode::Fill. See
* @ref Mesh::setPrimitive() for possible workaround. * @ref Mesh::setPrimitive() for a possible workaround.
* @requires_gles WebGL behaves always like @ref PolygonMode::Fill. See * @requires_gles WebGL behaves always like @ref PolygonMode::Fill. See
* @ref Mesh::setPrimitive() for possible workaround. * @ref Mesh::setPrimitive() for a possible workaround.
*/ */
enum class PolygonMode: GLenum { enum class PolygonMode: GLenum {
/** /**
@ -861,6 +877,8 @@ class MAGNUM_GL_EXPORT Renderer {
/** /**
* Starts of boundary edges are drawn as points. See also * Starts of boundary edges are drawn as points. See also
* @ref setPointSize(). * @ref setPointSize().
* @requires_es_extension Extension @gl_extension{NV,polygon_mode},
* not available with @m_class{m-doc-external} [ANGLE_polygon_mode](https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/ANGLE_polygon_mode.txt)
*/ */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
Point = GL_POINT Point = GL_POINT
@ -874,7 +892,8 @@ class MAGNUM_GL_EXPORT Renderer {
* *
* Initial value is @ref PolygonMode::Fill. * Initial value is @ref PolygonMode::Fill.
* @see @fn_gl_keyword{PolygonMode} * @see @fn_gl_keyword{PolygonMode}
* @requires_es_extension Extension @gl_extension{NV,polygon_mode}. * @requires_es_extension Extension @gl_extension{NV,polygon_mode} or
* @m_class{m-doc-external} [ANGLE_polygon_mode](https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/ANGLE_polygon_mode.txt).
* Otherwise behaves always like the default. See * Otherwise behaves always like the default. See
* @ref Mesh::setPrimitive() for possible workaround. * @ref Mesh::setPrimitive() for possible workaround.
* @requires_gles WebGL behaves always like the default. See * @requires_gles WebGL behaves always like the default. See

22
src/Magnum/GL/Test/RendererGLTest.cpp

@ -61,6 +61,9 @@ struct RendererGLTest: OpenGLTester {
void maxLineWidth(); void maxLineWidth();
void pointCoord(); void pointCoord();
#ifndef MAGNUM_TARGET_WEBGL
void polygonMode();
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void patchParameters(); void patchParameters();
#endif #endif
@ -86,6 +89,9 @@ using namespace Math::Literals;
RendererGLTest::RendererGLTest() { RendererGLTest::RendererGLTest() {
addTests({&RendererGLTest::maxLineWidth, addTests({&RendererGLTest::maxLineWidth,
&RendererGLTest::pointCoord, &RendererGLTest::pointCoord,
#ifndef MAGNUM_TARGET_WEBGL
&RendererGLTest::polygonMode,
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
&RendererGLTest::patchParameters, &RendererGLTest::patchParameters,
#endif #endif
@ -253,6 +259,22 @@ void RendererGLTest::pointCoord() {
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold})); (DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold}));
} }
#ifndef MAGNUM_TARGET_WEBGL
void RendererGLTest::polygonMode() {
#ifdef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::NV::polygon_mode>() &&
!Context::current().isExtensionSupported<Extensions::ANGLE::polygon_mode>())
CORRADE_SKIP("Neither" << Extensions::NV::polygon_mode::string() << "nor" << Extensions::ANGLE::polygon_mode::string() << "is supported.");
#endif
/* Just check for crashes and GL errors, revert back to the default mode to
not break other tests */
Renderer::setPolygonMode(Renderer::PolygonMode::Line);
Renderer::setPolygonMode(Renderer::PolygonMode::Fill);
MAGNUM_VERIFY_NO_GL_ERROR();
}
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void RendererGLTest::patchParameters() { void RendererGLTest::patchParameters() {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES

Loading…
Cancel
Save