Browse Source

Merge branch 'mosra:master' into android-multitouch

pull/527/head
nodoteve 5 years ago committed by GitHub
parent
commit
4cfa2846ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      CMakeLists.txt
  2. 2
      COPYING
  3. 2
      doc/building.dox
  4. 2
      doc/changelog-old.dox
  5. 86
      doc/changelog.dox
  6. 4
      doc/coding-style.dox
  7. 6
      doc/credits.dox
  8. 2
      doc/custom-buildsystems.dox
  9. 2
      doc/debug-tools.dox
  10. 12
      doc/developers.dox
  11. 23
      doc/file-formats.dox
  12. 2
      doc/generated/easings.cpp
  13. 4
      doc/platforms-android.dox
  14. 2
      doc/platforms-html5.dox
  15. 2
      doc/platforms-windows.dox
  16. 273
      doc/shaders.dox
  17. 2
      doc/snippets/CMakeLists.txt
  18. 33
      doc/snippets/MagnumGL.cpp
  19. 16
      doc/snippets/MagnumMath.cpp
  20. 451
      doc/snippets/MagnumShaders-gl.cpp
  21. 2
      doc/transformations.dox
  22. 2
      modules/FindCorrade.cmake
  23. 2
      modules/FindMagnum.cmake
  24. 21
      package/archlinux/PKGBUILD
  25. 21
      package/archlinux/PKGBUILD-coverage
  26. 21
      package/archlinux/PKGBUILD-release
  27. 2
      package/ci/appveyor-desktop-gles.bat
  28. 2
      package/ci/appveyor-desktop-mingw.bat
  29. 2
      package/ci/appveyor-desktop.bat
  30. 5
      package/ci/appveyor-lcov.sh
  31. 16
      package/ci/circleci.yml
  32. 2
      package/ci/emscripten.sh
  33. 2
      package/ci/travis-android-gles.sh
  34. 2
      package/ci/travis-ios-simulator.sh
  35. 6
      package/ci/unix-desktop-gles.sh
  36. 2
      package/ci/unix-desktop.sh
  37. 2
      src/Magnum/Animation/Test/PlayerTest.cpp
  38. 20
      src/Magnum/Animation/Test/TrackTest.cpp
  39. 4
      src/Magnum/Animation/Track.h
  40. 15
      src/Magnum/Array.h
  41. 2
      src/Magnum/Audio/Renderer.h
  42. 38
      src/Magnum/DebugTools/Test/CMakeLists.txt
  43. 40
      src/Magnum/GL/AbstractShaderProgram.cpp
  44. 49
      src/Magnum/GL/AbstractShaderProgram.h
  45. 2
      src/Magnum/GL/Attribute.h
  46. 2
      src/Magnum/GL/Buffer.h
  47. 2
      src/Magnum/GL/CMakeLists.txt
  48. 8
      src/Magnum/GL/Context.cpp
  49. 2
      src/Magnum/GL/Extensions.h
  50. 2
      src/Magnum/GL/Implementation/driverSpecific.cpp
  51. 4
      src/Magnum/GL/Mesh.h
  52. 4
      src/Magnum/GL/MeshView.cpp
  53. 2
      src/Magnum/GL/RenderbufferFormat.h
  54. 2
      src/Magnum/GL/Renderer.h
  55. 8
      src/Magnum/GL/Test/CMakeLists.txt
  56. 2
      src/Magnum/GL/Test/ContextTest.cpp
  57. 10
      src/Magnum/Implementation/converterUtilities.h
  58. 6
      src/Magnum/Magnum.h
  59. 4
      src/Magnum/Math/DualComplex.h
  60. 4
      src/Magnum/MeshTools/RemoveDuplicates.cpp
  61. 8
      src/Magnum/MeshTools/Test/CMakeLists.txt
  62. 2
      src/Magnum/MeshTools/Tipsify.cpp
  63. 2
      src/Magnum/MeshTools/Tipsify.h
  64. 4
      src/Magnum/MeshTools/sceneconverter.cpp
  65. 4
      src/Magnum/Platform/AndroidApplication.h
  66. 4
      src/Magnum/Platform/EmscriptenApplication.cpp
  67. 2
      src/Magnum/Platform/EmscriptenApplication.h
  68. 2
      src/Magnum/Platform/GlfwApplication.cpp
  69. 6
      src/Magnum/Platform/GlfwApplication.h
  70. 4
      src/Magnum/Platform/Sdl2Application.cpp
  71. 10
      src/Magnum/Platform/Sdl2Application.h
  72. 4
      src/Magnum/Platform/WindowlessCglApplication.cpp
  73. 4
      src/Magnum/Platform/WindowlessCglApplication.h
  74. 4
      src/Magnum/Platform/WindowlessEglApplication.cpp
  75. 4
      src/Magnum/Platform/WindowlessEglApplication.h
  76. 4
      src/Magnum/Platform/WindowlessGlxApplication.cpp
  77. 4
      src/Magnum/Platform/WindowlessGlxApplication.h
  78. 4
      src/Magnum/Platform/WindowlessIosApplication.h
  79. 4
      src/Magnum/Platform/WindowlessIosApplication.mm
  80. 4
      src/Magnum/Platform/WindowlessWglApplication.cpp
  81. 4
      src/Magnum/Platform/WindowlessWglApplication.h
  82. 4
      src/Magnum/Platform/WindowlessWindowsEglApplication.cpp
  83. 4
      src/Magnum/Platform/WindowlessWindowsEglApplication.h
  84. 4
      src/Magnum/Primitives/Test/GradientTest.cpp
  85. 2
      src/Magnum/ResourceManager.h
  86. 10
      src/Magnum/SceneGraph/Object.hpp
  87. 2
      src/Magnum/SceneGraph/Test/AnimableTest.cpp
  88. 2
      src/Magnum/ShaderTools/shaderconverter.cpp
  89. 70
      src/Magnum/Shaders/AbstractVector.h
  90. 43
      src/Magnum/Shaders/AbstractVectorGL.cpp
  91. 134
      src/Magnum/Shaders/AbstractVectorGL.h
  92. 20
      src/Magnum/Shaders/CMakeLists.txt
  93. 74
      src/Magnum/Shaders/DistanceFieldVector.frag
  94. 284
      src/Magnum/Shaders/DistanceFieldVector.h
  95. 259
      src/Magnum/Shaders/DistanceFieldVectorGL.cpp
  96. 400
      src/Magnum/Shaders/DistanceFieldVectorGL.h
  97. 96
      src/Magnum/Shaders/Flat.frag
  98. 237
      src/Magnum/Shaders/Flat.h
  99. 137
      src/Magnum/Shaders/Flat.vert
  100. 259
      src/Magnum/Shaders/FlatGL.cpp
  101. Some files were not shown because too many files have changed in this diff Show More

10
CMakeLists.txt

@ -30,11 +30,19 @@ if(HUNTER_ENABLED)
include(${CMAKE_CURRENT_LIST_DIR}/package/hunter/HunterInit.cmake)
endif()
# Don't restrict INTERPROCEDURAL_OPTIMIZATION only for icc on Linux
if(POLICY CMP0069)
cmake_policy(SET CMP0069 NEW)
endif()
# If CMAKE_AUTOMOC is set, all uses of corrade_add_resource() would otherwise
# complain on 3.10 that AUTOMOC is not processing GENERATED files
if(POLICY CMP0071)
cmake_policy(SET CMP0071 NEW)
endif()
# Superprojects can use just set(WITH_BLAH ON) without FORCE CACHE on 3.13+
if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
endif()
project(Magnum CXX)
@ -394,7 +402,7 @@ set(MAGNUM_PLUGINS_AUDIOIMPORTER_DEBUG_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBU
set(MAGNUM_PLUGINS_AUDIOIMPORTER_RELEASE_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_BINARY_INSTALL_DIR}/audioimporters)
set(MAGNUM_PLUGINS_AUDIOIMPORTER_RELEASE_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_LIBRARY_INSTALL_DIR}/audioimporters)
# Plugin dirs based on wheter we are in debug or release build, needed by some
# Plugin dirs based on whether we are in debug or release build, needed by some
# command-line tools
if(CORRADE_TARGET_WINDOWS)
set(MAGNUM_PLUGINS_DEBUG_DIR_INIT ${CMAKE_INSTALL_PREFIX}/${MAGNUM_PLUGINS_DEBUG_BINARY_INSTALL_DIR})

2
COPYING

@ -1,5 +1,5 @@
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020 Vladimír Vondruš <mosra@centrum.cz> and contributors
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> and contributors
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

2
doc/building.dox

