Browse Source

GL: implement {EXT,ARB}_draw_buffers{2,_blend,_indexed}.

I also figured out a new, faster & less verbose way to handle multiple
code paths in some cases -- why didn't I think of that earlier?
pull/388/merge
Vladimír Vondruš 6 years ago
parent
commit
0e50f0feea
  1. 5
      doc/changelog.dox
  2. 10
      doc/opengl-mapping.dox
  3. 7
      doc/opengl-support.dox
  4. 3
      src/Magnum/GL/Context.cpp
  5. 3
      src/Magnum/GL/Extensions.h
  6. 2
      src/Magnum/GL/Framebuffer.h
  7. 45
      src/Magnum/GL/Implementation/RendererState.cpp
  8. 9
      src/Magnum/GL/Implementation/RendererState.h
  9. 38
      src/Magnum/GL/Renderer.cpp
  10. 165
      src/Magnum/GL/Renderer.h
  11. 49
      src/Magnum/GL/Test/RendererGLTest.cpp
  12. 1
      src/MagnumExternal/OpenGL/GLES3/Emscripten/extensions.txt
  13. 42
      src/MagnumExternal/OpenGL/GLES3/flextGLEmscripten.h

5
doc/changelog.dox

@ -52,6 +52,11 @@ See also:
@webgl_extension{OVR,multiview2} extension. See also @webgl_extension{OVR,multiview2} extension. See also
[mosra/magnum#385](https://github.com/mosra/magnum/issues/385). [mosra/magnum#385](https://github.com/mosra/magnum/issues/385).
- @gl_extension{ARB,sample_locations} desktop extension - @gl_extension{ARB,sample_locations} desktop extension
- Implemented @gl_extension{EXT,draw_buffers2},
@gl_extension{ARB,draw_buffers_blend} desktop extensions,
@gl_extension{EXT,draw_buffers_indexed} ES extension and
@webgl_extension{EXT,draw_buffers_indexed} WebGL 2 extension in
@ref GL::Renderer
- Recognizing @gl_extension{AMD,shader_explicit_vertex_parameter} desktop - Recognizing @gl_extension{AMD,shader_explicit_vertex_parameter} desktop
and @gl_extension{NV,fragment_shader_barycentric} desktop / ES extensions. and @gl_extension{NV,fragment_shader_barycentric} desktop / ES extensions.
These add only shading language features. These add only shading language features.

10
doc/opengl-mapping.dox

@ -80,8 +80,8 @@ OpenGL function | Matching API
@fn_gl{BindVertexBuffer}, \n `glVertexArrayVertexBuffer()`, \n @fn_gl{BindVertexBuffers}, \n `glVertexArrayVertexBuffers()` | | @fn_gl{BindVertexBuffer}, \n `glVertexArrayVertexBuffer()`, \n @fn_gl{BindVertexBuffers}, \n `glVertexArrayVertexBuffers()` | |
@fn_gl_extension{BlendBarrier,KHR,blend_equation_advanced} | @ref GL::Renderer::blendBarrier() @fn_gl_extension{BlendBarrier,KHR,blend_equation_advanced} | @ref GL::Renderer::blendBarrier()
@fn_gl{BlendColor} | @ref GL::Renderer::setBlendColor() @fn_gl{BlendColor} | @ref GL::Renderer::setBlendColor()
@fn_gl{BlendEquation}, \n @fn_gl{BlendEquationSeparate} | @ref GL::Renderer::setBlendEquation() @fn_gl{BlendEquation}, \n `glBlendEquationi()`, \n @fn_gl{BlendEquationSeparate}, \n `glBlendEquationSeparatei()` | @ref GL::Renderer::setBlendEquation()
@fn_gl{BlendFunc}, \n @fn_gl{BlendFuncSeparate} | @ref GL::Renderer::setBlendFunction() @fn_gl{BlendFunc}, \n `glBlendFunci()`, \n @fn_gl{BlendFuncSeparate}, \n `glBlendFuncSeparatei()` | @ref GL::Renderer::setBlendFunction()
@fn_gl{BlitFramebuffer}, \n `glBlitNamedFramebuffer()` | @ref GL::AbstractFramebuffer::blit() @fn_gl{BlitFramebuffer}, \n `glBlitNamedFramebuffer()` | @ref GL::AbstractFramebuffer::blit()
@fn_gl{BufferData}, \n `glNamedBufferData()` | @ref GL::Buffer::setData() @fn_gl{BufferData}, \n `glNamedBufferData()` | @ref GL::Buffer::setData()
@fn_gl_extension{BufferPageCommitment,ARB,sparse_buffer}, \n `glNamedBufferPageCommitmentEXT()`, \n `glNamedBufferPageCommitmentARB()` | | @fn_gl_extension{BufferPageCommitment,ARB,sparse_buffer}, \n `glNamedBufferPageCommitmentEXT()`, \n `glNamedBufferPageCommitmentARB()` | |
@ -107,7 +107,7 @@ OpenGL function | Matching API
@fn_gl{ClearTexSubImage} | | @fn_gl{ClearTexSubImage} | |
@fn_gl{ClientWaitSync} | | @fn_gl{ClientWaitSync} | |
@fn_gl{ClipControl} | | @fn_gl{ClipControl} | |
@fn_gl{ColorMask} | @ref GL::Renderer::setColorMask() @fn_gl{ColorMask}, \n `glColorMaski()` | @ref GL::Renderer::setColorMask()
@fn_gl{CompileShader} | @ref GL::Shader::compile() @fn_gl{CompileShader} | @ref GL::Shader::compile()
@fn_gl{CompressedTexImage1D}, \n @fn_gl{CompressedTexImage2D}, \n @fn_gl{CompressedTexImage3D} | @ref GL::Texture::setCompressedImage(), \n @ref GL::TextureArray::setCompressedImage(), \n @ref GL::CubeMapTexture::setCompressedImage(), \n @ref GL::CubeMapTextureArray::setCompressedImage(), \n @ref GL::RectangleTexture::setCompressedImage() @fn_gl{CompressedTexImage1D}, \n @fn_gl{CompressedTexImage2D}, \n @fn_gl{CompressedTexImage3D} | @ref GL::Texture::setCompressedImage(), \n @ref GL::TextureArray::setCompressedImage(), \n @ref GL::CubeMapTexture::setCompressedImage(), \n @ref GL::CubeMapTextureArray::setCompressedImage(), \n @ref GL::RectangleTexture::setCompressedImage()
@fn_gl{CompressedTexSubImage1D}, \n `glCompressedTextureSubImage1D()`, \n @fn_gl{CompressedTexSubImage2D}, \n `glCompressedTextureSubImage2D()`, \n @fn_gl{CompressedTexSubImage3D}, \n `glCompressedTextureSubImage3D()` | @ref GL::Texture::setCompressedSubImage(), \n @ref GL::TextureArray::setCompressedSubImage(), \n @ref GL::CubeMapTexture::setCompressedSubImage(), \n @ref GL::CubeMapTextureArray::setCompressedSubImage(), \n @ref GL::RectangleTexture::setCompressedSubImage() @fn_gl{CompressedTexSubImage1D}, \n `glCompressedTextureSubImage1D()`, \n @fn_gl{CompressedTexSubImage2D}, \n `glCompressedTextureSubImage2D()`, \n @fn_gl{CompressedTexSubImage3D}, \n `glCompressedTextureSubImage3D()` | @ref GL::Texture::setCompressedSubImage(), \n @ref GL::TextureArray::setCompressedSubImage(), \n @ref GL::CubeMapTexture::setCompressedSubImage(), \n @ref GL::CubeMapTextureArray::setCompressedSubImage(), \n @ref GL::RectangleTexture::setCompressedSubImage()
@ -149,7 +149,7 @@ OpenGL function | Matching API
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{Enable}, `glDisable()` | @ref GL::Renderer::setFeature() @fn_gl{Enable} `glEnablei()`, \n `glDisable()`, `glDisablei()` | @ref GL::Renderer::enable(), \n @ref GL::Renderer::disable(), \n @ref GL::Renderer::setFeature()
@fn_gl{EnableVertexAttribArray}, \n `glEnableVertexArrayAttrib()`, \n `glDisableVertexAttribArray()`, \n `glDisableVertexArrayAttrib()`, \n `glDisableVertexArrayAttribEXT()` | @ref GL::Mesh::addVertexBuffer() @fn_gl{EnableVertexAttribArray}, \n `glEnableVertexArrayAttrib()`, \n `glDisableVertexAttribArray()`, \n `glDisableVertexArrayAttrib()`, \n `glDisableVertexArrayAttribEXT()` | @ref GL::Mesh::addVertexBuffer()
@fn_gl_extension{EvaluateDepthValues,ARB,sample_locations} | | @fn_gl_extension{EvaluateDepthValues,ARB,sample_locations} | |
@ -265,7 +265,7 @@ OpenGL function | Matching API
@fn_gl{InvalidateTexImage} | @ref GL::Texture::invalidateImage(), \n @ref GL::TextureArray::invalidateImage(), \n @ref GL::CubeMapTexture::invalidateImage(), \n @ref GL::CubeMapTextureArray::invalidateImage(), \n @ref GL::RectangleTexture::invalidateImage(), \n @ref GL::MultisampleTexture::invalidateImage() @fn_gl{InvalidateTexImage} | @ref GL::Texture::invalidateImage(), \n @ref GL::TextureArray::invalidateImage(), \n @ref GL::CubeMapTexture::invalidateImage(), \n @ref GL::CubeMapTextureArray::invalidateImage(), \n @ref GL::RectangleTexture::invalidateImage(), \n @ref GL::MultisampleTexture::invalidateImage()
@fn_gl{InvalidateTexSubImage} | @ref GL::Texture::invalidateSubImage(), \n @ref GL::TextureArray::invalidateSubImage(), \n @ref GL::CubeMapTexture::invalidateSubImage(), \n @ref GL::CubeMapTextureArray::invalidateSubImage(), \n @ref GL::RectangleTexture::invalidateSubImage(), \n @ref GL::MultisampleTexture::invalidateSubImage() @fn_gl{InvalidateTexSubImage} | @ref GL::Texture::invalidateSubImage(), \n @ref GL::TextureArray::invalidateSubImage(), \n @ref GL::CubeMapTexture::invalidateSubImage(), \n @ref GL::CubeMapTextureArray::invalidateSubImage(), \n @ref GL::RectangleTexture::invalidateSubImage(), \n @ref GL::MultisampleTexture::invalidateSubImage()
@fn_gl{IsBuffer}, \n @fn_gl{IsFramebuffer}, \n @fn_gl{IsProgram}, \n @fn_gl{IsProgramPipeline}, \n @fn_gl{IsQuery}, \n @fn_gl{IsRenderbuffer}, \n @fn_gl{IsSampler}, \n @fn_gl{IsShader}, \n @fn_gl{IsSync}, \n @fn_gl{IsTexture}, \n @fn_gl{IsTransformFeedback}, \n @fn_gl{IsVertexArray} | not needed, objects are strongly typed @fn_gl{IsBuffer}, \n @fn_gl{IsFramebuffer}, \n @fn_gl{IsProgram}, \n @fn_gl{IsProgramPipeline}, \n @fn_gl{IsQuery}, \n @fn_gl{IsRenderbuffer}, \n @fn_gl{IsSampler}, \n @fn_gl{IsShader}, \n @fn_gl{IsSync}, \n @fn_gl{IsTexture}, \n @fn_gl{IsTransformFeedback}, \n @fn_gl{IsVertexArray} | not needed, objects are strongly typed
@fn_gl{IsEnabled} | not queryable, @ref GL::Renderer::setFeature() setter only @fn_gl{IsEnabled}, `glIsEnabledi()` | not queryable, @ref GL::Renderer::setFeature() setter only
@fn_gl_extension{IsImageHandleResident,ARB,bindless_texture} | | @fn_gl_extension{IsImageHandleResident,ARB,bindless_texture} | |
@fn_gl_extension{IsTextureHandleResident,ARB,bindless_texture} | | @fn_gl_extension{IsTextureHandleResident,ARB,bindless_texture} | |

7
doc/opengl-support.dox

@ -76,7 +76,7 @@ GLSL 1.30 | done
@gl_extension{EXT,texture_array} | done @gl_extension{EXT,texture_array} | done
@gl_extension{EXT,texture_compression_rgtc} | done @gl_extension{EXT,texture_compression_rgtc} | done
@gl_extension{EXT,texture_shared_exponent} | done @gl_extension{EXT,texture_shared_exponent} | done
@gl_extension{EXT,draw_buffers2} | | @gl_extension{EXT,draw_buffers2} | done (GL 3.0 subset)
@gl_extension{EXT,texture_integer} | done (GL 3.0 subset) @gl_extension{EXT,texture_integer} | done (GL 3.0 subset)
@gl_extension{EXT,transform_feedback} | done @gl_extension{EXT,transform_feedback} | done
`MAGNUM_shader_vertex_id` \n @m_span{m-text m-dim} Pseudo-extension denoting support for the @glsl gl_VertexID @ce GLSL builtin. @m_endspan | done `MAGNUM_shader_vertex_id` \n @m_span{m-text m-dim} Pseudo-extension denoting support for the @glsl gl_VertexID @ce GLSL builtin. @m_endspan | done
@ -140,7 +140,7 @@ GLSL 3.30 | done
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 4.00 | done GLSL 4.00 | done
@gl_extension{ARB,draw_buffers_blend} | | @gl_extension{ARB,draw_buffers_blend} | done
@gl_extension{ARB,sample_shading} | done @gl_extension{ARB,sample_shading} | done
@gl_extension{ARB,texture_cube_map_array} | done @gl_extension{ARB,texture_cube_map_array} | done
@gl_extension{ARB,texture_gather} | missing limit queries @gl_extension{ARB,texture_gather} | missing limit queries
@ -354,7 +354,7 @@ Extension | Status
@gl_extension{EXT,color_buffer_half_float} | | @gl_extension{EXT,color_buffer_half_float} | |
@gl_extension{EXT,color_buffer_float} | | @gl_extension{EXT,color_buffer_float} | |
@gl_extension{EXT,copy_image} | | @gl_extension{EXT,copy_image} | |
@gl_extension{EXT,draw_buffers_indexed} | | @gl_extension{EXT,draw_buffers_indexed} | done
@gl_extension{EXT,geometry_shader} | missing some ES-specific limit queries @gl_extension{EXT,geometry_shader} | missing some ES-specific limit queries
@gl_extension{EXT,gpu_shader5} | done (shading language only) @gl_extension{EXT,gpu_shader5} | done (shading language only)
@gl_extension{EXT,shader_io_blocks} | done (shading language only) @gl_extension{EXT,shader_io_blocks} | done (shading language only)
@ -546,6 +546,7 @@ Extension | Status
@webgl_extension{EXT,color_buffer_float} | | @webgl_extension{EXT,color_buffer_float} | |
@webgl_extension{EXT,texture_compression_rgtc} | done @webgl_extension{EXT,texture_compression_rgtc} | done
@webgl_extension{EXT,texture_compression_bptc} | done @webgl_extension{EXT,texture_compression_bptc} | done
@webgl_extension{EXT,draw_buffers_indexed} | done
@webgl_extension{OES,texture_float_linear} | done @webgl_extension{OES,texture_float_linear} | done
@webgl_extension{OVR,multiview2} | | @webgl_extension{OVR,multiview2} | |
@webgl_extension{WEBGL,compressed_texture_s3tc} | done @webgl_extension{WEBGL,compressed_texture_s3tc} | done

3
src/Magnum/GL/Context.cpp

@ -265,6 +265,9 @@ constexpr Extension ExtensionList[]{
#endif #endif
_extension(EXT,texture_compression_rgtc), _extension(EXT,texture_compression_rgtc),
_extension(EXT,texture_compression_bptc), _extension(EXT,texture_compression_bptc),
#ifndef MAGNUM_TARGET_GLES2
_extension(EXT,draw_buffers_indexed),
#endif
_extension(OES,texture_float_linear), _extension(OES,texture_float_linear),
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
_extension(OVR,multiview2), _extension(OVR,multiview2),

3
src/Magnum/GL/Extensions.h

@ -295,6 +295,9 @@ namespace ANGLE {
#endif #endif
_extension(10,EXT,texture_compression_rgtc, GLES200, None) // #38 _extension(10,EXT,texture_compression_rgtc, GLES200, None) // #38
_extension(11,EXT,texture_compression_bptc, GLES200, None) // #39 _extension(11,EXT,texture_compression_bptc, GLES200, None) // #39
#ifndef MAGNUM_TARGET_GLES2
_extension(12,EXT,draw_buffers_indexed, GLES300, None) // #45
#endif
} namespace OES { } namespace OES {
#ifdef MAGNUM_TARGET_GLES2 #ifdef MAGNUM_TARGET_GLES2
_extension(15,OES,texture_float, GLES200, GLES300) // #1 _extension(15,OES,texture_float, GLES200, GLES300) // #1

2
src/Magnum/GL/Framebuffer.h

@ -80,7 +80,7 @@ possible to achieve the same with a @ref MultisampleTexture2D, support for it
is rather sparse on OpenGL ES and completely nonexistent on WebGL or is rather sparse on OpenGL ES and completely nonexistent on WebGL or
macOS / iOS. macOS / iOS.
@section GL-Framebuffer-usage-multiple-output Multiple fragment shader outputs @section GL-Framebuffer-usage-multiple-outputs Multiple fragment shader outputs
In a deferred rendering setup for example, a shader usually has more than one In a deferred rendering setup for example, a shader usually has more than one
output. That's finally where non-zero @ref ColorAttachment and @ref mapForDraw() output. That's finally where non-zero @ref ColorAttachment and @ref mapForDraw()

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

@ -107,6 +107,51 @@ RendererState::RendererState(Context& context, ContextState& contextState, std::
minSampleShadingImplementation = nullptr; minSampleShadingImplementation = nullptr;
#endif #endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
#ifdef MAGNUM_TARGET_GLES
if(context.isVersionSupported(Version::GLES320))
#endif
{
enableiImplementation = glEnablei;
disableiImplementation = glDisablei;
colorMaskiImplementation = glColorMaski;
blendFunciImplementation = glBlendFunci;
blendFuncSeparateiImplementation = glBlendFuncSeparatei;
blendEquationiImplementation = glBlendEquationi;
blendEquationSeparateiImplementation = glBlendEquationSeparatei;
}
#endif
#ifdef MAGNUM_TARGET_GLES
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
else
#endif
{
/* Not checking for the extension (nor adding it to the extension list)
as this is not any optional feature -- it can be only used when
the extension is present, and if it's not, the pointers are null */
#ifndef MAGNUM_TARGET_WEBGL
enableiImplementation = glEnableiEXT;
disableiImplementation = glDisableiEXT;
colorMaskiImplementation = glColorMaskiEXT;
blendFunciImplementation = glBlendFunciEXT;
blendFuncSeparateiImplementation = glBlendFuncSeparateiEXT;
blendEquationiImplementation = glBlendEquationiEXT;
blendEquationSeparateiImplementation = glBlendEquationSeparateiEXT;
#else
/* Emscripten doesn't support these yet (last checked Feb 2020) */
enableiImplementation = nullptr;
disableiImplementation = nullptr;
colorMaskiImplementation = nullptr;
blendFunciImplementation = nullptr;
blendFuncSeparateiImplementation = nullptr;
blendEquationiImplementation = nullptr;
blendEquationSeparateiImplementation = nullptr;
#endif
}
#endif
#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

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

@ -43,6 +43,15 @@ struct RendererState {
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void(*minSampleShadingImplementation)(GLfloat); void(*minSampleShadingImplementation)(GLfloat);
#endif #endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void(*enableiImplementation)(GLenum, GLuint);
void(*disableiImplementation)(GLenum, GLuint);
void(*blendEquationiImplementation)(GLuint, GLenum);
void(*blendEquationSeparateiImplementation)(GLuint, GLenum, GLenum);
void(*blendFunciImplementation)(GLuint, GLenum, GLenum);
void(*blendFuncSeparateiImplementation)(GLuint, GLenum, GLenum, GLenum, GLenum);
void(*colorMaskiImplementation)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean);
#endif
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
Renderer::GraphicsResetStatus(*graphicsResetStatusImplementation)(); Renderer::GraphicsResetStatus(*graphicsResetStatusImplementation)();

38
src/Magnum/GL/Renderer.cpp

@ -72,6 +72,20 @@ void Renderer::setFeature(const Feature feature, const bool enabled) {
enabled ? enable(feature) : disable(feature); enabled ? enable(feature) : disable(feature);
} }
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void Renderer::enable(const Feature feature, const UnsignedInt drawBuffer) {
Context::current().state().renderer->enableiImplementation(GLenum(feature), drawBuffer);
}
void Renderer::disable(const Feature feature, const UnsignedInt drawBuffer) {
Context::current().state().renderer->disableiImplementation(GLenum(feature), drawBuffer);
}
void Renderer::setFeature(const Feature feature, const UnsignedInt drawBuffer, const bool enabled) {
enabled ? enable(feature, drawBuffer) : disable(feature, drawBuffer);
}
#endif
void Renderer::setHint(const Hint target, const HintMode mode) { void Renderer::setHint(const Hint target, const HintMode mode) {
glHint(GLenum(target), GLenum(mode)); glHint(GLenum(target), GLenum(mode));
} }
@ -177,6 +191,12 @@ void Renderer::setColorMask(const GLboolean allowRed, const GLboolean allowGreen
glColorMask(allowRed, allowGreen, allowBlue, allowAlpha); glColorMask(allowRed, allowGreen, allowBlue, allowAlpha);
} }
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void Renderer::setColorMask(const UnsignedInt drawBuffer, const GLboolean allowRed, const GLboolean allowGreen, const GLboolean allowBlue, const GLboolean allowAlpha) {
Context::current().state().renderer->colorMaskiImplementation(drawBuffer, allowRed, allowGreen, allowBlue, allowAlpha);
}
#endif
void Renderer::setDepthMask(const GLboolean allow) { void Renderer::setDepthMask(const GLboolean allow) {
glDepthMask(allow); glDepthMask(allow);
} }
@ -205,6 +225,24 @@ void Renderer::setBlendFunction(const BlendFunction sourceRgb, const BlendFuncti
glBlendFuncSeparate(GLenum(sourceRgb), GLenum(destinationRgb), GLenum(sourceAlpha), GLenum(destinationAlpha)); glBlendFuncSeparate(GLenum(sourceRgb), GLenum(destinationRgb), GLenum(sourceAlpha), GLenum(destinationAlpha));
} }
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void Renderer::setBlendEquation(const UnsignedInt drawBuffer, const BlendEquation equation) {
Context::current().state().renderer->blendEquationiImplementation(drawBuffer, GLenum(equation));
}
void Renderer::setBlendEquation(const UnsignedInt drawBuffer, const BlendEquation rgb, const BlendEquation alpha) {
Context::current().state().renderer->blendEquationSeparateiImplementation(drawBuffer, GLenum(rgb), GLenum(alpha));
}
void Renderer::setBlendFunction(const UnsignedInt drawBuffer, const BlendFunction source, const BlendFunction destination) {
Context::current().state().renderer->blendFunciImplementation(drawBuffer, GLenum(source), GLenum(destination));
}
void Renderer::setBlendFunction(const UnsignedInt drawBuffer, const BlendFunction sourceRgb, const BlendFunction destinationRgb, const BlendFunction sourceAlpha, const BlendFunction destinationAlpha) {
Context::current().state().renderer->blendFuncSeparateiImplementation(drawBuffer, GLenum(sourceRgb), GLenum(destinationRgb), GLenum(sourceAlpha), GLenum(destinationAlpha));
}
#endif
void Renderer::setBlendColor(const Color4& color) { void Renderer::setBlendColor(const Color4& color) {
glBlendColor(color.r(), color.g(), color.b(), color.a()); glBlendColor(color.r(), color.g(), color.b(), color.a());
} }

165
src/Magnum/GL/Renderer.h

@ -324,6 +324,25 @@ class MAGNUM_GL_EXPORT Renderer {
*/ */
static void enable(Feature feature); static void enable(Feature feature);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Enable a feature for given draw buffer
* @param feature Feature to enable
* @param drawBuffer Draw buffer index
* @m_since_latest
*
* @see @ref disable(Feature, UnsignedInt),
* @ref setFeature(Feature, UnsignedInt, bool),
* @ref GL-Framebuffer-usage-multiple-outputs,
* @fn_gl2_keyword{Enablei,Enable}
* @requires_gl30 Extension @gl_extension{EXT,draw_buffers2}
* @requires_gles32 Extension @gl_extension{EXT,draw_buffers_indexed}
* @requires_webgl_extension WebGL 2.0 and extension
* @webgl_extension{EXT,draw_buffers_indexed}
*/
static void enable(Feature feature, UnsignedInt drawBuffer);
#endif
/** /**
* @brief Disable a feature * @brief Disable a feature
* *
@ -331,6 +350,25 @@ class MAGNUM_GL_EXPORT Renderer {
*/ */
static void disable(Feature feature); static void disable(Feature feature);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Disable a feature for given draw buffer
* @param feature Feature to disable
* @param drawBuffer Draw buffer index
* @m_since_latest
*
* @see @ref enable(Feature, UnsignedInt),
* @ref setFeature(Feature, UnsignedInt, bool),
* @ref GL-Framebuffer-usage-multiple-outputs
* @fn_gl2_keyword{Disablei,Disable}
* @requires_gl30 Extension @gl_extension{EXT,draw_buffers2}
* @requires_gles32 Extension @gl_extension{EXT,draw_buffers_indexed}
* @requires_webgl_extension WebGL 2.0 and extension
* @webgl_extension{EXT,draw_buffers_indexed}
*/
static void disable(Feature feature, UnsignedInt drawBuffer);
#endif
/** /**
* @brief Enable or disable a feature * @brief Enable or disable a feature
* *
@ -343,6 +381,24 @@ class MAGNUM_GL_EXPORT Renderer {
*/ */
static void setFeature(Feature feature, bool enabled); static void setFeature(Feature feature, bool enabled);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Enable or disable a feature for given draw buffer
* @param feature Feature to toggle
* @param drawBuffer Draw buffer index
* @param enabled Enable or disable
*
* @see @ref enable(Feature, UnsignedInt),
* @ref disable(Feature, UnsignedInt),
* @ref GL-Framebuffer-usage-multiple-outputs
* @requires_gl30 Extension @gl_extension{EXT,draw_buffers2}
* @requires_gles32 Extension @gl_extension{EXT,draw_buffers_indexed}
* @requires_webgl_extension WebGL 2.0 and extension
* @webgl_extension{EXT,draw_buffers_indexed}
*/
static void setFeature(Feature feature, UnsignedInt drawBuffer, bool enabled);
#endif
/** /**
* @brief Hint * @brief Hint
* *
@ -784,15 +840,38 @@ class MAGNUM_GL_EXPORT Renderer {
/** /**
* @brief Mask color writes * @brief Mask color writes
* @param allowRed Allow red channel to be written
* @param allowGreen Allow green channel to be written
* @param allowBlue Allow blue channel to be written
* @param allowAlpha Allow alpha channel to be written
* *
* Set to @cpp false @ce to disallow writing to given color channel. * Set to @cpp false @ce to disallow writing to given color channel.
* Initial values are all @cpp true @ce. * Initial values are all @cpp true @ce.
* @see @ref setDepthMask(), @ref setStencilMask(), * @see @ref setDepthMask(), @ref setStencilMask(),
* @fn_gl_keyword{ColorMask} * @fn_gl_keyword{ColorMask}
* @todo Masking only given draw buffer
*/ */
static void setColorMask(GLboolean allowRed, GLboolean allowGreen, GLboolean allowBlue, GLboolean allowAlpha); static void setColorMask(GLboolean allowRed, GLboolean allowGreen, GLboolean allowBlue, GLboolean allowAlpha);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Mask color writes for given draw buffer
* @param drawBuffer Draw buffer index
* @param allowRed Allow red channel to be written
* @param allowGreen Allow green channel to be written
* @param allowBlue Allow blue channel to be written
* @param allowAlpha Allow alpha channel to be written
* @m_since_latest
*
* @see @ref GL-Framebuffer-usage-multiple-outputs,
* @fn_gl2_keyword{ColorMaski,ColorMask}
* @requires_gl30 Extension @gl_extension{EXT,draw_buffers2}
* @requires_gles32 Extension @gl_extension{EXT,draw_buffers_indexed}
* @requires_webgl_extension WebGL 2.0 and extension
* @webgl_extension{EXT,draw_buffers_indexed}
*/
static void setColorMask(UnsignedInt drawBuffer, GLboolean allowRed, GLboolean allowGreen, GLboolean allowBlue, GLboolean allowAlpha);
#endif
/** /**
* @brief Mask depth writes * @brief Mask depth writes
* *
@ -1200,6 +1279,7 @@ class MAGNUM_GL_EXPORT Renderer {
/** /**
* @brief Set blend equation * @brief Set blend equation
* @param equation Blend equation
* *
* How to combine source color (pixel value) with destination color * How to combine source color (pixel value) with destination color
* (framebuffer). Initial value is @ref BlendEquation::Add. * (framebuffer). Initial value is @ref BlendEquation::Add.
@ -1209,8 +1289,27 @@ class MAGNUM_GL_EXPORT Renderer {
*/ */
static void setBlendEquation(BlendEquation equation); static void setBlendEquation(BlendEquation equation);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Set blend equation for given draw buffer
* @param drawBuffer Draw buffer index
* @param equation Blend equation
* @m_since_latest
*
* @see @ref GL-Framebuffer-usage-multiple-outputs,
* @fn_gl2_keyword{BlendEquationi,BlendEquation}
* @requires_gl40 Extension @gl_extension{ARB,draw_buffers_blend}
* @requires_gles32 Extension @gl_extension{EXT,draw_buffers_indexed}
* @requires_webgl_extension WebGL 2.0 and extension
* @webgl_extension{EXT,draw_buffers_indexed}
*/
static void setBlendEquation(UnsignedInt drawBuffer, BlendEquation equation);
#endif
/** /**
* @brief Set blend equation separately for RGB and alpha components * @brief Set blend equation separately for RGB and alpha components
* @param rgb Blend equation for RGB components
* @param alpha Blend equation for the alpha component
* *
* See @ref setBlendEquation(BlendEquation) for more information. * See @ref setBlendEquation(BlendEquation) for more information.
* @see @ref Feature::Blending, @ref setBlendFunction(), * @see @ref Feature::Blending, @ref setBlendFunction(),
@ -1218,6 +1317,24 @@ class MAGNUM_GL_EXPORT Renderer {
*/ */
static void setBlendEquation(BlendEquation rgb, BlendEquation alpha); static void setBlendEquation(BlendEquation rgb, BlendEquation alpha);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Set blend equation for given draw buffer
* @param drawBuffer Draw buffer index
* @param rgb Blend equation for RGB components
* @param alpha Blend equation for the alpha component
* @m_since_latest
*
* @see @ref GL-Framebuffer-usage-multiple-outputs,
* @fn_gl2_keyword{BlendEquationSeparatei,BlendEquationSeparate}
* @requires_gl40 Extension @gl_extension{ARB,draw_buffers_blend}
* @requires_gles32 Extension @gl_extension{EXT,draw_buffers_indexed}
* @requires_webgl_extension WebGL 2.0 and extension
* @webgl_extension{EXT,draw_buffers_indexed}
*/
static void setBlendEquation(UnsignedInt drawBuffer, BlendEquation rgb, BlendEquation alpha);
#endif
/** /**
* @brief Set blend function * @brief Set blend function
* @param source How the source blending factor is computed * @param source How the source blending factor is computed
@ -1233,6 +1350,28 @@ class MAGNUM_GL_EXPORT Renderer {
*/ */
static void setBlendFunction(BlendFunction source, BlendFunction destination); static void setBlendFunction(BlendFunction source, BlendFunction destination);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Set blend function for given draw buffer
* @param drawBuffer Draw buffer index
* @param source How the source blending factor is computed
* from pixel value
* @param destination How the destination blending factor is
* computed from framebuffer
* @m_since_latest
*
* See @ref setBlendFunction(BlendFunction, BlendFunction) for more
* information.
* @see @ref GL-Framebuffer-usage-multiple-outputs,
* @fn_gl2_keyword{BlendFunci,BlendFunc}
* @requires_gl40 Extension @gl_extension{ARB,draw_buffers_blend}
* @requires_gles32 Extension @gl_extension{EXT,draw_buffers_indexed}
* @requires_webgl_extension WebGL 2.0 and extension
* @webgl_extension{EXT,draw_buffers_indexed}
*/
static void setBlendFunction(UnsignedInt drawBuffer, BlendFunction source, BlendFunction destination);
#endif
/** /**
* @brief Set blend function separately for RGB and alpha components * @brief Set blend function separately for RGB and alpha components
* *
@ -1243,6 +1382,30 @@ class MAGNUM_GL_EXPORT Renderer {
*/ */
static void setBlendFunction(BlendFunction sourceRgb, BlendFunction destinationRgb, BlendFunction sourceAlpha, BlendFunction destinationAlpha); static void setBlendFunction(BlendFunction sourceRgb, BlendFunction destinationRgb, BlendFunction sourceAlpha, BlendFunction destinationAlpha);
/**
* @brief Set blend function separately for RGB and alpha components for given draw buffer
* @param drawBuffer Draw buffer index
* @param sourceRgb How the source blending factor is computed
* from pixel value for RGB components
* @param sourceAlpha How the source blending factor is computed
* from pixel value for the alpha component
* @param destinationRgb How the destination blending factor is
* computed from framebuffer for RGB components
* @param destinationAlpha How the destination blending factor is
* computed from framebuffer for the alpha component
* @m_since_latest
*
* See @ref setBlendFunction(BlendFunction, BlendFunction) for more
* information.
* @see @ref GL-Framebuffer-usage-multiple-outputs,
* @fn_gl2_keyword{BlendFuncSeparatei,BlendFuncSeparate}
* @requires_gl40 Extension @gl_extension{ARB,draw_buffers_blend}
* @requires_gles32 Extension @gl_extension{EXT,draw_buffers_indexed}
* @requires_webgl_extension WebGL 2.0 and extension
* @webgl_extension{EXT,draw_buffers_indexed}
*/
static void setBlendFunction(UnsignedInt drawBuffer, BlendFunction sourceRgb, BlendFunction destinationRgb, BlendFunction sourceAlpha, BlendFunction destinationAlpha);
/** /**
* @brief Set blend color * @brief Set blend color
* *

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

@ -32,6 +32,7 @@
#include "Magnum/DebugTools/CompareImage.h" #include "Magnum/DebugTools/CompareImage.h"
#include "Magnum/GL/AbstractShaderProgram.h" #include "Magnum/GL/AbstractShaderProgram.h"
#include "Magnum/GL/Context.h" #include "Magnum/GL/Context.h"
#include "Magnum/GL/Extensions.h"
#include "Magnum/GL/Framebuffer.h" #include "Magnum/GL/Framebuffer.h"
#include "Magnum/GL/Mesh.h" #include "Magnum/GL/Mesh.h"
#include "Magnum/GL/OpenGLTester.h" #include "Magnum/GL/OpenGLTester.h"
@ -54,6 +55,10 @@ struct RendererGLTest: OpenGLTester {
void maxLineWidth(); void maxLineWidth();
void pointCoord(); void pointCoord();
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void drawBuffersIndexed();
void drawBuffersBlend();
#endif
private: private:
PluginManager::Manager<Trade::AbstractImporter> _manager{"nonexistent"}; PluginManager::Manager<Trade::AbstractImporter> _manager{"nonexistent"};
@ -67,7 +72,12 @@ using namespace Math::Literals;
RendererGLTest::RendererGLTest() { RendererGLTest::RendererGLTest() {
addTests({&RendererGLTest::maxLineWidth, addTests({&RendererGLTest::maxLineWidth,
&RendererGLTest::pointCoord}); &RendererGLTest::pointCoord,
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
&RendererGLTest::drawBuffersIndexed,
&RendererGLTest::drawBuffersBlend
#endif
});
/* Load the plugins directly from the build tree. Otherwise they're either /* Load the plugins directly from the build tree. Otherwise they're either
static and already loaded or not present in the build tree */ static and already loaded or not present in the build tree */
@ -220,6 +230,43 @@ void RendererGLTest::pointCoord() {
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold})); (DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold}));
} }
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void RendererGLTest::drawBuffersIndexed() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::EXT::draw_buffers2>())
CORRADE_SKIP(Extensions::EXT::draw_buffers2::string() + std::string(" is not available."));
#else
if(!Context::current().isExtensionSupported<Extensions::EXT::draw_buffers_indexed>())
CORRADE_SKIP(Extensions::EXT::draw_buffers_indexed::string() + std::string(" is not available."));
#endif
/* Call the draw-buffer dependent functions, only expect that no GL error
is emitted to ensure we didn't mess up argument order or something */
Renderer::enable(Renderer::Feature::Blending, 1);
Renderer::disable(Renderer::Feature::Blending, 1);
Renderer::setColorMask(1, true, false, true, false);
MAGNUM_VERIFY_NO_GL_ERROR();
}
void RendererGLTest::drawBuffersBlend() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::ARB::draw_buffers_blend>())
CORRADE_SKIP(Extensions::ARB::draw_buffers_blend::string() + std::string(" is not available."));
#else
if(!Context::current().isExtensionSupported<Extensions::EXT::draw_buffers_indexed>())
CORRADE_SKIP(Extensions::EXT::draw_buffers_indexed::string() + std::string(" is not available."));
#endif
/* Call the draw-buffer dependent functions, only expect that no GL error
is emitted to ensure we didn't mess up argument order or something */
Renderer::setBlendFunction(1, Renderer::BlendFunction::One, Renderer::BlendFunction::OneMinusSourceAlpha);
Renderer::setBlendFunction(1, Renderer::BlendFunction::One, Renderer::BlendFunction::Zero, Renderer::BlendFunction::OneMinusSourceAlpha, Renderer::BlendFunction::SourceAlpha);
Renderer::setBlendEquation(1, Renderer::BlendEquation::Subtract);
Renderer::setBlendEquation(1, Renderer::BlendEquation::Add, Renderer::BlendEquation::Subtract);
MAGNUM_VERIFY_NO_GL_ERROR();
}
#endif
}}}} }}}}
CORRADE_TEST_MAIN(Magnum::GL::Test::RendererGLTest) CORRADE_TEST_MAIN(Magnum::GL::Test::RendererGLTest)