@ -214,7 +214,7 @@ There are also ArchLinux packages for @ref building-plugins-packages-arch "Magnu
@subsection building-packages-msys MSYS2 packages
[MSYS2](https://www.msys2.org/) package for the latest stable release is
mantained in the official repos. Installing is as simple as this:
maintained in the official repos. Installing is as simple as this:
@code{.sh}
pacman -S mingw-w64-x86_64-magnum # or mingw-w64-i686-magnum

2
doc/changelog-old.dox

@ -1470,7 +1470,7 @@ for a high-level overview.
- Support for @gl_extension{ARB,vertex_type_10f_11f_11f_rev} in
@cpp AbstractShaderProgram::Attribute::DataType @ce
- New variants of @cpp Shader::compile() @ce and @cpp AbstractShaderProgram::link() @ce,
allowing the driver to perform paralell compilation in multiple threads.
allowing the driver to perform parallel compilation in multiple threads.
- Added @cpp *Texture::maxSize() @ce queries
- @ref MeshTools::compile() for automagic creation of 2D and 3D meshes from
imported data

86
doc/changelog.dox

@ -147,6 +147,12 @@ See also:
@subsubsection changelog-latest-new-shaders Shaders library
- All builtin shaders now have opt-in support for uniform buffers on desktop,
OpenGL ES 3.0+ and WebGL 2.0, including multi-draw functionality for
massive driver overhead reduction. The @ref shaders overview page was
updated with an introduction the new features.
- @ref Shaders::FlatGL and @ref Shaders::PhongGL now support texture arrays,
available also in multi-draw and instanced scenarios
- Added @ref Shaders::PhongGL::setNormalTextureScale(), consuming the
recently added @ref Trade::MaterialAttribute::NormalTextureScale material
attribute
@ -155,6 +161,9 @@ See also:
@ref Trade::LightData
- Added @ref Shaders::PhongGL::setLightSpecularColors() for better control
over specular highlights
- Added @ref Shaders::PhongGL::Flag::NoSpecular as a significantly faster
alternative to setting specular color to @cpp 0x00000000_rgbaf @ce in case
specular highlights are not desired
@subsubsection changelog-latest-new-shadertools ShaderTools library
@ -223,6 +232,15 @@ See also:
@subsubsection changelog-latest-changes-gl GL library
- @ref GL::AbstractShaderProgram::draw(),
@relativeref{GL::AbstractShaderProgram,drawTransformFeedback()} and
@relativeref{GL::AbstractShaderProgram,dispatchCompute()} APIs now return
a reference to self and all subclasses in @ref Shaders return a subclass
reference from these. The functions used to @cpp void @ce as that made more
sense in the classic workflow where a large set of uniforms had to be set
prior to every draw, however with the new multidraw workflows that's no
longer the case and the inability to chain draw calls proved to be
annoying.
- The @ref GL::Context class got significantly optimized in terms of compile
time, header size and runtime as well, significantly reducing the amount of
allocations done at startup.
@ -317,7 +335,24 @@ See also:
@subsubsection changelog-latest-changes-trade Trade library
- Recognizing TIFF file header magic in @ref Trade::AnyImageImporter "AnyImageImporter"
- @ref Trade::AbstractImageConverter::doConvertToFile() and
@ref Trade::AbstractSceneConverter::doConvertToFile() are now
@cpp protected @ce instead of @cpp private @ce to allow calling them from
plugin implementations and reuse the provided fallback to
@relativeref{Trade::AbstractImageConverter,doConvertToData()}, for example
when the implementation only neeeds to do a format detection based on file
extension
- Recognizing BMP and TIFF file header magic in @relativeref{Trade,AnyImageImporter}
- @ref Audio::AnyImporter "AnyAudioImporter",
@relativeref{Trade,AnyImageImporter}, @relativeref{Trade,AnyImageConverter},
@relativeref{Trade,AnySceneImporter}, @relativeref{Trade,AnySceneConverter}
and @ref ShaderTools::AnyConverter "AnyShaderConverter" are now capable of
propagating configuration options to the concrete plugin, which is useful
mainly when using @ref magnum-imageconverter and other utilities as you can
now specify just the `-i` / `-c` options without having to specify which
plugin to apply the option to with `-I` / `-C`. For better usability, the
plugins also warn if the user specifies and option that is not present in
the target implementation.
- Added @ref Trade::PhongMaterialData::hasCommonTextureTransformation(),
@ref Trade::PhongMaterialData::ambientTextureMatrix(),
@ref Trade::PhongMaterialData::diffuseTextureMatrix(),
@ -401,6 +436,9 @@ See also:
- For meshes with multiple sets of vertex attributes (such as texture
coordinates), @ref MeshTools::compile() should be using only the first set
but it wasn't.
- @ref Shaders::MeshVisualizerGL3D "Shaders::MeshVisualizerGL*D" shader
compilation failed with missing @glsl gl_PrimitiveID @ce due to GLSL 3.20
not being properly used for the @glsl #version @ce directive
- @ref Shaders::PhongGL was normalizing light direction in vertex shader,
causing the fragment-interpolated direction being incorrect with visible
artifacts on long polygons under low light angle
@ -444,7 +482,10 @@ See also:
It was also commonly confused with @relativeref{Corrade,Containers::Array},
which is a type with totally different semantics. To avoid breaking
existing code, conversion from and to @ref Math::Vector is now provided and
this type is included in all places where it was originally used.
this type is included in all places where it was originally used. For
custom uses, the @relativeref{Corrade,Containers::Array1}, @relativeref{Corrade,Containers::Array2} or
@relativeref{Corrade,Containers::Array3} types provide a suitable
alternative as well.
- Markup styling for Emscripten application was switched to prefer using
CSS classes instead of the @cb{.css} #container @ce, @cb{.css} #sizer @ce,
@cb{.css} #expander @ce, @cb{.css} #listener @ce, @cb{.css} #canvas @ce,
@ -459,19 +500,17 @@ See also:
@ref DebugTools::FrameProfilerGL. The new name plays better with IDE
autocompletion and makes the GL-specific class appear next to the
API-independent base in alphabetically sorted lists.
- @cpp Shaders::AbstractVector @ce, @cpp Shaders::DistanceFieldVector @ce,
@cpp Shaders::Flat @ce, @cpp Shaders::Generic @ce,
@cpp Shaders::MeshVisualizer2D @ce, @cpp Shaders::MeshVisualizer3D @ce,
@cpp Shaders::Phong @ce, @cpp Shaders::Vector @ce,
@cpp Shaders::VertexColor @ce and related 2D/3D typedefs are deprecated in
favor of @ref Shaders::AbstractVectorGL,
@ref Shaders::DistanceFieldVectorGL, @ref Shaders::FlatGL,
@ref Shaders::GenericGL, @ref Shaders::MeshVisualizerGL2D,
@ref Shaders::MeshVisualizerGL3D, @ref Shaders::PhongGL,
@ref Shaders::VectorGL, @ref Shaders::VertexColorGL and correspondingly
renamed typedefs to make room for Vulkan shaders and functionality shared
between OpenGL and Vulkan implementation such as uniform buffer layout
definitions
- @cpp Shaders::DistanceFieldVector @ce, @cpp Shaders::Flat @ce,
@cpp Shaders::Generic @ce, @cpp Shaders::MeshVisualizer2D @ce,
@cpp Shaders::MeshVisualizer3D @ce, @cpp Shaders::Phong @ce,
@cpp Shaders::Vector @ce, @cpp Shaders::VertexColor @ce and related 2D/3D
typedefs are deprecated in favor of @ref Shaders::DistanceFieldVectorGL,
@ref Shaders::FlatGL, @ref Shaders::GenericGL,
@ref Shaders::MeshVisualizerGL2D, @ref Shaders::MeshVisualizerGL3D,
@ref Shaders::PhongGL, @ref Shaders::VectorGL, @ref Shaders::VertexColorGL
and correspondingly renamed typedefs to make room for Vulkan shaders and
functionality shared between OpenGL and Vulkan implementation such as
uniform buffer layout definitions
- @ref Shaders::PhongGL::setLightPositions() and
@ref Shaders::PhongGL::setLightPosition() taking three-component vectors
are deprecated in favor of variants taking four-component vectors, where the
@ -655,6 +694,10 @@ See also:
isn't available anymore. For backwards compatibility, light positions
supplied through three-component vectors are now represented as directional
lights, which is close, but not exactly the same as before.
- The @cpp Shaders::AbstractVector @ce base class for @ref Shaders::VectorGL
and @ref Shaders::DistanceFieldVectorGL is removed, as its benefits were
rather questionable --- on the contrary, it made subclass implementation
more verbose and less clear
- Mutable access to @ref Trade::PhongMaterialData color and texture
information, deprecated in 2020.06, is now removed, as it's impossible to
implement through the redesigned @ref Trade::MaterialData APIs. However
@ -684,8 +727,9 @@ See also:
- Added a note about MinGW GCC and Clang ABI incompatibility to
@ref platforms-windows "Windows platform docs" (see [mosra/magnum#227](https://github.com/mosra/magnum/issues/227) and
[mosra/magnum#439](https://github.com/mosra/magnum/issues/439))
- Various documentation fixes (see [mosra/magnum#492](https://github.com/mosra/magnum/issues/492))
- @ref Corrade::Utility::Debug and friends were always brought to the )
- Various documentation fixes (see [mosra/magnum#492](https://github.com/mosra/magnum/issues/492),
[mosra/magnum#521](https://github.com/mosra/magnum/pull/521))
- @ref Corrade::Utility::Debug and friends were always brought to the
@ref Magnum namespace via a @cpp using @ce directive, but this was never
reflected in the docs and thus hidden from users. Now it's shown in the
docs as a set of @ref Debug etc typedefs instead, to make them more
@ -770,7 +814,7 @@ Released 2020-06-27, tagged as
@cpp "intel-windows-crazy-broken-vao-dsa" @ce workarounds for Intel
Windows drivers, disabling @gl_extension{ARB,direct_state_access} code
paths in everything releated to buffers and meshes. There are several
issues occuring only in heavier apps, impossible to track down and
issues occurring only in heavier apps, impossible to track down and
reproduce in a controlled environment. These two replace the previous
@cpp "intel-windows-buggy-dsa-bufferdata-for-index-buffers" @ce workaround
that attempted to fix this by doing an explicit buffer binding in some
@ -1085,7 +1129,7 @@ Released 2020-06-27, tagged as
[mosra/magnum#401](https://github.com/mosra/magnum/pull/401))
- HiDPI capability checking on macOS and iOS got fixed to behave correctly
when the capability is explicitly set to @cb{.xml} <false/> @ce in the
`Info.plist` file and additionally, unless overriden, it's assumed to be
`Info.plist` file and additionally, unless overridden, it's assumed to be
enabled by default on macOS 10.15+ and iOS 13+. Applications running on
these platforms no longer need to supply a custom `Info.plist` in order to
enable HiDPI. See @ref platforms-macos-hidpi for more information.
@ -1402,7 +1446,7 @@ Released 2020-06-27, tagged as
was deprecated in 2019.10 is now removed. Usually a deprecated feature is
kept for at least a year before removal, but in this case it was severely
limiting multithreaded applications and removing it was necessary.
- Locations of generic shader attributes was changed in order to accomodate
- Locations of generic shader attributes was changed in order to accommodate
for new attributes and use cases. This may break custom shaders if these
rely on generic attribute definitions or are used together with
@ref MeshTools::compile(). To avoid further breakages you're advised to
@ -1522,7 +1566,7 @@ Released 2019-10-24, tagged as
- @ref DebugTools::CompareImage and @ref DebugTools::CompareImageToFile now
accept also @ref Corrade::Containers::StridedArrayView2D on the left side
of the comparison for added flexibility. See
@ref DebugTools-CompareImage-pixels for more infromation.
@ref DebugTools-CompareImage-pixels for more information.
@subsubsection changelog-2019-10-new-gl GL library

4
doc/coding-style.dox

@ -70,7 +70,7 @@ removing redundant prefixes) is encouraged.
When a namespace has classes which are commonly forward-declared, consider
making a forward declaration header --- it should have the same name as the
namespace itself and contain foward declarations for all classes, enums and
namespace itself and contain forward declarations for all classes, enums and
copies of all meaningful typedefs. See @ref compilation-forward-declarations
for more information.
@ -312,7 +312,7 @@ CORRADE_COMPARE(b, Vector2(1, 0));
CORRADE_VERIFY(!(std::is_convertible<Vector2, Vector2i>::value));
@endcode
If some type should be constructible also from base type (additionaly to copy
If some type should be constructible also from base type (additionally to copy
constructor), don't forget to test that too. The test is also usually needed
only for low-level frequently used types (vectors, matrices) where such error
would do largest harm. Depending on how copy constructor is implemented, you

6
doc/credits.dox

@ -39,7 +39,7 @@ overview the dependencies are color-coded:
no license requirements, such as usage of public APIs like Vulkan or OpenAL
or usage of platform-specific interfaces.
- A @m_class{m-label m-success} **green** label marks licenses that make the
dependency safe to use in a commerical setting without having to release
dependency safe to use in a commercial setting without having to release
your source code, usually requiring you to give attribution.
- A @m_class{m-label m-primary} **light blue** label marks public domain
software. In some countries there's no notion of public domain, in which
@ -81,6 +81,8 @@ Big thanks to everyone involved!
Are the below lists missing your name or something's wrong?
[Let us know!](https://magnum.graphics/contact/)
- **Aaron Gokaslan** ([\@Skylion007](https://github.com/Skylion007)) ---
various minor code modernization, typo fixes
- **[\@abgita](https://github.com/abgita)** --- minor typo fixes
- **Alan Jefferson** ([\@alanjfs](https://github.com/alanjfs)) --- extensive
usability and first-time-use feedback
@ -210,7 +212,7 @@ Are the below lists missing your name or something's wrong?
- **Thibault Jochem** ([\@Tryum](https://github.com/Tryum)) ---
@ref Platform::GlfwApplication improvements
- **Thomas Tissot-Dupont** ([\@dolphineye](https://github.com/dolphineye))
--- OpenGL ES compatiblity improvements
--- OpenGL ES compatibility improvements
- **Travis Watkins** ([\@amaranth](https://github.com/amaranth)) --- support
for windowless applications under macOS
*/

2
doc/custom-buildsystems.dox

@ -84,7 +84,7 @@ more information.
While dynamic plugins work without buildsystem integration, static plugins are
handled automagically with CMake and you need to replicate the magic manually
when using a custom buildsystem. This is just about compiling an additonal
when using a custom buildsystem. This is just about compiling an additional
`*.cpp` file together with your final app, see @ref plugins-static for more
information.

2
doc/debug-tools.dox

@ -46,7 +46,7 @@ of them to any object.
Basic usage involves instancing @ref DebugTools::ResourceManager and keeping it
for the whole lifetime of debug renderers. Next you need some
@ref SceneGraph::DrawableGroup instance. You can use the same group as for the
rest of your scene, but preferrably use dedicated one for debug renderers, so
rest of your scene, but preferably use dedicated one for debug renderers, so
you can easily enable or disable debug rendering.
Next step is to create configuration for your debug renderers and create

12
doc/developers.dox

@ -634,7 +634,7 @@ unless it doesn't affect public API at all.
capabilities on the same platform (DSA / non-DSA is one of them), add
separate code paths:
- new private and `MAGNUM_LOCAL` `thingImplementation*()` functions, each
implementing one code path, preferrably @cpp static @ce
implementing one code path, preferably @cpp static @ce
- a `thingImplementation` (member) function pointer in `src/Magnum/Implementation/SomeState.h`
that gets populated in `src/Magnum/GL/Implementation/SomeState.cpp`
based on extension / version availability
@ -683,7 +683,7 @@ unless it doesn't affect public API at all.
`KnownWorkarounds` array in `src/Magnum/GL/Implementation/driverSpecific.cpp`,
ideally reuse some of the already existing vendor prefixes
2. If the workaround can be tied down to a particular platform / target, add
apropriate @cpp #ifdef @ce around it
appropriate @cpp #ifdef @ce around it
3. Create (or extend) a pair of (member) @cpp private @ce `MAGNUM_LOCAL`
`*Implementation*()` functions in the affected class, `*ImplementationDefault()`
having the optimistic default behavior, the other having the workaround.
@ -706,7 +706,7 @@ unless it doesn't affect public API at all.
@ref opengl-workarounds
Removeing a workaround is simply a matter of searching for its string, removing
all occurences of that string and removing all `*Implementation*()` functions
all occurrences of that string and removing all `*Implementation*()` functions
that were used only if the workaround was in place. No need to deprecate
anything, users explicitly disabling given workaround will only be informed
that such workaround does not exist anymore.
@ -992,7 +992,7 @@ inverse.
replace `... —` with `..., 20XZ —` there as well
4. Copy all `Find*.cmake` modules to dependent projects to update the
copyright year in these as well
5. Update other occurences by hand:
5. Update other occurrences by hand:
- `package/debian/copyright`
- `doc/conf.py`
- All flextGL `*.template` files in `src/external/OpenGL` and
@ -1061,7 +1061,7 @@ inverse.
- add a temporary <tt>\@<b></b>anchor changelog-latest</tt> (and
equivalent in other repos) on top so the links from main page work
properly
8. Convert all occurences of
8. Convert all occurrences of
- <tt>\@m_since_latest_{thing}</tt> to <tt>\@m_since_{thing,20XY,ab}</tt>
- <tt>\@m_since_latest</tt> to <tt>\@m_since{20XY,ab}</tt>
- <tt>\@m_deprecated_since_latest_{thing}</tt> to
@ -1103,7 +1103,7 @@ inverse.
new functionality
- add release annoucement link under the button on front page
21. Publish the release announcement, verify it looks correct
22. Advertise the release announcement, preferrably Monday 5 PM, never Friday
22. Advertise the release announcement, preferably Monday 5 PM, never Friday
or weekends
- come up with some 100-character-long extended title
- Twitter (extended title + url and some hashtags), first dry-run the

23
doc/file-formats.dox

@ -28,16 +28,17 @@ namespace Magnum {
@brief Support tables for widely used image, scene, audio and font formats
@tableofcontents
The @ref Trade::AnyImageImporter "AnyImageImporter",
@ref Trade::AnySceneImporter "AnySceneImporter",
@ref Trade::AnyImageConverter "AnyImageConverter",
@ref Trade::AnySceneConverter "AnySceneConverter" and other `Any*` plugins can
be used for generic handling of any of the recognized formats, they'll proxy
the operation to a concrete plugin implementation. The following tables list
the most widely used formats with alternative plugin implementations and known
caveats for each. When one format is supported by more than one plugin, you
can use @ref Corrade::PluginManager::AbstractManager::setPreferredPlugins() to
@m_footernavigation
The @ref Audio::AnyImporter "AnyAudioImporter",
@relativeref{Trade,AnyImageImporter}, @relativeref{Trade,AnySceneImporter},
@relativeref{Trade,AnyImageConverter}, @relativeref{Trade,AnySceneConverter}
and @ref ShaderTools::AnyConverter "AnyShaderConverter" plugins can be used for
generic handling of any of the recognized formats, they'll proxy the operation
to a concrete plugin implementation. The following tables list the most widely
used formats with alternative plugin implementations and known caveats for
each. When one format is supported by more than one plugin, you can use
@ref Corrade::PluginManager::AbstractManager::setPreferredPlugins() to
prioritize a particular plugin implementation.
See the @ref file-formats-legend section at the bottom of the page for a
@ -610,7 +611,7 @@ mentioning requirements coming from the license:
dependencies, which don't require anything from you in order to use them
and put no restrictions on use
- @m_class{m-label m-success} **green** marks licenses that make the
dependency safe to use in a commerical setting without having to release
dependency safe to use in a commercial setting without having to release
your source code, usually requiring you to give attribution.
- @m_class{m-label m-warning} **yellow** marks licenses that require you to
either dynamically link to the software to be able to use it in a

2
doc/generated/easings.cpp

@ -204,7 +204,7 @@ const Color3 success = 0x3bd267_srgbf;
int main() {
using namespace Animation::Easing;
#define _c(name) Utility::String::lowercase(#name), name
#define _c(name) Utility::String::lowercase(std::string{#name}), name
generate(_c(linear), {},
/* [linear] */
CubicBezier2D{Vector2{0.0f}, Vector2{1.0f/3.0f},

4
doc/platforms-android.dox

@ -250,7 +250,7 @@ endif()
@endcode
On the first run, the macro will attempt to detect SDK location, Android Build
Tools version and Android Platfrom version and it prints them to the output
Tools version and Android Platform version and it prints them to the output
like this:
@code{.shell-session}
@ -1137,7 +1137,7 @@ This for 3.3.0:
@endcode
And probably a dozen other variants, but I am not willing to waste my time any
further by enumerating all possible embarrasing crashes of cursed tools. The
further by enumerating all possible embarrassing crashes of cursed tools. The
oldest Android Gradle plugin version that worked with Gradle 6.6.1 and NDK r19
was 3.6.0, and to change it update the following entry in your `build.gradle`:

2
doc/platforms-html5.dox

@ -379,7 +379,7 @@ using a @cb{.css} padding-bottom @ce style with a percentage equal to inverse
of the ratio for @cb{.css} div#expander @ce --- for example, a 2.35:1 ratio
would be @cb{.html} <div class="mn-expander" style="padding-bottom: 42.553%"> @ce.
Size of the canvas can be also overriden by specifying one of the
Size of the canvas can be also overridden by specifying one of the
@cb{.css} .mn-width-* @ce CSS classes on the
@cb{.html} <div class="mn-container"> @ce:

2
doc/platforms-windows.dox

@ -128,7 +128,7 @@ much as possible:
@section platform-windows-icon Executable icon
In order to supply an icon for the executable, make an `*.ico` file
(preferrably out of multiple different sizes) and create a `*.rc` file
(preferably out of multiple different sizes) and create a `*.rc` file
referencing it. The first argument can be anything (it can be used for
retrieving the icon later at runtime via Windows APIs), Windows always pick the
first icon in the `*.rc` file for the executable.

273
doc/shaders.dox

@ -34,8 +34,7 @@ namespace Magnum {
Magnum contains a set of general-purpose shaders for easy prototyping, UI
rendering and data visualization/debugging in both 2D and 3D scenes. The
following shaders are available, see documentation of each class for sample
output and example setup:
following shaders are available:
- @ref Shaders::FlatGL "Shaders::FlatGL*D" --- flat shading using single
color or texture
@ -48,32 +47,245 @@ output and example setup:
- @ref Shaders::MeshVisualizerGL2D / @ref Shaders::MeshVisualizerGL3D ---
wireframe visualization
All the builtin shaders can be used on unextended OpenGL 2.1 and OpenGL ES 2.0
/ WebGL 1.0, but they try to use the most recent technology available to have
them as efficient as possible on every configuration.
The essential functionality of builtin shaders can be used even on unextended
OpenGL 2.1 and OpenGL ES 2.0 / WebGL 1.0, but the code will try to use the most
recent technology available to have them as efficient as possible on every
configuration. Some functionality, such as uniform buffers, texture arrays or
object ID rendering, requires newer versions or extensions, as noted in
documentation of a particular feature.
@section shaders-usage Usage
Shader usage is divided into two parts: configuring vertex attributes in the
mesh and configuring the shader itself.
Shader usage is divided into two parts: describing vertex attributes in the
mesh and setting up the shader itself.
Each shader expects some set of vertex attributes, thus when adding vertex
Each shader expects some set of vertex attributes, thus when adding a vertex
buffer into the mesh, you need to specify which shader attributes are on which
position in the buffer. See @ref GL::Mesh::addVertexBuffer() for details and
usage examples. Example mesh configuration for @ref Shaders::PhongGL shader:
usage examples. Example mesh configuration for the @ref Shaders::PhongGL
shader:
@snippet MagnumShaders-gl.cpp shaders-setup
Each shader then has its own set of configuration functions. Some configuration
is static, specified commonly as flags in constructor, directly affecting
compiled shader code. Other configuration is specified through uniforms and
various binding points, commonly exposed through various setters. All shader
uniforms have a reasonable defaults so you are able to see at least something
when using the shader directly without any further configuration, but in most
cases you may want to specify at least the transformation/projection matrices.
Example configuration and rendering using @link Shaders::PhongGL @endlink:
various binding points, commonly exposed through various setters. For uniforms
there's two different workflows --- a classical one, where uniforms have
immediate setters, and a uniform buffer workflow, where the uniform parameters
are saved to a structure and then uploaded to a GPU buffer. Let's compare both
approaches:
@snippet MagnumShaders-gl.cpp shaders-rendering
@subsection shaders-usage-classic Using classic uniforms
The most straightforward and portable way, working even on old OpenGL ES 2.0
and WebGL 1.0 platforms, is using classic uniform setters. All shader uniforms
have a reasonable defaults so you are able to see at least something when using
the shader directly without any further configuration, but in most cases you
may want to specify at least the transformation/projection matrices.
Example configuration and rendering using @link Shaders::PhongGL @endlink ---
by default it's just colored and uses a single light, and we set a color of
both in addition to transformation, projection and normal matrices:
@snippet MagnumShaders-gl.cpp shaders-classic
@subsection shaders-usage-ubo Using uniform buffers
Uniform buffers require GL 3.1, OpenGL ES 3.0 or WebGL 2.0 and are more verbose
to set up, but when used the right way they can result in greatly reduced
driver overhead. Uniform buffers get enabled using the
@relativeref{Shaders::PhongGL,Flag::UniformBuffers} flag that's implemented for
all builtin shaders, and after that you're not supposed to use most of the
`set*()` APIs anymore, instead you have to fill uniform structures, upload them
to @ref GL::Buffer instances and then bind those via various `bind*Buffer()`
APIs. To simplify porting, documentation of each classic uniform setter lists
the equivalent uniform buffer APIs.
Because some parameters such as projection, material or light setup don't
change every draw, they are organized into buffers based on expected frequency
of change. This way you can fill the projection and material buffers just once
at the start, light setup only when the camera position changes and with much
less to upload for every draw. The separation is also done in a way that makes
it possible to reuse projection/transformation data among different shaders,
e.g. for a depth pre-pass.
In the following example, projection and transformation parameters are supplied
via generic shader-independent @ref Shaders::ProjectionUniform3D and
@ref Shaders::TransformationUniform3D structures and Phong-specific parameters
then via @ref Shaders::PhongDrawUniform, @ref Shaders::PhongMaterialUniform and
@ref Shaders::PhongLightUniform structures. While the structures expose the
fields directly, the data layout may be non-trivial and it's thus recommended
to use the setters unless they prove to be a performance bottleneck:
@snippet MagnumShaders-gl.cpp shaders-ubo
Altogether, this results in the same output as in the classic uniform case
shown above. Similarly to the classic uniforms, default-constructed structures
have reasonable defaults to make the shader render at least something, but note
that you *have to* bind the buffer to get the defaults, without a buffer bound
you'll get a fully black mesh at best and nothing rendered at all in the worst
cases.
@m_class{m-block m-success}
@par Importance of buffer usage and storage flags
With uniform buffers, it's very important what kind of memory gets used for
the backing storage. In the above snippets, the (implicit)
@ref GL::BufferUsage::StaticDraw got used for simplicity, but for data that
are changed for every draw it could make sense to pick
@ref GL::BufferUsage::DynamicDraw instead.
@par
The most ideal way may be to use @gl_extension{ARB,buffer_storage}
from OpenGL 4.4, and instead of @ref GL::Buffer::setData() calling
@relativeref{GL::Buffer,setStorage()} directly with the uniform data and
with empty @ref GL::Buffer::StorageFlags, which makes the buffer immutable.
Updating such immutable buffer can be still done via
@ref GL::Buffer::copy() from another buffer, but setting or mapping the
data from the CPU side won't be possible.
@par
As with everything, be sure to profile and pick the best workflow for your
target platform --- what's best for desktop may not be the best in WebGL,
and what works with WebGL running on top GL may not be the best with WebGL
that's itself implemented using D3D or Metal.
@subsection shaders-usage-multidraw Multidraw and reducing driver overhead
The main advantage of uniform buffers is the ability to specify data for
multiple draws together --- after all, having to reupload three or four buffers
for every draw like shown above wouldn't be really faster or easier than
setting the uniforms directly. On the other hand, uploading everything first
and binding a different subrange each time would avoid the reupload, but since
most drivers have uniform buffer alignment requirement as high as 256 bytes
(@ref GL::Buffer::uniformOffsetAlignment()), the per-draw buffers would have to
be very sparse.
Instead, it's possible to construct the shaders with a statically defined
draw count, fill the buffers with data for that many draws at once and then use
@relativeref{Shaders::PhongGL,setDrawOffset()} to pick concrete per-draw
parameters. Since material parameters are commonly shared among multiple draws,
the desired usage is to upload unique materials and then reference them via a
@ref Shaders::PhongDrawUniform::materialId "Shaders::*DrawUniform::materialId".
The following snippet shows drawing three different meshes, where two of them
share the same material definition. The projection and light buffer is the same
as above:
@snippet MagnumShaders-gl.cpp shaders-multi
While this minimizes the state changes to just a single immediate uniform being
changed between draws, it's possible to go even further by using
@ref GL::MeshView instances onto a single @ref GL::Mesh instead of several
different @ref GL::Mesh objects --- that way the attribute layout doesn't need
to be updated and it's just submitting draws with different offsets and counts.
Finally, with mesh views and on platforms that support @gl_extension{ARB,shader_draw_parameters} from OpenGL 4.6 or the
@gl_extension{ANGLE,multi_draw} / @webgl_extension{WEBGL,multi_draw} ES and
WebGL extension, it's possible to directly submit a multi-draw command. The
shader needs to have @relativeref{Shaders::PhongGL,Flag::MultiDraw} enabled,
which will make it use the @glsl gl_DrawID @ce builtin to pick the per-draw
parameters on its own. The above snippet modified for multidraw would then look
like this, uniform upload and binding is the same as before:
@snippet MagnumShaders-gl.cpp shaders-multidraw
<b></b>
@m_class{m-block m-warning}
@par Uniform buffer size limits
Note that size of a single uniform buffer that can be bound to a shader is
quite limited (@ref GL::AbstractShaderProgram::maxUniformBlockSize(),
usually just 16 or 64 kB), and another reason the parameters are separated
and deduplicated among several buffers is to maximize use of that memory.
With that you should always be able to submit at least 256 draws at once as
the biggest per-draw uniform structure used by builtin shaders has a size
of a 4x4 matrix.
@par
For larger batches the expected workflow is to still upload everything at
once but then bind and draw smaller (and properly aligned) subranges that
fit into the limit. For convenience, all uniform structures are guaranteed
to fit evenly into multiples of 768 bytes, which should be large enough for
even the strictest @ref GL::Buffer::uniformOffsetAlignment() requirements.
@subsection shaders-usage-instancing Instancing
@ref Shaders::FlatGL and @ref Shaders::PhongGL support instancing, which allows
them to render the same mesh several times but with different transformation
and material applied. It can be thought of as a more constrained variant of the
multidraw mentioned above, but instead of uniform buffers the per-instance
parameters are passed through instanced mesh attributes.
No uniform buffer requirement means this feature can be used even on OpenGL ES
2.0 and WebGL 1.0 targets if corresponding instancing extensions are available.
Using attributes instead of uniform buffers also means there's no limitation on
how many instances can be drawn at once, on the other hand a mesh can have only
a certain amount of attribute bindings and thus only the basic properties can
be specified per-instance such as the transformation matrix or base color.
The following snippet shows a setup similar to the multidraw above, except that
it's just the same sphere drawn three times in different locations and with a
different material applied. Note that the per-instance color is achieved by
using the usual vertex color attribute, only instanced:
@snippet MagnumShaders-gl.cpp shaders-instancing
@subsection shaders-usage-textures Using textures
Unless the shader requires a texture to work (which is the case of
@ref Shaders::VectorGL and @ref Shaders::DistanceFieldVectorGL), by default all
shaders are just colored. Enabling a texture is done via a flag (such as
@ref Shaders::Phong::Flag::DiffuseTexture) and then the texture is bound via an
appropriate `bind*Texture()` call. In most cases the texture value is
multiplied with the corresponding color uniform.
@snippet MagnumShaders-gl.cpp shaders-textures
All shaders that support textures are also able to apply arbitrary
transformation to the texture coordinate attribute by enabling
@relativeref{Shaders::PhongGL,Flag::TextureTransformation} on a particular
shader. Desired transformation is then supplied via
@relativeref{Shaders::PhongGL,setTextureMatrix()} (or a
@ref Shaders::TextureTransformationUniform in case uniform buffers are used).
This can be useful for animations, when you have a larger atlas with switchable
texture variations for a single mesh, or when you have texture coordinates
quantized in some nontrivial way.
Texture transformation is also useful in the
@ref shaders-usage-multidraw "multidraw" or
@ref shaders-usage-instancing "instancing" scenarios mentioned above, since
each draw will most likely require a different texture. There are two options:
- Upload the textures to subrectangles of a larger @ref GL::Texture2D and
then specify @ref Shaders::TextureTransformationUniform::offset and
@relativeref{Shaders::TextureTransformationUniform,rotationScaling} for
each draw, or in case of an instanced draw supply an instanced
@relativeref{Shaders::PhongGL,TextureOffset} attribute and have a global
scale set for all instanced via
@relativeref{Shaders::PhongGL,setTextureMatrix()}.
- Enable @relativeref{Shaders::PhongGL,Flag::TextureArrays} in the shader
(not available on OpenGL ES 2.0 or WebGL 1.0), upload the textures to
slices of a @ref GL::Texture2DArray and specify
@ref Shaders::TextureTransformationUniform::layer for each draw, or in case
of an instanced draw supply a layer in an instanced
@relativeref{Shaders::PhongGL,TextureOffsetLayer} attribute.
While with a @ref GL::Texture2D you may hit texture size limits (not to mention
you possible issues with materials that relied on a certain wrapping mode),
@ref GL::Texture2DArray is generally able to contain a lot more data, however
all slices have to be of the same size. You can also combine the two approaches
and pack differently sized textures to slices of a texture array and then set
both offset/scale and a layer per-draw.
The following snippet shows a multi-draw setup with a different texture array
layer used by each draw. While the projection, transformation, draw material
and light buffers are the same as before, there's a new per-draw
@ref Shaders::TextureTransformationUniform buffer supplying the layer
information:
@snippet MagnumShaders-gl.cpp shaders-texture-arrays
While the primary use case of texture arrays is with uniform buffers and
multidraw, they work in the classic uniform workflow as well --- use
@relativeref{Shaders::PhongGL,setTextureLayer()} there instead.
@section shaders-generic Generic vertex attributes and framebuffer attachments
@ -81,28 +293,29 @@ Many shaders share the same vertex attribute definitions, such as positions,
normals, texture coordinates etc. It's thus possible to configure the mesh
for a *generic* shader and then render it with any compatible shader.
Definition of all generic attributes is available in the
@ref Shaders::GenericGL class. Configuration of the above mesh using generic
attributes could then look like this:
@ref Shaders::GenericGL class. Setup of the mesh @ref shaders-usage "shown above"
using generic attributes could then look like this:
@snippet MagnumShaders-gl.cpp shaders-generic
Note that in this particular case both configurations are equivalent, because
@ref Shaders::PhongGL also uses generic vertex attribute definitions. Then you
can render the mesh using @ref Shaders::PhongGL shader like above, or use for
example @ref Shaders::FlatGL3D or even @ref Shaders::MeshVisualizerGL3D with
the same mesh reconfiguration. The unused attributes will be simply ignored.
Note that in this particular case both setups are equivalent, because
@ref Shaders::PhongGL attribute definitions are just aliases to the generic
ones. Then you can render the mesh using the @ref Shaders::PhongGL shader like
above, or use for example @ref Shaders::FlatGL3D or even
@ref Shaders::MeshVisualizerGL3D with the same mesh reconfiguration. The unused
attributes will be simply ignored.
@snippet MagnumShaders-gl.cpp shaders-meshvisualizer
The @ref MeshTools::compile() utility configures meshes using generic vertex
attribute definitions to make them usable with any shader.
Besides vertex attributes, the @ref Shaders::GenericGL contains generic
definitions for framebuffer outputs as well --- in many cases a shader has just
one (color) output, but some shaders such as @ref Shaders::FlatGL or
@ref Shaders::PhongGL offer an object ID output as well. A setup equivalent to
what's done in Flat shader's @ref Shaders-FlatGL-object-id but using the
generic definitions would look like this:
attribute definitions to make them usable with any builtin shader.
Besides vertex attributes, @ref Shaders::GenericGL contains generic definitions
for framebuffer outputs as well --- in many cases a shader has just one (color)
output, but some shaders such as @ref Shaders::FlatGL or @ref Shaders::PhongGL
offer an object ID output as well. A setup equivalent to what's done in Flat
shader's @ref Shaders-FlatGL-object-id but using the generic definitions would
look like this:
@snippet MagnumShaders-gl.cpp shaders-generic-object-id
*/

2
doc/snippets/CMakeLists.txt

@ -141,7 +141,7 @@ if(WITH_DEBUGTOOLS)
# CompareImage documentation snippet. I need it executable so I can
# copy&paste the output to the documentation. Also not using
# corrade_add_test() because it shouldn't be run as part of CTest as it
# purposedly fails.
# purposely fails.
add_executable(debugtools-compareimage debugtools-compareimage.cpp)
target_link_libraries(debugtools-compareimage PRIVATE
MagnumDebugTools

33
doc/snippets/MagnumGL.cpp

@ -121,7 +121,15 @@ carBumpTexture.setStorage(5, GL::TextureFormat::RGB8, {256, 256})
#endif
{
#if defined(CORRADE_TARGET_GCC) && __GNUC__ >= 11
#pragma GCC diagnostic push
/* Stupid thing. YES I WANT THIS TO BE A FUNCTION, CAN YOU SHUT UP */
#pragma GCC diagnostic ignored "-Wvexing-parse"
#endif
auto importSomeMesh() -> std::tuple<GL::Mesh, GL::Buffer, GL::Buffer>;
#if defined(CORRADE_TARGET_GCC) && __GNUC__ >= 11
#pragma GCC diagnostic pop
#endif
/* [opengl-wrapping-nocreate] */
GL::Mesh mesh{NoCreate};
GL::Buffer vertices{NoCreate}, indices{NoCreate};
@ -269,11 +277,32 @@ enum: UnsignedInt {
/* [AbstractShaderProgram-output-attributes] */
#if !defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
/* [AbstractShaderProgram-hide-irrelevant] */
/* [AbstractShaderProgram-return-hide-irrelevant] */
public:
MyShader& draw(GL::Mesh& mesh) {
return static_cast<MyShader&>(GL::AbstractShaderProgram::draw(mesh));
}
MyShader& draw(GL::Mesh&& mesh) {
return static_cast<MyShader&>(GL::AbstractShaderProgram::draw(mesh));
}
MyShader& draw(GL::MeshView& mesh) {
return static_cast<MyShader&>(GL::AbstractShaderProgram::draw(mesh));
}
MyShader& draw(GL::MeshView&& mesh) {
return static_cast<MyShader&>(GL::AbstractShaderProgram::draw(mesh));
}
/* Omit these if the shader is not ready for multidraw */
MyShader& draw(Containers::ArrayView<const Containers::Reference<GL::MeshView>> meshes) {
return static_cast<MyShader&>(GL::AbstractShaderProgram::draw(meshes));
}
MyShader& draw(std::initializer_list<Containers::Reference<GL::MeshView>> meshes) {
return static_cast<MyShader&>(GL::AbstractShaderProgram::draw(meshes));
}
private:
using GL::AbstractShaderProgram::drawTransformFeedback;
using GL::AbstractShaderProgram::dispatchCompute;
/* [AbstractShaderProgram-hide-irrelevant] */
/* [AbstractShaderProgram-return-hide-irrelevant] */
public:
#endif

16
doc/snippets/MagnumMath.cpp

@ -625,6 +625,11 @@ static_cast<void>(radians);
}
{
#if defined(CORRADE_TARGET_GCC) && __GNUC__ >= 11
#pragma GCC diagnostic push
/* Stupid thing. YES I WANT THIS TO BE A FUNCTION, CAN YOU SHUT UP */
#pragma GCC diagnostic ignored "-Wvexing-parse"
#endif
/* [Deg-usage-convert] */
Double foo();
@ -634,6 +639,9 @@ Radd radians{foo()};
/* [Deg-usage-convert] */
static_cast<void>(degrees);
static_cast<void>(radians);
#if defined(CORRADE_TARGET_GCC) && __GNUC__ >= 11
#pragma GCC diagnostic pop
#endif
}
{
@ -646,6 +654,11 @@ static_cast<void>(b);
}
{
#if defined(CORRADE_TARGET_GCC) && __GNUC__ >= 11
#pragma GCC diagnostic push
/* Stupid thing. YES I WANT THIS TO BE A FUNCTION, CAN YOU SHUT UP */
#pragma GCC diagnostic ignored "-Wvexing-parse"
#endif
Double foo();
/* [Deg-usage-comparison] */
Rad angle();
@ -654,6 +667,9 @@ Deg x = angle(); // convert to degrees for easier comparison
if(x < 30.0_degf) foo();
//if(x > 1.57_radf) bar(); // error, both need to be of the same type
/* [Deg-usage-comparison] */
#if defined(CORRADE_TARGET_GCC) && __GNUC__ >= 11
#pragma GCC diagnostic pop
#endif
}
{

451
doc/snippets/MagnumShaders-gl.cpp

@ -35,6 +35,7 @@
#include "Magnum/GL/DefaultFramebuffer.h"
#include "Magnum/GL/Framebuffer.h"
#include "Magnum/GL/Mesh.h"
#include "Magnum/GL/MeshView.h"
#include "Magnum/GL/Shader.h"
#include "Magnum/GL/Renderbuffer.h"
#include "Magnum/GL/RenderbufferFormat.h"
@ -54,6 +55,16 @@
#include "Magnum/Shaders/VertexColorGL.h"
#include "Magnum/Trade/LightData.h"
#ifndef MAGNUM_TARGET_GLES2
#include "Magnum/GL/TextureArray.h"
#include "Magnum/Shaders/DistanceFieldVector.h"
#include "Magnum/Shaders/Flat.h"
#include "Magnum/Shaders/Generic.h"
#include "Magnum/Shaders/MeshVisualizer.h"
#include "Magnum/Shaders/Phong.h"
#include "Magnum/Shaders/Vector.h"
#endif
#define DOXYGEN_IGNORE(...) __VA_ARGS__
using namespace Magnum;
@ -86,29 +97,241 @@ mesh.addVertexBuffer(vertices, 0,
//...
;
/* [shaders-setup] */
}
#endif
/* [shaders-rendering] */
Matrix4 transformationMatrix, projectionMatrix;
GL::Texture2D diffuseTexture, specularTexture;
{
GL::Mesh mesh;
/* [shaders-classic] */
Matrix4 transformationMatrix{DOXYGEN_IGNORE()}, projectionMatrix{DOXYGEN_IGNORE()};
Shaders::PhongGL shader{Shaders::PhongGL::Flag::DiffuseTexture};
shader.bindDiffuseTexture(diffuseTexture)
Shaders::PhongGL shader;
shader
.setTransformationMatrix(transformationMatrix)
.setProjectionMatrix(projectionMatrix)
.setNormalMatrix(transformationMatrix.normalMatrix())
.setDiffuseColor(0x2f83cc_rgbf)
.setLightColors({0xe9ecae_rgbf})
.draw(mesh);
/* [shaders-classic] */
}
#ifndef MAGNUM_TARGET_GLES2
{
GL::Mesh mesh;
Matrix4 transformationMatrix, projectionMatrix;
/* [shaders-ubo] */
GL::Buffer projectionUniform, lightUniform, materialUniform,
transformationUniform, drawUniform;
projectionUniform.setData({
Shaders::ProjectionUniform3D{}
.setProjectionMatrix(projectionMatrix)
});
lightUniform.setData({
Shaders::PhongLightUniform{}
.setColor(0xe9ecae_rgbf)
});
materialUniform.setData({
Shaders::PhongMaterialUniform{}
.setDiffuseColor(0x2f83cc_rgbf)
});
transformationUniform.setData({
Shaders::TransformationUniform3D{}
.setTransformationMatrix(transformationMatrix)
});
drawUniform.setData({
Shaders::PhongDrawUniform{}
.setNormalMatrix(transformationMatrix.normalMatrix())
});
Shaders::PhongGL shader{Shaders::PhongGL::Flag::UniformBuffers};
shader
.bindProjectionBuffer(projectionUniform)
.bindLightBuffer(lightUniform)
.bindMaterialBuffer(materialUniform)
.bindTransformationBuffer(transformationUniform)
.bindDrawBuffer(drawUniform)
.draw(mesh);
/* [shaders-ubo] */
}
{
GL::Buffer projectionUniform, transformationUniform, drawUniform, lightUniform,
materialUniform;
/* [shaders-multi] */
GL::Mesh redCone{DOXYGEN_IGNORE()}, yellowCube{DOXYGEN_IGNORE()}, redSphere{DOXYGEN_IGNORE()};
Matrix4 redConeTransformation{DOXYGEN_IGNORE()},
yellowCubeTransformation{DOXYGEN_IGNORE()},
redSphereTransformation{DOXYGEN_IGNORE()};
materialUniform.setData({
Shaders::PhongMaterialUniform{}
.setDiffuseColor(0xcd3431_rgbf),
Shaders::PhongMaterialUniform{}
.setDiffuseColor(0xc7cf2f_rgbf),
});
transformationUniform.setData({
Shaders::TransformationUniform3D{}
.setTransformationMatrix(redConeTransformation),
Shaders::TransformationUniform3D{}
.setTransformationMatrix(yellowCubeTransformation),
Shaders::TransformationUniform3D{}
.setTransformationMatrix(redSphereTransformation),
});
drawUniform.setData({
Shaders::PhongDrawUniform{}
.setNormalMatrix(redConeTransformation.normalMatrix())
.setMaterialId(0),
Shaders::PhongDrawUniform{}
.setNormalMatrix(yellowCubeTransformation.normalMatrix())
.setMaterialId(1),
Shaders::PhongDrawUniform{}
.setNormalMatrix(redSphereTransformation.normalMatrix())
.setMaterialId(0),
});
/* One light, two materials, three draws */
Shaders::PhongGL shader{Shaders::PhongGL::Flag::UniformBuffers, 1, 2, 3};
shader
.bindProjectionBuffer(projectionUniform)
.bindTransformationBuffer(transformationUniform)
.bindDrawBuffer(drawUniform)
.bindLightBuffer(lightUniform)
.bindMaterialBuffer(materialUniform)
.setDrawOffset(0)
.draw(redCone)
.setDrawOffset(1)
.draw(yellowCube)
.setDrawOffset(2)
.draw(redSphere);
/* [shaders-multi] */
}
{
GL::Mesh mesh;
/* [shaders-multidraw] */
GL::MeshView redConeView{DOXYGEN_IGNORE(mesh)}, yellowCubeView{DOXYGEN_IGNORE(mesh)}, redSphereView{DOXYGEN_IGNORE(mesh)};
DOXYGEN_IGNORE()
/* One light, two materials, three draws; with multidraw enabled */
Shaders::PhongGL shader{Shaders::PhongGL::Flag::MultiDraw, 1, 2, 3};
shader
DOXYGEN_IGNORE()
.draw({redConeView, yellowCubeView, redSphereView});
/* [shaders-multidraw] */
}
#endif
{
Matrix4 projectionMatrix;
/* [shaders-instancing] */
Matrix4 redSphereTransformation{DOXYGEN_IGNORE()},
yellowSphereTransformation{DOXYGEN_IGNORE()},
greenSphereTransformation{DOXYGEN_IGNORE()};
struct {
Matrix4 transformationMatrix;
Matrix3x3 normalMatrix;
Color3 color;
} instanceData[]{
{redSphereTransformation,
redSphereTransformation.normalMatrix(),
0xcd3431_rgbf},
{yellowSphereTransformation,
yellowSphereTransformation.normalMatrix(),
0xc7cf2f_rgbf},
{greenSphereTransformation,
greenSphereTransformation.normalMatrix(),
0x3bd267_rgbf},
};
GL::Mesh sphereInstanced{DOXYGEN_IGNORE()};
sphereInstanced.addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0,
Shaders::PhongGL::TransformationMatrix{},
Shaders::PhongGL::NormalMatrix{},
Shaders::PhongGL::Color3{});
sphereInstanced.setInstanceCount(3);
Shaders::PhongGL shader{Shaders::PhongGL::Flag::InstancedTransformation|
Shaders::PhongGL::Flag::VertexColor};
shader
.setProjectionMatrix(projectionMatrix)
DOXYGEN_IGNORE()
.draw(sphereInstanced);
/* [shaders-instancing] */
}
{
GL::Mesh mesh;
/* [shaders-textures] */
GL::Texture2D diffuseTexture;
DOXYGEN_IGNORE()
Shaders::PhongGL shader{Shaders::PhongGL::Flag::DiffuseTexture};
shader.bindDiffuseTexture(diffuseTexture)
DOXYGEN_IGNORE()
.draw(mesh);
/* [shaders-rendering] */
/* [shaders-textures] */
}
#ifndef MAGNUM_TARGET_GLES2
{
GL::Mesh mesh;
GL::MeshView redConeView{DOXYGEN_IGNORE(mesh)}, yellowCubeView{DOXYGEN_IGNORE(mesh)}, redSphereView{DOXYGEN_IGNORE(mesh)};
/* [shaders-texture-arrays] */
ImageView2D coneDiffuse{DOXYGEN_IGNORE({}, {})}, cubeDiffuse{DOXYGEN_IGNORE({}, {})}, sphereDiffuse{DOXYGEN_IGNORE({}, {})};
GL::Texture2DArray diffuseTexture;
diffuseTexture
DOXYGEN_IGNORE()
/* Assuming all iamges have the same format and size */
.setStorage(1, GL::textureFormat(coneDiffuse.format()),
{coneDiffuse.size(), 3})
.setSubImage(0, {}, coneDiffuse)
.setSubImage(1, {}, cubeDiffuse)
.setSubImage(2, {}, sphereDiffuse);
GL::Buffer textureTransformationUniform;
textureTransformationUniform.setData({
Shaders::TextureTransformationUniform{}
.setLayer(0),
Shaders::TextureTransformationUniform{}
.setLayer(1),
Shaders::TextureTransformationUniform{}
.setLayer(2),
});
Shaders::PhongGL shader{
Shaders::PhongGL::Flag::MultiDraw|
Shaders::PhongGL::Flag::DiffuseTexture|
Shaders::PhongGL::Flag::TextureArrays,
1, 2, 3};
shader
DOXYGEN_IGNORE()
.bindDiffuseTexture(diffuseTexture)
.bindTextureTransformationBuffer(textureTransformationUniform)
.draw({redConeView, yellowCubeView, redSphereView});
/* [shaders-texture-arrays] */
}
#endif
{
GL::Buffer vertices;
GL::Mesh mesh;
/* [shaders-generic] */
mesh.addVertexBuffer(vertices, 0,
Shaders::GenericGL3D::Position{},
Shaders::GenericGL3D::Normal{},
Shaders::GenericGL3D::TextureCoordinates{});
/* [shaders-generic] */
}
{
GL::Mesh mesh;
Matrix4 transformationMatrix, projectionMatrix;
/* [shaders-meshvisualizer] */
Shaders::MeshVisualizerGL3D visualizerShader{Shaders::MeshVisualizerGL3D::Flag::Wireframe};
visualizerShader
Shaders::MeshVisualizerGL3D shader{Shaders::MeshVisualizerGL3D::Flag::Wireframe};
shader
.setColor(0x2f83cc_rgbf)
.setWireframeColor(0xdcdcdc_rgbf)
.setViewportSize(Vector2{GL::defaultFramebuffer.viewport().size()})
@ -118,6 +341,9 @@ visualizerShader
/* [shaders-meshvisualizer] */
}
/* internal compiler error: in gimplify_init_constructor, at gimplify.c:4271
on GCC 4.8 in the [60] array */
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__*100 + __GNUC_MINOR__ >= 500
{
/* [DistanceFieldVectorGL-usage1] */
struct Vertex {
@ -150,12 +376,51 @@ Shaders::DistanceFieldVectorGL2D shader;
shader.setColor(0x2f83cc_rgbf)
.setOutlineColor(0xdcdcdc_rgbf)
.setOutlineRange(0.6f, 0.4f)
.bindVectorTexture(texture)
.setTransformationProjectionMatrix(projectionMatrix*transformationMatrix)
.bindVectorTexture(texture)
.draw(mesh);
/* [DistanceFieldVectorGL-usage2] */
}
#endif
#ifndef MAGNUM_TARGET_GLES2
{
GL::Mesh mesh;
Matrix3 transformationMatrix, projectionMatrix;
GL::Texture2D texture;
/* [DistanceFieldVectorGL-ubo] */
GL::Buffer projectionTransformationUniform, materialUniform, drawUniform;
projectionTransformationUniform.setData({
Shaders::TransformationProjectionUniform2D{}
.setTransformationProjectionMatrix(transformationMatrix*projectionMatrix)
});
materialUniform.setData({
Shaders::DistanceFieldVectorMaterialUniform{}
.setColor(0x2f83cc_rgbf)
.setOutlineColor(0xdcdcdc_rgbf)
.setOutlineRange(0.6f, 0.4f)
});
drawUniform.setData({
Shaders::DistanceFieldVectorDrawUniform{}
.setMaterialId(0)
});
Shaders::DistanceFieldVectorGL2D shader{
Shaders::DistanceFieldVectorGL2D::Flag::UniformBuffers
};
shader
.bindTransformationProjectionBuffer(projectionTransformationUniform)
.bindMaterialBuffer(materialUniform)
.bindDrawBuffer(drawUniform)
.bindVectorTexture(texture)
.draw(mesh);
/* [DistanceFieldVectorGL-ubo] */
}
#endif
/* internal compiler error: in gimplify_init_constructor, at gimplify.c:4271
on GCC 4.8 in the [60] array */
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__*100 + __GNUC_MINOR__ >= 500
{
/* [FlatGL-usage-colored1] */
struct Vertex {
@ -217,6 +482,7 @@ shader.setTransformationProjectionMatrix(projectionMatrix*transformationMatrix)
.draw(mesh);
/* [FlatGL-usage-textured2] */
}
#endif
#ifndef MAGNUM_TARGET_GLES2
{
@ -274,6 +540,35 @@ mesh.setInstanceCount(Containers::arraySize(instanceData))
/* [FlatGL-usage-instancing] */
}
#ifndef MAGNUM_TARGET_GLES2
{
GL::Mesh mesh;
Matrix4 transformationMatrix, projectionMatrix;
/* [FlatGL-ubo] */
GL::Buffer projectionTransformationUniform, materialUniform, drawUniform;
projectionTransformationUniform.setData({
Shaders::TransformationProjectionUniform3D{}
.setTransformationProjectionMatrix(transformationMatrix*projectionMatrix)
});
materialUniform.setData({
Shaders::FlatMaterialUniform{}
.setColor(0x2f83cc_rgbf)
});
drawUniform.setData({
Shaders::FlatDrawUniform{}
.setMaterialId(0)
});
Shaders::FlatGL3D shader{Shaders::FlatGL3D::Flag::UniformBuffers};
shader
.bindTransformationProjectionBuffer(projectionTransformationUniform)
.bindMaterialBuffer(materialUniform)
.bindDrawBuffer(drawUniform)
.draw(mesh);
/* [FlatGL-ubo] */
}
#endif
{
struct: GL::AbstractShaderProgram {
void foo() {
@ -320,6 +615,9 @@ mesh.setInstanceCount(Containers::arraySize(instanceData))
/* [PhongGL-usage-instancing] */
}
/* internal compiler error: in gimplify_init_constructor, at gimplify.c:4271
on GCC 4.8 in the [60] array */
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__*100 + __GNUC_MINOR__ >= 500
{
/* [MeshVisualizerGL3D-usage-geom1] */
struct Vertex {
@ -463,6 +761,47 @@ shader.setColorMapTransformation(0.0f, 1.0f/Math::max(objectIds))
}
#endif
#ifndef MAGNUM_TARGET_GLES2
{
GL::Mesh mesh;
Matrix4 transformationMatrix, projectionMatrix;
GL::Texture2D texture;
/* [MeshVisualizerGL3D-ubo] */
GL::Buffer projectionUniform, materialUniform, transformationUniform,
drawUniform;
projectionUniform.setData({
Shaders::ProjectionUniform3D{}
.setProjectionMatrix(projectionMatrix)
});
materialUniform.setData({
Shaders::MeshVisualizerMaterialUniform{}
.setColor(0x2f83cc_rgbf)
.setWireframeColor(0xdcdcdc_rgbf)
});
transformationUniform.setData({
Shaders::TransformationUniform3D{}
.setTransformationMatrix(transformationMatrix)
});
drawUniform.setData({
Shaders::MeshVisualizerDrawUniform3D{}
.setMaterialId(0)
});
Shaders::MeshVisualizerGL3D shader{
Shaders::MeshVisualizerGL3D::Flag::Wireframe|
Shaders::MeshVisualizerGL3D::Flag::UniformBuffers
};
shader
.setViewportSize(Vector2{GL::defaultFramebuffer.viewport().size()})
.bindProjectionBuffer(projectionUniform)
.bindMaterialBuffer(materialUniform)
.bindTransformationBuffer(transformationUniform)
.bindDrawBuffer(drawUniform)
.draw(mesh);
/* [MeshVisualizerGL3D-ubo] */
}
#endif
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__*100 + __GNUC_MINOR__ >= 500
{
/* [PhongGL-usage-colored1] */
@ -580,6 +919,48 @@ shader.bindTextures(&diffuseAlphaTexture, &diffuseAlphaTexture, nullptr, nullptr
/* [PhongGL-usage-alpha] */
}
#ifndef MAGNUM_TARGET_GLES2
{
GL::Mesh mesh;
Matrix4 transformationMatrix, projectionMatrix;
GL::Texture2D texture;
/* [PhongGL-ubo] */
GL::Buffer projectionUniform, lightUniform, materialUniform,
transformationUniform, drawUniform;
projectionUniform.setData({
Shaders::ProjectionUniform3D{}
.setProjectionMatrix(projectionMatrix)
});
lightUniform.setData({
Shaders::PhongLightUniform{}
});
materialUniform.setData({
Shaders::PhongMaterialUniform{}
.setDiffuseColor(0x2f83cc_rgbf)
.setShininess(200.0f)
});
transformationUniform.setData({
Shaders::TransformationUniform3D{}
.setTransformationMatrix(transformationMatrix)
});
drawUniform.setData({
Shaders::PhongDrawUniform{}
.setNormalMatrix(transformationMatrix.normalMatrix())
.setMaterialId(0)
});
Shaders::PhongGL shader{Shaders::PhongGL::Flag::UniformBuffers};
shader
.bindProjectionBuffer(projectionUniform)
.bindLightBuffer(lightUniform)
.bindMaterialBuffer(materialUniform)
.bindTransformationBuffer(transformationUniform)
.bindDrawBuffer(drawUniform)
.draw(mesh);
/* [PhongGL-ubo] */
}
#endif
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__*100 + __GNUC_MINOR__ >= 500
{
/* [VectorGL-usage1] */
@ -611,7 +992,40 @@ shader.setColor(0x2f83cc_rgbf)
.draw(mesh);
/* [VectorGL-usage2] */
}
#endif
#ifndef MAGNUM_TARGET_GLES2
{
GL::Mesh mesh;
Matrix3 transformationMatrix, projectionMatrix;
GL::Texture2D texture;
/* [VectorGL-ubo] */
GL::Buffer projectionTransformationUniform, materialUniform, drawUniform;
projectionTransformationUniform.setData({
Shaders::TransformationProjectionUniform2D{}
.setTransformationProjectionMatrix(transformationMatrix*projectionMatrix)
});
materialUniform.setData({
Shaders::VectorMaterialUniform{}
.setColor(0x2f83cc_rgbf)
});
drawUniform.setData({
Shaders::VectorDrawUniform{}
.setMaterialId(0)
});
Shaders::VectorGL2D shader{Shaders::VectorGL2D::Flag::UniformBuffers};
shader
.bindTransformationProjectionBuffer(projectionTransformationUniform)
.bindMaterialBuffer(materialUniform)
.bindDrawBuffer(drawUniform)
.bindVectorTexture(texture)
.draw(mesh);
/* [VectorGL-ubo] */
}
#endif
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__*100 + __GNUC_MINOR__ >= 500
{
/* [VertexColorGL-usage1] */
struct Vertex {
@ -643,4 +1057,23 @@ shader.setTransformationProjectionMatrix(projectionMatrix*transformationMatrix)
}
#endif
#ifndef MAGNUM_TARGET_GLES2
{
GL::Mesh mesh;
Matrix4 transformationMatrix, projectionMatrix;
/* [VertexColorGL-ubo] */
GL::Buffer projectionTransformationUniform;
projectionTransformationUniform.setData({
Shaders::TransformationProjectionUniform3D{}
.setTransformationProjectionMatrix(transformationMatrix*projectionMatrix)
});
Shaders::VertexColorGL3D shader{Shaders::VertexColorGL3D::Flag::UniformBuffers};
shader
.bindTransformationProjectionBuffer(projectionTransformationUniform)
.draw(mesh);
/* [VertexColorGL-ubo] */
}
#endif
}

2
doc/transformations.dox

@ -319,7 +319,7 @@ create helper functions, if you need them.
The @ref SceneGraph API provides a hierarchical transformation hierarchy and a
correct camera-relative transformation is calculated automatically in the
background, avoiding the need for manualy handling of model / view
background, avoiding the need for manually handling of model / view
transformations. In particular, camera position is always specified as relative
to scene root and it gets inverted when calculating the final per-object
transformation. See @ref scenegraph for detailed description.

2
modules/FindCorrade.cmake

@ -100,7 +100,7 @@
# CORRADE_TARGET_MINGW - Defined if compiling under MinGW
# CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT - Defined if PluginManager
# doesn't support dynamic plugin loading due to platform limitations
# CORRADE_TESTSUITE_TARGET_XCTEST - Defined if TestSuite is targetting Xcode
# CORRADE_TESTSUITE_TARGET_XCTEST - Defined if TestSuite is targeting Xcode
# XCTest
# CORRADE_UTILITY_USE_ANSI_COLORS - Defined if ANSI escape sequences are used
# for colored output with Utility::Debug on Windows

2
modules/FindMagnum.cmake

@ -608,7 +608,7 @@ foreach(_component ${Magnum_FIND_COMPONENTS})
# Dynamic plugins don't have any prefix (e.g. `lib` on Linux),
# search with empty prefix and then reset that back so we don't
# accidentaly break something else
# accidentally break something else
set(_tmp_prefixes "${CMAKE_FIND_LIBRARY_PREFIXES}")
set(CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES};")

21
package/archlinux/PKGBUILD

@ -65,20 +65,23 @@ build() {
check() {
cd "$_rootdir/build"
CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_invalidate_subdata GL_ARB_multi_bind GL_ARB_robustness GL_ARB_separate_shader_objects GL_ARB_texture_storage GL_ARB_texture_storage_multisample GL_ARB_shading_language_420pack GL_ARB_explicit_uniform_location GL_ARB_explicit_attrib_location GL_ARB_texture_filter_anisotropic" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_direct_state_access" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_get_texture_sub_image" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_vertex_array_object" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_KHR_debug" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
export CORRADE_TEST_SKIP_BENCHMARKS=ON
export CORRADE_TEST_COLOR=ON
ctest --output-on-failure -j5
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_invalidate_subdata GL_ARB_multi_bind GL_ARB_robustness GL_ARB_separate_shader_objects GL_ARB_texture_storage GL_ARB_texture_storage_multisample GL_ARB_shading_language_420pack GL_ARB_explicit_uniform_location GL_ARB_explicit_attrib_location GL_ARB_texture_filter_anisotropic" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_direct_state_access" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_get_texture_sub_image" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_vertex_array_object" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_uniform_buffer_object" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_KHR_debug" ctest --output-on-failure -j5 -R GLTest
# Run all Vulkan tests with SwiftShader as well
# Keep in sync with PKGBUILD-coverage, PKGBUILD-release and
# package/ci/unix-desktop-vulkan.sh
MAGNUM_DEVICE=cpu CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R VkTest
MAGNUM_DEVICE=cpu ctest --output-on-failure -j5 -R VkTest
for device in "" cpu; do
MAGNUM_DEVICE=$device MAGNUM_VULKAN_VERSION=1.0 CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R VkTest
MAGNUM_DEVICE=$device MAGNUM_DISABLE_EXTENSIONS="VK_KHR_get_physical_device_properties2 VK_KHR_get_memory_requirements2 VK_KHR_bind_memory2 VK_KHR_create_renderpass2 VK_KHR_copy_commands2 VK_KHR_maintenance1 VK_KHR_multiview VK_KHR_maintenance2" MAGNUM_VULKAN_VERSION=1.0 CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R VkTest
MAGNUM_DEVICE=$device MAGNUM_VULKAN_VERSION=1.0 ctest --output-on-failure -j5 -R VkTest
MAGNUM_DEVICE=$device MAGNUM_DISABLE_EXTENSIONS="VK_KHR_get_physical_device_properties2 VK_KHR_get_memory_requirements2 VK_KHR_bind_memory2 VK_KHR_create_renderpass2 VK_KHR_copy_commands2 VK_KHR_maintenance1 VK_KHR_multiview VK_KHR_maintenance2" MAGNUM_VULKAN_VERSION=1.0 ctest --output-on-failure -j5 -R VkTest
done
}

21
package/archlinux/PKGBUILD-coverage

@ -65,21 +65,24 @@ build() {
check() {
cd "$_rootdir/build-coverage"
CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 || true
export CORRADE_TEST_SKIP_BENCHMARKS=ON
export CORRADE_TEST_COLOR=ON
ctest --output-on-failure -j5 || true
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_invalidate_subdata GL_ARB_multi_bind GL_ARB_separate_shader_objects GL_ARB_texture_storage GL_ARB_texture_storage_multisample GL_ARB_texture_multisample GL_ARB_shading_language_420pack GL_ARB_explicit_uniform_location GL_ARB_explicit_attrib_location GL_ARB_texture_filter_anisotropic" CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest || true
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_direct_state_access GL_ARB_robustness GL_ARB_multi_bind" CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest || true
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_get_texture_sub_image" CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest || true
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_vertex_array_object" CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest || true
MAGNUM_DISABLE_EXTENSIONS="GL_KHR_debug" CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest || true
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_invalidate_subdata GL_ARB_multi_bind GL_ARB_separate_shader_objects GL_ARB_texture_storage GL_ARB_texture_storage_multisample GL_ARB_texture_multisample GL_ARB_shading_language_420pack GL_ARB_explicit_uniform_location GL_ARB_explicit_attrib_location GL_ARB_texture_filter_anisotropic" ctest --output-on-failure -j5 -R GLTest || true
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_direct_state_access GL_ARB_robustness GL_ARB_multi_bind" ctest --output-on-failure -j5 -R GLTest || true
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_get_texture_sub_image" ctest --output-on-failure -j5 -R GLTest || true
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_vertex_array_object" ctest --output-on-failure -j5 -R GLTest || true
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_uniform_buffer_object" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_KHR_debug" ctest --output-on-failure -j5 -R GLTest || true
# Run all Vulkan tests with SwiftShader as well
# Keep in sync with PKGBUILD, PKGBUILD-release and
# package/ci/unix-desktop-vulkan.sh
MAGNUM_DEVICE=cpu CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R VkTest || true
MAGNUM_DEVICE=cpu ctest --output-on-failure -j5 -R VkTest || true
for device in "" cpu; do
MAGNUM_DEVICE=$device MAGNUM_VULKAN_VERSION=1.0 CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R VkTest || true
MAGNUM_DEVICE=$device MAGNUM_DISABLE_EXTENSIONS="VK_KHR_get_physical_device_properties2 VK_KHR_get_memory_requirements2 VK_KHR_bind_memory2 VK_KHR_create_renderpass2 VK_KHR_copy_commands2 VK_KHR_maintenance1 VK_KHR_multiview VK_KHR_maintenance2" MAGNUM_VULKAN_VERSION=1.0 CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R VkTest || true
MAGNUM_DEVICE=$device MAGNUM_VULKAN_VERSION=1.0 ctest --output-on-failure -j5 -R VkTest || true
MAGNUM_DEVICE=$device MAGNUM_DISABLE_EXTENSIONS="VK_KHR_get_physical_device_properties2 VK_KHR_get_memory_requirements2 VK_KHR_bind_memory2 VK_KHR_create_renderpass2 VK_KHR_copy_commands2 VK_KHR_maintenance1 VK_KHR_multiview VK_KHR_maintenance2" MAGNUM_VULKAN_VERSION=1.0 ctest --output-on-failure -j5 -R VkTest || true
done
./Debug/bin/magnum-al-info > /dev/null

21
package/archlinux/PKGBUILD-release

@ -101,22 +101,25 @@ build() {
}
check() {
export CORRADE_TEST_SKIP_BENCHMARKS=ON
export CORRADE_TEST_COLOR=ON
for i in build build-release; do
cd "$_rootdir/$i"
CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_invalidate_subdata GL_ARB_multi_bind GL_ARB_robustness GL_ARB_separate_shader_objects GL_ARB_texture_storage GL_ARB_texture_storage_multisample GL_ARB_shading_language_420pack GL_ARB_explicit_uniform_location GL_ARB_explicit_attrib_location GL_ARB_texture_filter_anisotropic" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_direct_state_access" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_get_texture_sub_image" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_vertex_array_object" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_KHR_debug" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
ctest --output-on-failure -j5
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_invalidate_subdata GL_ARB_multi_bind GL_ARB_robustness GL_ARB_separate_shader_objects GL_ARB_texture_storage GL_ARB_texture_storage_multisample GL_ARB_shading_language_420pack GL_ARB_explicit_uniform_location GL_ARB_explicit_attrib_location GL_ARB_texture_filter_anisotropic" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_direct_state_access" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_get_texture_sub_image" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_vertex_array_object" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_ARB_uniform_buffer_object" ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_KHR_debug" ctest --output-on-failure -j5 -R GLTest
# Run all Vulkan tests with SwiftShader as well
# Keep in sync with PKGBUILD, PKGBUILD-coverage and
# package/ci/unix-desktop-vulkan.sh
MAGNUM_DEVICE=cpu CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R VkTest
MAGNUM_DEVICE=cpu ctest --output-on-failure -j5 -R VkTest
for device in "" cpu; do
MAGNUM_DEVICE=$device MAGNUM_VULKAN_VERSION=1.0 CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R VkTest
MAGNUM_DEVICE=$device MAGNUM_DISABLE_EXTENSIONS="VK_KHR_get_physical_device_properties2 VK_KHR_get_memory_requirements2 VK_KHR_bind_memory2 VK_KHR_create_renderpass2 VK_KHR_copy_commands2 VK_KHR_maintenance1 VK_KHR_multiview VK_KHR_maintenance2" MAGNUM_VULKAN_VERSION=1.0 CORRADE_TEST_SKIP_BENCHMARKS=ON CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R VkTest
MAGNUM_DEVICE=$device MAGNUM_VULKAN_VERSION=1.0 ctest --output-on-failure -j5 -R VkTest
MAGNUM_DEVICE=$device MAGNUM_DISABLE_EXTENSIONS="VK_KHR_get_physical_device_properties2 VK_KHR_get_memory_requirements2 VK_KHR_bind_memory2 VK_KHR_create_renderpass2 VK_KHR_copy_commands2 VK_KHR_maintenance1 VK_KHR_multiview VK_KHR_maintenance2" MAGNUM_VULKAN_VERSION=1.0 ctest --output-on-failure -j5 -R VkTest
done
done
}

2
package/ci/appveyor-desktop-gles.bat

@ -58,7 +58,7 @@ cmake --build . || exit /b
rem Test
set CORRADE_TEST_COLOR=ON
ctest -V -E GLTest || exit /b
ctest -V -E "GLTest|GLBenchmark" || exit /b
rem Test install, after running the tests as for them it shouldn't be needed
cmake --build . --target install || exit /b

2
package/ci/appveyor-desktop-mingw.bat

@ -60,7 +60,7 @@ cmake --build . || exit /b
rem Test
set CORRADE_TEST_COLOR=ON
ctest -V -E "(GL|Vk)Test" || exit /b
ctest -V -E "GLTest|GLBenchmark|VkTest" || exit /b
rem Test install, after running the tests as for them it shouldn't be needed
cmake --build . --target install || exit /b

2
package/ci/appveyor-desktop.bat

@ -69,7 +69,7 @@ cmake --build . || exit /b
rem Test
set CORRADE_TEST_COLOR=ON
ctest -V -E "(GL|Vk)Test" || exit /b
ctest -V -E "GLTest|GLBenchmark|VkTest" || exit /b
rem Test install, after running the tests as for them it shouldn't be needed
cmake --build . --target install || exit /b

5
package/ci/appveyor-lcov.sh

@ -9,7 +9,10 @@ curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.ta
pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig
pacman -U --noconfirm msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz
pacman -Sy --noconfirm mingw-w64-x86_64-perl
# Newer packages use zstd, but this old pacman has no idea what that is.
# Download the last perl that's still compressed with xz.
curl -O http://repo.msys2.org/msys/x86_64/perl-5.30.2-1-x86_64.pkg.tar.xz
pacman -U --noconfirm perl-5.30.2-1-x86_64.pkg.tar.xz
# mingw lcov package is empty, so download and use it manually
# https://github.com/appveyor/ci/issues/1628

16
package/ci/circleci.yml

@ -16,9 +16,12 @@ executors:
ubuntu-18_04:
docker:
- image: ubuntu:bionic-20200921
xcode-10_3:
xcode-11_2:
# Molten-vk isn't in (non-updated) Homebrew on the 9.4 or 10.0/1/2 image,
# have to use 10.3 instead; since 2021-06-08 it refuses to work on 10.14 so
# have to use 11.2 at least
macos:
xcode: 10.3.0
xcode: 11.2.1
xcode-11_6:
macos:
xcode: 11.6.0
@ -391,9 +394,7 @@ jobs:
script: unix-desktop.sh
macos-gl:
# Molten-vk isn't in (non-updated) Homebrew on the 9.4 or 10.0/1/2 image,
# have to use 10.3 instead
executor: xcode-10_3
executor: xcode-11_2
environment:
CMAKE_CXX_FLAGS: --coverage
CONFIGURATION: Debug
@ -425,8 +426,9 @@ jobs:
macos-static:
# Molten-vk isn't in (non-updated) Homebrew on the 9.4 or 10.0/1/2 image,
# have to use 10.3 instead
executor: xcode-10_3
# have to use 10.3 instead; since 2021-06-08 it refuses to work on 10.14 so
# have to use 11.2 at least
executor: xcode-11_2
environment:
# STUPID yml interprets unquoted ON as a boolean
BUILD_STATIC: "ON"

2
package/ci/emscripten.sh

@ -73,7 +73,7 @@ cmake .. \
ninja
# Test
CORRADE_TEST_COLOR=ON ctest -V -E "(GL|AL)Test"
CORRADE_TEST_COLOR=ON ctest -V -E "GLTest|GLBenchmark|ALTest"
# Test install, after running the tests as for them it shouldn't be needed
ninja install

2
package/ci/travis-android-gles.sh

@ -83,7 +83,7 @@ ninja -j4
echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a
emulator -avd test -no-audio -no-window &
android-wait-for-emulator
CORRADE_TEST_COLOR=ON ctest -V -E GLTest
CORRADE_TEST_COLOR=ON ctest -V -E "GLTest|GLBenchmark"
# Test install, after running the tests as for them it shouldn't be needed
ninja install

2
package/ci/travis-ios-simulator.sh

@ -70,7 +70,7 @@ set -o pipefail && cmake --build . --config Release | xcpretty
# TODO: find a better way to avoid
# Library not loaded: /System/Library/Frameworks/OpenGLES.framework/OpenGLES
# error
DYLD_FALLBACK_LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/OpenGLES.framework/ DYLD_FALLBACK_FRAMEWORK_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks CORRADE_TEST_COLOR=ON ctest -V -C Release -E GLTest
DYLD_FALLBACK_LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/OpenGLES.framework/ DYLD_FALLBACK_FRAMEWORK_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks CORRADE_TEST_COLOR=ON ctest -V -C Release -E "GLTest|GLBenchmark"
# Test install, after running the tests as for them it shouldn't be needed
set -o pipefail && cmake --build . --config Release --target install | xcpretty

6
package/ci/unix-desktop-gles.sh

@ -56,6 +56,12 @@ cmake .. \
-DBUILD_GL_TESTS=ON \
-G Ninja
ninja $NINJA_JOBS
# Don't run any benchmarks. SwiftShader doesn't support
# EXT_disjoint_timer_query anyway and the CPU-side things are run in the usual
# desktop build already.
export CORRADE_TEST_SKIP_BENCHMARKS=ON
CORRADE_TEST_COLOR=ON ctest -V
MAGNUM_DISABLE_EXTENSIONS="GL_OES_vertex_array_object GL_NV_framebuffer_multisample GL_NV_framebuffer_blit GL_EXT_robustness GL_EXT_draw_elements_base_vertex" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest
MAGNUM_DISABLE_EXTENSIONS="GL_OES_vertex_array_object GL_NV_framebuffer_multisample GL_NV_framebuffer_blit GL_EXT_robustness GL_EXT_draw_elements_base_vertex GL_OES_draw_elements_base_vertex GL_ANGLE_base_vertex_base_instance" CORRADE_TEST_COLOR=ON ctest --output-on-failure -j5 -R GLTest

2
package/ci/unix-desktop.sh

@ -67,7 +67,7 @@ cmake .. \
-DBUILD_PLUGINS_STATIC=$BUILD_STATIC \
-G Ninja
ninja $NINJA_JOBS
ASAN_OPTIONS="color=always" LSAN_OPTIONS="color=always suppressions=$(pwd)/../package/ci/leaksanitizer.conf" TSAN_OPTIONS="color=always" CORRADE_TEST_COLOR=ON ctest -V -E "(GL|Vk)Test"
ASAN_OPTIONS="color=always" LSAN_OPTIONS="color=always suppressions=$(pwd)/../package/ci/leaksanitizer.conf" TSAN_OPTIONS="color=always" CORRADE_TEST_COLOR=ON ctest -V -E "GLTest|GLBenchmark|VkTest"
# Test install, after running the tests as for them it shouldn't be needed
ninja install

2
src/Magnum/Animation/Test/PlayerTest.cpp

@ -120,7 +120,7 @@ const struct {
initializer (not when there's just a struct and also not when
the struct is only a chrono member itself). Keeping at least one
instance here so I can monitor when this gets fixed. */
#if !defined(CORRADE_MSVC2017_COMPATIBILITY) || defined(CORRADE_MSVC2015_COMPATIBLITY)
#if !defined(CORRADE_MSVC2017_COMPATIBILITY) || defined(CORRADE_MSVC2015_COMPATIBILITY)
std::chrono::hours{100*365*24},
#else
std::chrono::minutes{100*365*24*60},

20
src/Magnum/Animation/Test/TrackTest.cpp

@ -48,6 +48,9 @@ struct TrackTest: TestSuite::Tester {
void constructInitializerListInterpolationInterpolator();
void constructInitializerListInterpolationInterpolatorDefaults();
void constructCopy();
void constructMove();
void convertView();
void at();
@ -106,6 +109,9 @@ TrackTest::TrackTest() {
&TrackTest::constructInitializerListInterpolationInterpolator,
&TrackTest::constructInitializerListInterpolationInterpolatorDefaults,
&TrackTest::constructCopy,
&TrackTest::constructMove,
&TrackTest::convertView});
addInstancedTests({&TrackTest::at,
@ -389,6 +395,20 @@ void TrackTest::constructInitializerListInterpolationInterpolatorDefaults() {
CORRADE_COMPARE(a.values()[0], (Vector3{3.0f, 1.0f, 0.1f}));
}
void TrackTest::constructCopy() {
CORRADE_VERIFY(!std::is_copy_constructible<Track<Float, Vector3>>::value);
CORRADE_VERIFY(!std::is_copy_assignable<Track<Float, Vector3>>::value);
}
void TrackTest::constructMove() {
/* The move is defaulted, so verify just the right attributes */
CORRADE_VERIFY(std::is_nothrow_move_constructible<Track<Float, Vector3>>::value);
CORRADE_VERIFY(std::is_nothrow_move_assignable<Track<Float, Vector3>>::value);
CORRADE_VERIFY(std::is_nothrow_move_constructible<Track<Float, Vector3>>::value);
CORRADE_VERIFY(std::is_nothrow_move_assignable<Track<Float, Vector3>>::value);
}
void TrackTest::convertView() {
Track<Float, Vector3> a{
{{1.0f, {3.0f, 1.0f, 0.1f}},

4
src/Magnum/Animation/Track.h

@ -234,13 +234,13 @@ template<class K, class V, class R
Track(const Track<K, V, R>&) = delete;
/** @brief Move constructor */
Track(Track<K, V, R>&&) = default;
Track(Track<K, V, R>&&) noexcept = default;
/** @brief Copying is not allowed */
Track<K, V, R>& operator=(const Track<K, V, R>&) = delete;
/** @brief Move constructor */
Track<K, V, R>& operator=(Track<K, V, R>&&) = default;
Track<K, V, R>& operator=(Track<K, V, R>&&) noexcept = default;
/** @brief Conversion to a view */
operator TrackView<const K, const V, R>() const noexcept {

15
src/Magnum/Array.h

@ -141,9 +141,10 @@ CORRADE_IGNORE_DEPRECATED_PUSH
/**
@brief One-dimensional array
@tparam T Data type
@m_deprecated_since_latest Use @ref Math::Vector instead.
@m_deprecated_since_latest Use @ref Math::Vector or @ref Containers::Array1
instead.
*/
template<class T> class CORRADE_DEPRECATED("use Math::Vector instead") Array1D: public Array<1, T> {
template<class T> class CORRADE_DEPRECATED("use Math::Vector or Containers::Array1 instead") Array1D: public Array<1, T> {
public:
/** @copydoc Array::Array() */
constexpr /*implicit*/ Array1D() = default;
@ -164,9 +165,10 @@ template<class T> class CORRADE_DEPRECATED("use Math::Vector instead") Array1D:
/**
@brief Two-dimensional array
@tparam T Data type
@m_deprecated_since_latest Use @ref Math::Vector2 instead.
@m_deprecated_since_latest Use @ref Math::Vector2 or @ref Containers::Array2
instead.
*/
template<class T> class CORRADE_DEPRECATED("use Math::Vector2 instead") Array2D: public Array<2, T> {
template<class T> class CORRADE_DEPRECATED("use Math::Vector2 or Containers::Array2 instead") Array2D: public Array<2, T> {
public:
/** @copydoc Array::Array() */
constexpr /*implicit*/ Array2D() = default;
@ -198,9 +200,10 @@ template<class T> class CORRADE_DEPRECATED("use Math::Vector2 instead") Array2D
/**
@brief Three-dimensional array
@tparam T Data type
@m_deprecated_since_latest Use @ref Math::Vector3 instead.
@m_deprecated_since_latest Use @ref Math::Vector3 or @ref Containers::Array3
instead.
*/
template<class T> class CORRADE_DEPRECATED("use Math::Vector3 instead") Array3D: public Array<3, T> {
template<class T> class CORRADE_DEPRECATED("use Math::Vector3 or Containers::Array3 instead") Array3D: public Array<3, T> {
public:
/** @copydoc Array::Array() */
constexpr /*implicit*/ Array3D() {}

2
src/Magnum/Audio/Renderer.h

@ -50,7 +50,7 @@ class Renderer {
* @see @ref error()
*/
enum class Error: ALenum {
NoError = AL_NO_ERROR, /**< No error occured */
NoError = AL_NO_ERROR, /**< No error occurred */
InvalidName = AL_INVALID_NAME, /**< Invalid name parameter */
InvalidEnum = AL_INVALID_ENUM, /**< Invalid enum parameter */
InvalidValue = AL_INVALID_VALUE, /**< Invalid enum value parameter */

38
src/Magnum/DebugTools/Test/CMakeLists.txt

@ -88,6 +88,20 @@ if(WITH_TRADE)
if(WITH_TGAIMPORTER)
target_link_libraries(DebugToolsCompareImageTest PRIVATE TgaImporter)
endif()
else()
# So the plugins get properly built when building the test
if(WITH_ANYIMAGECONVERTER)
add_dependencies(DebugToolsCompareImageTest AnyImageConverter)
endif()
if(WITH_ANYIMAGEIMPORTER)
add_dependencies(DebugToolsCompareImageTest AnyImageImporter)
endif()
if(WITH_TGAIMAGECONVERTER)
add_dependencies(DebugToolsCompareImageTest TgaImageConverter)
endif()
if(WITH_TGAIMPORTER)
add_dependencies(DebugToolsCompareImageTest TgaImporter)
endif()
endif()
endif()
@ -130,6 +144,20 @@ if(TARGET_GL)
if(WITH_TGAIMPORTER)
target_link_libraries(DebugToolsScreenshotGLTest PRIVATE TgaImporter)
endif()
else()
# So the plugins get properly built when building the test
if(WITH_ANYIMAGECONVERTER)
add_dependencies(DebugToolsScreenshotGLTest AnyImageConverter)
endif()
if(WITH_ANYIMAGEIMPORTER)
add_dependencies(DebugToolsScreenshotGLTest AnyImageImporter)
endif()
if(WITH_TGAIMAGECONVERTER)
add_dependencies(DebugToolsScreenshotGLTest TgaImageConverter)
endif()
if(WITH_TGAIMPORTER)
add_dependencies(DebugToolsScreenshotGLTest TgaImporter)
endif()
endif()
if(CORRADE_BUILD_STATIC AND NOT BUILD_PLUGINS_STATIC)
@ -164,6 +192,16 @@ if(TARGET_GL)
target_link_libraries(DebugToolsForceRendererGLTest PRIVATE TgaImporter)
target_link_libraries(DebugToolsObjectRendererGLTest PRIVATE TgaImporter)
endif()
else()
# So the plugins get properly built when building the test
if(WITH_ANYIMAGEIMPORTER)
add_dependencies(DebugToolsForceRendererGLTest AnyImageImporter)
add_dependencies(DebugToolsObjectRendererGLTest AnyImageImporter)
endif()
if(WITH_TGAIMPORTER)
add_dependencies(DebugToolsForceRendererGLTest TgaImporter)
add_dependencies(DebugToolsObjectRendererGLTest TgaImporter)
endif()
endif()
endif()
endif()

40
src/Magnum/GL/AbstractShaderProgram.cpp

@ -350,11 +350,11 @@ std::pair<bool, std::string> AbstractShaderProgram::validate() {
return {success, std::move(message)};
}
void AbstractShaderProgram::draw(Mesh& mesh) {
CORRADE_ASSERT(mesh._countSet, "GL::AbstractShaderProgram::draw(): Mesh::setCount() was never called, probably a mistake?", );
AbstractShaderProgram& AbstractShaderProgram::draw(Mesh& mesh) {
CORRADE_ASSERT(mesh._countSet, "GL::AbstractShaderProgram::draw(): Mesh::setCount() was never called, probably a mistake?", *this);
/* Nothing to draw, exit without touching any state */
if(!mesh._count || !mesh._instanceCount) return;
if(!mesh._count || !mesh._instanceCount) return *this;
use();
@ -363,13 +363,14 @@ void AbstractShaderProgram::draw(Mesh& mesh) {
#else
mesh.drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._indexOffset);
#endif
return *this;
}
void AbstractShaderProgram::draw(MeshView& mesh) {
CORRADE_ASSERT(mesh._countSet, "GL::AbstractShaderProgram::draw(): MeshView::setCount() was never called, probably a mistake?", );
AbstractShaderProgram& AbstractShaderProgram::draw(MeshView& mesh) {
CORRADE_ASSERT(mesh._countSet, "GL::AbstractShaderProgram::draw(): MeshView::setCount() was never called, probably a mistake?", *this);
/* Nothing to draw, exit without touching any state */
if(!mesh._count || !mesh._instanceCount) return;
if(!mesh._count || !mesh._instanceCount) return *this;
use();
@ -378,17 +379,18 @@ void AbstractShaderProgram::draw(MeshView& mesh) {
#else
mesh._original->drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._indexOffset);
#endif
return *this;
}
void AbstractShaderProgram::draw(Containers::ArrayView<const Containers::Reference<MeshView>> meshes) {
if(meshes.empty()) return;
AbstractShaderProgram& AbstractShaderProgram::draw(Containers::ArrayView<const Containers::Reference<MeshView>> meshes) {
if(meshes.empty()) return *this;
use();
#ifndef CORRADE_NO_ASSERT
const Mesh* original = &*meshes.front()->_original;
for(std::size_t i = 0; i != meshes.size(); ++i)
CORRADE_ASSERT(&*meshes[i]->_original == original, "GL::AbstractShaderProgram::draw(): all meshes must be views of the same original mesh, expected" << original << "but got" << &*meshes[i]->_original << "at index" << i, );
CORRADE_ASSERT(&*meshes[i]->_original == original, "GL::AbstractShaderProgram::draw(): all meshes must be views of the same original mesh, expected" << original << "but got" << &*meshes[i]->_original << "at index" << i, *this);
#endif
#ifndef MAGNUM_TARGET_GLES
@ -396,34 +398,38 @@ void AbstractShaderProgram::draw(Containers::ArrayView<const Containers::Referen
#else
Context::current().state().mesh.multiDrawImplementation(meshes);
#endif
return *this;
}
void AbstractShaderProgram::draw(std::initializer_list<Containers::Reference<MeshView>> meshes) {
draw(Containers::arrayView(meshes));
AbstractShaderProgram& AbstractShaderProgram::draw(std::initializer_list<Containers::Reference<MeshView>> meshes) {
return draw(Containers::arrayView(meshes));
}
#ifndef MAGNUM_TARGET_GLES
void AbstractShaderProgram::drawTransformFeedback(Mesh& mesh, TransformFeedback& xfb, UnsignedInt stream) {
AbstractShaderProgram& AbstractShaderProgram::drawTransformFeedback(Mesh& mesh, TransformFeedback& xfb, UnsignedInt stream) {
/* Nothing to draw, exit without touching any state */
if(!mesh._instanceCount) return;
if(!mesh._instanceCount) return *this;
use();
mesh.drawInternal(xfb, stream, mesh._instanceCount);
return *this;
}
void AbstractShaderProgram::drawTransformFeedback(MeshView& mesh, TransformFeedback& xfb, UnsignedInt stream) {
/* Nothing to draw, exit without touching any state */
if(!mesh._instanceCount) return;
AbstractShaderProgram& AbstractShaderProgram::drawTransformFeedback(MeshView& mesh, TransformFeedback& xfb, UnsignedInt stream) {
/* If nothing to draw, exit without touching any state */
if(mesh._instanceCount) return *this;
use();
mesh._original->drawInternal(xfb, stream, mesh._instanceCount);
return *this;
}
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void AbstractShaderProgram::dispatchCompute(const Vector3ui& workgroupCount) {
AbstractShaderProgram& AbstractShaderProgram::dispatchCompute(const Vector3ui& workgroupCount) {
use();
glDispatchCompute(workgroupCount.x(), workgroupCount.y(), workgroupCount.z());
return *this;
}
#endif

49
src/Magnum/GL/AbstractShaderProgram.h

@ -87,12 +87,14 @@ functions and properties:
@snippet MagnumGL.cpp AbstractShaderProgram-xfb
</li>
<li>And optionally, **hiding irrelevant draw/dispatch functions** to prevent
users from accidentally calling @ref draw() on compute shaders,
@ref drawTransformFeedback() on shaders that don't have transform feedback
or @ref dispatchCompute() on shaders that aren't compute. For example:
@snippet MagnumGL.cpp AbstractShaderProgram-hide-irrelevant
<li>And optionally, **return derived type from relevant draw/dispatch functions**
to make it possible for users to easily chain draw calls, and on the other
hand **hide the irrelevant APIs** to prevent users from accidentally
calling @ref draw() on compute shaders, @ref drawTransformFeedback() on
shaders that don't have transform feedback or @ref dispatchCompute() on
shaders that aren't compute. For example:
@snippet MagnumGL.cpp AbstractShaderProgram-return-hide-irrelevant
</ul>
@subsection GL-AbstractShaderProgram-attribute-location Binding attribute and fragment data location
@ -109,7 +111,7 @@ layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 textureCoordinates;
@endcode
Similarly for ouput attributes, you can also specify blend equation color index
Similarly for output attributes, you can also specify blend equation color index
for them (see @ref Renderer::BlendFunction for more information about using
color input index):
@ -584,7 +586,7 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
static Int maxCombinedShaderOutputResources();
/**
* @brief Max supported shader storage block size
* @brief Max supported shader storage block size in bytes
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If neither extension @gl_extension{ARB,shader_storage_buffer_object}
@ -598,7 +600,7 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
#endif
/**
* @brief Max supported uniform block size
* @brief Max supported uniform block size in bytes
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @gl_extension{ARB,uniform_buffer_object}
@ -751,7 +753,7 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
/**
* @brief Draw a mesh
* @param mesh Mesh to draw
* @return Reference to self (for method chaining)
* @m_since{2020,06}
*
* Expects that @p mesh is compatible with this shader and is fully set
@ -794,16 +796,19 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
* @requires_gl Specifying base vertex for indexed meshes is not
* available in OpenGL ES or WebGL.
*/
void draw(Mesh& mesh);
AbstractShaderProgram& draw(Mesh& mesh);
/**
* @overload
* @m_since{2020,06}
*/
void draw(Mesh&& mesh) { draw(mesh); }
AbstractShaderProgram& draw(Mesh&& mesh) {
return draw(mesh);
}
/**
* @brief Draw a mesh view
* @return Reference to self (for method chaining)
* @m_since{2020,06}
*
* See @ref draw(Mesh&) for more information.
@ -828,16 +833,19 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
* @requires_gl Specifying base vertex for indexed meshes is not
* available in OpenGL ES or WebGL.
*/
void draw(MeshView& mesh);
AbstractShaderProgram& draw(MeshView& mesh);
/**
* @overload
* @m_since{2020,06}
*/
void draw(MeshView&& mesh) { draw(mesh); }
AbstractShaderProgram& draw(MeshView&& mesh) {
return draw(mesh);
}
/**
* @brief Draw multiple meshes at once
* @return Reference to self (for method chaining)
* @m_since{2020,06}
*
* On OpenGL ES, if neither @gl_extension{EXT,multi_draw_arrays} nor
@ -872,13 +880,13 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
* if the mesh is indexed and @ref MeshView::baseVertex() is not
* `0`
*/
void draw(Containers::ArrayView<const Containers::Reference<MeshView>> meshes);
AbstractShaderProgram& draw(Containers::ArrayView<const Containers::Reference<MeshView>> meshes);
/**
* @overload
* @m_since{2020,06}
*/
void draw(std::initializer_list<Containers::Reference<MeshView>> meshes);
AbstractShaderProgram& draw(std::initializer_list<Containers::Reference<MeshView>> meshes);
#ifndef MAGNUM_TARGET_GLES
/**
@ -886,6 +894,7 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
* @param mesh Mesh to draw
* @param xfb Transform feedback to use for vertex count
* @param stream Transform feedback stream ID
* @return Reference to self (for method chaining)
* @m_since{2020,06}
*
* Expects that @p mesh is compatible with this shader, is fully set up
@ -911,10 +920,11 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
* @requires_gl42 Extension @gl_extension{ARB,transform_feedback_instanced}
* if @ref Mesh::instanceCount() is more than `1`
*/
void drawTransformFeedback(Mesh& mesh, TransformFeedback& xfb, UnsignedInt stream = 0);
AbstractShaderProgram& drawTransformFeedback(Mesh& mesh, TransformFeedback& xfb, UnsignedInt stream = 0);
/**
* @brief Draw a mesh view with vertices coming out of transform feedback
* @return Reference to self (for method chaining)
* @m_since{2020,06}
*
* Everything set by @ref MeshView::setCount(),
@ -931,13 +941,14 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
* @requires_gl42 Extension @gl_extension{ARB,transform_feedback_instanced}
* if @ref MeshView::instanceCount() is more than `1`
*/
void drawTransformFeedback(MeshView& mesh, TransformFeedback& xfb, UnsignedInt stream = 0);
AbstractShaderProgram& drawTransformFeedback(MeshView& mesh, TransformFeedback& xfb, UnsignedInt stream = 0);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* @brief Dispatch compute
* @param workgroupCount Workgroup count in given dimension
* @return Reference to self (for method chaining)
*
* Valid only on programs with compute shader attached.
* @see @fn_gl{DispatchCompute}
@ -946,7 +957,7 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
* and older.
* @requires_gles Compute shaders are not available in WebGL.
*/
void dispatchCompute(const Vector3ui& workgroupCount);
AbstractShaderProgram& dispatchCompute(const Vector3ui& workgroupCount);
#endif
protected:

2
src/Magnum/GL/Attribute.h

@ -360,7 +360,7 @@ template<UnsignedInt location, class T> class Attribute {
*
* Used for describing matrix attributes. Implicitly the same as size
* of given vector type (e.g. @cpp 9 @ce for a
* @ref Magnum::Matrix3 "Matrix3"), but can be overriden for example to
* @ref Magnum::Matrix3 "Matrix3"), but can be overridden for example to
* ensure four-byte column alignment with 1- and 2-byte data types.
* @see @ref Vectors
*/

2
src/Magnum/GL/Buffer.h

@ -477,7 +477,7 @@ class MAGNUM_GL_EXPORT Buffer: public AbstractObject {
/**
* Only one or more discrete subranges of the mapping will be
* modified. See @ref flushMappedRange() for more information. May
* only be used in conjuction with @ref MapFlag::Write.
* only be used in conjunction with @ref MapFlag::Write.
*/
#ifndef MAGNUM_TARGET_GLES2
FlushExplicit = GL_MAP_FLUSH_EXPLICIT_BIT,

2
src/Magnum/GL/CMakeLists.txt

@ -176,7 +176,7 @@ add_library(MagnumGLObjects OBJECT
${MagnumGL_HEADERS}
${MagnumGL_PRIVATE_HEADERS})
# We can use both implicit include path (GLES2/gl2.h) where our headers can
# be overriden with system ones or explicit (MagnumExternal/OpenGL/GLES2/gl2ext.h)
# be overridden with system ones or explicit (MagnumExternal/OpenGL/GLES2/gl2ext.h)
# where only our headers will be used
target_include_directories(MagnumGLObjects PUBLIC
$<TARGET_PROPERTY:Magnum,INTERFACE_INCLUDE_DIRECTORIES>)

8
src/Magnum/GL/Context.cpp

@ -719,7 +719,7 @@ Context::Context(NoCreateT, Utility::Arguments& args, Int argc, const char** arg
bother with String allocations. */
const Containers::StringView disabledWorkarounds = args.value<Containers::StringView>("disable-workarounds");
if(!disabledWorkarounds.isEmpty()) {
const Containers::Array<Containers::StringView> split = disabledWorkarounds.splitWithoutEmptyParts();
const Containers::Array<Containers::StringView> split = disabledWorkarounds.splitOnWhitespaceWithoutEmptyParts();
arrayReserve(_driverWorkarounds, split.size());
for(const Containers::StringView workaround: split)
disableDriverWorkaround(workaround);
@ -730,7 +730,7 @@ Context::Context(NoCreateT, Utility::Arguments& args, Int argc, const char** arg
and another binary search in tryCreate(). */
const Containers::StringView disabledExtensions = args.value<Containers::StringView>("disable-extensions");
if(!disabledExtensions.isEmpty()) {
const Containers::Array<Containers::StringView> split = disabledExtensions.splitWithoutEmptyParts();
const Containers::Array<Containers::StringView> split = disabledExtensions.splitOnWhitespaceWithoutEmptyParts();
arrayReserve(_disabledExtensions, split.size());
for(const Containers::StringView extension: split) {
if(const Extension* found = findExtension(extension)) {
@ -751,7 +751,7 @@ Context::Context(Context&& other) noexcept:
#ifdef MAGNUM_BUILD_DEPRECATED
_supportedExtensions{std::move(other._supportedExtensions)},
#endif
_state{std::move(other._state)},
_state{other._state},
_detectedDrivers{std::move(other._detectedDrivers)},
_driverWorkarounds{std::move(other._driverWorkarounds)},
_disabledExtensions{std::move(other._disabledExtensions)},
@ -1074,7 +1074,7 @@ Containers::Array<Containers::StringView> Context::extensionStrings() const {
#ifndef MAGNUM_TARGET_GLES3
/* OpenGL 2.1 / OpenGL ES 2.0 doesn't have glGetStringi() */
return Containers::StringView{reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)), Containers::StringViewFlag::Global}.splitWithoutEmptyParts();
return Containers::StringView{reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)), Containers::StringViewFlag::Global}.splitOnWhitespaceWithoutEmptyParts();
#endif
}

2
src/Magnum/GL/Extensions.h

@ -35,7 +35,7 @@ namespace Magnum { namespace GL {
/* Standard Android build system thinks that it's okay to define unmangled
unprefixed macros. I think that whoever did that needs to be punished,
becuase I am then not able to use that identifier for extension names.
because I am then not able to use that identifier for extension names.
Use CORRADE_TARGET_ANDROID here instead. */
#ifdef ANDROID
#undef ANDROID

2
src/Magnum/GL/Implementation/driverSpecific.cpp

@ -415,7 +415,7 @@ auto Context::detectedDriver() -> DetectedDrivers {
_detectedDrivers = DetectedDrivers{};
#ifndef MAGNUM_TARGET_WEBGL
#if !defined(MAGNUM_TARGET_WEBGL) && !defined(CORRADE_TARGET_APPLE)
const Containers::StringView renderer = rendererString();
#endif
#if !defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_WEBGL)

4
src/Magnum/GL/Mesh.h

@ -275,7 +275,7 @@ this:
@snippet MagnumGL.cpp Mesh-dynamic
@section GL-Mesh-buffer-ownership Transfering buffer ownership
@section GL-Mesh-buffer-ownership Transferring buffer ownership
If a vertex/index buffer is used only by a single mesh, it's possible to
transfer its ownership to the mesh itself to simplify resource management on
@ -298,7 +298,7 @@ getting only a moved-out instance. For example:
Basic workflow is: bind specific framebuffer for drawing (if needed), set up
respective shader (see
@ref GL-AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation"
for more infromation) and call @ref AbstractShaderProgram::draw().
for more information) and call @ref AbstractShaderProgram::draw().
@section GL-Mesh-webgl-restrictions WebGL restrictions

4
src/Magnum/GL/MeshView.cpp

@ -174,8 +174,8 @@ void MeshView::multiDrawElementsBaseVertexImplementationANGLE(const GLenum mode,
Containers::ArrayView<GLsizei> instanceCount;
Containers::ArrayView<GLuint> baseInstance;
Containers::ArrayTuple data{
{Containers::NoInit, std::size_t(drawCount), instanceCount},
{Containers::ValueInit, std::size_t(drawCount), baseInstance},
{NoInit, std::size_t(drawCount), instanceCount},
{ValueInit, std::size_t(drawCount), baseInstance},
};
for(GLsizei& i: instanceCount) i = 1;

2
src/Magnum/GL/RenderbufferFormat.h

@ -114,7 +114,7 @@ enum class RenderbufferFormat: GLenum {
* RGBA, each component normalized unsigned byte.
* @requires_gles30 Extension @gl_extension{ARM,rgba8} or @gl_extension{OES,rgb8_rgba8}
* in OpenGL ES 2.0.
* @requires_webgl20 Not availabe in WebGL 1.0, use for example
* @requires_webgl20 Not available in WebGL 1.0, use for example
* @ref RenderbufferFormat::RGB565 or @ref RenderbufferFormat::RGBA4
* instead.
*/

2
src/Magnum/GL/Renderer.h

@ -2114,7 +2114,7 @@ class MAGNUM_GL_EXPORT Renderer {
* WebGL.
*/
enum class GraphicsResetStatus: GLenum {
/** No reset occured since last call. */
/** No reset occurred since last call. */
NoError = GL_NO_ERROR,
/**

8
src/Magnum/GL/Test/CMakeLists.txt

@ -168,6 +168,14 @@ if(BUILD_GL_TESTS)
if(WITH_TGAIMPORTER)
target_link_libraries(GLRendererGLTest PRIVATE TgaImporter)
endif()
else()
# So the plugins get properly built when building the test
if(WITH_ANYIMAGEIMPORTER)
add_dependencies(GLRendererGLTest AnyImageImporter)
endif()
if(WITH_TGAIMPORTER)
add_dependencies(GLRendererGLTest TgaImporter)
endif()
endif()
corrade_add_test(GLShaderGLTest ShaderGLTest.cpp

2
src/Magnum/GL/Test/ContextTest.cpp

@ -101,7 +101,7 @@ void ContextTest::isExtension() {
}
/* Variadic check (used in variadic Configuration::addDisabledExtensions()),
check that it properly fails for each occurence of a non-extension */
check that it properly fails for each occurrence of a non-extension */
#ifndef MAGNUM_TARGET_WEBGL
CORRADE_VERIFY(Implementation::IsExtension<
Extensions::KHR::debug,

10
src/Magnum/Implementation/converterUtilities.h

@ -38,7 +38,7 @@ namespace Magnum { namespace Implementation {
/* Used only in executables where we don't want it to be exported */
namespace {
void setOptions(PluginManager::AbstractPlugin& plugin, const std::string& options) {
void setOptions(PluginManager::AbstractPlugin& plugin, const std::string& anyPluginName, const std::string& options) {
for(const std::string& option: Utility::String::splitWithoutEmptyParts(options, ',')) {
auto keyValue = Utility::String::partition(option, '=');
Utility::String::trimInPlace(keyValue[0]);
@ -60,8 +60,12 @@ void setOptions(PluginManager::AbstractPlugin& plugin, const std::string& option
/* Provide a warning message in case the plugin doesn't define given
option in its default config. The plugin is not *required* to have
those tho (could be backward compatibility entries, for example), so
not an error. */
if(groupNotRecognized || !group->hasValue(keyParts.back())) {
not an error.
If it's an Any* plugin, then this check is provided by it directly,
and since the Any* plugin obviously don't expose the options of the concrete plugins, this warning would fire for them always, which
wouldn't help anything. */
if((groupNotRecognized || !group->hasValue(keyParts.back())) && plugin.plugin() != anyPluginName) {
Warning{} << "Option" << keyValue[0] << "not recognized by" << plugin.plugin();
}

6
src/Magnum/Magnum.h

@ -1171,9 +1171,9 @@ typedef Math::Frustum<Double> Frustumd;
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifdef MAGNUM_BUILD_DEPRECATED
template<UnsignedInt, class T> class CORRADE_DEPRECATED("use Math::Vector instead") Array;
template<class T> class CORRADE_DEPRECATED("use Math::Vector instead") Array1D;
template<class T> class CORRADE_DEPRECATED("use Math::Vector2 instead") Array2D;
template<class T> class CORRADE_DEPRECATED("use Math::Vector3 instead") Array3D;
template<class T> class CORRADE_DEPRECATED("use Math::Vector or Containers::Array1 instead") Array1D;
template<class T> class CORRADE_DEPRECATED("use Math::Vector2 or Containers::Array2 instead") Array2D;
template<class T> class CORRADE_DEPRECATED("use Math::Vector3 or Containers::Array3 instead") Array3D;
#endif
enum class InputFileCallbackPolicy: UnsignedByte;

4
src/Magnum/Math/DualComplex.h

@ -108,7 +108,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
}
/**
* @brief Create dual complext from rotation complex and translation vector
* @brief Create dual complex from rotation complex and translation vector
* @m_since_latest
*
* @f[
@ -242,7 +242,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
}
/**
* @brief Multipy with dual complex number
* @brief Multiply with dual complex number
*
* @f[
* \hat a \hat b = a_0 b_0 + \epsilon (a_0 b_\epsilon + a_\epsilon)

4
src/Magnum/MeshTools/RemoveDuplicates.cpp

@ -73,7 +73,7 @@ std::size_t removeDuplicatesInto(const Containers::StridedArrayView2D<const char
CORRADE_ASSERT(indices.size() == dataSize,
"MeshTools::removeDuplicatesInto(): output index array has" << indices.size() << "elements but expected" << dataSize, {});
/* Table containing index of first occurence for each unique entry.
/* Table containing index of first occurrence for each unique entry.
Reserving more buckets than necessary (i.e. as if each entry was
unique). */
std::unordered_map<const void*, UnsignedInt, ArrayHash, ArrayEqual> table{
@ -113,7 +113,7 @@ std::size_t removeDuplicatesInPlaceInto(const Containers::StridedArrayView2D<cha
CORRADE_ASSERT(indices.size() == dataSize,
"MeshTools::removeDuplicatesInPlaceInto(): output index array has" << indices.size() << "elements but expected" << dataSize, {});
/* Table containing index of first occurence for each unique entry.
/* Table containing index of first occurrence for each unique entry.
Reserving more buckets than necessary (i.e. as if each entry was
unique). */
std::unordered_map<const void*, UnsignedInt, ArrayHash, ArrayEqual> table{

8
src/Magnum/MeshTools/Test/CMakeLists.txt

@ -133,5 +133,13 @@ if(BUILD_GL_TESTS)
if(WITH_TGAIMPORTER)
target_link_libraries(MeshToolsCompileGLTest PRIVATE TgaImporter)
endif()
else()
# So the plugins get properly built when building the test
if(WITH_ANYIMAGEIMPORTER)
add_dependencies(MeshToolsCompileGLTest AnyImageImporter)
endif()
if(WITH_TGAIMPORTER)
add_dependencies(MeshToolsCompileGLTest TgaImporter)
endif()
endif()
endif()

2
src/Magnum/MeshTools/Tipsify.cpp

@ -39,7 +39,7 @@ template<class T> void tipsifyInPlaceImplementation(const Containers::StridedArr
Containers::Array<UnsignedInt> liveTriangleCount, neighborOffset, neighbors;
Implementation::buildAdjacency<T>(indices, vertexCount, liveTriangleCount, neighborOffset, neighbors);
/* Global time, per-vertex caching timestamps, per-triangle emmited flag */
/* Global time, per-vertex caching timestamps, per-triangle emitted flag */
UnsignedInt time = cacheSize+1;
Containers::Array<UnsignedInt> timestamp{vertexCount};
/** @todo Have some bitset/staticbitset class for this */

2
src/Magnum/MeshTools/Tipsify.h

@ -53,7 +53,7 @@ Optimizes the mesh for vertex-bound applications by rearranging its index
array for beter usage of post-transform vertex cache. Algorithm used:
* *Pedro V. Sander, Diego Nehab, and Joshua Barczak --- Fast Triangle Reordering
for Vertex Locality and Reduced Overdraw, SIGGRAPH 2007,
http://gfx.cs.princeton.edu/pubs/Sander_2007_%3ETR/index.php*.
https://gfx.cs.princeton.edu/pubs/Sander_2007_%3eTR/tipsy.pdf*.
@todo Ability to compute vertex count automatically
*/
MAGNUM_MESHTOOLS_EXPORT void tipsifyInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, UnsignedInt vertexCount, std::size_t cacheSize);

4
src/Magnum/MeshTools/sceneconverter.cpp

@ -263,7 +263,7 @@ used.)")
/* Set options, if passed */
if(args.isSet("verbose")) importer->addFlags(Trade::ImporterFlag::Verbose);
Implementation::setOptions(*importer, args.value("importer-options"));
Implementation::setOptions(*importer, "AnySceneImporter", args.value("importer-options"));
std::chrono::high_resolution_clock::duration importTime;
@ -823,7 +823,7 @@ used.)")
/* Set options, if passed */
if(args.isSet("verbose")) converter->addFlags(Trade::SceneConverterFlag::Verbose);
if(i < args.arrayValueCount("converter-options"))
Implementation::setOptions(*converter, args.arrayValue("converter-options", i));
Implementation::setOptions(*converter, "AnySceneConverter", args.arrayValue("converter-options", i));
/* This is the last --converter (or the implicit AnySceneConverter at
the end), output to a file and exit the loop */

4
src/Magnum/Platform/AndroidApplication.h

@ -766,7 +766,7 @@ class AndroidApplication::MouseEvent: public InputEvent {
/**
* Left mouse button. Note that this button is not set if only
* touch or stylus event occured.
* touch or stylus event occurred.
* @attention Available since Android 4.0 (API level 14), not
* detectable in earlier versions.
*/
@ -851,7 +851,7 @@ class AndroidApplication::MouseMoveEvent: public InputEvent {
enum class Button: std::int32_t {
/**
* Left mouse button. Note that this button is not set if only
* touch or stylus event occured.
* touch or stylus event occurred.
* @attention Available since Android 4.0 (API level 14), not
* detectable in earlier versions.
*/

4
src/Magnum/Platform/EmscriptenApplication.cpp

@ -284,7 +284,7 @@ void EmscriptenApplication::create(const Configuration& configuration, const GLC
Vector2 EmscriptenApplication::dpiScaling(const Configuration& configuration) const {
std::ostream* verbose = _verboseLog ? Debug::output() : nullptr;
/* Use values from the configuration only if not overriden on command line.
/* Use values from the configuration only if not overridden on command line.
In any case explicit scaling has a precedence before the policy. */
if(!_commandLineDpiScaling.isZero()) {
Debug{verbose} << "Platform::EmscriptenApplication: user-defined DPI scaling" << _commandLineDpiScaling;
@ -824,7 +824,7 @@ void EmscriptenApplication::redraw() {
is possible), and no amount of \\\\$$$ helps avoiding that
xylophone); but doing so means we forever hardcode what
functions are exported and thus whatever extra Emscripten needs
to export will be overriden by this, causing only pain and
to export will be overridden by this, causing only pain and
misery.
So instead we rely on the implementation details of dynCall,

2
src/Magnum/Platform/EmscriptenApplication.h

@ -234,7 +234,7 @@ for a guide covering all platform differences.
For this application in particular, @ref windowSize() can be different than
@ref framebufferSize() on HiDPI displays --- which is different from
@ref Sdl2Application behavior on Emscripten. By default, @ref dpiScaling() is
@cpp 1.0f @ce in both dimensions but it can be overriden using custom DPI
@cpp 1.0f @ce in both dimensions but it can be overridden using custom DPI
scaling --- the `--magnum-dpi-scaling` command-line options are supported the
same way as in @ref Sdl2Application, only in the form of URL GET parameters,
similarly to all other @ref platforms-html5-environment "command-line options".

2
src/Magnum/Platform/GlfwApplication.cpp

@ -147,7 +147,7 @@ Vector2 GlfwApplication::dpiScaling(const Configuration& configuration) {
/** @todo */
#endif
/* Use values from the configuration only if not overriden on command line
/* Use values from the configuration only if not overridden on command line
to something non-default. In any case explicit scaling has a precedence
before the policy. */
Implementation::GlfwDpiScalingPolicy dpiScalingPolicy{};

6
src/Magnum/Platform/GlfwApplication.h

@ -116,6 +116,10 @@ the first part and point `CMAKE_PREFIX_PATH` to its installation dir if
necessary.
@code{.cmake}
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
# These two will be off-by-default when GLFW 3.4 gets released
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory(glfw EXCLUDE_FROM_ALL)
set(WITH_GLFWAPPLICATION ON CACHE BOOL "" FORCE)
@ -1120,7 +1124,7 @@ class GlfwApplication::Configuration {
* @brief DPI scaling policy
*
* DPI scaling policy when requesting a particular window size. Can
* be overriden on command-line using `--magnum-dpi-scaling` or via
* be overridden on command-line using `--magnum-dpi-scaling` or via
* the `MAGNUM_DPI_SCALING` environment variable.
* @see @ref setSize(), @ref Platform-Sdl2Application-dpi
*/

4
src/Magnum/Platform/Sdl2Application.cpp

@ -207,7 +207,7 @@ Vector2 Sdl2Application::dpiScaling(const Configuration& configuration) {
/* Handled below, warning printed only when using virtual DPI scaling */
#endif
/* Use values from the configuration only if not overriden on command line
/* Use values from the configuration only if not overridden on command line
to something non-default. In any case explicit scaling has a precedence
before the policy. */
Implementation::Sdl2DpiScalingPolicy dpiScalingPolicy{};
@ -887,7 +887,7 @@ bool Sdl2Application::mainLoopIteration() {
switch(event.type) {
case SDL_WINDOWEVENT:
switch(event.window.event) {
/* Not using SDL_WINDOWEVENT_RESIZED, because that doens't
/* Not using SDL_WINDOWEVENT_RESIZED, because that doesn't
get fired when the window is resized programmatically
(such as through setMaxWindowSize()) */
case SDL_WINDOWEVENT_SIZE_CHANGED: {

10
src/Magnum/Platform/Sdl2Application.h

@ -419,25 +419,25 @@ The default is depending on the platform:
@ref windowSize() and @ref framebufferSize() will differ depending on
whether `NSHighResolutionCapable` is enabled in the `*.plist` file or not.
By default, @ref dpiScaling() is @cpp 1.0f @ce in both dimensions but it
can be overriden using custom DPI scaling.
can be overridden using custom DPI scaling.
- On Windows, the default is @ref Configuration::DpiScalingPolicy::Framebuffer.
The @ref windowSize() and @ref framebufferSize() is always the same.
Depending on whether the DPI awareness was enabled in the manifest file or
set by the `SetProcessDpiAwareness()` API, @ref dpiScaling() is either
@cpp 1.0f @ce in both dimensions, indicating a low-DPI screen or a
non-DPI-aware app, or some other value for HiDPI screens. In both cases the
value can be overriden using custom DPI scaling.
value can be overridden using custom DPI scaling.
- On Linux, the default is @ref Configuration::DpiScalingPolicy::Virtual,
taken from the `Xft.dpi` property. If the property is not available, it
falls back to @ref Configuration::DpiScalingPolicy::Physical, querying the
monitor DPI value. The @ref windowSize() and @ref framebufferSize() is
always the same, @ref dpiScaling() contains the queried DPI scaling value.
The value can be overriden using custom DPI scaling.
The value can be overridden using custom DPI scaling.
- On @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten", the default is physical DPI
scaling, taken from [Window.getDevicePixelRatio()](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio). The
@ref windowSize() and @ref framebufferSize() is always the same,
@ref dpiScaling() contains the queried DPI scaling value. The value can be
overriden using custom DPI scaling. Note that this is different from the
overridden using custom DPI scaling. Note that this is different from the
behavior in @ref EmscriptenApplication --- Emscripten's SDL implementation
has some additional emulation code that reports event coordinates in
framebuffer pixels instead of CSS pixels. See
@ -1755,7 +1755,7 @@ class Sdl2Application::Configuration {
* @brief DPI scaling policy
*
* DPI scaling policy when requesting a particular window size. Can
* be overriden on command-line using `--magnum-dpi-scaling` or via
* be overridden on command-line using `--magnum-dpi-scaling` or via
* the `MAGNUM_DPI_SCALING` environment variable.
* @see @ref setSize(), @ref Platform-Sdl2Application-dpi
*/

4
src/Magnum/Platform/WindowlessCglApplication.cpp

@ -72,7 +72,7 @@ WindowlessCglContext::WindowlessCglContext(const Configuration& configuration, G
Error() << "Platform::WindowlessCglContext: cannot create context";
}
WindowlessCglContext::WindowlessCglContext(WindowlessCglContext&& other): _pixelFormat{other._pixelFormat}, _context{other._context} {
WindowlessCglContext::WindowlessCglContext(WindowlessCglContext&& other) noexcept: _pixelFormat{other._pixelFormat}, _context{other._context} {
other._pixelFormat = {};
other._context = {};
}
@ -82,7 +82,7 @@ WindowlessCglContext::~WindowlessCglContext() {
if(_pixelFormat) CGLDestroyPixelFormat(_pixelFormat);
}
WindowlessCglContext& WindowlessCglContext::operator=(WindowlessCglContext&& other) {
WindowlessCglContext& WindowlessCglContext::operator=(WindowlessCglContext&& other) noexcept {
using std::swap;
swap(other._pixelFormat, _pixelFormat);
swap(other._context, _context);

4
src/Magnum/Platform/WindowlessCglApplication.h

@ -98,13 +98,13 @@ class WindowlessCglContext {
WindowlessCglContext(const WindowlessCglContext&) = delete;
/** @brief Move constructor */
WindowlessCglContext(WindowlessCglContext&& other);
WindowlessCglContext(WindowlessCglContext&& other) noexcept;
/** @brief Copying is not allowed */
WindowlessCglContext& operator=(const WindowlessCglContext&) = delete;
/** @brief Move assignment */
WindowlessCglContext& operator=(WindowlessCglContext&& other);
WindowlessCglContext& operator=(WindowlessCglContext&& other) noexcept;
/**
* @brief Destructor

4
src/Magnum/Platform/WindowlessEglApplication.cpp

@ -499,7 +499,7 @@ WindowlessEglContext::WindowlessEglContext(const Configuration& configuration, G
#endif
}
WindowlessEglContext::WindowlessEglContext(WindowlessEglContext&& other):
WindowlessEglContext::WindowlessEglContext(WindowlessEglContext&& other) noexcept:
#ifndef MAGNUM_TARGET_WEBGL
_sharedContext{other._sharedContext},
#endif
@ -541,7 +541,7 @@ WindowlessEglContext::~WindowlessEglContext() {
_display) eglTerminate(_display);
}
WindowlessEglContext& WindowlessEglContext::operator=(WindowlessEglContext&& other) {
WindowlessEglContext& WindowlessEglContext::operator=(WindowlessEglContext&& other) noexcept {
using std::swap;
#ifndef MAGNUM_TARGET_WEBGL
swap(other._sharedContext, _sharedContext);

4
src/Magnum/Platform/WindowlessEglApplication.h

@ -108,13 +108,13 @@ class WindowlessEglContext {
WindowlessEglContext(const WindowlessEglContext&) = delete;
/** @brief Move constructor */
WindowlessEglContext(WindowlessEglContext&& other);
WindowlessEglContext(WindowlessEglContext&& other) noexcept;
/** @brief Copying is not allowed */
WindowlessEglContext& operator=(const WindowlessEglContext&) = delete;
/** @brief Move assignment */
WindowlessEglContext& operator=(WindowlessEglContext&& other);
WindowlessEglContext& operator=(WindowlessEglContext&& other) noexcept;
/**
* @brief Destructor

4
src/Magnum/Platform/WindowlessGlxApplication.cpp

@ -280,7 +280,7 @@ WindowlessGlxContext::WindowlessGlxContext(const WindowlessGlxContext::Configura
}
}
WindowlessGlxContext::WindowlessGlxContext(WindowlessGlxContext&& other): _display{other._display}, _pbuffer{other._pbuffer}, _context{other._context} {
WindowlessGlxContext::WindowlessGlxContext(WindowlessGlxContext&& other) noexcept: _display{other._display}, _pbuffer{other._pbuffer}, _context{other._context} {
other._display = {};
other._context = {};
other._pbuffer = {};
@ -292,7 +292,7 @@ WindowlessGlxContext::~WindowlessGlxContext() {
if(_display) XCloseDisplay(_display);
}
WindowlessGlxContext& WindowlessGlxContext::operator=(WindowlessGlxContext&& other) {
WindowlessGlxContext& WindowlessGlxContext::operator=(WindowlessGlxContext&& other) noexcept {
using std::swap;
swap(other._display, _display);
swap(other._pbuffer, _pbuffer);

4
src/Magnum/Platform/WindowlessGlxApplication.h

@ -119,13 +119,13 @@ class WindowlessGlxContext {
WindowlessGlxContext(const WindowlessGlxContext&) = delete;
/** @brief Move constructor */
WindowlessGlxContext(WindowlessGlxContext&& other);
WindowlessGlxContext(WindowlessGlxContext&& other) noexcept;
/** @brief Copying is not allowed */
WindowlessGlxContext& operator=(const WindowlessGlxContext&) = delete;
/** @brief Move assignment */
WindowlessGlxContext& operator=(WindowlessGlxContext&& other);
WindowlessGlxContext& operator=(WindowlessGlxContext&& other) noexcept;
/**
* @brief Destructor

4
src/Magnum/Platform/WindowlessIosApplication.h

@ -91,13 +91,13 @@ class WindowlessIosContext {
WindowlessIosContext(const WindowlessIosContext&) = delete;
/** @brief Move constructor */
WindowlessIosContext(WindowlessIosContext&& other);
WindowlessIosContext(WindowlessIosContext&& other) noexcept;
/** @brief Copying is not allowed */
WindowlessIosContext& operator=(const WindowlessIosContext&) = delete;
/** @brief Move assignment */
WindowlessIosContext& operator=(WindowlessIosContext&& other);
WindowlessIosContext& operator=(WindowlessIosContext&& other) noexcept;
/**
* @brief Destructor

4
src/Magnum/Platform/WindowlessIosApplication.mm

@ -52,7 +52,7 @@ WindowlessIosContext::WindowlessIosContext(const Configuration&, GLContext*) {
}
}
WindowlessIosContext::WindowlessIosContext(WindowlessIosContext&& other): _context{other._context} {
WindowlessIosContext::WindowlessIosContext(WindowlessIosContext&& other) noexcept: _context{other._context} {
other._context = {};
}
@ -60,7 +60,7 @@ WindowlessIosContext::~WindowlessIosContext() {
if(_context) [_context dealloc];
}
WindowlessIosContext& WindowlessIosContext::operator=(WindowlessIosContext&& other) {
WindowlessIosContext& WindowlessIosContext::operator=(WindowlessIosContext&& other) noexcept {
using std::swap;
swap(other._context, _context);
return *this;

4
src/Magnum/Platform/WindowlessWglApplication.cpp

@ -266,7 +266,7 @@ WindowlessWglContext::WindowlessWglContext(const Configuration& configuration, G
Error() << "Platform::WindowlessWglContext: cannot create context:" << GetLastError();
}
WindowlessWglContext::WindowlessWglContext(WindowlessWglContext&& other): _window{other._window}, _deviceContext{other._deviceContext}, _context{other._context} {
WindowlessWglContext::WindowlessWglContext(WindowlessWglContext&& other) noexcept: _window{other._window}, _deviceContext{other._deviceContext}, _context{other._context} {
other._window = {};
other._deviceContext = {};
other._context = {};
@ -277,7 +277,7 @@ WindowlessWglContext::~WindowlessWglContext() {
if(_window) DestroyWindow(_window);
}
WindowlessWglContext& WindowlessWglContext::operator=(WindowlessWglContext&& other) {
WindowlessWglContext& WindowlessWglContext::operator=(WindowlessWglContext&& other) noexcept {
using std::swap;
swap(other._window, _window);
swap(other._deviceContext, _deviceContext);

4
src/Magnum/Platform/WindowlessWglApplication.h

@ -106,13 +106,13 @@ class WindowlessWglContext {
WindowlessWglContext(const WindowlessWglContext&) = delete;
/** @brief Move constructor */
WindowlessWglContext(WindowlessWglContext&& other);
WindowlessWglContext(WindowlessWglContext&& other) noexcept;
/** @brief Copying is not allowed */
WindowlessWglContext& operator=(const WindowlessWglContext&) = delete;
/** @brief Move assignment */
WindowlessWglContext& operator=(WindowlessWglContext&& other);
WindowlessWglContext& operator=(WindowlessWglContext&& other) noexcept;
/**
* @brief Destructor

4
src/Magnum/Platform/WindowlessWindowsEglApplication.cpp

@ -163,7 +163,7 @@ WindowlessWindowsEglContext::WindowlessWindowsEglContext(const Configuration& co
Error() << "Platform::WindowlessWindowsEglContext: cannot create window surface:" << Implementation::eglErrorString(eglGetError());
}
WindowlessWindowsEglContext::WindowlessWindowsEglContext(WindowlessWindowsEglContext&& other): _window{other._window}, _display{other._display}, _surface{other._surface}, _context{other._context} {
WindowlessWindowsEglContext::WindowlessWindowsEglContext(WindowlessWindowsEglContext&& other) noexcept: _window{other._window}, _display{other._display}, _surface{other._surface}, _context{other._context} {
other._window = {};
other._display = {};
other._surface = {};
@ -177,7 +177,7 @@ WindowlessWindowsEglContext::~WindowlessWindowsEglContext() {
if(_window) DestroyWindow(_window);
}
WindowlessWindowsEglContext& WindowlessWindowsEglContext::operator=(WindowlessWindowsEglContext&& other) {
WindowlessWindowsEglContext& WindowlessWindowsEglContext::operator=(WindowlessWindowsEglContext&& other) noexcept {
using std::swap;
swap(other._window, _window);
swap(other._display, _display);

4
src/Magnum/Platform/WindowlessWindowsEglApplication.h

@ -91,13 +91,13 @@ class WindowlessWindowsEglContext {
WindowlessWindowsEglContext(const WindowlessWindowsEglContext&) = delete;
/** @brief Move constructor */
WindowlessWindowsEglContext(WindowlessWindowsEglContext&& other);
WindowlessWindowsEglContext(WindowlessWindowsEglContext&& other) noexcept;
/** @brief Copying is not allowed */
WindowlessWindowsEglContext& operator=(const WindowlessWindowsEglContext&) = delete;
/** @brief Move assignment */
WindowlessWindowsEglContext& operator=(WindowlessWindowsEglContext&& other);
WindowlessWindowsEglContext& operator=(WindowlessWindowsEglContext&& other) noexcept;
/**
* @brief Destructor

4
src/Magnum/Primitives/Test/GradientTest.cpp

@ -60,7 +60,7 @@ GradientTest::GradientTest() {
using namespace Magnum::Math::Literals;
void GradientTest::gradient2D() {
/* The corners sould have 0.2, 0.4, 0.6, 0.8 blends */
/* The corners should have 0.2, 0.4, 0.6, 0.8 blends */
Trade::MeshData gradient = Primitives::gradient2D(
{-1.0f, 2.0f}, {0.2f, 0.6f, 1.0f},
{1.0f, -2.0f}, {0.4f, 1.0f, 0.0f});
@ -115,7 +115,7 @@ void GradientTest::gradient2DVertical() {
}
void GradientTest::gradient3D() {
/* The corners sould have 0.2, 0.4, 0.6, 0.8 blends */
/* The corners should have 0.2, 0.4, 0.6, 0.8 blends */
Trade::MeshData gradient = Primitives::gradient3D(
{-1.0f, 2.0f, -1.5f}, {0.2f, 0.6f, 1.0f},
{1.0f, -2.0f, -1.5f}, {0.4f, 1.0f, 0.0f});

2
src/Magnum/ResourceManager.h

@ -570,7 +570,7 @@ template<class T> struct ResourceManagerData<T>::Data {
Data(const Data&) = delete;
Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) {
Data(Data&& other) noexcept: data{other.data}, state{other.state}, policy{other.policy}, referenceCount{other.referenceCount} {
other.data = nullptr;
other.referenceCount = 0;
}

10
src/Magnum/SceneGraph/Object.hpp

@ -211,7 +211,7 @@ template<class Transformation> std::vector<typename Transformation::DataType> Ob
/* Mark all original objects as joints and create initial list of joints
from them */
for(std::size_t i = 0; i != objects.size(); ++i) {
/* Multiple occurences of one object in the array, don't overwrite it
/* Multiple occurrences of one object in the array, don't overwrite it
with different counter */
if(objects[i].get().counter != 0xFFFFu) continue;
@ -231,7 +231,7 @@ template<class Transformation> std::vector<typename Transformation::DataType> Ob
/* Mark all objects up the hierarchy as visited */
auto it = objects.begin();
while(!objects.empty()) {
/* Already visited, remove and continue to next (duplicate occurence) */
/* Already visited, remove and continue to next (duplicate occurrence) */
if(it->get().flags & Flag::Visited) {
it = objects.erase(it);
continue;
@ -276,7 +276,7 @@ template<class Transformation> std::vector<typename Transformation::DataType> Ob
for(std::size_t i = 0; i != jointTransformations.size(); ++i)
computeJointTransformation(jointObjects, jointTransformations, i, finalTransformation);
/* Copy transformation for second or next occurences from first occurence
/* Copy transformation for second or next occurrences from first occurrence
of duplicate object */
for(std::size_t i = 0; i != objectCount; ++i) {
if(jointObjects[i].get().counter != i)
@ -285,7 +285,7 @@ template<class Transformation> std::vector<typename Transformation::DataType> Ob
/* All visited marks are now cleaned, clean joint marks and counters */
for(auto i: jointObjects) {
/* All not-already cleaned objects (...duplicate occurences) should
/* All not-already cleaned objects (...duplicate occurrences) should
have joint mark */
CORRADE_INTERNAL_ASSERT(i.get().counter == 0xFFFFu || i.get().flags & Flag::Joint);
i.get().flags &= ~Flag::Joint;
@ -301,7 +301,7 @@ template<class Transformation> typename Transformation::DataType Object<Transfor
std::reference_wrapper<Object<Transformation>> o = jointObjects[joint];
/* Transformation already computed ("unvisited" by this function before
either due to recursion or duplicate object occurences), done */
either due to recursion or duplicate object occurrences), done */
if(!(o.get().flags & Flag::Visited)) return jointTransformations[joint];
/* Initialize transformation */

2
src/Magnum/SceneGraph/Test/AnimableTest.cpp

@ -370,7 +370,7 @@ template<class T> void AnimableTest::pause() {
CORRADE_COMPARE(animable.time, 1.5f);
/* Unpausing, next step should continue from absolute time when pause
occured */
occurred */
animable.setState(AnimationState::Running);
group.step(5.0f, 0.5f);
CORRADE_COMPARE(animable.state(), AnimationState::Running);

2
src/Magnum/ShaderTools/shaderconverter.cpp

@ -366,7 +366,7 @@ see documentation of a particular converter for more information.)")
/* Set options if passed */
if(i < args.arrayValueCount("converter-options"))
Implementation::setOptions(*converter, args.arrayValue("converter-options", i));
Implementation::setOptions(*converter, "AnyShaderConverter", args.arrayValue("converter-options", i));
/* Parse format, if passed. If --info is desired, implicitly set the
output format to SPIR-V */

70
src/Magnum/Shaders/AbstractVector.h

@ -1,70 +0,0 @@
#ifndef Magnum_Shaders_AbstractVector_h
#define Magnum_Shaders_AbstractVector_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifdef MAGNUM_BUILD_DEPRECATED
/** @file
* @brief Typedef @ref Magnum::Shaders::AbstractVector, alias @ref Magnum::Shaders::AbstractVector2D, @ref Magnum::Shaders::AbstractVector3D
* @m_deprecated_since_latest Use @ref Magnum/Shaders/AbstractVectorGL.h, the
* @ref Magnum::Shaders::AbstractVectorGL "AbstractVectorGL" class and
* related typedefs instead.
*/
#endif
#include "Magnum/configure.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#include <Corrade/Utility/Macros.h>
#include "Magnum/Shaders/AbstractVectorGL.h"
CORRADE_DEPRECATED_FILE("use Magnum/Shaders/AbstractVectorGL.h, the AbstractVectorGL class and related typedefs instead")
namespace Magnum { namespace Shaders {
/** @brief @copybrief AbstractVectorGL
* @m_deprecated_since_latest Use @ref AbstractVectorGL instead.
*/
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Multiple definitions still broken */
template<UnsignedInt dimensions> using AbstractVector CORRADE_DEPRECATED_ALIAS("use AbstractVectorGL instead") = AbstractVectorGL<dimensions>;
#endif
/** @brief @copybrief AbstractVectorGL2D
* @m_deprecated_since_latest Use @ref AbstractVectorGL2D instead.
*/
typedef CORRADE_DEPRECATED("use AbstractVectorGL2D instead") AbstractVectorGL2D AbstractVector2D;
/** @brief @copybrief AbstractVectorGL3D
* @m_deprecated_since_latest Use @ref AbstractVectorGL3D instead.
*/
typedef CORRADE_DEPRECATED("use AbstractVectorGL3D instead") AbstractVectorGL3D AbstractVector3D;
}}
#else
#error use Magnum/Shaders/AbstractVectorGL.h, the AbstractVectorGL class and related typedefs instead
#endif
#endif

43
src/Magnum/Shaders/AbstractVectorGL.cpp

@ -1,43 +0,0 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "AbstractVectorGL.h"
#include "Magnum/GL/Texture.h"
#include "Magnum/Shaders/visibility.h"
namespace Magnum { namespace Shaders {
template<UnsignedInt dimensions> AbstractVectorGL<dimensions>& AbstractVectorGL<dimensions>::bindVectorTexture(GL::Texture2D& texture) {
texture.bind(VectorTextureUnit);
return *this;
}
#ifndef DOXYGEN_GENERATING_OUTPUT
template class MAGNUM_SHADERS_EXPORT AbstractVectorGL<2>;
template class MAGNUM_SHADERS_EXPORT AbstractVectorGL<3>;
#endif
}}

134
src/Magnum/Shaders/AbstractVectorGL.h

@ -1,134 +0,0 @@
#ifndef Magnum_Shaders_AbstractVectorGL_h
#define Magnum_Shaders_AbstractVectorGL_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/** @file
* @brief Class @ref Magnum::Shaders::AbstractVectorGL, typedef @ref Magnum::Shaders::AbstractVectorGL2D, @ref Magnum::Shaders::AbstractVectorGL3D
* @m_since_latest
*/
#include "Magnum/GL/AbstractShaderProgram.h"
#include "Magnum/Shaders/GenericGL.h"
namespace Magnum { namespace Shaders {
/**
@brief Base for vector OpenGL shaders
@m_since_latest
See @ref DistanceFieldVectorGL and @ref VectorGL for more information.
@see @ref shaders, @ref AbstractVectorGL2D, @ref AbstractVectorGL3D
*/
template<UnsignedInt dimensions> class AbstractVectorGL: public GL::AbstractShaderProgram {
public:
/**
* @brief Vertex position
*
* @ref shaders-generic "Generic attribute",
* @ref Magnum::Vector2 "Vector2" in 2D, @ref Magnum::Vector3 "Vector3"
* in 3D.
*/
typedef typename GenericGL<dimensions>::Position Position;
/**
* @brief 2D texture coordinates
*
* @ref shaders-generic "Generic attribute",
* @ref Magnum::Vector2 "Vector2".
*/
typedef typename GenericGL<dimensions>::TextureCoordinates TextureCoordinates;
enum: UnsignedInt {
/**
* Color shader output. @ref shaders-generic "Generic output",
* present always. Expects three- or four-component floating-point
* or normalized buffer attachment.
*/
ColorOutput = GenericGL<dimensions>::ColorOutput
};
/** @brief Copying is not allowed */
AbstractVectorGL(const AbstractVectorGL<dimensions>&) = delete;
/** @brief Move constructor */
AbstractVectorGL(AbstractVectorGL<dimensions>&&) noexcept = default;
/** @brief Copying is not allowed */
AbstractVectorGL<dimensions>& operator=(const AbstractVectorGL<dimensions>&) = delete;
/** @brief Move assignment */
AbstractVectorGL<dimensions>& operator=(AbstractVectorGL<dimensions>&&) noexcept = default;
/** @{
* @name Texture binding
*/
/**
* @brief Bind vector texture
* @return Reference to self (for method chaining)
*
* @see @ref DistanceFieldVectorGL::Flag::TextureTransformation,
* @ref VectorGL::Flag::TextureTransformation,
* @ref DistanceFieldVectorGL::setTextureMatrix(),
* @ref VectorGL::setTextureMatrix()
*/
AbstractVectorGL<dimensions>& bindVectorTexture(GL::Texture2D& texture);
/**
* @}
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/* Those textures are quite specific (and likely reused multiple times
per frame for e.g. text rendering, so put them in a specific slot.
Older iOS (and iOS WebGL) has only 8 texture units, so can't go
above that. Unit 7 is used by TextureTools::DistanceField. */
enum: Int { VectorTextureUnit = 6 };
explicit AbstractVectorGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
explicit AbstractVectorGL() = default;
~AbstractVectorGL() = default;
};
/**
@brief Base for two-dimensional vector OpenGL shaders
@m_since_latest
*/
typedef AbstractVectorGL<2> AbstractVectorGL2D;
/**
@brief Base for three-dimensional vector OpenGL shader
@m_since_latest
*/
typedef AbstractVectorGL<3> AbstractVectorGL3D;
}}
#endif

20
src/Magnum/Shaders/CMakeLists.txt

@ -31,9 +31,6 @@ corrade_add_resource(MagnumShaders_RESOURCES_GL resources-gl.conf)
set_target_properties(MagnumShaders_RESOURCES_GL-dependencies PROPERTIES FOLDER "Magnum/Shaders")
set(MagnumShaders_SRCS
AbstractVectorGL.cpp
VertexColorGL.cpp
${MagnumShaders_RESOURCES_GL})
set(MagnumShaders_GracefulAssert_SRCS
@ -41,16 +38,22 @@ set(MagnumShaders_GracefulAssert_SRCS
FlatGL.cpp
MeshVisualizerGL.cpp
PhongGL.cpp
VectorGL.cpp)
VectorGL.cpp
VertexColorGL.cpp)
set(MagnumShaders_HEADERS
DistanceFieldVector.h
DistanceFieldVectorGL.h
AbstractVectorGL.h
Flat.h
FlatGL.h
Generic.h
GenericGL.h
MeshVisualizer.h
MeshVisualizerGL.h
Phong.h
PhongGL.h
Shaders.h
Vector.h
VectorGL.h
VertexColorGL.h
@ -58,13 +61,6 @@ set(MagnumShaders_HEADERS
if(MAGNUM_BUILD_DEPRECATED)
list(APPEND MagnumShaders_HEADERS
DistanceFieldVector.h
AbstractVector.h
Flat.h
Generic.h
MeshVisualizer.h
Phong.h
Vector.h
VertexColor.h)
endif()

74
src/Magnum/Shaders/DistanceFieldVector.frag

@ -29,8 +29,13 @@
#define texture texture2D
#endif
#ifndef RUNTIME_CONST
#define const
#endif
/* Uniforms */
#ifndef UNIFORM_BUFFERS
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 2)
#endif
@ -63,10 +68,59 @@ uniform lowp float smoothness
#endif
;
/* Uniform buffers */
#else
#ifndef MULTI_DRAW
#if DRAW_COUNT > 1
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 0)
#endif
uniform highp uint drawOffset
#ifndef GL_ES
= 0u
#endif
;
#else
#define drawOffset 0u
#endif
#define drawId drawOffset
#endif
struct DrawUniform {
highp uvec4 materialIdReservedReservedReservedReserved;
#define draw_materialIdReserved materialIdReservedReservedReservedReserved.x
};
layout(std140
#ifdef EXPLICIT_BINDING
, binding = 2
#endif
) uniform Draw {
DrawUniform draws[DRAW_COUNT];
};
struct MaterialUniform {
lowp vec4 color;
lowp vec4 reserved;
lowp vec4 outlineColor;
lowp vec4 outlineRangeSmoothnessReserved;
#define material_outlineRange outlineRangeSmoothnessReserved.xy
#define material_smoothness outlineRangeSmoothnessReserved.z
};
layout(std140
#ifdef EXPLICIT_BINDING
, binding = 4
#endif
) uniform Material {
MaterialUniform materials[MATERIAL_COUNT];
};
#endif
/* Textures */
#ifdef EXPLICIT_TEXTURE_LAYER
/* See AbstractVector.h for details about the ID */
#ifdef EXPLICIT_BINDING
layout(binding = 6)
#endif
uniform lowp sampler2D vectorTexture;
@ -75,6 +129,10 @@ uniform lowp sampler2D vectorTexture;
in mediump vec2 interpolatedTextureCoordinates;
#ifdef MULTI_DRAW
flat in highp uint drawId;
#endif
/* OUtput */
#ifdef NEW_GLSL
@ -85,6 +143,18 @@ out lowp vec4 fragmentColor;
#endif
void main() {
#ifdef UNIFORM_BUFFERS
#if MATERIAL_COUNT > 1
mediump const uint materialId = draws[drawId].draw_materialIdReserved & 0xffffu;
#else
#define materialId 0u
#endif
lowp const float smoothness = materials[materialId].material_smoothness;
lowp const vec4 color = materials[materialId].color;
lowp const vec4 outlineColor = materials[materialId].outlineColor;
lowp const vec2 outlineRange = materials[materialId].material_outlineRange;
#endif
lowp float intensity = texture(vectorTexture, interpolatedTextureCoordinates).r;
/* Fill color */

284
src/Magnum/Shaders/DistanceFieldVector.h

@ -25,26 +25,288 @@
DEALINGS IN THE SOFTWARE.
*/
#ifdef MAGNUM_BUILD_DEPRECATED
/** @file
* @brief Typedef @ref Magnum::Shaders::DistanceFieldVector, alias @ref Magnum::Shaders::DistanceFieldVector2D, @ref Magnum::Shaders::DistanceFieldVector3D
* @m_deprecated_since_latest Use @ref Magnum/Shaders/DistanceFieldVectorGL.h,
* the @ref Magnum::Shaders::DistanceFieldVectorGL "DistanceFieldVectorGL"
* class and related typedefs instead.
* @brief Struct @ref Magnum::Shaders::DistanceFieldVectorDrawUniform, @ref Magnum::Shaders::DistanceFieldVectorMaterialUniform
*/
#endif
#include "Magnum/configure.h"
#include "Magnum/Magnum.h"
#include "Magnum/Math/Color.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#include <Corrade/Utility/Macros.h>
#include "Magnum/Shaders/DistanceFieldVectorGL.h"
CORRADE_DEPRECATED_FILE("use Magnum/Shaders/DistanceFieldVectorGL.h, the DistanceFieldVectorGL class and related typedefs instead")
#endif
namespace Magnum { namespace Shaders {
/**
@brief Per-draw uniform for distance field vector shaders
@m_since_latest
Together with the generic @ref TransformationProjectionUniform2D /
@ref TransformationProjectionUniform3D contains parameters that are specific to
each draw call. Texture transformation, if needed, is supplied separately in a
@ref TextureTransformationUniform; material-related properties are expected to
be shared among multiple draw calls and thus are provided in a separate
@ref DistanceFieldVectorMaterialUniform structure, referenced by
@ref materialId.
@see @ref DistanceFieldVectorGL::bindDrawBuffer()
*/
struct DistanceFieldVectorDrawUniform {
/** @brief Construct with default parameters */
constexpr explicit DistanceFieldVectorDrawUniform(DefaultInitT = DefaultInit) noexcept:
#if ((defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)) && defined(CORRADE_TARGET_BIG_ENDIAN)
_pad0{}, /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
materialId{0}
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
#ifndef CORRADE_TARGET_BIG_ENDIAN
, _pad0{}
#endif
, _pad1{}, _pad2{}, _pad3{}
#endif
{}
/** @brief Construct without initializing the contents */
explicit DistanceFieldVectorDrawUniform(NoInitT) noexcept {}
/** @{
* @name Convenience setters
*
* Provided to allow the use of method chaining for populating a structure
* in a single expression, otherwise equivalent to accessing the fields
* directly. Also guaranteed to provide backwards compatibility when
* packing of the actual fields changes.
*/
/**
* @brief Set the @ref materialId field
* @return Reference to self (for method chaining)
*/
DistanceFieldVectorDrawUniform& setMaterialId(UnsignedInt id) {
materialId = id;
return *this;
}
/**
* @}
*/
/** @var materialId
* @brief Material ID
*
* References a particular material from a
* @ref DistanceFieldVectorMaterialUniform array. Useful when an UBO with
* more than one material is supplied or in a multi-draw scenario. Should
* be less than the material count passed to the
* @ref DistanceFieldVectorGL::DistanceFieldVectorGL(Flags, UnsignedInt, UnsignedInt)
* constructor, if material count is @cpp 1 @ce, this field is assumed to
* be @cpp 0 @ce and isn't even read by the shader. Default value is
* @cpp 0 @ce, meaning the first material gets used.
*/
/* This field is an UnsignedInt in the shader and materialId is extracted
as (value & 0xffff), so the order has to be different on BE */
#ifndef CORRADE_TARGET_BIG_ENDIAN
alignas(4) UnsignedShort materialId;
/* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
UnsignedShort
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:16; /* reserved for skinOffset */
#endif
#else
alignas(4) UnsignedShort
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:16; /* reserved for skinOffset */
UnsignedShort materialId;
#endif
/* warning: Member __pad1__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad1 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32; /* reserved for objectId */
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad2 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad3 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
#endif
};
/**
@brief Material uniform for distance field vector shaders
@m_since_latest
Describes material properties referenced from
@ref DistanceFieldVectorDrawUniform::materialId.
@see @ref DistanceFieldVectorGL::bindMaterialBuffer()
*/
struct DistanceFieldVectorMaterialUniform {
/** @brief Construct with default parameters */
constexpr explicit DistanceFieldVectorMaterialUniform(DefaultInitT = DefaultInit) noexcept: color{1.0f, 1.0f, 1.0f, 1.0f},
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
/* Otherwise it refuses to constexpr, on 3.8 at least */
_pad0{}, _pad1{}, _pad2{}, _pad3{},
#endif
outlineColor{0.0f, 0.0f, 0.0f, 0.0f}, outlineStart{0.5f}, outlineEnd{1.0f}, smoothness{0.04f}
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
, _pad4{}
#endif
{}
/** @brief Construct without initializing the contents */
explicit DistanceFieldVectorMaterialUniform(NoInitT) noexcept: color{NoInit}, outlineColor{NoInit} {}
/** @{
* @name Convenience setters
*
* Provided to allow the use of method chaining for populating a structure
* in a single expression, otherwise equivalent to accessing the fields
* directly. Also guaranteed to provide backwards compatibility when
* packing of the actual fields changes.
*/
/**
* @brief Set the @ref color field
* @return Reference to self (for method chaining)
*/
DistanceFieldVectorMaterialUniform& setColor(const Color4& color) {
this->color = color;
return *this;
}
/**
* @brief Set the @ref outlineColor field
* @return Reference to self (for method chaining)
*/
DistanceFieldVectorMaterialUniform& setOutlineColor(const Color4& color) {
outlineColor = color;
return *this;
}
/**
* @brief Set the @ref outlineStart and @ref outlineEnd fields
* @return Reference to self (for method chaining)
*/
DistanceFieldVectorMaterialUniform& setOutlineRange(Float start, Float end) {
outlineStart = start;
outlineEnd = end;
return *this;
}
/**
* @brief Set the @ref smoothness field
* @return Reference to self (for method chaining)
*/
DistanceFieldVectorMaterialUniform& setSmoothness(Float smoothness) {
this->smoothness = smoothness;
return *this;
}
/**
* @}
*/
/**
* @brief Fill color
*
* Default value is @cpp 0xffffffff_rgbaf @ce.
* @see @ref DistanceFieldVectorGL::setColor()
*/
Color4 color;
/* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32; /* reserved for backgroundColor */
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad1 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad2 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad3 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
#endif
/**
* @brief Outline color
*
* Default value is @cpp 0x00000000_rgbaf @ce and the outline is not drawn
* --- see @ref outlineStart and @ref outlineEnd for more information.
* @see @ref DistanceFieldVectorGL::setColor()
*/
Color4 outlineColor;
/**
* @brief Outline start
*
* Describe where fill ends and possible outline starts. Default value is
* @cpp 0.5f @ce, larger values will make the vector art look thinner,
* smaller will make it look thicker.
* @see @ref DistanceFieldVectorGL::setOutlineRange()
*/
Float outlineStart;
/**
* @brief Outline end
*
* Describe where outline ends. If set to a value larger than
* @ref outlineStart, the outline is not drawn. Initial value is
* @cpp 1.0f @ce.
* @see @ref DistanceFieldVectorGL::setOutlineRange()
*/
Float outlineEnd;
/**
* @brief Smoothness radius
*
* Larger values will make edges look less aliased (but blurry), smaller
* values will make them look more crisp (but possibly aliased). Initial
* value is @cpp 0.04f @ce.
* @see @ref DistanceFieldVectorGL::setSmoothness()
*/
Float smoothness;
/* warning: Member __pad4__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad4 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
#endif
};
#ifdef MAGNUM_BUILD_DEPRECATED
/** @brief @copybrief DistanceFieldVectorGL
* @m_deprecated_since_latest Use @ref DistanceFieldVectorGL instead.
*/
@ -61,10 +323,8 @@ typedef CORRADE_DEPRECATED("use DistanceFieldVectorGL2D instead") DistanceFieldV
* @m_deprecated_since_latest Use @ref DistanceFieldVectorGL3D instead.
*/
typedef CORRADE_DEPRECATED("use DistanceFieldVectorGL3D instead") DistanceFieldVectorGL3D DistanceFieldVector3D;
#endif
}}
#else
#error use Magnum/Shaders/DistanceFieldVectorGL.h, the DistanceFieldVectorGL class and related typedefs instead
#endif
#endif

259
src/Magnum/Shaders/DistanceFieldVectorGL.cpp

@ -32,15 +32,71 @@
#include "Magnum/GL/Context.h"
#include "Magnum/GL/Extensions.h"
#include "Magnum/GL/Shader.h"
#include "Magnum/GL/Texture.h"
#include "Magnum/Math/Color.h"
#include "Magnum/Math/Matrix3.h"
#include "Magnum/Math/Matrix4.h"
#ifndef MAGNUM_TARGET_GLES2
#include <Corrade/Utility/FormatStl.h>
#include "Magnum/GL/Buffer.h"
#endif
#include "Magnum/Shaders/Implementation/CreateCompatibilityShader.h"
namespace Magnum { namespace Shaders {
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>::DistanceFieldVectorGL(const Flags flags): _flags{flags} {
namespace {
enum: Int { TextureUnit = 6 };
#ifndef MAGNUM_TARGET_GLES2
enum: Int {
/* Not using the zero binding to avoid conflicts with
ProjectionBufferBinding from other shaders which can likely stay
bound to the same buffer for the whole time */
TransformationProjectionBufferBinding = 1,
DrawBufferBinding = 2,
TextureTransformationBufferBinding = 3,
MaterialBufferBinding = 4
};
#endif
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>::DistanceFieldVectorGL(const Flags flags
#ifndef MAGNUM_TARGET_GLES2
, const UnsignedInt materialCount, const UnsignedInt drawCount
#endif
):
_flags{flags}
#ifndef MAGNUM_TARGET_GLES2
, _materialCount{materialCount},
_drawCount{drawCount}
#endif
{
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || materialCount,
"Shaders::DistanceFieldVectorGL: material count can't be zero", );
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || drawCount,
"Shaders::DistanceFieldVectorGL: draw count can't be zero", );
#endif
#ifndef MAGNUM_TARGET_GLES
if(flags >= Flag::UniformBuffers)
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::ARB::uniform_buffer_object);
#endif
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::MultiDraw) {
#ifndef MAGNUM_TARGET_GLES
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::ARB::shader_draw_parameters);
#elif !defined(MAGNUM_TARGET_WEBGL)
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::ANGLE::multi_draw);
#else
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::WEBGL::multi_draw);
#endif
}
#endif
#ifdef MAGNUM_BUILD_STATIC
/* Import resources on static build, if not already */
if(!Utility::Resource::hasGroup("MagnumShadersGL"))
@ -60,15 +116,35 @@ template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>::DistanceFiel
GL::Shader frag = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Fragment);
vert.addSource(flags & Flag::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "")
.addSource(dimensions == 2 ? "#define TWO_DIMENSIONS\n" : "#define THREE_DIMENSIONS\n")
.addSource(rs.get("generic.glsl"))
.addSource(rs.get("AbstractVector.vert"));
.addSource(dimensions == 2 ? "#define TWO_DIMENSIONS\n" : "#define THREE_DIMENSIONS\n");
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
vert.addSource(Utility::formatString(
"#define UNIFORM_BUFFERS\n"
"#define DRAW_COUNT {}\n",
drawCount));
vert.addSource(flags >= Flag::MultiDraw ? "#define MULTI_DRAW\n" : "");
}
#endif
vert.addSource(rs.get("generic.glsl"))
.addSource(rs.get("Vector.vert"));
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
frag.addSource(Utility::formatString(
"#define UNIFORM_BUFFERS\n"
"#define MATERIAL_COUNT {}\n"
"#define DRAW_COUNT {}\n",
materialCount,
drawCount));
frag.addSource(flags >= Flag::MultiDraw ? "#define MULTI_DRAW\n" : "");
}
#endif
frag.addSource(rs.get("generic.glsl"))
.addSource(rs.get("DistanceFieldVector.frag"));
CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, frag}));
GL::AbstractShaderProgram::attachShaders({vert, frag});
attachShaders({vert, frag});
/* ES3 has this done in the shader directly */
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
@ -76,74 +152,201 @@ template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>::DistanceFiel
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_attrib_location>(version))
#endif
{
GL::AbstractShaderProgram::bindAttributeLocation(AbstractVectorGL<dimensions>::Position::Location, "position");
GL::AbstractShaderProgram::bindAttributeLocation(AbstractVectorGL<dimensions>::TextureCoordinates::Location, "textureCoordinates");
bindAttributeLocation(Position::Location, "position");
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
}
#endif
CORRADE_INTERNAL_ASSERT_OUTPUT(GL::AbstractShaderProgram::link());
CORRADE_INTERNAL_ASSERT_OUTPUT(link());
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
#endif
{
_transformationProjectionMatrixUniform = GL::AbstractShaderProgram::uniformLocation("transformationProjectionMatrix");
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
if(_drawCount > 1) _drawOffsetUniform = uniformLocation("drawOffset");
} else
#endif
{
_transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
if(flags & Flag::TextureTransformation)
_textureMatrixUniform = GL::AbstractShaderProgram::uniformLocation("textureMatrix");
_colorUniform = GL::AbstractShaderProgram::uniformLocation("color");
_outlineColorUniform = GL::AbstractShaderProgram::uniformLocation("outlineColor");
_outlineRangeUniform = GL::AbstractShaderProgram::uniformLocation("outlineRange");
_smoothnessUniform = GL::AbstractShaderProgram::uniformLocation("smoothness");
_textureMatrixUniform = uniformLocation("textureMatrix");
_colorUniform = uniformLocation("color");
_outlineColorUniform = uniformLocation("outlineColor");
_outlineRangeUniform = uniformLocation("outlineRange");
_smoothnessUniform = uniformLocation("smoothness");
}
}
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::shading_language_420pack>(version))
#endif
{
GL::AbstractShaderProgram::setUniform(GL::AbstractShaderProgram::uniformLocation("vectorTexture"),
AbstractVectorGL<dimensions>::VectorTextureUnit);
setUniform(uniformLocation("vectorTexture"), TextureUnit);
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
setUniformBlockBinding(uniformBlockIndex("TransformationProjection"), TransformationProjectionBufferBinding);
setUniformBlockBinding(uniformBlockIndex("Draw"), DrawBufferBinding);
setUniformBlockBinding(uniformBlockIndex("Material"), MaterialBufferBinding);
if(flags & Flag::TextureTransformation)
setUniformBlockBinding(uniformBlockIndex("TextureTransformation"), TextureTransformationBufferBinding);
}
#endif
}
/* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
#ifdef MAGNUM_TARGET_GLES
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
/* Draw offset is zero by default */
} else
#endif
{
setTransformationProjectionMatrix(MatrixTypeFor<dimensions, Float>{Math::IdentityInit});
if(flags & Flag::TextureTransformation)
setTextureMatrix(Matrix3{Math::IdentityInit});
setColor(Color4{1.0f}); /* Outline color is zero by default */
setColor(Color4{1.0f});
/* Outline color is zero by default */
setOutlineRange(0.5f, 1.0f);
setSmoothness(0.04f);
}
#endif
}
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>::DistanceFieldVectorGL(const Flags flags): DistanceFieldVectorGL{flags, 1, 1} {}
#endif
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::setTransformationProjectionMatrix(const MatrixTypeFor<dimensions, Float>& matrix) {
GL::AbstractShaderProgram::setUniform(_transformationProjectionMatrixUniform, matrix);
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::DistanceFieldVectorGL::setTransformationProjectionMatrix(): the shader was created with uniform buffers enabled", *this);
#endif
setUniform(_transformationProjectionMatrixUniform, matrix);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::setTextureMatrix(const Matrix3& matrix) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::DistanceFieldVectorGL::setTextureMatrix(): the shader was created with uniform buffers enabled", *this);
#endif
CORRADE_ASSERT(_flags & Flag::TextureTransformation,
"Shaders::DistanceFieldVectorGL::setTextureMatrix(): the shader was not created with texture transformation enabled", *this);
GL::AbstractShaderProgram::setUniform(_textureMatrixUniform, matrix);
setUniform(_textureMatrixUniform, matrix);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::setColor(const Color4& color) {
GL::AbstractShaderProgram::setUniform(_colorUniform, color);
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::DistanceFieldVectorGL::setColor(): the shader was created with uniform buffers enabled", *this);
#endif
setUniform(_colorUniform, color);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::setOutlineColor(const Color4& color) {
GL::AbstractShaderProgram::setUniform(_outlineColorUniform, color);
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::DistanceFieldVectorGL::setOutlineColor(): the shader was created with uniform buffers enabled", *this);
#endif
setUniform(_outlineColorUniform, color);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::setOutlineRange(Float start, Float end) {
GL::AbstractShaderProgram::setUniform(_outlineRangeUniform, Vector2(start, end));
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::DistanceFieldVectorGL::setOutlineRange(): the shader was created with uniform buffers enabled", *this);
#endif
setUniform(_outlineRangeUniform, Vector2(start, end));
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::setSmoothness(Float value) {
GL::AbstractShaderProgram::setUniform(_smoothnessUniform, value);
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::DistanceFieldVectorGL::setSmoothness(): the shader was created with uniform buffers enabled", *this);
#endif
setUniform(_smoothnessUniform, value);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::setDrawOffset(const UnsignedInt offset) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::DistanceFieldVectorGL::setDrawOffset(): the shader was not created with uniform buffers enabled", *this);
CORRADE_ASSERT(offset < _drawCount,
"Shaders::DistanceFieldVectorGL::setDrawOffset(): draw offset" << offset << "is out of bounds for" << _drawCount << "draws", *this);
if(_drawCount > 1) setUniform(_drawOffsetUniform, offset);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::bindTransformationProjectionBuffer(GL::Buffer& buffer) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::DistanceFieldVectorGL::bindTransformationProjectionBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, TransformationProjectionBufferBinding);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::bindTransformationProjectionBuffer(GL::Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::DistanceFieldVectorGL::bindTransformationProjectionBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, TransformationProjectionBufferBinding, offset, size);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::bindDrawBuffer(GL::Buffer& buffer) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::DistanceFieldVectorGL::bindDrawBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, DrawBufferBinding);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::bindDrawBuffer(GL::Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::DistanceFieldVectorGL::bindDrawBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, DrawBufferBinding, offset, size);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::bindTextureTransformationBuffer(GL::Buffer& buffer) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::DistanceFieldVectorGL::bindTextureTransformationBuffer(): the shader was not created with uniform buffers enabled", *this);
CORRADE_ASSERT(_flags & Flag::TextureTransformation,
"Shaders::DistanceFieldVectorGL::bindTextureTransformationBuffer(): the shader was not created with texture transformation enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, TextureTransformationBufferBinding);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::bindTextureTransformationBuffer(GL::Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::DistanceFieldVectorGL::bindTextureTransformationBuffer(): the shader was not created with uniform buffers enabled", *this);
CORRADE_ASSERT(_flags & Flag::TextureTransformation,
"Shaders::DistanceFieldVectorGL::bindTextureTransformationBuffer(): the shader was not created with texture transformation enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, TextureTransformationBufferBinding, offset, size);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::bindMaterialBuffer(GL::Buffer& buffer) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::DistanceFieldVectorGL::bindMaterialBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, MaterialBufferBinding);
return *this;
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::bindMaterialBuffer(GL::Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::DistanceFieldVectorGL::bindMaterialBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, MaterialBufferBinding, offset, size);
return *this;
}
#endif
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>& DistanceFieldVectorGL<dimensions>::bindVectorTexture(GL::Texture2D& texture) {
texture.bind(TextureUnit);
return *this;
}
@ -159,6 +362,10 @@ Debug& operator<<(Debug& debug, const DistanceFieldVectorGLFlag value) {
/* LCOV_EXCL_START */
#define _c(v) case DistanceFieldVectorGLFlag::v: return debug << "::" #v;
_c(TextureTransformation)
#ifndef MAGNUM_TARGET_GLES2
_c(UniformBuffers)
_c(MultiDraw)
#endif
#undef _c
/* LCOV_EXCL_STOP */
}
@ -168,7 +375,11 @@ Debug& operator<<(Debug& debug, const DistanceFieldVectorGLFlag value) {
Debug& operator<<(Debug& debug, const DistanceFieldVectorGLFlags value) {
return Containers::enumSetDebugOutput(debug, value, "Shaders::DistanceFieldVectorGL::Flags{}", {
DistanceFieldVectorGLFlag::TextureTransformation
DistanceFieldVectorGLFlag::TextureTransformation,
#ifndef MAGNUM_TARGET_GLES2
DistanceFieldVectorGLFlag::MultiDraw, /* Superset of UniformBuffers */
DistanceFieldVectorGLFlag::UniformBuffers
#endif
});
}

400
src/Magnum/Shaders/DistanceFieldVectorGL.h

@ -31,14 +31,19 @@
*/
#include "Magnum/DimensionTraits.h"
#include "Magnum/Shaders/AbstractVectorGL.h"
#include "Magnum/GL/AbstractShaderProgram.h"
#include "Magnum/Shaders/GenericGL.h"
#include "Magnum/Shaders/visibility.h"
namespace Magnum { namespace Shaders {
namespace Implementation {
enum class DistanceFieldVectorGLFlag: UnsignedByte {
TextureTransformation = 1 << 0
TextureTransformation = 1 << 0,
#ifndef MAGNUM_TARGET_GLES2
UniformBuffers = 1 << 1,
MultiDraw = UniformBuffers|(1 << 2)
#endif
};
typedef Containers::EnumSet<DistanceFieldVectorGLFlag> DistanceFieldVectorGLFlags;
}
@ -48,9 +53,10 @@ namespace Implementation {
@m_since_latest
Renders vector graphics in a form of signed distance field. See
@ref TextureTools::DistanceField for more information. Note that the final
rendered outlook will greatly depend on radius of input distance field and
value passed to @ref setSmoothness(). You need to provide @ref Position and
@ref TextureTools::DistanceField for more information and @ref VectorGL for a
simpler variant of this shader. Note that the final rendered outlook will
greatly depend on radius of input distance field and value passed to
@ref setSmoothness(). You need to provide @ref Position and
@ref TextureCoordinates attributes in your triangle mesh and call at least
@ref bindVectorTexture(). By default, the shader renders the distance field
texture with a white color in an identity transformation, use
@ -74,13 +80,72 @@ Common rendering setup:
@snippet MagnumShaders-gl.cpp DistanceFieldVectorGL-usage2
@section Shaders-DistanceFieldVectorGL-ubo Uniform buffers
See @ref shaders-usage-ubo for a high-level overview that applies to all
shaders. In this particular case, because the shader doesn't need a separate
projection and transformation matrix, a combined one is supplied via a
@ref TransformationProjectionUniform2D / @ref TransformationProjectionUniform3D
buffer. To maximize use of the limited uniform buffer memory, materials are
supplied separately in a @ref DistanceFieldVectorMaterialUniform buffer and
then referenced via @relativeref{DistanceFieldVectorDrawUniform,materialId}
from a @ref DistanceFieldVectorDrawUniform; for optional texture transformation
a per-draw @ref TextureTransformationUniform can be supplied as well. A uniform
buffer setup equivalent to the above would look like this:
@snippet MagnumShaders-gl.cpp DistanceFieldVectorGL-ubo
For a multidraw workflow enable @ref Flag::MultiDraw, supply desired material
and draw count in the @ref DistanceFieldVectorGL(Flags, UnsignedInt, UnsignedInt)
constructor and specify material references and texture offsets for every draw.
Texture arrays aren't currently supported for this shader. Besides that, the
usage is similar for all shaders, see @ref shaders-usage-multidraw for an
example.
@requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object} for uniform
buffers.
@requires_gl46 Extension @gl_extension{ARB,shader_draw_parameters} for
multidraw.
@requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
@requires_webgl20 Uniform buffers are not available in WebGL 1.0.
@requires_es_extension Extension @m_class{m-doc-external} [ANGLE_multi_draw](https://chromium.googlesource.com/angle/angle/+/master/extensions/ANGLE_multi_draw.txt)
(unlisted) for multidraw.
@requires_webgl_extension Extension @webgl_extension{ANGLE,multi_draw} for
multidraw.
@see @ref shaders, @ref DistanceFieldVectorGL2D, @ref DistanceFieldVectorGL3D
@todo Use fragment shader derivations to have proper smoothness in perspective/
large zoom levels, make it optional as it might have negative performance
impact
*/
template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVectorGL: public AbstractVectorGL<dimensions> {
template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVectorGL: public GL::AbstractShaderProgram {
public:
/**
* @brief Vertex position
*
* @ref shaders-generic "Generic attribute",
* @ref Magnum::Vector2 "Vector2" in 2D, @ref Magnum::Vector3 "Vector3"
* in 3D.
*/
typedef typename GenericGL<dimensions>::Position Position;
/**
* @brief 2D texture coordinates
*
* @ref shaders-generic "Generic attribute",
* @ref Magnum::Vector2 "Vector2".
*/
typedef typename GenericGL<dimensions>::TextureCoordinates TextureCoordinates;
enum: UnsignedInt {
/**
* Color shader output. @ref shaders-generic "Generic output",
* present always. Expects three- or four-component floating-point
* or normalized buffer attachment.
*/
ColorOutput = GenericGL<dimensions>::ColorOutput
};
#ifdef DOXYGEN_GENERATING_OUTPUT
/**
* @brief Flag
@ -94,7 +159,48 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* @see @ref setTextureMatrix()
* @m_since{2020,06}
*/
TextureTransformation = 1 << 0
TextureTransformation = 1 << 0,
#ifndef MAGNUM_TARGET_GLES2
/**
* Use uniform buffers. Expects that uniform data are supplied via
* @ref bindTransformationProjectionBuffer(),
* @ref bindDrawBuffer(), @ref bindTextureTransformationBuffer(),
* and @ref bindMaterialBuffer() instead of direct uniform setters.
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL
* 1.0.
* @m_since_latest
*/
UniformBuffers = 1 << 1,
/**
* Enable multidraw functionality. Implies @ref Flag::UniformBuffers
* and adds the value from @ref setDrawOffset() with the
* @glsl gl_DrawID @ce builtin, which makes draws submitted via
* @ref GL::AbstractShaderProgram::draw(Containers::ArrayView<const Containers::Reference<MeshView>>)
* pick up per-draw parameters directly, without having to rebind
* the uniform buffers or specify @ref setDrawOffset() before each
* draw. In a non-multidraw scenario, @glsl gl_DrawID @ce is
* @cpp 0 @ce, which means a shader with this flag enabled can be
* used for regular draws as well.
* @requires_gl46 Extension @gl_extension{ARB,uniform_buffer_object}
* and @gl_extension{ARB,shader_draw_parameters}
* @requires_es_extension OpenGL ES 3.0 and extension
* @m_class{m-doc-external} [ANGLE_multi_draw](https://chromium.googlesource.com/angle/angle/+/master/extensions/ANGLE_multi_draw.txt)
* (unlisted). While the extension alone needs only OpenGL ES
* 2.0, the shader implementation relies on uniform buffers,
* which require OpenGL ES 3.0.
* @requires_webgl_extension WebGL 2.0 and extension
* @webgl_extension{ANGLE,multi_draw}. While the extension
* alone needs only WebGL 1.0, the shader implementation
* relies on uniform buffers, which require WebGL 2.0.
* @m_since_latest
*/
MultiDraw = UniformBuffers|(1 << 2)
#endif
};
/**
@ -114,9 +220,50 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
/**
* @brief Constructor
* @param flags Flags
*
* While this function is meant mainly for the classic uniform
* scenario (without @ref Flag::UniformBuffers set), it's equivalent to
* @ref DistanceFieldVectorGL(Flags, UnsignedInt, UnsignedInt) with
* @p materialCount and @p drawCount set to @cpp 1 @ce.
*/
explicit DistanceFieldVectorGL(Flags flags = {});
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Construct for a multi-draw scenario
* @param flags Flags
* @param materialCount Size of a @ref DistanceFieldVectorMaterialUniform
* buffer bound with @ref bindMaterialBuffer()
* @param drawCount Size of a @ref TransformationProjectionUniform2D
* / @ref TransformationProjectionUniform3D /
* @ref DistanceFieldVectorDrawUniform /
* @ref TextureTransformationUniform buffer bound with
* @ref bindTransformationProjectionBuffer(), @ref bindDrawBuffer()
* and @ref bindTextureTransformationBuffer()
*
* If @p flags contains @ref Flag::UniformBuffers, @p materialCount and
* @p drawCount describe the uniform buffer sizes as these are required
* to have a statically defined size. The draw offset is then set via
* @ref setDrawOffset() and the per-draw materials are specified via
* @ref DistanceFieldVectorDrawUniform::materialId.
*
* If @p flags don't contain @ref Flag::UniformBuffers,
* @p materialCount and @p drawCount is ignored and the constructor
* behaves the same as @ref DistanceFieldVectorGL(Flags).
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
/** @todo this constructor will eventually need to have also joint
count, per-vertex weight count, view count for multiview and clip
plane count ... and putting them in arbitrary order next to each
other is too error-prone, so it needs some other solution
(accepting pairs of parameter type and value like in GL context
creation, e.g., which will probably need a new enum as reusing Flag
for this might be too confusing) */
explicit DistanceFieldVectorGL(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Construct without creating the underlying OpenGL object
*
@ -129,12 +276,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* However note that this is a low-level and a potentially dangerous
* API, see the documentation of @ref NoCreate for alternatives.
*/
explicit DistanceFieldVectorGL(NoCreateT) noexcept
/** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT
: AbstractVectorGL<dimensions>{NoCreate}
#endif
{}
explicit DistanceFieldVectorGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
/** @brief Copying is not allowed */
DistanceFieldVectorGL(const DistanceFieldVectorGL<dimensions>&) = delete;
@ -154,8 +296,40 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
*/
Flags flags() const { return _flags; }
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Material count
* @m_since_latest
*
* Statically defined size of the
* @ref DistanceFieldVectorMaterialUniform uniform buffer. Has use only
* if @ref Flag::UniformBuffers is set.
* @see @ref bindMaterialBuffer()
* @requires_gles30 Not defined on OpenGL ES 2.0 builds.
* @requires_webgl20 Not defined on WebGL 1.0 builds.
*/
UnsignedInt materialCount() const { return _materialCount; }
/**
* @brief Draw count
* @m_since_latest
*
* Statically defined size of each of the
* @ref TransformationProjectionUniform2D /
* @ref TransformationProjectionUniform3D,
* @ref DistanceFieldVectorDrawUniform and
* @ref TextureTransformationUniform uniform buffers. Has use only if
* @ref Flag::UniformBuffers is set.
* @requires_gles30 Not defined on OpenGL ES 2.0 builds.
* @requires_webgl20 Not defined on WebGL 1.0 builds.
*/
UnsignedInt drawCount() const { return _drawCount; }
#endif
/** @{
* @name Uniform setters
*
* Used only if @ref Flag::UniformBuffers is not set.
*/
/**
@ -163,6 +337,11 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* @return Reference to self (for method chaining)
*
* Initial value is an identity matrix.
*
* Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref TransformationProjectionUniform2D::transformationProjectionMatrix /
* @ref TransformationProjectionUniform3D::transformationProjectionMatrix
* and call @ref bindTransformationProjectionBuffer() instead.
*/
DistanceFieldVectorGL<dimensions>& setTransformationProjectionMatrix(const MatrixTypeFor<dimensions, Float>& matrix);
@ -174,6 +353,11 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* Expects that the shader was created with
* @ref Flag::TextureTransformation enabled. Initial value is an
* identity matrix.
*
* Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref TextureTransformationUniform::rotationScaling and
* @ref TextureTransformationUniform::offset and call
* @ref bindTextureTransformationBuffer() instead.
*/
DistanceFieldVectorGL<dimensions>& setTextureMatrix(const Matrix3& matrix);
@ -182,6 +366,10 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* @return Reference to self (for method chaining)
*
* Initial value is @cpp 0xffffffff_rgbaf @ce.
*
* Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref DistanceFieldVectorMaterialUniform::color and call
* @ref bindMaterialBuffer() instead.
* @see @ref setOutlineColor()
*/
DistanceFieldVectorGL<dimensions>& setColor(const Color4& color);
@ -192,6 +380,10 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
*
* Initial value is @cpp 0x00000000_rgbaf @ce and the outline is not
* drawn --- see @ref setOutlineRange() for more information.
*
* Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref DistanceFieldVectorMaterialUniform::outlineColor and call
* @ref bindMaterialBuffer() instead.
* @see @ref setOutlineRange(), @ref setColor()
*/
DistanceFieldVectorGL<dimensions>& setOutlineColor(const Color4& color);
@ -208,6 +400,10 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* larger than @p start, the outline is not drawn. Initial value is
* @cpp 1.0f @ce.
*
* Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref DistanceFieldVectorMaterialUniform::outlineStart and
* @ref DistanceFieldVectorMaterialUniform::outlineEnd and call
* @ref bindMaterialBuffer() instead.
* @see @ref setOutlineColor()
*/
DistanceFieldVectorGL<dimensions>& setOutlineRange(Float start, Float end);
@ -219,6 +415,10 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* Larger values will make edges look less aliased (but blurry),
* smaller values will make them look more crisp (but possibly
* aliased). Initial value is @cpp 0.04f @ce.
*
* Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref DistanceFieldVectorMaterialUniform::smoothness and call
* @ref bindMaterialBuffer() instead.
*/
DistanceFieldVectorGL<dimensions>& setSmoothness(Float value);
@ -226,11 +426,165 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* @}
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES2
/** @{
* @name Uniform buffer binding and related uniform setters
*
* Used if @ref Flag::UniformBuffers is set.
*/
/**
* @brief Set a draw offset
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Specifies which item in the @ref TransformationProjectionUniform2D /
* @ref TransformationProjectionUniform3D,
* @ref DistanceFieldVectorDrawUniform and
* @ref TextureTransformationUniform buffers bound with
* @ref bindTransformationProjectionBuffer(), @ref bindDrawBuffer() and
* @ref bindTextureTransformationBuffer() should be used for current
* draw. Expects that @ref Flag::UniformBuffers is set and @p offset is
* less than @ref drawCount(). Initial value is @cpp 0 @ce, if
* @ref drawCount() is @cpp 1 @ce, the function is a no-op as the
* shader assumes draw offset to be always zero.
*
* If @ref Flag::MultiDraw is set, @glsl gl_DrawID @ce is added to this
* value, which makes each draw submitted via
* @ref GL::AbstractShaderProgram::draw(Containers::ArrayView<const Containers::Reference<MeshView>>)
* pick up its own per-draw parameters.
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
DistanceFieldVectorGL<dimensions>& setDrawOffset(UnsignedInt offset);
/**
* @brief Set a transformation and projection uniform buffer
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Expects that @ref Flag::UniformBuffers is set. The buffer is
* expected to contain @ref drawCount() instances of
* @ref TransformationProjectionUniform2D /
* @ref TransformationProjectionUniform3D. At the very least you need
* to call also @ref bindDrawBuffer() and @ref bindMaterialBuffer().
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
DistanceFieldVectorGL<dimensions>& bindTransformationProjectionBuffer(GL::Buffer& buffer);
/**
* @overload
* @m_since_latest
*/
DistanceFieldVectorGL<dimensions>& bindTransformationProjectionBuffer(GL::Buffer& buffer, GLintptr offset, GLsizeiptr size);
/**
* @brief Set a draw uniform buffer
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Expects that @ref Flag::UniformBuffers is set. The buffer is
* expected to contain @ref drawCount() instances of
* @ref DistanceFieldVectorDrawUniform. At the very least you need to
* call also @ref bindTransformationProjectionBuffer() and
* @ref bindMaterialBuffer().
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
DistanceFieldVectorGL<dimensions>& bindDrawBuffer(GL::Buffer& buffer);
/**
* @overload
* @m_since_latest
*/
DistanceFieldVectorGL<dimensions>& bindDrawBuffer(GL::Buffer& buffer, GLintptr offset, GLsizeiptr size);
/**
* @brief Set a texture transformation uniform buffer
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Expects that both @ref Flag::UniformBuffers and
* @ref Flag::TextureTransformation is set. The buffer is expected to
* contain @ref drawCount() instances of
* @ref TextureTransformationUniform.
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
DistanceFieldVectorGL<dimensions>& bindTextureTransformationBuffer(GL::Buffer& buffer);
/**
* @overload
* @m_since_latest
*/
DistanceFieldVectorGL<dimensions>& bindTextureTransformationBuffer(GL::Buffer& buffer, GLintptr offset, GLsizeiptr size);
/**
* @brief Set a material uniform buffer
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Expects that @ref Flag::UniformBuffers is set. The buffer is
* expected to contain @ref materialCount() instances of
* @ref DistanceFieldVectorMaterialUniform. At the very least you need
* to call also @ref bindTransformationProjectionBuffer() and
* @ref bindDrawBuffer().
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
DistanceFieldVectorGL<dimensions>& bindMaterialBuffer(GL::Buffer& buffer);
/**
* @overload
* @m_since_latest
*/
DistanceFieldVectorGL<dimensions>& bindMaterialBuffer(GL::Buffer& buffer, GLintptr offset, GLsizeiptr size);
/**
* @}
*/
#endif
/** @{
* @name Texture binding
*/
/**
* @brief Bind vector texture
* @return Reference to self (for method chaining)
*
* @see @ref DistanceFieldVectorGL::Flag::TextureTransformation,
* @ref VectorGL::Flag::TextureTransformation,
* @ref DistanceFieldVectorGL::setTextureMatrix(),
* @ref VectorGL::setTextureMatrix()
*/
DistanceFieldVectorGL<dimensions>& bindVectorTexture(GL::Texture2D& texture);
/**
* @}
*/
/* Overloads to remove WTF-factor from method chaining order */
DistanceFieldVectorGL<dimensions>& bindVectorTexture(GL::Texture2D& texture) {
AbstractVectorGL<dimensions>::bindVectorTexture(texture);
return *this;
#ifndef DOXYGEN_GENERATING_OUTPUT
DistanceFieldVectorGL<dimensions>& draw(GL::Mesh& mesh) {
return static_cast<DistanceFieldVectorGL<dimensions>&>(GL::AbstractShaderProgram::draw(mesh));
}
DistanceFieldVectorGL<dimensions>& draw(GL::Mesh&& mesh) {
return static_cast<DistanceFieldVectorGL<dimensions>&>(GL::AbstractShaderProgram::draw(mesh));
}
DistanceFieldVectorGL<dimensions>& draw(GL::MeshView& mesh) {
return static_cast<DistanceFieldVectorGL<dimensions>&>(GL::AbstractShaderProgram::draw(mesh));
}
DistanceFieldVectorGL<dimensions>& draw(GL::MeshView&& mesh) {
return static_cast<DistanceFieldVectorGL<dimensions>&>(GL::AbstractShaderProgram::draw(mesh));
}
DistanceFieldVectorGL<dimensions>& draw(Containers::ArrayView<const Containers::Reference<GL::MeshView>> meshes) {
return static_cast<DistanceFieldVectorGL<dimensions>&>(GL::AbstractShaderProgram::draw(meshes));
}
DistanceFieldVectorGL<dimensions>& draw(std::initializer_list<Containers::Reference<GL::MeshView>> meshes) {
return static_cast<DistanceFieldVectorGL<dimensions>&>(GL::AbstractShaderProgram::draw(meshes));
}
#endif
@ -244,12 +598,20 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
#endif
Flags _flags;
#ifndef MAGNUM_TARGET_GLES2
UnsignedInt _materialCount{}, _drawCount{};
#endif
Int _transformationProjectionMatrixUniform{0},
_textureMatrixUniform{1},
_colorUniform{2},
_outlineColorUniform{3},
_outlineRangeUniform{4},
_smoothnessUniform{5};
#ifndef MAGNUM_TARGET_GLES2
/* Used instead of all other uniforms when Flag::UniformBuffers is set,
so it can alias them */
Int _drawOffsetUniform{0};
#endif
};
/**
@ -266,10 +628,10 @@ typedef DistanceFieldVectorGL<3> DistanceFieldVectorGL3D;
#ifdef DOXYGEN_GENERATING_OUTPUT
/** @debugoperatorclassenum{DistanceFieldVectorGL,DistanceFieldVectorGL::Flag} */
template<UnsignedInt dimensions> Debug& operator<<(Debug& debug, DistanceFieldVector<dimensions>::Flag value);
template<UnsignedInt dimensions> Debug& operator<<(Debug& debug, DistanceFieldVectorGL<dimensions>::Flag value);
/** @debugoperatorclassenum{DistanceFieldVectorGL,DistanceFieldVectorGL::Flags} */
template<UnsignedInt dimensions> Debug& operator<<(Debug& debug, DistanceFieldVector<dimensions>::Flags value);
template<UnsignedInt dimensions> Debug& operator<<(Debug& debug, DistanceFieldVectorGL<dimensions>::Flags value);
#else
namespace Implementation {
MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, DistanceFieldVectorGLFlag value);

96
src/Magnum/Shaders/Flat.frag

@ -33,10 +33,15 @@
#define in varying
#endif
#ifndef RUNTIME_CONST
#define const
#endif
/* Uniforms */
#ifndef UNIFORM_BUFFERS
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 2)
layout(location = 3)
#endif
uniform lowp vec4 color
#ifndef GL_ES
@ -46,7 +51,7 @@ uniform lowp vec4 color
#ifdef ALPHA_MASK
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 3)
layout(location = 4)
#endif
uniform lowp float alphaMask
#ifndef GL_ES
@ -57,25 +62,85 @@ uniform lowp float alphaMask
#ifdef OBJECT_ID
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 4)
layout(location = 5)
#endif
/* mediump is just 2^10, which might not be enough, this is 2^16 */
uniform highp uint objectId; /* defaults to zero */
#endif
/* Uniform buffers */
#else
#ifndef MULTI_DRAW
#if DRAW_COUNT > 1
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 0)
#endif
uniform highp uint drawOffset
#ifndef GL_ES
= 0u
#endif
;
#else
#define drawOffset 0u
#endif
#define drawId drawOffset
#endif
struct DrawUniform {
highp uvec4 materialIdReservedObjectIdReservedReserved;
#define draw_materialIdReserved materialIdReservedObjectIdReservedReserved.x
#define draw_objectId materialIdReservedObjectIdReservedReserved.y
};
layout(std140
#ifdef EXPLICIT_BINDING
, binding = 2
#endif
) uniform Draw {
DrawUniform draws[DRAW_COUNT];
};
struct MaterialUniform {
lowp vec4 color;
highp vec4 alphaMaskReservedReservedReserved;
#define material_alphaMask alphaMaskReservedReservedReserved.x
};
layout(std140
#ifdef EXPLICIT_BINDING
, binding = 4
#endif
) uniform Material {
MaterialUniform materials[MATERIAL_COUNT];
};
#endif
/* Textures */
#ifdef TEXTURED
#ifdef EXPLICIT_TEXTURE_LAYER
#ifdef EXPLICIT_BINDING
layout(binding = 0)
#endif
uniform lowp sampler2D textureData;
uniform lowp
#ifndef TEXTURE_ARRAYS
sampler2D
#else
sampler2DArray
#endif
textureData;
#endif
/* Inputs */
#ifdef TEXTURED
in mediump vec2 interpolatedTextureCoordinates;
in mediump
#ifndef TEXTURE_ARRAYS
vec2
#else
vec3
#endif
interpolatedTextureCoordinates;
#endif
#ifdef VERTEX_COLOR
@ -102,7 +167,26 @@ layout(location = OBJECT_ID_OUTPUT_ATTRIBUTE_LOCATION)
out highp uint fragmentObjectId;
#endif
#ifdef MULTI_DRAW
flat in highp uint drawId;
#endif
void main() {
#ifdef UNIFORM_BUFFERS
#ifdef OBJECT_ID
highp const uint objectId = draws[drawId].draw_objectId;
#endif
#if MATERIAL_COUNT > 1
mediump const uint materialId = draws[drawId].draw_materialIdReserved & 0xffffu;
#else
#define materialId 0u
#endif
lowp const vec4 color = materials[materialId].color;
#ifdef ALPHA_MASK
lowp const float alphaMask = materials[materialId].material_alphaMask;
#endif
#endif
fragmentColor =
#ifdef TEXTURED
texture(textureData, interpolatedTextureCoordinates)*

237
src/Magnum/Shaders/Flat.h

@ -25,26 +25,241 @@
DEALINGS IN THE SOFTWARE.
*/
#ifdef MAGNUM_BUILD_DEPRECATED
/** @file
* @brief Typedef @ref Magnum::Shaders::Flat, alias @ref Magnum::Shaders::Flat2D, @ref Magnum::Shaders::Flat3D
* @m_deprecated_since_latest Use @ref Magnum/Shaders/FlatGL.h, the
* @ref Magnum::Shaders::FlatGL "FlatGL" class and
* related typedefs instead.
* @brief Struct @ref Magnum::Shaders::FlatDrawUniform, @ref Magnum::Shaders::FlatMaterialUniform
*/
#endif
#include "Magnum/configure.h"
#include "Magnum/Magnum.h"
#include "Magnum/Math/Color.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#include <Corrade/Utility/Macros.h>
#include "Magnum/Shaders/FlatGL.h"
CORRADE_DEPRECATED_FILE("use Magnum/Shaders/FlatGL.h, the FlatGL class and related typedefs instead")
#endif
namespace Magnum { namespace Shaders {
/**
@brief Per-draw uniform for flat shaders
@m_since_latest
Together with the generic @ref TransformationProjectionUniform2D /
@ref TransformationProjectionUniform3D contains parameters that are specific to
each draw call. Texture transformation, if needed, is supplied separately in a
@ref TextureTransformationUniform; material-related properties are expected to
be shared among multiple draw calls and thus are provided in a separate
@ref FlatMaterialUniform structure, referenced by @ref materialId.
@see @ref FlatGL::bindDrawBuffer()
*/
struct FlatDrawUniform {
/** @brief Construct with default parameters */
constexpr explicit FlatDrawUniform(DefaultInitT = DefaultInit) noexcept:
#if ((defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)) && defined(CORRADE_TARGET_BIG_ENDIAN)
_pad0{}, /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
materialId{0},
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8) && !defined(CORRADE_TARGET_BIG_ENDIAN)
_pad0{},
#endif
objectId{0}
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
, _pad1{}, _pad2{}
#endif
{}
/** @brief Construct without initializing the contents */
explicit FlatDrawUniform(NoInitT) noexcept {}
/** @{
* @name Convenience setters
*
* Provided to allow the use of method chaining for populating a structure
* in a single expression, otherwise equivalent to accessing the fields
* directly. Also guaranteed to provide backwards compatibility when
* packing of the actual fields changes.
*/
/**
* @brief Set the @ref materialId field
* @return Reference to self (for method chaining)
*/
FlatDrawUniform& setMaterialId(UnsignedInt id) {
materialId = id;
return *this;
}
/**
* @brief Set the @ref objectId field
* @return Reference to self (for method chaining)
*/
FlatDrawUniform& setObjectId(UnsignedInt id) {
objectId = id;
return *this;
}
/**
* @}
*/
/** @var materialId
* @brief Material ID
*
* References a particular material from a @ref FlatMaterialUniform array.
* Useful when an UBO with more than one material is supplied or in a
* multi-draw scenario. Should be less than the material count passed to
* the @ref FlatGL::FlatGL(Flags, UnsignedInt, UnsignedInt) constructor, if
* material count is @cpp 1 @ce, this field is assumed to be @cpp 0 @ce and
* isn't even read by the shader. Default value is @cpp 0 @ce, meaning the
* first material gets used.
*/
/* This field is an UnsignedInt in the shader and materialId is extracted
as (value & 0xffff), so the order has to be different on BE */
#ifndef CORRADE_TARGET_BIG_ENDIAN
UnsignedShort materialId;
/* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
UnsignedShort
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:16; /* reserved for skinOffset */
#endif
#else
UnsignedShort
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:16; /* reserved for skinOffset */
UnsignedShort materialId;
#endif
/**
* @brief Object ID
*
* Used only for the object ID framebuffer output, not to access any other
* uniform data. Default value is @cpp 0 @ce.
*
* Used only if @ref FlatGL::Flag::ObjectId is enabled, ignored otherwise.
* If @ref FlatGL::Flag::InstancedObjectId is enabled as well, this value
* is added to the ID coming from the @ref FlatGL::ObjectId attribute.
* @see @ref FlatGL::setObjectId()
*/
UnsignedInt objectId;
/* warning: Member __pad1__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad1 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad2 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
#endif
};
/**
@brief Material uniform for flat shaders
@m_since_latest
Describes material properties referenced from
@ref FlatDrawUniform::materialId.
@see @ref FlatGL::bindMaterialBuffer()
*/
struct FlatMaterialUniform {
/** @brief Construct with default parameters */
constexpr explicit FlatMaterialUniform(DefaultInitT = DefaultInit) noexcept: color{1.0f, 1.0f, 1.0f, 1.0f}, alphaMask{0.5f}
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
, _pad0{}, _pad1{}, _pad2{}
#endif
{}
/** @brief Construct without initializing the contents */
explicit FlatMaterialUniform(NoInitT) noexcept: color{NoInit} {}
/** @{
* @name Convenience setters
*
* Provided to allow the use of method chaining for populating a structure
* in a single expression, otherwise equivalent to accessing the fields
* directly. Also guaranteed to provide backwards compatibility when
* packing of the actual fields changes.
*/
/**
* @brief Set the @ref alphaMask field
* @return Reference to self (for method chaining)
*/
FlatMaterialUniform& setAlphaMask(Float alphaMask) {
this->alphaMask = alphaMask;
return *this;
}
/**
* @brief Set the @ref color field
* @return Reference to self (for method chaining)
*/
FlatMaterialUniform& setColor(const Color4& color) {
this->color = color;
return *this;
}
/**
* @}
*/
/**
* @brief Color
*
* Default value is @cpp 0xffffffff_rgbaf @ce.
*
* If @ref FlatGL::Flag::VertexColor is enabled, the color is multiplied
* with a color coming from the @ref FlatGL::Color3 / @ref FlatGL::Color4
* attribute.
* @see @ref FlatGL::setColor()
*/
Color4 color;
/**
* @brief Alpha mask value
*
* Fragments with alpha values smaller than the mask value will be
* discarded. Default value is @cpp 0.5f @ce.
*
* Used only if @ref FlatGL::Flag::AlphaMask is enabled, ignored otherwise.
* @see @ref FlatGL::setAlphaMask()
*/
Float alphaMask;
/* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad1 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad2 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
#endif
};
#ifdef MAGNUM_BUILD_DEPRECATED
/** @brief @copybrief FlatGL
* @m_deprecated_since_latest Use @ref FlatGL instead.
*/
@ -61,10 +276,8 @@ typedef CORRADE_DEPRECATED("use FlatGL2D instead") FlatGL2D Flat2D;
* @m_deprecated_since_latest Use @ref FlatGL3D instead.
*/
typedef CORRADE_DEPRECATED("use FlatGL3D instead") FlatGL3D Flat3D;
#endif
}}
#else
#error use Magnum/Shaders/FlatGL.h, the FlatGL class and related typedefs instead
#endif
#endif

137
src/Magnum/Shaders/Flat.vert

@ -27,13 +27,30 @@
#extension GL_EXT_gpu_shader4: require
#endif
#if defined(UNIFORM_BUFFERS) && defined(TEXTURE_ARRAYS) && !defined(GL_ES)
#extension GL_ARB_shader_bit_encoding: require
#endif
#ifdef MULTI_DRAW
#ifndef GL_ES
#extension GL_ARB_shader_draw_parameters: require
#else /* covers WebGL as well */
#extension GL_ANGLE_multi_draw: require
#endif
#endif
#ifndef NEW_GLSL
#define in attribute
#define out varying
#endif
#ifndef RUNTIME_CONST
#define const
#endif
/* Uniforms */
#ifndef UNIFORM_BUFFERS
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 0)
#endif
@ -64,6 +81,66 @@ uniform mediump mat3 textureMatrix
;
#endif
#ifdef TEXTURE_ARRAYS
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 2)
#endif
/* mediump is just 2^10, which might not be enough, this is 2^16 */
uniform highp uint textureLayer; /* defaults to zero */
#endif
/* Uniform buffers */
#else
#if DRAW_COUNT > 1
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 0)
#endif
uniform highp uint drawOffset
#ifndef GL_ES
= 0u
#endif
;
#else
#define drawOffset 0u
#endif
layout(std140
#ifdef EXPLICIT_BINDING
, binding = 1
#endif
) uniform TransformationProjection {
highp
#ifdef TWO_DIMENSIONS
/* Can't be a mat3 because of ANGLE, see DrawUniform in Phong.vert for
details */
mat3x4
#elif defined(THREE_DIMENSIONS)
mat4
#else
#error
#endif
transformationProjectionMatrices[DRAW_COUNT];
};
#ifdef TEXTURE_TRANSFORMATION
struct TextureTransformationUniform {
highp vec4 rotationScaling;
highp vec4 offsetLayerReserved;
#define textureTransformation_offset offsetLayerReserved.xy
#define textureTransformation_layer offsetLayerReserved.z
};
layout(std140
#ifdef EXPLICIT_BINDING
, binding = 3
#endif
) uniform TextureTransformation {
TextureTransformationUniform textureTransformations[DRAW_COUNT];
};
#endif
#endif
/* Inputs */
#ifdef EXPLICIT_ATTRIB_LOCATION
@ -115,13 +192,25 @@ in highp mat4 instancedTransformationMatrix;
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = TEXTURE_OFFSET_ATTRIBUTE_LOCATION)
#endif
in mediump vec2 instancedTextureOffset;
in mediump
#ifndef TEXTURE_ARRAYS
vec2
#else
vec3
#endif
instancedTextureOffset;
#endif
/* Outputs */
#ifdef TEXTURED
out mediump vec2 interpolatedTextureCoordinates;
out mediump
#ifndef TEXTURE_ARRAYS
vec2
#else
vec3
#endif
interpolatedTextureCoordinates;
#endif
#ifdef VERTEX_COLOR
@ -132,7 +221,39 @@ out lowp vec4 interpolatedVertexColor;
flat out highp uint interpolatedInstanceObjectId;
#endif
#ifdef MULTI_DRAW
flat out highp uint drawId;
#endif
void main() {
#ifdef UNIFORM_BUFFERS
#ifdef MULTI_DRAW
drawId = drawOffset + uint(
#ifndef GL_ES
gl_DrawIDARB /* Using GL_ARB_shader_draw_parameters, not GLSL 4.6 */
#else
gl_DrawID
#endif
);
#else
#define drawId drawOffset
#endif
#ifdef TWO_DIMENSIONS
highp const mat3 transformationProjectionMatrix = mat3(transformationProjectionMatrices[drawId]);
#elif defined(THREE_DIMENSIONS)
highp const mat4 transformationProjectionMatrix = transformationProjectionMatrices[drawId];
#else
#error
#endif
#ifdef TEXTURE_TRANSFORMATION
mediump const mat3 textureMatrix = mat3(textureTransformations[drawId].rotationScaling.xy, 0.0, textureTransformations[drawId].rotationScaling.zw, 0.0, textureTransformations[drawId].textureTransformation_offset, 1.0);
#ifdef TEXTURE_ARRAYS
highp const uint textureLayer = floatBitsToUint(textureTransformations[drawId].textureTransformation_layer);
#endif
#endif
#endif
#ifdef TWO_DIMENSIONS
gl_Position.xywz = vec4(transformationProjectionMatrix*
#ifdef INSTANCED_TRANSFORMATION
@ -151,17 +272,25 @@ void main() {
#ifdef TEXTURED
/* Texture coordinates, if needed */
interpolatedTextureCoordinates =
interpolatedTextureCoordinates.xy =
#ifdef TEXTURE_TRANSFORMATION
(textureMatrix*vec3(
#ifdef INSTANCED_TEXTURE_OFFSET
instancedTextureOffset +
instancedTextureOffset.xy +
#endif
textureCoordinates, 1.0)).xy
#else
textureCoordinates
#endif
;
#ifdef TEXTURE_ARRAYS
interpolatedTextureCoordinates.z = float(
#ifdef INSTANCED_TEXTURE_OFFSET
uint(instancedTextureOffset.z) +
#endif
textureLayer
);
#endif
#endif
#ifdef VERTEX_COLOR

259
src/Magnum/Shaders/FlatGL.cpp

@ -39,16 +39,78 @@
#include "Magnum/Shaders/Implementation/CreateCompatibilityShader.h"
#ifndef MAGNUM_TARGET_GLES2
#include <Corrade/Utility/FormatStl.h>
#include "Magnum/GL/Buffer.h"
#include "Magnum/GL/TextureArray.h"
#endif
namespace Magnum { namespace Shaders {
namespace {
enum: Int { TextureUnit = 0 };
#ifndef MAGNUM_TARGET_GLES2
enum: Int {
/* Not using the zero binding to avoid conflicts with
ProjectionBufferBinding from other shaders which can likely stay
bound to the same buffer for the whole time */
TransformationProjectionBufferBinding = 1,
DrawBufferBinding = 2,
TextureTransformationBufferBinding = 3,
MaterialBufferBinding = 4
};
#endif
}
template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(const Flags flags): _flags(flags) {
template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(const Flags flags
#ifndef MAGNUM_TARGET_GLES2
, const UnsignedInt materialCount, const UnsignedInt drawCount
#endif
):
_flags{flags}
#ifndef MAGNUM_TARGET_GLES2
, _materialCount{materialCount}, _drawCount{drawCount}
#endif
{
CORRADE_ASSERT(!(flags & Flag::TextureTransformation) || (flags & Flag::Textured),
"Shaders::FlatGL: texture transformation enabled but the shader is not textured", );
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || materialCount,
"Shaders::FlatGL: material count can't be zero", );
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || drawCount,
"Shaders::FlatGL: draw count can't be zero", );
#endif
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(flags & Flag::TextureArrays) || (flags & Flag::Textured),
"Shaders::FlatGL: texture arrays enabled but the shader is not textured", );
CORRADE_ASSERT(!(flags & Flag::UniformBuffers) || !(flags & Flag::TextureArrays) || flags >= (Flag::TextureArrays|Flag::TextureTransformation),
"Shaders::FlatGL: texture arrays require texture transformation enabled as well if uniform buffers are used", );
#endif
#ifndef MAGNUM_TARGET_GLES
if(flags >= Flag::UniformBuffers)
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::ARB::uniform_buffer_object);
#endif
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::MultiDraw) {
#ifndef MAGNUM_TARGET_GLES
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::ARB::shader_draw_parameters);
#elif !defined(MAGNUM_TARGET_WEBGL)
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::ANGLE::multi_draw);
#else
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::WEBGL::multi_draw);
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES
if(flags >= Flag::TextureArrays)
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::EXT::texture_array);
#endif
#ifdef MAGNUM_BUILD_STATIC
/* Import resources on static build, if not already */
if(!Utility::Resource::hasGroup("MagnumShadersGL"))
@ -70,22 +132,49 @@ template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(const Flags flags):
vert.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "")
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
.addSource(flags & Flag::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags & Flag::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
#endif
.addSource(dimensions == 2 ? "#define TWO_DIMENSIONS\n" : "#define THREE_DIMENSIONS\n")
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif
.addSource(flags & Flag::InstancedTransformation ? "#define INSTANCED_TRANSFORMATION\n" : "")
.addSource(flags >= Flag::InstancedTextureOffset ? "#define INSTANCED_TEXTURE_OFFSET\n" : "")
.addSource(rs.get("generic.glsl"))
.addSource(flags >= Flag::InstancedTextureOffset ? "#define INSTANCED_TEXTURE_OFFSET\n" : "");
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
vert.addSource(Utility::formatString(
"#define UNIFORM_BUFFERS\n"
"#define DRAW_COUNT {}\n",
drawCount));
vert.addSource(flags >= Flag::MultiDraw ? "#define MULTI_DRAW\n" : "");
}
#endif
vert.addSource(rs.get("generic.glsl"))
.addSource(rs.get("Flat.vert"));
frag.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags & Flag::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
#endif
.addSource(flags & Flag::AlphaMask ? "#define ALPHA_MASK\n" : "")
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags & Flag::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif
.addSource(rs.get("generic.glsl"))
;
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
frag.addSource(Utility::formatString(
"#define UNIFORM_BUFFERS\n"
"#define DRAW_COUNT {}\n"
"#define MATERIAL_COUNT {}\n",
drawCount,
materialCount));
frag.addSource(flags >= Flag::MultiDraw ? "#define MULTI_DRAW\n" : "");
}
#endif
frag.addSource(rs.get("generic.glsl"))
.addSource(rs.get("Flat.frag"));
CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, frag}));
@ -124,53 +213,112 @@ template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(const Flags flags):
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
#endif
{
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
if(_drawCount > 1) _drawOffsetUniform = uniformLocation("drawOffset");
} else
#endif
{
_transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
if(flags & Flag::TextureTransformation)
_textureMatrixUniform = uniformLocation("textureMatrix");
#ifndef MAGNUM_TARGET_GLES2
if(flags & Flag::TextureArrays)
_textureLayerUniform = uniformLocation("textureLayer");
#endif
_colorUniform = uniformLocation("color");
if(flags & Flag::AlphaMask) _alphaMaskUniform = uniformLocation("alphaMask");
#ifndef MAGNUM_TARGET_GLES2
if(flags & Flag::ObjectId) _objectIdUniform = uniformLocation("objectId");
#endif
}
}
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::shading_language_420pack>(version))
#endif
{
if(flags & Flag::Textured) setUniform(uniformLocation("textureData"), TextureUnit);
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
setUniformBlockBinding(uniformBlockIndex("TransformationProjection"), TransformationProjectionBufferBinding);
setUniformBlockBinding(uniformBlockIndex("Draw"), DrawBufferBinding);
if(flags & Flag::TextureTransformation)
setUniformBlockBinding(uniformBlockIndex("TextureTransformation"), TextureTransformationBufferBinding);
setUniformBlockBinding(uniformBlockIndex("Material"), MaterialBufferBinding);
}
#endif
}
/* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
#ifdef MAGNUM_TARGET_GLES
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
/* Draw offset is zero by default */
} else
#endif
{
setTransformationProjectionMatrix(MatrixTypeFor<dimensions, Float>{Math::IdentityInit});
if(flags & Flag::TextureTransformation)
setTextureMatrix(Matrix3{Math::IdentityInit});
/* Texture layer is zero by default */
setColor(Magnum::Color4{1.0f});
if(flags & Flag::AlphaMask) setAlphaMask(0.5f);
/* Object ID is zero by default */
}
#endif
}
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(const Flags flags): FlatGL{flags, 1, 1} {}
#endif
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::setTransformationProjectionMatrix(const MatrixTypeFor<dimensions, Float>& matrix) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::FlatGL::setTransformationProjectionMatrix(): the shader was created with uniform buffers enabled", *this);
#endif
setUniform(_transformationProjectionMatrixUniform, matrix);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::setTextureMatrix(const Matrix3& matrix) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::FlatGL::setTextureMatrix(): the shader was created with uniform buffers enabled", *this);
#endif
CORRADE_ASSERT(_flags & Flag::TextureTransformation,
"Shaders::FlatGL::setTextureMatrix(): the shader was not created with texture transformation enabled", *this);
setUniform(_textureMatrixUniform, matrix);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::setTextureLayer(UnsignedInt id) {
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::FlatGL::setTextureLayer(): the shader was created with uniform buffers enabled", *this);
CORRADE_ASSERT(_flags & Flag::TextureArrays,
"Shaders::FlatGL::setTextureLayer(): the shader was not created with texture arrays enabled", *this);
setUniform(_textureLayerUniform, id);
return *this;
}
#endif
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::setColor(const Magnum::Color4& color) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::FlatGL::setColor(): the shader was created with uniform buffers enabled", *this);
#endif
setUniform(_colorUniform, color);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::setAlphaMask(Float mask) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::FlatGL::setAlphaMask(): the shader was created with uniform buffers enabled", *this);
#endif
CORRADE_ASSERT(_flags & Flag::AlphaMask,
"Shaders::FlatGL::setAlphaMask(): the shader was not created with alpha mask enabled", *this);
setUniform(_alphaMaskUniform, mask);
@ -179,6 +327,8 @@ template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::setAlph
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::setObjectId(UnsignedInt id) {
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),
"Shaders::FlatGL::setObjectId(): the shader was created with uniform buffers enabled", *this);
CORRADE_ASSERT(_flags & Flag::ObjectId,
"Shaders::FlatGL::setObjectId(): the shader was not created with object ID enabled", *this);
setUniform(_objectIdUniform, id);
@ -186,12 +336,98 @@ template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::setObje
}
#endif
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::setDrawOffset(const UnsignedInt offset) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::FlatGL::setDrawOffset(): the shader was not created with uniform buffers enabled", *this);
CORRADE_ASSERT(offset < _drawCount,
"Shaders::FlatGL::setDrawOffset(): draw offset" << offset << "is out of bounds for" << _drawCount << "draws", *this);
if(_drawCount > 1) setUniform(_drawOffsetUniform, offset);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindTransformationProjectionBuffer(GL::Buffer& buffer) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::FlatGL::bindTransformationProjectionBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, TransformationProjectionBufferBinding);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindTransformationProjectionBuffer(GL::Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::FlatGL::bindTransformationProjectionBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, TransformationProjectionBufferBinding, offset, size);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindDrawBuffer(GL::Buffer& buffer) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::FlatGL::bindDrawBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, DrawBufferBinding);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindDrawBuffer(GL::Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::FlatGL::bindDrawBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, DrawBufferBinding, offset, size);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindTextureTransformationBuffer(GL::Buffer& buffer) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::FlatGL::bindTextureTransformationBuffer(): the shader was not created with uniform buffers enabled", *this);
CORRADE_ASSERT(_flags & Flag::TextureTransformation,
"Shaders::FlatGL::bindTextureTransformationBuffer(): the shader was not created with texture transformation enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, TextureTransformationBufferBinding);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindTextureTransformationBuffer(GL::Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::FlatGL::bindTextureTransformationBuffer(): the shader was not created with uniform buffers enabled", *this);
CORRADE_ASSERT(_flags & Flag::TextureTransformation,
"Shaders::FlatGL::bindTextureTransformationBuffer(): the shader was not created with texture transformation enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, TextureTransformationBufferBinding, offset, size);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindMaterialBuffer(GL::Buffer& buffer) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::FlatGL::bindMaterialBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, MaterialBufferBinding);
return *this;
}
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindMaterialBuffer(GL::Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
CORRADE_ASSERT(_flags >= Flag::UniformBuffers,
"Shaders::FlatGL::bindMaterialBuffer(): the shader was not created with uniform buffers enabled", *this);
buffer.bind(GL::Buffer::Target::Uniform, MaterialBufferBinding, offset, size);
return *this;
}
#endif
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindTexture(GL::Texture2D& texture) {
CORRADE_ASSERT(_flags & Flag::Textured,
"Shaders::FlatGL::bindTexture(): the shader was not created with texturing enabled", *this);
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags & Flag::TextureArrays),
"Shaders::FlatGL::bindTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead", *this);
#endif
texture.bind(TextureUnit);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> FlatGL<dimensions>& FlatGL<dimensions>::bindTexture(GL::Texture2DArray& texture) {
CORRADE_ASSERT(_flags & Flag::Textured,
"Shaders::FlatGL::bindTexture(): the shader was not created with texturing enabled", *this);
CORRADE_ASSERT(_flags & Flag::TextureArrays,
"Shaders::FlatGL::bindTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead", *this);
texture.bind(TextureUnit);
return *this;
}
#endif
template class MAGNUM_SHADERS_EXPORT FlatGL<2>;
template class MAGNUM_SHADERS_EXPORT FlatGL<3>;
@ -214,11 +450,16 @@ Debug& operator<<(Debug& debug, const FlatGLFlag value) {
#endif
_c(InstancedTransformation)
_c(InstancedTextureOffset)
#ifndef MAGNUM_TARGET_GLES2
_c(UniformBuffers)
_c(MultiDraw)
_c(TextureArrays)
#endif
#undef _c
/* LCOV_EXCL_STOP */
}
return debug << "(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")";
return debug << "(" << Debug::nospace << reinterpret_cast<void*>(UnsignedShort(value)) << Debug::nospace << ")";
}
Debug& operator<<(Debug& debug, const FlatGLFlags value) {
@ -232,7 +473,13 @@ Debug& operator<<(Debug& debug, const FlatGLFlags value) {
FlatGLFlag::InstancedObjectId, /* Superset of ObjectId */
FlatGLFlag::ObjectId,
#endif
FlatGLFlag::InstancedTransformation});
FlatGLFlag::InstancedTransformation,
#ifndef MAGNUM_TARGET_GLES2
FlatGLFlag::MultiDraw, /* Superset of UniformBuffers */
FlatGLFlag::UniformBuffers,
FlatGLFlag::TextureArrays
#endif
});
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save