1
src/MagnumExternal/OpenGL/GLES3/Emscripten/extensions.txt vendored

@ -10,6 +10,7 @@ extension EXT_disjoint_timer_query optional
extension EXT_color_buffer_float optional extension EXT_color_buffer_float optional
extension EXT_texture_compression_rgtc optional extension EXT_texture_compression_rgtc optional
extension EXT_texture_compression_bptc optional extension EXT_texture_compression_bptc optional
extension EXT_draw_buffers_indexed optional
# WebGL has only OVR_multiview2, but we need the definitions from OVR_multiview # WebGL has only OVR_multiview2, but we need the definitions from OVR_multiview
extension OVR_multiview optional extension OVR_multiview optional
extension OVR_multiview2 optional extension OVR_multiview2 optional

42
src/MagnumExternal/OpenGL/GLES3/flextGLEmscripten.h vendored

@ -745,6 +745,37 @@ typedef struct __GLsync *GLsync;
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F
/* GL_EXT_draw_buffers_indexed */
#define GL_BLEND_EQUATION_RGB 0x8009
#define GL_BLEND_EQUATION_ALPHA 0x883D
#define GL_BLEND_SRC_RGB 0x80C9
#define GL_BLEND_SRC_ALPHA 0x80CB
#define GL_BLEND_DST_RGB 0x80C8
#define GL_BLEND_DST_ALPHA 0x80CA
#define GL_COLOR_WRITEMASK 0x0C23
#define GL_BLEND 0x0BE2
#define GL_FUNC_ADD 0x8006
#define GL_FUNC_SUBTRACT 0x800A
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
#define GL_MIN 0x8007
#define GL_MAX 0x8008
#define GL_ZERO 0
#define GL_ONE 1
#define GL_SRC_COLOR 0x0300
#define GL_ONE_MINUS_SRC_COLOR 0x0301
#define GL_DST_COLOR 0x0306
#define GL_ONE_MINUS_DST_COLOR 0x0307
#define GL_SRC_ALPHA 0x0302
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_DST_ALPHA 0x0304
#define GL_ONE_MINUS_DST_ALPHA 0x0305
#define GL_CONSTANT_COLOR 0x8001
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
#define GL_CONSTANT_ALPHA 0x8003
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
#define GL_SRC_ALPHA_SATURATE 0x0308
/* GL_OVR_multiview */ /* GL_OVR_multiview */
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630
@ -1073,6 +1104,17 @@ GLAPI void glGetQueryivEXT(GLenum, GLenum, GLint *);
GLAPI GLboolean glIsQueryEXT(GLuint); GLAPI GLboolean glIsQueryEXT(GLuint);
GLAPI void glQueryCounterEXT(GLuint, GLenum); GLAPI void glQueryCounterEXT(GLuint, GLenum);
/* GL_EXT_draw_buffers_indexed */
GLAPI void glBlendEquationSeparateiEXT(GLuint, GLenum, GLenum);
GLAPI void glBlendEquationiEXT(GLuint, GLenum);
GLAPI void glBlendFuncSeparateiEXT(GLuint, GLenum, GLenum, GLenum, GLenum);
GLAPI void glBlendFunciEXT(GLuint, GLenum, GLenum);
GLAPI void glColorMaskiEXT(GLuint, GLboolean, GLboolean, GLboolean, GLboolean);
GLAPI void glDisableiEXT(GLenum, GLuint);
GLAPI void glEnableiEXT(GLenum, GLuint);
GLAPI GLboolean glIsEnablediEXT(GLenum, GLuint);
/* GL_OVR_multiview */ /* GL_OVR_multiview */
GLAPI void glFramebufferTextureMultiviewOVR(GLenum, GLenum, GLuint, GLint, GLint, GLsizei); GLAPI void glFramebufferTextureMultiviewOVR(GLenum, GLenum, GLuint, GLint, GLint, GLsizei);

Loading…
Cancel
Save