From 2066d82ea495bdc2bbabf848289b98d450a1de7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 16 Apr 2021 16:34:45 +0200 Subject: [PATCH] Shaders: suffix all existing shaders with GL. To make room for Vulkan shaders. Also renaming the headers, of course everything is still aliased to the old names (and marked as deprecated). --- doc/changelog-old.dox | 35 +- doc/changelog.dox | 234 ++-- doc/developers.dox | 4 +- doc/generated/primitives.cpp | 28 +- doc/generated/shaders.cpp | 40 +- doc/namespaces.dox | 14 +- doc/shaders.dox | 54 +- doc/snippets/CMakeLists.txt | 2 +- doc/snippets/MagnumGL.cpp | 26 +- doc/snippets/MagnumSceneGraph-gl.cpp | 12 +- ...MagnumShaders.cpp => MagnumShaders-gl.cpp} | 258 ++-- doc/snippets/MagnumText.cpp | 4 +- doc/snippets/MagnumTrade.cpp | 8 +- src/Magnum/DebugTools/ForceRenderer.cpp | 8 +- src/Magnum/DebugTools/ForceRenderer.h | 2 +- src/Magnum/DebugTools/ObjectRenderer.cpp | 6 +- src/Magnum/DebugTools/ObjectRenderer.h | 2 +- .../DebugTools/Test/FrameProfilerGLTest.cpp | 4 +- src/Magnum/GL/Framebuffer.h | 4 +- src/Magnum/GL/Mesh.h | 2 +- src/Magnum/GL/Renderer.h | 7 +- src/Magnum/Math/Vector.h | 5 + src/Magnum/MeshTools/Compile.cpp | 16 +- src/Magnum/MeshTools/Compile.h | 39 +- src/Magnum/MeshTools/Test/CompileGLTest.cpp | 54 +- src/Magnum/SceneGraph/Drawable.h | 4 +- src/Magnum/Shaders/AbstractVector.h | 106 +- ...bstractVector.cpp => AbstractVectorGL.cpp} | 8 +- src/Magnum/Shaders/AbstractVectorGL.h | 126 ++ src/Magnum/Shaders/CMakeLists.txt | 48 +- src/Magnum/Shaders/DistanceFieldVector.h | 253 +--- ...ldVector.cpp => DistanceFieldVectorGL.cpp} | 44 +- src/Magnum/Shaders/DistanceFieldVectorGL.h | 275 +++++ src/Magnum/Shaders/Flat.h | 517 +------- src/Magnum/Shaders/{Flat.cpp => FlatGL.cpp} | 60 +- src/Magnum/Shaders/FlatGL.h | 539 +++++++++ src/Magnum/Shaders/Generic.h | 470 +------- src/Magnum/Shaders/GenericGL.h | 521 ++++++++ .../CreateCompatibilityShader.h | 2 +- src/Magnum/Shaders/MeshVisualizer.h | 1030 +--------------- ...eshVisualizer.cpp => MeshVisualizerGL.cpp} | 136 +-- src/Magnum/Shaders/MeshVisualizerGL.h | 1038 ++++++++++++++++ src/Magnum/Shaders/Phong.h | 1029 +--------------- src/Magnum/Shaders/{Phong.cpp => PhongGL.cpp} | 150 +-- src/Magnum/Shaders/PhongGL.h | 1052 +++++++++++++++++ src/Magnum/Shaders/Shaders.h | 68 +- src/Magnum/Shaders/Test/CMakeLists.txt | 28 +- .../Test/DistanceFieldVectorGLTest.cpp | 34 +- ...est.cpp => DistanceFieldVectorGL_Test.cpp} | 48 +- src/Magnum/Shaders/Test/FlatGLTest.cpp | 158 +-- .../Test/{FlatTest.cpp => FlatGL_Test.cpp} | 60 +- src/Magnum/Shaders/Test/GenericGL_Test.cpp | 118 ++ src/Magnum/Shaders/Test/GenericTest.cpp | 116 -- .../Shaders/Test/MeshVisualizerGLTest.cpp | 430 +++---- .../Shaders/Test/MeshVisualizerGL_Test.cpp | 145 +++ .../Shaders/Test/MeshVisualizerTest.cpp | 143 --- src/Magnum/Shaders/Test/PhongGLTest.cpp | 250 ++-- .../Test/{PhongTest.cpp => PhongGL_Test.cpp} | 56 +- src/Magnum/Shaders/Test/VectorGLTest.cpp | 34 +- .../{VectorTest.cpp => VectorGL_Test.cpp} | 48 +- src/Magnum/Shaders/Test/VertexColorGLTest.cpp | 26 +- ...exColorTest.cpp => VertexColorGL_Test.cpp} | 32 +- src/Magnum/Shaders/Vector.h | 220 +--- .../Shaders/{Vector.cpp => VectorGL.cpp} | 40 +- src/Magnum/Shaders/VectorGL.h | 242 ++++ src/Magnum/Shaders/VertexColor.h | 152 +-- .../{VertexColor.cpp => VertexColorGL.cpp} | 14 +- src/Magnum/Shaders/VertexColorGL.h | 172 +++ .../{resources.conf => resources-gl.conf} | 2 +- src/Magnum/Text/Renderer.cpp | 12 +- src/Magnum/Text/Renderer.h | 4 +- src/Magnum/TextureTools/DistanceField.h | 2 +- .../TextureTools/distancefieldconverter.cpp | 2 +- src/Magnum/Trade/MeshData.h | 16 +- 74 files changed, 5821 insertions(+), 5127 deletions(-) rename doc/snippets/{MagnumShaders.cpp => MagnumShaders-gl.cpp} (70%) rename src/Magnum/Shaders/{AbstractVector.cpp => AbstractVectorGL.cpp} (83%) create mode 100644 src/Magnum/Shaders/AbstractVectorGL.h rename src/Magnum/Shaders/{DistanceFieldVector.cpp => DistanceFieldVectorGL.cpp} (75%) create mode 100644 src/Magnum/Shaders/DistanceFieldVectorGL.h rename src/Magnum/Shaders/{Flat.cpp => FlatGL.cpp} (78%) create mode 100644 src/Magnum/Shaders/FlatGL.h create mode 100644 src/Magnum/Shaders/GenericGL.h rename src/Magnum/Shaders/{MeshVisualizer.cpp => MeshVisualizerGL.cpp} (83%) create mode 100644 src/Magnum/Shaders/MeshVisualizerGL.h rename src/Magnum/Shaders/{Phong.cpp => PhongGL.cpp} (75%) create mode 100644 src/Magnum/Shaders/PhongGL.h rename src/Magnum/Shaders/Test/{DistanceFieldVectorTest.cpp => DistanceFieldVectorGL_Test.cpp} (51%) rename src/Magnum/Shaders/Test/{FlatTest.cpp => FlatGL_Test.cpp} (53%) create mode 100644 src/Magnum/Shaders/Test/GenericGL_Test.cpp create mode 100644 src/Magnum/Shaders/Test/MeshVisualizerGL_Test.cpp delete mode 100644 src/Magnum/Shaders/Test/MeshVisualizerTest.cpp rename src/Magnum/Shaders/Test/{PhongTest.cpp => PhongGL_Test.cpp} (54%) rename src/Magnum/Shaders/Test/{VectorTest.cpp => VectorGL_Test.cpp} (54%) rename src/Magnum/Shaders/Test/{VertexColorTest.cpp => VertexColorGL_Test.cpp} (63%) rename src/Magnum/Shaders/{Vector.cpp => VectorGL.cpp} (78%) create mode 100644 src/Magnum/Shaders/VectorGL.h rename src/Magnum/Shaders/{VertexColor.cpp => VertexColorGL.cpp} (89%) create mode 100644 src/Magnum/Shaders/VertexColorGL.h rename src/Magnum/Shaders/{resources.conf => resources-gl.conf} (95%) diff --git a/doc/changelog-old.dox b/doc/changelog-old.dox index 096538b09..1c549b7bd 100644 --- a/doc/changelog-old.dox +++ b/doc/changelog-old.dox @@ -316,10 +316,12 @@ Released 2018-05-01, tagged as are deprecated because texture binding (a global state) is confused there with uniform setup (a shader-local state). That can lead to accidental state mismatches where a texture is forgotten to be rebound. Use - @ref Shaders::AbstractVector::bindVectorTexture() "Shaders::*Vector::bindVectorTexture()", - @ref Shaders::Flat::bindTexture(), @ref Shaders::Phong::bindAmbientTexture(), - @ref Shaders::Phong::bindDiffuseTexture(), @ref Shaders::Phong::bindSpecularTexture() - and @ref Shaders::Phong::bindTextures() instead. + @cpp Shaders::*Vector::bindVectorTexture() @ce, + @cpp Shaders::Flat::bindTexture() @ce, + @cpp Shaders::Phong::bindAmbientTexture() @ce, + @cpp Shaders::Phong::bindDiffuseTexture() @ce, + @cpp Shaders::Phong::bindSpecularTexture() @ce + and @cpp Shaders::Phong::bindTextures() @ce instead. @subsection changelog-2018-04-compatibility Potential compatibility breakages, removed APIs @@ -919,9 +921,10 @@ a high-level overview. @subsubsection changelog-2018-02-changes-shaders Shaders library -- @ref Shaders::Flat now sets default color to white only in textured version -- @ref Shaders::Phong gained the ability to have both color and texture -- @ref Shaders::Phong is now able to do alpha-masking (see +- @cpp Shaders::Flat @ce now sets default color to white only in textured + version +- @cpp Shaders::Phong @ce gained the ability to have both color and texture +- @cpp Shaders::Phong @ce is now able to do alpha-masking (see [mosra/magnum#112](https://github.com/mosra/magnum/issues/112), [mosra/magnum-examples#29](https://github.com/mosra/magnum-examples/issues/29)) @@ -1307,8 +1310,8 @@ for a high-level overview. - Fixed @cpp TextureTools::distanceField() @ce to work in GLSL < 4.20 (see [mosra/magnum#62](https://github.com/mosra/magnum/issues/62)). -- Fixed @ref Shaders::MeshVisualizer to work in GLSL ES. -- Fixed @ref Shaders::Vector "Shaders::*Vector" on Intel GPUs. +- Fixed @cpp Shaders::MeshVisualizer @ce to work in GLSL ES. +- Fixed @cpp Shaders::*Vector @ce on Intel GPUs. - Fixed assertion on contexts without default framebuffer (see [mosra/magnum#93](https://github.com/mosra/magnum/issues/93)). - Fixed cases where shader would use extension that is not advertised by the @@ -1528,8 +1531,8 @@ for a high-level overview. - Fixed usage with OpenGL ES 3.1 contexts (it complained about invalid version) -- Fixed compilation of Shaders::MeshVisualizer under WebGL and with ANGLE, - see [mosra/magnum#56](https://github.com/mosra/magnum/issues/56) +- Fixed compilation of @cpp Shaders::MeshVisualizer @ce under WebGL and with + ANGLE, see [mosra/magnum#56](https://github.com/mosra/magnum/issues/56) - Fixed various build issues on Mac OS X, see [mosra/magnum#51](https://github.com/mosra/magnum/issues/51) and [mosra/magnum#54](https://github.com/mosra/magnum/issues/54) @@ -1672,10 +1675,10 @@ No dependency changes in this release. preserve source compatibility with other application classes. - @ref SceneGraph::Drawable::drawables() function as a non-ambiguous alternative to @cpp group() @ce -- Ability to specify background color color in @ref Shaders::Vector, +- Ability to specify background color color in @cpp Shaders::Vector @ce, allowing it to use without blending enabled (fully transparent black was used previously) -- New @ref Shaders::Generic class with common definitions, so you can +- New @cpp Shaders::Generic @ce class with common definitions, so you can configure mesh for the generic shader and render it with any other compatible shader - Convenience @cpp hasNormals() @ce, @cpp hasTextureCoords2D() @ce functions @@ -1707,7 +1710,7 @@ No dependency changes in this release. - Implementation of @ref Platform::Sdl2Application::viewportEvent() "Platform::*Application::viewportEvent()" is not required anymore, because in many cases the application doesn't need to react to window resize events at all -- Textured @ref Shaders::Flat now multiplies texture with the specified +- Textured @cpp Shaders::Flat @ce now multiplies texture with the specified color instead of ignoring it. See also [mosra/magnum#34](https://github.com/mosra/magnum/issues/34) - All deprecated functions and types are now emitting compiler warnings to encourage updating the code @@ -1724,7 +1727,7 @@ No dependency changes in this release. - @cpp Mesh::addVertexBuffer() @ce now properly computes offsets for matrix attributes - Taking index buffer offset into account in @cpp MeshView @ce class -- Fixed various issues with textured @ref Shaders::Flat shader (actually +- Fixed various issues with textured @cpp Shaders::Flat @ce shader (actually the textured version was not working at all) - Various OS X-related fixes in @ref Shaders library. See also [mosra/magnum#27](https://github.com/mosra/magnum/issues/27). @@ -1840,7 +1843,7 @@ for a high-level overview. - New translation-only transformation in @ref SceneGraph supporting also purely integral coordinates, useful e.g. for UI or 2D platformers. - Detailed collision queries and new `InvertedSphere` shape in Shapes library -- Texture support in @ref Shaders::Flat +- Texture support in @cpp Shaders::Flat @ce - Mouse button queries in @ref Platform::Sdl2Application::MouseMoveEvent "Platform::*Application::MouseMoveEvent" @subsection changelog-2013-10-changes Changes diff --git a/doc/changelog.dox b/doc/changelog.dox index 1794ddd02..f6b54981e 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -142,13 +142,14 @@ See also: @subsubsection changelog-latest-new-shaders Shaders library -- Added @ref Shaders::Phong::setNormalTextureScale(), consuming the recently - added @ref Trade::MaterialAttribute::NormalTextureScale material attribute -- @ref Shaders::Phong was reworked to support directional and +- Added @ref Shaders::PhongGL::setNormalTextureScale(), consuming the + recently added @ref Trade::MaterialAttribute::NormalTextureScale material + attribute +- @ref Shaders::PhongGL was reworked to support directional and range-attenuated point lights to follow the additions to @ref Trade::LightData -- Added @ref Shaders::Phong::setLightSpecularColors() for better control over - speculat highlights +- Added @ref Shaders::PhongGL::setLightSpecularColors() for better control + over specular highlights @subsubsection changelog-latest-new-shadertools ShaderTools library @@ -293,13 +294,13 @@ See also: @subsubsection changelog-latest-changes-shaders Shaders library -- In the original implementation of normal mapping in @ref Shaders::Phong, +- In the original implementation of normal mapping in @ref Shaders::PhongGL, there shader didn't provide a way to supply bitangent direction, forcing users to patch normal maps. This is now possible using newly added - @ref Shaders::Phong::Tangent4, @ref Shaders::Phong::Bitangent attributes - and a @ref Shaders::Phong::Flag::Bitangent flag, implementing support for - both four-component tangents (used by glTF, for example) and separate - tangent and bitangent direction (used by Assimp). + @ref Shaders::PhongGL::Tangent4, @ref Shaders::PhongGL::Bitangent + attributes and a @ref Shaders::PhongGL::Flag::Bitangent flag, implementing + support for both four-component tangents (used by glTF, for example) and + separate tangent and bitangent direction (used by Assimp). @subsubsection changelog-latest-changes-trade Trade library @@ -383,10 +384,10 @@ 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::Phong was normalizing light direction in vertex shader, +- @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 -- @ref Shaders::Phong wasn't normalizing normals coming from normal textures, +- @ref Shaders::PhongGL wasn't normalizing normals coming from normal textures, which may have caused slight artifacts due to limited precision of 8-bit pixel formats - @ref Text::AbstractFontConverter::exportFontToData() and @@ -441,19 +442,32 @@ 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. -- @ref Shaders::Phong::setLightPositions() and - @ref Shaders::Phong::setLightPosition() taking three-component vectors are - deprecated in favor of variants taking four-component vectors, where the +- @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 +- @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 last component distinguishes between directional and point lights -- @cpp Shaders::Phong::setLightPosition(const Vector3&) @ce is deprecated in - favor of @ref Shaders::Phong::setLightPositions() with a single item --- +- @cpp Shaders::PhongGL::setLightPosition(const Vector3&) @ce is deprecated + in favor of @ref Shaders::PhongGL::setLightPositions() with a single item --- it's short enough to not warrant the existence of a dedicated overload -- @ref Shaders::Phong::setLightColors() and - @ref Shaders::Phong::setLightColor() taking four-component colors are +- @ref Shaders::PhongGL::setLightColors() and + @ref Shaders::PhongGL::setLightColor() taking four-component colors are deprecated in favor of variants taking just three-component colors, as the alpha had no meaningful use anyway. -- @cpp Shaders::Phong::setLightColor(const Magnum::Color4&) @ce is deprecated - in favor of @ref Shaders::Phong::setLightColors() with a single item --- +- @cpp Shaders::PhongGL::setLightColor(const Magnum::Color4&) @ce is deprecated + in favor of @ref Shaders::PhongGL::setLightColors() with a single item --- it's short enough to not warrant the existence of a dedicated overload - @cpp Trade::AbstractMaterialData @ce as well as its containing header `Magnum/Trade/AbstractMaterialData.h` is now a deprecated alias to the new @@ -570,9 +584,9 @@ See also: function instead. - `Platform::Sdl2Application::Configuration::WindowFlags::AllowHighDpi`, had no effect anymore - - `Shaders::Generic::Color` and `Shaders::VertexColor::Color`, use - @ref Shaders::VertexColor::Color3 or @ref Shaders::VertexColor::Color4 - instead + - `Shaders::GenericGL::Color` and `Shaders::VertexColorGL::Color`, use + @ref Shaders::VertexColorGL::Color3 or + @ref Shaders::VertexColorGL::Color4 instead - @ref Trade::CameraData constructor not taking an explicit type enum, use @ref Trade::CameraData::CameraData(CameraType, Rad, Float, Float, Float, const void*) instead @@ -619,7 +633,7 @@ See also: made both @cpp nullptr @ce even before the object/feature destructors were called and so it's assumed no code relied on such behavior, nevertheless it's a subtle change worth mentioning. -- Due to the rework of @ref Shaders::Phong to support directional and +- Due to the rework of @ref Shaders::PhongGL to support directional and attenuated point lights, the original behavior of unattenuated point lights isn't available anymore. For backwards compatibility, light positions supplied through three-component vectors are now represented as directional @@ -884,21 +898,22 @@ Released 2020-06-27, tagged as @subsubsection changelog-2020-06-new-shaders Shaders library -- New @ref Shaders::MeshVisualizer2D for 2D mesh visualization -- Tangent space visualization in @ref Shaders::MeshVisualizer3D +- New @cpp Shaders::MeshVisualizer2D @ce for 2D mesh visualization +- Tangent space visualization in @cpp Shaders::MeshVisualizer3D @ce - Object, vertex and primitive ID visualization in - @ref Shaders::MeshVisualizer2D and @ref Shaders::MeshVisualizer3D -- Texture coordinate transformation in @ref Shaders::DistanceFieldVector, - @ref Shaders::Flat, @ref Shaders::Phong and @ref Shaders::Vector -- Ability to render per-instance / per-vertex object ID in @ref Shaders::Flat - and @ref Shaders::Phong, in addition to uniform object ID + @cpp Shaders::MeshVisualizer2D @ce and @cpp Shaders::MeshVisualizer3D @ce +- Texture coordinate transformation in @cpp Shaders::DistanceFieldVector @ce, + @cpp Shaders::Flat @ce, @cpp Shaders::Phong @ce and @cpp Shaders::Vector @ce +- Ability to render per-instance / per-vertex object ID in + @cpp Shaders::Flat @ce and @cpp Shaders::Phong @ce, in addition to uniform + object ID - New attribute definitions and an location allocation scheme in - @ref Shaders::Generic --- @ref Shaders::Generic::Tangent4, - @ref Shaders::Generic::Bitangent, @ref Shaders::Generic::ObjectId plus - @ref Shaders::Generic::TransformationMatrix, - @ref Shaders::Generic::NormalMatrix and - @ref Shaders::Generic::TextureOffset for instancing -- Instancing in @ref Shaders::Flat and @ref Shaders::Phong + @cpp Shaders::Generic @ce --- @cpp Shaders::Generic::Tangent4 @ce, + @cpp Shaders::Generic::Bitangent @ce, @cpp Shaders::Generic::ObjectId @ce + plus @cpp Shaders::Generic::TransformationMatrix @ce, + @cpp Shaders::Generic::NormalMatrix @ce and + @cpp Shaders::Generic::TextureOffset @ce for instancing +- Instancing in @cpp Shaders::Flat @ce and @cpp Shaders::Phong @ce @subsubsection changelog-2020-06-new-trade Trade library @@ -966,10 +981,10 @@ Released 2020-06-27, tagged as `Magnum/version.h` header. This header is not included by any other header to avoid trigerring a full rebuild when Git commit changes. If Git is not found, only the first two defines are present. -- @ref Shaders::MeshVisualizer3D::Flag::Wireframe now implicitly enables - @ref Shaders::MeshVisualizer3D::Flag::NoGeometryShader also on WebGL in +- @cpp Shaders::MeshVisualizer3D::Flag::Wireframe @ce now implicitly enables + @cpp Shaders::MeshVisualizer3D::Flag::NoGeometryShader @ce also on WebGL in addition to ES2, since this platform doesn't have a possibility to have - geometry shaders either. Same is done for @ref Shaders::MeshVisualizer2D. + geometry shaders either. Same is done for @cpp Shaders::MeshVisualizer2D @ce. @subsubsection changelog-2020-06-changes-audio Audio library @@ -1206,9 +1221,9 @@ Released 2020-06-27, tagged as - @ref Resource was unnecessarily querying the @ref ResourceManager for updated data even in cases where no resource update was done since last check -- For a @ref Shaders::Phong with zero lights, alpha mask default value was - incorrectly @cpp 0.0f @ce instead of @cpp 0.5f @ce on OpenGL ES -- @ref Shaders::MeshVisualizer3D accidentally didn't enable +- For a @cpp Shaders::Phong @ce with zero lights, alpha mask default value + was incorrectly @cpp 0.0f @ce instead of @cpp 0.5f @ce on OpenGL ES +- @cpp Shaders::MeshVisualizer3D @ce accidentally didn't enable @glsl noperspective @ce interpolation on desktop, resulting in minor wireframe rendering artifacts - @ref Math::angle() got fixed to not produce NaN results for vectors, @@ -1310,14 +1325,14 @@ Released 2020-06-27, tagged as @ref Primitives::GridFlag::TextureCoordinates and @ref Primitives::GridFlag::Normals for naming consistency - @cpp Shaders::MeshVisualizer @ce is deprecated as the shader can now handle - both 2D and 3D, use @ref Shaders::MeshVisualizer3D instead -- Default constructor of @ref Shaders::MeshVisualizer3D is deprecated, you're - now required to enable at least one visualization feature when constructing - it + both 2D and 3D, use @cpp Shaders::MeshVisualizer3D @ce instead +- Default constructor of @cpp Shaders::MeshVisualizer3D @ce is deprecated, + you're now required to enable at least one visualization feature when + constructing it - @cpp Shaders::MeshVisualizer::setTransformationProjectionMatrix() @ce is deprecated on the 3D variant, use separate - @ref Shaders::MeshVisualizer3D::setTransformationMatrix() and - @ref Shaders::MeshVisualizer3D::setProjectionMatrix() instead + @cpp Shaders::MeshVisualizer3D::setTransformationMatrix() @ce and + @cpp Shaders::MeshVisualizer3D::setProjectionMatrix() @ce instead - Mutable access to @ref Trade::PhongMaterialData color and texture information is deprecated. This was mainly used to populate the contents in asset importers, but the class was redesigned and this is no longer @@ -1374,13 +1389,13 @@ Released 2020-06-27, tagged as 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 - reuse the definitions from @ref Shaders::Generic (and propagating them to - shader code as well) instead of hardcoding the locations directly. - - @ref Shaders::Generic::Color3 / @ref Shaders::Generic::Color4 location - changed from @cpp 3 @ce to @cpp 2 @ce - - @ref Shaders::Generic::Normal location changed from @cpp 2 @ce to + reuse the definitions from @cpp Shaders::Generic @ce (and propagating them + to shader code as well) instead of hardcoding the locations directly. + - @cpp Shaders::Generic::Color3 @ce / @cpp Shaders::Generic::Color4 @ce + location changed from @cpp 3 @ce to @cpp 2 @ce + - @cpp Shaders::Generic::Normal @ce location changed from @cpp 2 @ce to @cpp 5 @ce - - @ref Shaders::Generic::Tangent location changed from @cpp 4 @ce to + - @cpp Shaders::Generic::Tangent @ce location changed from @cpp 4 @ce to @cpp 3 @ce - Removed remaining APIs deprecated in version 2018.04: - @cpp Audio::Buffer::Format @ce, use @ref Audio::BufferFormat instead @@ -1390,12 +1405,12 @@ Released 2020-06-27, tagged as @cpp Shaders::Phong::setDiffuseTexture() @ce, @cpp Shaders::Phong::setSpecularTexture() @ce and @cpp Shaders::Phong::setTextures() @ce, use - @ref Shaders::AbstractVector::bindVectorTexture() "Shaders::*Vector::bindVectorTexture()", - @ref Shaders::Flat::bindTexture(), - @ref Shaders::Phong::bindAmbientTexture(), - @ref Shaders::Phong::bindDiffuseTexture(), - @ref Shaders::Phong::bindSpecularTexture() and - @ref Shaders::Phong::bindTextures() instead + @cpp Shaders::*Vector::bindVectorTexture() @ce, + @cpp Shaders::Flat::bindTexture() @ce, + @cpp Shaders::Phong::bindAmbientTexture() @ce, + @cpp Shaders::Phong::bindDiffuseTexture() @ce, + @cpp Shaders::Phong::bindSpecularTexture() @ce and + @cpp Shaders::Phong::bindTextures() @ce instead - @ref MeshPrimitive is now four bytes instead of one, to allow wrapping implementation-specific values using @ref meshPrimitiveWrap() and @ref meshPrimitiveUnwrap() @@ -1415,7 +1430,7 @@ Released 2020-06-27, tagged as [mosra/magnum#394](https://github.com/mosra/magnum/pull/394), [mosra/magnum#418](https://github.com/mosra/magnum/pull/418), [mosra/magnum#424](https://github.com/mosra/magnum/pull/424)) -- @ref Shaders::Generic now shows the recommended way how to propagate +- @cpp Shaders::Generic @ce now shows the recommended way how to propagate generic attribute locations to custom shader code (see [mosra/magnum#443](https://github.com/mosra/magnum/issues/443)) @@ -1719,10 +1734,11 @@ Released 2019-10-24, tagged as @subsubsection changelog-2019-10-new-shaders Shaders library -- Normal texture support in @ref Shaders::Phong -- Added @ref Shaders::Generic3D::Tangent generic vertex attribute definition -- Object ID output in @ref Shaders::Flat and @ref Shaders::Phong -- Vertex color support in @ref Shaders::Flat and @ref Shaders::Phong +- Normal texture support in @cpp Shaders::Phong @ce +- Added @cpp Shaders::Generic3D::Tangent @ce generic vertex attribute + definition +- Object ID output in @cpp Shaders::Flat @ce and @cpp Shaders::Phong @ce +- Vertex color support in @cpp Shaders::Flat @ce and @cpp Shaders::Phong @ce @subsubsection changelog-2019-10-new-text Text library @@ -1867,12 +1883,12 @@ Released 2019-10-24, tagged as - All shaders now have rendering output tests, making them more robust for future additions and refactorings. See also [mosra/magnum#382](https://github.com/mosra/magnum/pull/382). -- @ref Shaders::Phong now clamps the specular factor to minimize artifacts +- @cpp Shaders::Phong @ce now clamps the specular factor to minimize artifacts when shininess is near zero -- @ref Shaders::Phong can now handle zero lights, in which case its output is - equivalent to @ref Shaders::Flat3D. See @ref Shaders-Phong-lights-zero for - more information. -- @ref Shaders::MeshVisualizer is fixed to work properly on Intel Windows +- @cpp Shaders::Phong @ce can now handle zero lights, in which case its output + is equivalent to @cpp Shaders::Flat3D @ce. See + @ref Shaders-PhongGL-lights-zero for more information. +- @cpp Shaders::MeshVisualizer @ce is fixed to work properly on Intel Windows drivers, adding a new @cpp "intel-windows-explicit-uniform-location-is-less-explicit-than-you-hoped" @ce workaround @@ -2081,8 +2097,8 @@ Released 2019-10-24, tagged as passing a freshly created @ref GL::Buffer to it was causing @ref GL::Renderer::Error::InvalidOperation on systems without @gl_extension{ARB,direct_state_access}. -- Fixed @ref Shaders::Vector and @ref Shaders::DistanceFieldVector to work - on iOS, which has only 8 texture binding slots in total (see +- Fixed @cpp Shaders::Vector @ce and @cpp Shaders::DistanceFieldVector @ce to + work on iOS, which has only 8 texture binding slots in total (see [mosra/magnum-examples#65](https://github.com/mosra/magnum-examples/issues/65) and [mosra/magnum#374](https://github.com/mosra/magnum/pull/374)) @@ -2247,10 +2263,10 @@ Released 2019-10-24, tagged as to indicate an invalid format, better catching accidentally forgotten initialization. Valid code shouldn't be affected by this change, but broken code that seemingly worked before might start throwing assertions now. -- @ref Shaders::MeshVisualizer now asserts if its wireframe-related setters - are called when the @ref Shaders::MeshVisualizer::Flag::Wireframe flag was - not set, consistently with other shaders. This might cause failures in code - that was calling them unnecessarily before. +- @cpp Shaders::MeshVisualizer @ce now asserts if its wireframe-related + setters are called when the @cpp Shaders::MeshVisualizer::Flag::Wireframe @ce + flag was not set, consistently with other shaders. This might cause + failures in code that was calling them unnecessarily before. @section changelog-2019-01 2019.01 @@ -2645,15 +2661,17 @@ Released 2018-10-23, tagged as @subsubsection changelog-2018-10-new-shaders Shaders library -- New dedicated @ref Shaders::VertexColor::Color3 and - @ref Shaders::VertexColor::Color4 attribute specifiers for more convenient - distinction between three- and four-component vertex color attribute. -- Support for multiple lights in @ref Shaders::Phong -- Classical alpha masking support in @ref Shaders::Flat and - @ref Shaders::Phong -- Debug output for the @ref Shaders::Flat::Flag / @ref Shaders::Flat::Flags, - @ref Shaders::MeshVisualizer::Flag / @ref Shaders::MeshVisualizer::Flags - and @ref Shaders::Phong::Flag / @ref Shaders::Phong::Flags enums / enum +- New dedicated @cpp Shaders::VertexColor::Color3 @ce and + @cpp Shaders::VertexColor::Color4 @ce attribute specifiers for more + convenient distinction between three- and four-component vertex color + attribute. +- Support for multiple lights in @cpp Shaders::Phong @ce +- Classical alpha masking support in @cpp Shaders::Flat @ce and + @cpp Shaders::Phong @ce +- Debug output for the @cpp Shaders::Flat::Flag @ce / + @cpp Shaders::Flat::Flags @ce, @cpp Shaders::MeshVisualizer::Flag @ce / + @cpp Shaders::MeshVisualizer::Flags @ce and + @cpp Shaders::Phong::Flag @ce / @cpp Shaders::Phong::Flags @ce enums / enum sets @subsubsection changelog-2018-10-new-trade Trade library @@ -2787,13 +2805,14 @@ Released 2018-10-23, tagged as - All shaders now have reasonable default values for uniforms in order to further simplify and remove friction from quick prototyping use cases -- @ref Shaders::Flat::bindTexture(), @ref Shaders::Phong::bindAmbientTexture(), - @ref Shaders::Phong::bindDiffuseTexture(), - @ref Shaders::Phong::bindSpecularTexture() and - @ref Shaders::Phong::bindTextures() now assert that the shader was created - with the corresponding flag enabled to prevent accidental "black screen of - death" errors. -- Ambient color in untextured @ref Shaders::Phong now defaults to +- @cpp Shaders::Flat::bindTexture() @ce, + @cpp Shaders::Phong::bindAmbientTexture() @ce, + @cpp Shaders::Phong::bindDiffuseTexture() @ce, + @cpp Shaders::Phong::bindSpecularTexture() @ce and + @cpp Shaders::Phong::bindTextures() @ce now assert that the shader was + created with the corresponding flag enabled to prevent accidental "black + screen of death" errors. +- Ambient color in untextured @cpp Shaders::Phong @ce now defaults to @cpp 0x00000000_rgbaf @ce in order to support alpha-masked drawing out of the box @@ -2866,8 +2885,8 @@ Released 2018-10-23, tagged as - Vertex attribute divisor in @ref GL::Mesh::addVertexBufferInstanced() was not properly cleaned up after when @gl_extension{ARB,vertex_array_object} was disabled, causing subsequent draws to misbehave -- Fixed @ref Shaders::DistanceFieldVector and @ref Shaders::Vector to be - properly movable +- Fixed @cpp Shaders::DistanceFieldVector @ce and @cpp Shaders::Vector @ce to + be properly movable - Restored backwards compatibility to the templated @ref GL::Buffer::map() overload --- it was not possible to call it with @cpp void @ce template parameter @@ -2960,9 +2979,9 @@ Released 2018-10-23, tagged as tuple was deprecated, use the simpler version taking just @cpp Trade::MeshData2D @ce / @cpp Trade::MeshData3D @ce and directly returning a @ref GL::Mesh instead -- `Shaders::VertexColor::Color` is deprecated, use the direct - @ref Shaders::VertexColor::Color3 or @ref Shaders::VertexColor::Color4 - alternatives instead +- @cpp Shaders::VertexColor::Color @ce is deprecated, use the direct + @cpp Shaders::VertexColor::Color3 @ce or + @cpp Shaders::VertexColor::Color4 @ce alternatives instead - @cpp Trade::AbstractMaterialData @ce constructor taking just two parameters and @ref Trade::PhongMaterialData constructor taking three parameters are deprecated, use @cpp Trade::AbstractMaterialData::AbstractMaterialData(MaterialType, Flags, MaterialAlphaMode, Float, const void*) @ce @@ -3006,14 +3025,15 @@ Released 2018-10-23, tagged as are no longer @cpp virtual @ce functions. If you need to override their functionality, simply call the subclass implementation directly instead of calling it through a @ref SceneGraph::Camera. -- @ref Shaders::Flat::bindTexture(), @ref Shaders::Phong::bindAmbientTexture(), - @ref Shaders::Phong::bindDiffuseTexture(), - @ref Shaders::Phong::bindSpecularTexture() and - @ref Shaders::Phong::bindTextures() now assert that the shader was created - with the corresponding flag enabled to prevent accidental "black screen of - death" errors. This might cause your application to abort if it was calling - these functions when not needed. -- Ambient color in untextured @ref Shaders::Phong now defaults to +- @cpp Shaders::Flat::bindTexture() @ce, + @cpp Shaders::Phong::bindAmbientTexture() @ce, + @cpp Shaders::Phong::bindDiffuseTexture() @ce, + @cpp Shaders::Phong::bindSpecularTexture() @ce and + @cpp Shaders::Phong::bindTextures() @ce now assert that the shader was + created with the corresponding flag enabled to prevent accidental "black + screen of death" errors. This might cause your application to abort if it + was calling these functions when not needed. +- Ambient color in untextured @cpp Shaders::Phong @ce now defaults to @cpp 0x00000000_rgbaf @ce in order to support alpha-masked drawing out of the box. This may break code that assumed the alpha channel being opaque by default. diff --git a/doc/developers.dox b/doc/developers.dox index bebabdf9e..3c8ccd731 100644 --- a/doc/developers.dox +++ b/doc/developers.dox @@ -508,14 +508,14 @@ in inverse --- but usually @ref developers-deprecation "deprecate first". @section developers-adding-attribute Checklist for adding a new mesh attribute 1. Extend @ref Trade::MeshAttribute with the new entry -2. Add a corresponding reserved type to @ref Shaders::Generic, if not there +2. Add a corresponding reserved type to @ref Shaders::GenericGL, if not there already - Also update `src/Magnum/Shaders/generic.glsl` with the reserved ID 3. Update the type assertion in the @ref Trade::MeshAttributeData constructor to account for the new type 4. Add a pair of convenience getters to @ref Trade::MeshData similar to e.g. @ref Trade::MeshData::normalsInto() / @ref Trade::MeshData::normalsAsArray() - with a type that's the same as the one used in the @ref Shaders::Generic + with a type that's the same as the one used in the @ref Shaders::GenericGL definition, test that it does the right thing for every supported type 5. Update @ref Trade::operator<<(Debug&, MeshAttribute) for the new entry 6. Update @ref MeshTools::compile() to recognize the new attribute. If there diff --git a/doc/generated/primitives.cpp b/doc/generated/primitives.cpp index ab42a42de..ae3164a0e 100644 --- a/doc/generated/primitives.cpp +++ b/doc/generated/primitives.cpp @@ -71,10 +71,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -185,7 +185,7 @@ int PrimitiveVisualizer::exec() { GL::Renderer::setLineWidth(2.0f); { - Shaders::VertexColor2D shader; + Shaders::VertexColorGL2D shader; shader.setTransformationProjectionMatrix(Projection2D*Transformation2D); for(auto fun: {&PrimitiveVisualizer::axis2D}) { @@ -204,7 +204,7 @@ int PrimitiveVisualizer::exec() { } { - Shaders::VertexColor3D shader; + Shaders::VertexColorGL3D shader; shader.setTransformationProjectionMatrix(Projection3D*Transformation3D); for(auto fun: {&PrimitiveVisualizer::axis3D}) { @@ -223,7 +223,7 @@ int PrimitiveVisualizer::exec() { } { - Shaders::Flat2D shader; + Shaders::FlatGL2D shader; shader.setColor(OutlineColor) .setTransformationProjectionMatrix(Projection2D*Transformation2D); @@ -248,7 +248,7 @@ int PrimitiveVisualizer::exec() { } { - Shaders::Flat3D shader; + Shaders::FlatGL3D shader; shader.setColor(OutlineColor) .setTransformationProjectionMatrix(Projection3D*Transformation3D); @@ -278,7 +278,7 @@ int PrimitiveVisualizer::exec() { } } - Shaders::MeshVisualizer2D wireframe2D{Shaders::MeshVisualizer2D::Flag::Wireframe}; + Shaders::MeshVisualizerGL2D wireframe2D{Shaders::MeshVisualizerGL2D::Flag::Wireframe}; wireframe2D.setColor(0x00000000_srgbaf) .setWireframeColor(OutlineColor) .setWireframeWidth(2.0f) @@ -286,7 +286,7 @@ int PrimitiveVisualizer::exec() { .setTransformationProjectionMatrix(Projection2D*Transformation2D); { - Shaders::Flat2D flat; + Shaders::FlatGL2D flat; flat.setColor(BaseColor) .setTransformationProjectionMatrix(Projection2D*Transformation2D); @@ -309,7 +309,7 @@ int PrimitiveVisualizer::exec() { } } - Shaders::MeshVisualizer3D wireframe3D{Shaders::MeshVisualizer3D::Flag::Wireframe}; + Shaders::MeshVisualizerGL3D wireframe3D{Shaders::MeshVisualizerGL3D::Flag::Wireframe}; wireframe3D.setColor(0x00000000_srgbaf) .setWireframeColor(OutlineColor) .setWireframeWidth(2.0f) @@ -318,7 +318,7 @@ int PrimitiveVisualizer::exec() { .setProjectionMatrix(Projection3D); { - Shaders::Phong phong; + Shaders::PhongGL phong; phong.setAmbientColor(0x22272e_srgbf) .setDiffuseColor(BaseColor) .setSpecularColor(0x000000_srgbf) @@ -354,7 +354,7 @@ int PrimitiveVisualizer::exec() { } { - Shaders::VertexColor2D shader; + Shaders::VertexColorGL2D shader; shader.setTransformationProjectionMatrix(Projection2D*Transformation2D); for(auto fun: {&PrimitiveVisualizer::gradient2D, @@ -377,7 +377,7 @@ int PrimitiveVisualizer::exec() { } { - Shaders::VertexColor3D shader; + Shaders::VertexColorGL3D shader; shader.setTransformationProjectionMatrix(Projection3D*Transformation3D); for(auto fun: {&PrimitiveVisualizer::gradient3D, diff --git a/doc/generated/shaders.cpp b/doc/generated/shaders.cpp index 09dd64280..772959b7e 100644 --- a/doc/generated/shaders.cpp +++ b/doc/generated/shaders.cpp @@ -60,12 +60,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -162,7 +162,7 @@ namespace { } std::string ShaderVisualizer::phong() { - Shaders::Phong{} + Shaders::PhongGL{} .setAmbientColor(0x22272e_srgbf) .setDiffuseColor(BaseColor) .setShininess(200.0f) @@ -180,7 +180,7 @@ std::string ShaderVisualizer::meshVisualizer2D() { Matrix3::projection(Vector2{3.0f})* Matrix3::rotation(13.7_degf); - Shaders::MeshVisualizer2D{Shaders::MeshVisualizer2D::Flag::Wireframe} + Shaders::MeshVisualizerGL2D{Shaders::MeshVisualizerGL2D::Flag::Wireframe} .setColor(BaseColor) .setWireframeColor(OutlineColor) .setWireframeWidth(2.0f) @@ -206,7 +206,7 @@ std::string ShaderVisualizer::meshVisualizer2DPrimitiveId() { .setStorage(1, GL::TextureFormat::SRGB8Alpha8, size) .setSubImage(0, {}, ImageView2D{PixelFormat::RGB8Srgb, size, map}); - Shaders::MeshVisualizer2D{Shaders::MeshVisualizer2D::Flag::PrimitiveId} + Shaders::MeshVisualizerGL2D{Shaders::MeshVisualizerGL2D::Flag::PrimitiveId} .setTransformationProjectionMatrix(projection) .setColorMapTransformation(1.0f/255.0f, 1.0f/8.0f) .bindColorMapTexture(colorMapTexture) @@ -220,10 +220,10 @@ std::string ShaderVisualizer::meshVisualizer3D() { Matrix4::rotationZ(13.7_degf)* Matrix4::rotationX(-12.6_degf); - Shaders::MeshVisualizer3D{Shaders::MeshVisualizer3D::Flag::Wireframe| - Shaders::MeshVisualizer3D::Flag::TangentDirection| - Shaders::MeshVisualizer3D::Flag::BitangentFromTangentDirection| - Shaders::MeshVisualizer3D::Flag::NormalDirection} + Shaders::MeshVisualizerGL3D{Shaders::MeshVisualizerGL3D::Flag::Wireframe| + Shaders::MeshVisualizerGL3D::Flag::TangentDirection| + Shaders::MeshVisualizerGL3D::Flag::BitangentFromTangentDirection| + Shaders::MeshVisualizerGL3D::Flag::NormalDirection} .setColor(BaseColor) .setWireframeColor(OutlineColor) .setWireframeWidth(2.0f) @@ -253,7 +253,7 @@ std::string ShaderVisualizer::meshVisualizer3DPrimitiveId() { .setStorage(1, GL::TextureFormat::SRGB8Alpha8, size) .setSubImage(0, {}, ImageView2D{PixelFormat::RGB8Srgb, size, map}); - Shaders::MeshVisualizer3D{Shaders::MeshVisualizer3D::Flag::PrimitiveId} + Shaders::MeshVisualizerGL3D{Shaders::MeshVisualizerGL3D::Flag::PrimitiveId} .setTransformationMatrix(transformation) .setProjectionMatrix(Projection) .setColorMapTransformation(1.0f/255.0f, 1.0f/32.0f) @@ -264,7 +264,7 @@ std::string ShaderVisualizer::meshVisualizer3DPrimitiveId() { } std::string ShaderVisualizer::flat() { - Shaders::Flat3D{} + Shaders::FlatGL3D{} .setColor(BaseColor) .setTransformationProjectionMatrix(Projection*Transformation) .draw(MeshTools::compile(Primitives::uvSphereSolid(16, 32))); @@ -290,11 +290,11 @@ std::string ShaderVisualizer::vertexColor() { mesh.setPrimitive(GL::MeshPrimitive::Triangles) .setCount(sphere.indexCount()) .addVertexBuffer(vertices, 0, - Shaders::VertexColor3D::Position{}, - Shaders::VertexColor3D::Color3{}) + Shaders::VertexColorGL3D::Position{}, + Shaders::VertexColorGL3D::Color3{}) .setIndexBuffer(indices, 0, GL::MeshIndexType::UnsignedInt); - Shaders::VertexColor3D shader; + Shaders::VertexColorGL3D shader; shader.setTransformationProjectionMatrix(Projection*Transformation) .draw(mesh); @@ -319,7 +319,7 @@ std::string ShaderVisualizer::vector() { GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::One, GL::Renderer::BlendFunction::OneMinusSourceAlpha); GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add, GL::Renderer::BlendEquation::Add); - Shaders::Vector2D{} + Shaders::VectorGL2D{} .setColor(BaseColor) .bindVectorTexture(texture) .setTransformationProjectionMatrix({}) @@ -348,7 +348,7 @@ std::string ShaderVisualizer::distanceFieldVector() { GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::One, GL::Renderer::BlendFunction::OneMinusSourceAlpha); GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add, GL::Renderer::BlendEquation::Add); - Shaders::DistanceFieldVector2D{} + Shaders::DistanceFieldVectorGL2D{} .setColor(BaseColor) .setOutlineColor(OutlineColor) .setOutlineRange(0.6f, 0.4f) diff --git a/doc/namespaces.dox b/doc/namespaces.dox index 4af84179d..62c0ad507 100644 --- a/doc/namespaces.dox +++ b/doc/namespaces.dox @@ -446,19 +446,19 @@ See @ref building, @ref cmake and @ref shaders for more information. @m_div{m-col-m-4 m-col-t-6 m-text-center m-nopadt m-nopadx} @image html shaders-flat.png width=256px -@ref Flat @m_class{m-label m-success} **2D** @m_class{m-label m-primary} **3D** +@ref FlatGL @m_class{m-label m-success} **2D** @m_class{m-label m-primary} **3D** @m_enddiv @m_div{m-col-m-4 m-col-t-6 m-text-center m-nopadt m-nopadx} @image html shaders-phong.png width=256px -@ref Phong @m_class{m-label m-primary} **3D** +@ref PhongGL @m_class{m-label m-primary} **3D** @m_enddiv @m_div{m-clearfix-t} @m_enddiv @m_div{m-col-m-4 m-push-t-3 m-push-m-0 m-col-t-6 m-text-center m-nopadt m-nopadx} @image html shaders-vertexcolor.png width=256px -@ref VertexColor @m_class{m-label m-success} **2D** @m_class{m-label m-primary} **3D** +@ref VertexColorGL @m_class{m-label m-success} **2D** @m_class{m-label m-primary} **3D** @m_enddiv @endparblock @@ -471,22 +471,22 @@ See @ref building, @ref cmake and @ref shaders for more information. @m_div{m-col-m-3 m-col-t-6 m-text-center m-nopadt m-nopadx} @image html shaders-meshvisualizer2d.png width=256px -@ref MeshVisualizer2D "MeshVisualizer2D" @m_class{m-label m-success} **2D** +@ref MeshVisualizerGL2D @m_class{m-label m-success} **2D** @m_enddiv @m_div{m-col-m-3 m-col-t-6 m-text-center m-nopadt m-nopadx} @image html shaders-meshvisualizer3d.png width=256px -@ref MeshVisualizer3D "MeshVisualizer3D" @m_class{m-label m-primary} **3D** +@ref MeshVisualizerGL3D @m_class{m-label m-primary} **3D** @m_enddiv @m_div{m-col-m-3 m-col-t-6 m-text-center m-nopadt m-nopadx} @image html shaders-vector.png width=256px -@ref Vector @m_class{m-label m-success} **2D** @m_class{m-label m-primary} **3D** +@ref VectorGL @m_class{m-label m-success} **2D** @m_class{m-label m-primary} **3D** @m_enddiv @m_div{m-col-m-3 m-col-t-6 m-text-center m-nopadt m-nopadx} @image html shaders-distancefieldvector.png width=256px -@ref DistanceFieldVector @m_class{m-label m-success} **2D** @m_class{m-label m-primary} **3D** +@ref DistanceFieldVectorGL @m_class{m-label m-success} **2D** @m_class{m-label m-primary} **3D** @m_enddiv @endparblock diff --git a/doc/shaders.dox b/doc/shaders.dox index 40d7ff063..eb867025f 100644 --- a/doc/shaders.dox +++ b/doc/shaders.dox @@ -37,14 +37,16 @@ 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: -- @ref Shaders::Flat "Shaders::Flat*D" --- flat shading using single color or - texture -- @ref Shaders::Vector "Shaders::Vector*D" --- colored vector graphics -- @ref Shaders::DistanceFieldVector "Shaders::DistanceFieldVector*D" -- +- @ref Shaders::FlatGL "Shaders::FlatGL*D" --- flat shading using single + color or texture +- @ref Shaders::VectorGL "Shaders::VectorGL*D" --- colored vector graphics +- @ref Shaders::DistanceFieldVectorGL "Shaders::DistanceFieldVectorGL*D" -- colored and outlined vector graphics -- @ref Shaders::VertexColor "Shaders::VertexColor*D" --- vertex-colored meshes -- @ref Shaders::Phong --- Phong shading using colors or textures, 3D only -- @ref Shaders::MeshVisualizer --- wireframe visualization, 3D only +- @ref Shaders::VertexColorGL "Shaders::VertexColorGL*D" --- vertex-colored + meshes +- @ref Shaders::PhongGL --- Phong shading using colors or textures, 3D only +- @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 @@ -58,9 +60,9 @@ mesh and configuring the shader itself. Each shader expects some set of vertex attributes, thus when adding 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::Phong shader: +usage examples. Example mesh configuration for @ref Shaders::PhongGL shader: -@snippet MagnumShaders.cpp shaders-setup +@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 @@ -69,39 +71,39 @@ 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::Phong @endlink: +Example configuration and rendering using @link Shaders::PhongGL @endlink: -@snippet MagnumShaders.cpp shaders-rendering +@snippet MagnumShaders-gl.cpp shaders-rendering @section shaders-generic Generic vertex attributes and framebuffer attachments 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::Generic -class. Configuration of the above mesh using generic attributes could then look -like this: +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: -@snippet MagnumShaders.cpp shaders-generic +@snippet MagnumShaders-gl.cpp shaders-generic Note that in this particular case both configurations are equivalent, because -@ref Shaders::Phong also uses generic vertex attribute definitions. Then you -can render the mesh using @ref Shaders::Phong shader like above, or use for -example @ref Shaders::Flat3D or even @ref Shaders::MeshVisualizer with the same -mesh reconfiguration. The unused attributes will be simply ignored. +@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. -@snippet MagnumShaders.cpp shaders-meshvisualizer +@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::Generic contains generic +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::Flat or -@ref Shaders::Phong offer an object ID output as well. A setup equivalent to -what's done in Flat shader's @ref Shaders-Flat-object-id but using the generic -definitions would look like this: +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.cpp shaders-generic-object-id +@snippet MagnumShaders-gl.cpp shaders-generic-object-id */ } diff --git a/doc/snippets/CMakeLists.txt b/doc/snippets/CMakeLists.txt index 236b38714..dd8510fd4 100644 --- a/doc/snippets/CMakeLists.txt +++ b/doc/snippets/CMakeLists.txt @@ -86,7 +86,7 @@ if(WITH_GL) add_library(snippets-MagnumGL STATIC MagnumGL.cpp MagnumMeshTools-gl.cpp - MagnumShaders.cpp + MagnumShaders-gl.cpp MagnumText.cpp) target_link_libraries(snippets-MagnumGL PRIVATE MagnumGL) set_target_properties(snippets-MagnumGL PROPERTIES FOLDER "Magnum/doc/snippets") diff --git a/doc/snippets/MagnumGL.cpp b/doc/snippets/MagnumGL.cpp index 93e3880bd..a17f87d98 100644 --- a/doc/snippets/MagnumGL.cpp +++ b/doc/snippets/MagnumGL.cpp @@ -52,7 +52,7 @@ #include "Magnum/MeshTools/CompressIndices.h" #include "Magnum/Primitives/Cube.h" #include "Magnum/Primitives/Plane.h" -#include "Magnum/Shaders/Phong.h" +#include "Magnum/Shaders/PhongGL.h" #include "Magnum/Trade/MeshData.h" #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) @@ -1039,7 +1039,7 @@ buffer.setData(MeshTools::interleave(plane.positions3DAsArray(), GL::Mesh mesh; mesh.setPrimitive(plane.primitive()) .setCount(plane.vertexCount()) - .addVertexBuffer(buffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{}); + .addVertexBuffer(buffer, 0, Shaders::PhongGL::Position{}, Shaders::PhongGL::Normal{}); /* [Mesh-interleaved] */ } @@ -1099,7 +1099,7 @@ indexBuffer.setData(indexData); GL::Mesh mesh; mesh.setPrimitive(cube.primitive()) .setCount(cube.indexCount()) - .addVertexBuffer(vertexBuffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{}) + .addVertexBuffer(vertexBuffer, 0, Shaders::PhongGL::Position{}, Shaders::PhongGL::Normal{}) .setIndexBuffer(indexBuffer, 0, indexType); /* [Mesh-indexed-tools] */ } @@ -1169,14 +1169,14 @@ GL::Mesh mesh; GL::Buffer vertices, indices; // ... mesh.addVertexBuffer(std::move(vertices), 0, - Shaders::Phong::Position{}, - Shaders::Phong::Normal{}) + Shaders::PhongGL::Position{}, + Shaders::PhongGL::Normal{}) .setIndexBuffer(std::move(indices), 0, MeshIndexType::UnsignedInt); /* [Mesh-buffer-ownership] */ /* [Mesh-buffer-ownership-multiple] */ -mesh.addVertexBuffer(vertices, 0, Shaders::Phong::Position{}, 20) - .addVertexBuffer(std::move(vertices), 0, 20, Shaders::Phong::Normal{}); +mesh.addVertexBuffer(vertices, 0, Shaders::PhongGL::Position{}, 20) + .addVertexBuffer(std::move(vertices), 0, 20, Shaders::PhongGL::Normal{}); /* [Mesh-buffer-ownership-multiple] */ } @@ -1186,20 +1186,20 @@ GL::Buffer buffer; GL::Mesh mesh; mesh.addVertexBuffer(buffer, 76, /* initial array offset */ 4, /* skip vertex weight (Float) */ - Shaders::Phong::Position(), /* vertex position */ + Shaders::PhongGL::Position(), /* vertex position */ 8, /* skip texture coordinates (Vector2) */ - Shaders::Phong::Normal()); /* vertex normal */ + Shaders::PhongGL::Normal()); /* vertex normal */ /* [Mesh-addVertexBuffer1] */ /* [Mesh-addVertexBuffer2] */ -mesh.addVertexBuffer(buffer, 76, 4, Shaders::Phong::Position{}, 20) - .addVertexBuffer(buffer, 76, 24, Shaders::Phong::Normal{}, 0); +mesh.addVertexBuffer(buffer, 76, 4, Shaders::PhongGL::Position{}, 20) + .addVertexBuffer(buffer, 76, 24, Shaders::PhongGL::Normal{}, 0); /* [Mesh-addVertexBuffer2] */ /* [Mesh-addVertexBuffer3] */ Int vertexCount = 352; -mesh.addVertexBuffer(buffer, 76 + 4*vertexCount, Shaders::Phong::Position{}) - .addVertexBuffer(buffer, 76 + 24*vertexCount, Shaders::Phong::Normal{}); +mesh.addVertexBuffer(buffer, 76 + 4*vertexCount, Shaders::PhongGL::Position{}) + .addVertexBuffer(buffer, 76 + 24*vertexCount, Shaders::PhongGL::Normal{}); /* [Mesh-addVertexBuffer3] */ } diff --git a/doc/snippets/MagnumSceneGraph-gl.cpp b/doc/snippets/MagnumSceneGraph-gl.cpp index 8f22182a5..b5d99d6b3 100644 --- a/doc/snippets/MagnumSceneGraph-gl.cpp +++ b/doc/snippets/MagnumSceneGraph-gl.cpp @@ -39,8 +39,8 @@ #include "Magnum/SceneGraph/MatrixTransformation3D.h" #include "Magnum/SceneGraph/Object.h" #include "Magnum/SceneGraph/Scene.h" -#include "Magnum/Shaders/Flat.h" -#include "Magnum/Shaders/Phong.h" +#include "Magnum/Shaders/FlatGL.h" +#include "Magnum/Shaders/PhongGL.h" #include "Magnum/Trade/MeshData.h" using namespace Magnum; @@ -110,7 +110,7 @@ class RedCubeDrawable: public SceneGraph::Drawable3D { } GL::Mesh _mesh; - Shaders::Phong _shader; + Shaders::PhongGL _shader; }; /* [Drawable-usage] */ @@ -127,14 +127,14 @@ class RedCube: public Object3D, public SceneGraph::Drawable3D { void draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera) override; GL::Mesh _mesh; - Shaders::Phong _shader; + Shaders::PhongGL _shader; }; /* [Drawable-usage-multiple-inheritance] */ void draw(const Matrix4&, SceneGraph::Camera3D&); void draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera) { /* [Drawable-usage-shader] */ -Shaders::Flat3D shader; +Shaders::FlatGL3D shader; shader.setTransformationProjectionMatrix( camera.projectionMatrix()*transformationMatrix); /* [Drawable-usage-shader] */ @@ -188,7 +188,7 @@ struct MyApplication: Platform::Application { /* [Drawable-multiple-groups] */ // ... - Shaders::Phong _shader; + Shaders::PhongGL _shader; SceneGraph::DrawableGroup3D _phongObjects, _transparentObjects; }; diff --git a/doc/snippets/MagnumShaders.cpp b/doc/snippets/MagnumShaders-gl.cpp similarity index 70% rename from doc/snippets/MagnumShaders.cpp rename to doc/snippets/MagnumShaders-gl.cpp index f607c50b0..96177ac94 100644 --- a/doc/snippets/MagnumShaders.cpp +++ b/doc/snippets/MagnumShaders-gl.cpp @@ -46,12 +46,12 @@ #include "Magnum/Math/Matrix4.h" #include "Magnum/Math/FunctionsBatch.h" #include "Magnum/MeshTools/Duplicate.h" -#include "Magnum/Shaders/DistanceFieldVector.h" -#include "Magnum/Shaders/Flat.h" -#include "Magnum/Shaders/MeshVisualizer.h" -#include "Magnum/Shaders/Phong.h" -#include "Magnum/Shaders/Vector.h" -#include "Magnum/Shaders/VertexColor.h" +#include "Magnum/Shaders/DistanceFieldVectorGL.h" +#include "Magnum/Shaders/FlatGL.h" +#include "Magnum/Shaders/MeshVisualizerGL.h" +#include "Magnum/Shaders/PhongGL.h" +#include "Magnum/Shaders/VectorGL.h" +#include "Magnum/Shaders/VertexColorGL.h" #include "Magnum/Trade/LightData.h" #define DOXYGEN_IGNORE(...) __VA_ARGS__ @@ -80,9 +80,9 @@ vertices.setData(data, GL::BufferUsage::StaticDraw); GL::Mesh mesh; mesh.addVertexBuffer(vertices, 0, - Shaders::Phong::Position{}, - Shaders::Phong::Normal{}, - Shaders::Phong::TextureCoordinates{}) + Shaders::PhongGL::Position{}, + Shaders::PhongGL::Normal{}, + Shaders::PhongGL::TextureCoordinates{}) //... ; /* [shaders-setup] */ @@ -91,7 +91,7 @@ mesh.addVertexBuffer(vertices, 0, Matrix4 transformationMatrix, projectionMatrix; GL::Texture2D diffuseTexture, specularTexture; -Shaders::Phong shader{Shaders::Phong::Flag::DiffuseTexture}; +Shaders::PhongGL shader{Shaders::PhongGL::Flag::DiffuseTexture}; shader.bindDiffuseTexture(diffuseTexture) .setTransformationMatrix(transformationMatrix) .setNormalMatrix(transformationMatrix.normalMatrix()) @@ -101,13 +101,13 @@ shader.bindDiffuseTexture(diffuseTexture) /* [shaders-generic] */ mesh.addVertexBuffer(vertices, 0, - Shaders::Generic3D::Position{}, - Shaders::Generic3D::Normal{}, - Shaders::Generic3D::TextureCoordinates{}); + Shaders::GenericGL3D::Position{}, + Shaders::GenericGL3D::Normal{}, + Shaders::GenericGL3D::TextureCoordinates{}); /* [shaders-generic] */ /* [shaders-meshvisualizer] */ -Shaders::MeshVisualizer3D visualizerShader{Shaders::MeshVisualizer3D::Flag::Wireframe}; +Shaders::MeshVisualizerGL3D visualizerShader{Shaders::MeshVisualizerGL3D::Flag::Wireframe}; visualizerShader .setColor(0x2f83cc_rgbf) .setWireframeColor(0xdcdcdc_rgbf) @@ -119,7 +119,7 @@ visualizerShader } { -/* [DistanceFieldVector-usage1] */ +/* [DistanceFieldVectorGL-usage1] */ struct Vertex { Vector2 position; Vector2 textureCoordinates; @@ -133,31 +133,31 @@ vertices.setData(data, GL::BufferUsage::StaticDraw); GL::Mesh mesh; mesh.addVertexBuffer(vertices, 0, - Shaders::DistanceFieldVector2D::Position{}, - Shaders::DistanceFieldVector2D::TextureCoordinates{}) + Shaders::DistanceFieldVectorGL2D::Position{}, + Shaders::DistanceFieldVectorGL2D::TextureCoordinates{}) // ... ; -/* [DistanceFieldVector-usage1] */ +/* [DistanceFieldVectorGL-usage1] */ } { GL::Mesh mesh; -/* [DistanceFieldVector-usage2] */ +/* [DistanceFieldVectorGL-usage2] */ Matrix3 transformationMatrix, projectionMatrix; GL::Texture2D texture; -Shaders::DistanceFieldVector2D shader; +Shaders::DistanceFieldVectorGL2D shader; shader.setColor(0x2f83cc_rgbf) .setOutlineColor(0xdcdcdc_rgbf) .setOutlineRange(0.6f, 0.4f) .bindVectorTexture(texture) .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix) .draw(mesh); -/* [DistanceFieldVector-usage2] */ +/* [DistanceFieldVectorGL-usage2] */ } { -/* [Flat-usage-colored1] */ +/* [FlatGL-usage-colored1] */ struct Vertex { Vector3 position; }; @@ -169,25 +169,25 @@ GL::Buffer vertices; vertices.setData(data, GL::BufferUsage::StaticDraw); GL::Mesh mesh; -mesh.addVertexBuffer(vertices, 0, Shaders::Flat3D::Position{}) +mesh.addVertexBuffer(vertices, 0, Shaders::FlatGL3D::Position{}) // ... ; -/* [Flat-usage-colored1] */ +/* [FlatGL-usage-colored1] */ -/* [Flat-usage-colored2] */ +/* [FlatGL-usage-colored2] */ Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f)); Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); -Shaders::Flat3D shader; +Shaders::FlatGL3D shader; shader.setColor(0x2f83cc_rgbf) .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix) .draw(mesh); -/* [Flat-usage-colored2] */ +/* [FlatGL-usage-colored2] */ } { -/* [Flat-usage-textured1] */ +/* [FlatGL-usage-textured1] */ struct Vertex { Vector3 position; Vector2 textureCoordinates; @@ -201,21 +201,21 @@ vertices.setData(data, GL::BufferUsage::StaticDraw); GL::Mesh mesh; mesh.addVertexBuffer(vertices, 0, - Shaders::Flat3D::Position{}, - Shaders::Flat3D::TextureCoordinates{}) + Shaders::FlatGL3D::Position{}, + Shaders::FlatGL3D::TextureCoordinates{}) // ... ; -/* [Flat-usage-textured1] */ +/* [FlatGL-usage-textured1] */ -/* [Flat-usage-textured2] */ +/* [FlatGL-usage-textured2] */ Matrix4 transformationMatrix, projectionMatrix; GL::Texture2D texture; -Shaders::Flat3D shader{Shaders::Flat3D::Flag::Textured}; +Shaders::FlatGL3D shader{Shaders::FlatGL3D::Flag::Textured}; shader.setTransformationProjectionMatrix(projectionMatrix*transformationMatrix) .bindTexture(texture) .draw(mesh); -/* [Flat-usage-textured2] */ +/* [FlatGL-usage-textured2] */ } #ifndef MAGNUM_TARGET_GLES2 @@ -224,39 +224,39 @@ GL::Framebuffer framebuffer{{}}; GL::Mesh mesh; Vector2i size; UnsignedInt meshId{}; -/* [Flat-usage-object-id] */ +/* [FlatGL-usage-object-id] */ GL::Renderbuffer color, objectId; color.setStorage(GL::RenderbufferFormat::RGBA8, size); objectId.setStorage(GL::RenderbufferFormat::R16UI, size); // large as needed framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, color) .attachRenderbuffer(GL::Framebuffer::ColorAttachment{1}, objectId); -Shaders::Flat3D shader{Shaders::Flat3D::Flag::ObjectId}; +Shaders::FlatGL3D shader{Shaders::FlatGL3D::Flag::ObjectId}; // ... framebuffer.mapForDraw({ - {Shaders::Flat3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, - {Shaders::Flat3D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}}}) + {Shaders::FlatGL3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, + {Shaders::FlatGL3D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}}}) .clearColor(0, 0x1f1f1f_rgbf) .clearColor(1, Vector4ui{0}) .bind(); shader.setObjectId(meshId) .draw(mesh); -/* [Flat-usage-object-id] */ +/* [FlatGL-usage-object-id] */ /* [shaders-generic-object-id] */ framebuffer.mapForDraw({ - {Shaders::Generic3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, - {Shaders::Generic3D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}}}); + {Shaders::GenericGL3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, + {Shaders::GenericGL3D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}}}); /* [shaders-generic-object-id] */ } #endif { GL::Mesh mesh; -/* [Flat-usage-instancing] */ +/* [FlatGL-usage-instancing] */ struct { Matrix4 transformation; Color3 color; @@ -269,38 +269,38 @@ struct { mesh.setInstanceCount(Containers::arraySize(instanceData)) .addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0, - Shaders::Flat3D::TransformationMatrix{}, - Shaders::Flat3D::Color3{}); -/* [Flat-usage-instancing] */ + Shaders::FlatGL3D::TransformationMatrix{}, + Shaders::FlatGL3D::Color3{}); +/* [FlatGL-usage-instancing] */ } { struct: GL::AbstractShaderProgram { void foo() { -/* [Generic-custom-bind] */ -bindAttributeLocation(Shaders::Generic3D::Position::Location, "position"); -bindAttributeLocation(Shaders::Generic3D::Normal::Location, "normal"); -/* [Generic-custom-bind] */ +/* [GenericGL-custom-bind] */ +bindAttributeLocation(Shaders::GenericGL3D::Position::Location, "position"); +bindAttributeLocation(Shaders::GenericGL3D::Normal::Location, "normal"); +/* [GenericGL-custom-bind] */ } } shader; } { GL::Shader vert{GL::Version::None, GL::Shader::Type::Vertex}; -/* [Generic-custom-preprocessor] */ +/* [GenericGL-custom-preprocessor] */ vert.addSource(Utility::formatString( "#define POSITION_ATTRIBUTE_LOCATION {}\n" "#define NORMAL_ATTRIBUTE_LOCATION {}\n", - Shaders::Generic3D::Position::Location, - Shaders::Generic3D::Normal::Location)) + Shaders::GenericGL3D::Position::Location, + Shaders::GenericGL3D::Normal::Location)) // … .addFile("MyShader.vert"); -/* [Generic-custom-preprocessor] */ +/* [GenericGL-custom-preprocessor] */ } { GL::Mesh mesh; -/* [Phong-usage-instancing] */ +/* [PhongGL-usage-instancing] */ struct { Matrix4 transformation; Matrix3x3 normal; @@ -315,13 +315,13 @@ for(auto& instance: instanceData) mesh.setInstanceCount(Containers::arraySize(instanceData)) .addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0, - Shaders::Phong::TransformationMatrix{}, - Shaders::Phong::NormalMatrix{}); -/* [Phong-usage-instancing] */ + Shaders::PhongGL::TransformationMatrix{}, + Shaders::PhongGL::NormalMatrix{}); +/* [PhongGL-usage-instancing] */ } { -/* [MeshVisualizer-usage-geom1] */ +/* [MeshVisualizerGL3D-usage-geom1] */ struct Vertex { Vector3 position; }; @@ -333,32 +333,32 @@ GL::Buffer vertices; vertices.setData(data, GL::BufferUsage::StaticDraw); GL::Mesh mesh; -mesh.addVertexBuffer(vertices, 0, Shaders::MeshVisualizer3D::Position{}); -/* [MeshVisualizer-usage-geom1] */ +mesh.addVertexBuffer(vertices, 0, Shaders::MeshVisualizerGL3D::Position{}); +/* [MeshVisualizerGL3D-usage-geom1] */ -/* [MeshVisualizer-usage-geom2] */ +/* [MeshVisualizerGL3D-usage-geom2] */ Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f)); Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); -Shaders::MeshVisualizer3D shader{Shaders::MeshVisualizer3D::Flag::Wireframe}; +Shaders::MeshVisualizerGL3D shader{Shaders::MeshVisualizerGL3D::Flag::Wireframe}; shader.setColor(0x2f83cc_rgbf) .setWireframeColor(0xdcdcdc_rgbf) .setViewportSize(Vector2{GL::defaultFramebuffer.viewport().size()}) .setTransformationMatrix(transformationMatrix) .setProjectionMatrix(projectionMatrix) .draw(mesh); -/* [MeshVisualizer-usage-geom2] */ +/* [MeshVisualizerGL3D-usage-geom2] */ -/* [MeshVisualizer-usage-no-geom-old] */ +/* [MeshVisualizerGL3D-usage-no-geom-old] */ Containers::Array vertexIndex{Containers::arraySize(data)}; std::iota(vertexIndex.begin(), vertexIndex.end(), 0.0f); GL::Buffer vertexIndices; vertexIndices.setData(vertexIndex, GL::BufferUsage::StaticDraw); -mesh.addVertexBuffer(vertexIndices, 0, Shaders::MeshVisualizer3D::VertexIndex{}); -/* [MeshVisualizer-usage-no-geom-old] */ +mesh.addVertexBuffer(vertexIndices, 0, Shaders::MeshVisualizerGL3D::VertexIndex{}); +/* [MeshVisualizerGL3D-usage-no-geom-old] */ } #endif @@ -367,7 +367,7 @@ mesh.addVertexBuffer(vertexIndices, 0, Shaders::MeshVisualizer3D::VertexIndex{}) on GCC 4.8 in the [60] array */ #if !defined(__GNUC__) || defined(__clang__) || __GNUC__*100 + __GNUC_MINOR__ >= 500 { -/* [MeshVisualizer-usage-tbn1] */ +/* [MeshVisualizerGL3D-usage-tbn1] */ struct Vertex { Vector3 position; Vector4 tangent; @@ -382,32 +382,32 @@ vertices.setData(data); GL::Mesh mesh; mesh.addVertexBuffer(vertices, 0, - Shaders::MeshVisualizer3D::Position{}, - Shaders::MeshVisualizer3D::Tangent4{}, - Shaders::MeshVisualizer3D::Normal{}); -/* [MeshVisualizer-usage-tbn1] */ + Shaders::MeshVisualizerGL3D::Position{}, + Shaders::MeshVisualizerGL3D::Tangent4{}, + Shaders::MeshVisualizerGL3D::Normal{}); +/* [MeshVisualizerGL3D-usage-tbn1] */ -/* [MeshVisualizer-usage-tbn2] */ +/* [MeshVisualizerGL3D-usage-tbn2] */ Matrix4 transformationMatrix, projectionMatrix; -Shaders::MeshVisualizer3D shader{ - Shaders::MeshVisualizer3D::Flag::TangentDirection| - Shaders::MeshVisualizer3D::Flag::BitangentFromTangentDirection| - Shaders::MeshVisualizer3D::Flag::NormalDirection}; +Shaders::MeshVisualizerGL3D shader{ + Shaders::MeshVisualizerGL3D::Flag::TangentDirection| + Shaders::MeshVisualizerGL3D::Flag::BitangentFromTangentDirection| + Shaders::MeshVisualizerGL3D::Flag::NormalDirection}; shader.setViewportSize(Vector2{GL::defaultFramebuffer.viewport().size()}) .setTransformationMatrix(transformationMatrix) .setProjectionMatrix(projectionMatrix) .setNormalMatrix(transformationMatrix.normalMatrix()) .setLineLength(0.3f) .draw(mesh); -/* [MeshVisualizer-usage-tbn2] */ +/* [MeshVisualizerGL3D-usage-tbn2] */ } #endif #endif { -/* [MeshVisualizer-usage-no-geom1] */ +/* [MeshVisualizerGL3D-usage-no-geom1] */ Containers::StridedArrayView1D indices; Containers::StridedArrayView1D indexedPositions; @@ -415,24 +415,24 @@ Containers::StridedArrayView1D indexedPositions; GL::Buffer vertices{MeshTools::duplicate(indices, indexedPositions)}; GL::Mesh mesh; -mesh.addVertexBuffer(vertices, 0, Shaders::MeshVisualizer3D::Position{}); -/* [MeshVisualizer-usage-no-geom1] */ +mesh.addVertexBuffer(vertices, 0, Shaders::MeshVisualizerGL3D::Position{}); +/* [MeshVisualizerGL3D-usage-no-geom1] */ } { GL::Mesh mesh; -/* [MeshVisualizer-usage-no-geom2] */ +/* [MeshVisualizerGL3D-usage-no-geom2] */ Matrix4 transformationMatrix, projectionMatrix; -Shaders::MeshVisualizer3D shader{ - Shaders::MeshVisualizer3D::Flag::Wireframe| - Shaders::MeshVisualizer3D::Flag::NoGeometryShader}; +Shaders::MeshVisualizerGL3D shader{ + Shaders::MeshVisualizerGL3D::Flag::Wireframe| + Shaders::MeshVisualizerGL3D::Flag::NoGeometryShader}; shader.setColor(0x2f83cc_rgbf) .setWireframeColor(0xdcdcdc_rgbf) .setTransformationMatrix(transformationMatrix) .setProjectionMatrix(projectionMatrix) .draw(mesh); -/* [MeshVisualizer-usage-no-geom2] */ +/* [MeshVisualizerGL3D-usage-no-geom2] */ } #ifndef MAGNUM_TARGET_GLES2 @@ -440,7 +440,7 @@ shader.setColor(0x2f83cc_rgbf) GL::Mesh mesh; Containers::ArrayView objectIds; Matrix4 transformationMatrix, projectionMatrix; -/* [MeshVisualizer-usage-object-id] */ +/* [MeshVisualizerGL3D-usage-object-id] */ const auto map = DebugTools::ColorMap::turbo(); const Vector2i size{Int(map.size()), 1}; @@ -452,20 +452,20 @@ colorMapTexture .setStorage(1, GL::TextureFormat::RGBA8, size) .setSubImage(0, {}, ImageView2D{PixelFormat::RGB8Srgb, size, map}); -Shaders::MeshVisualizer3D shader{ - Shaders::MeshVisualizer3D::Flag::InstancedObjectId}; +Shaders::MeshVisualizerGL3D shader{ + Shaders::MeshVisualizerGL3D::Flag::InstancedObjectId}; shader.setColorMapTransformation(0.0f, 1.0f/Math::max(objectIds)) .setTransformationMatrix(transformationMatrix) .setProjectionMatrix(projectionMatrix) .bindColorMapTexture(colorMapTexture) .draw(mesh); -/* [MeshVisualizer-usage-object-id] */ +/* [MeshVisualizerGL3D-usage-object-id] */ } #endif #if !defined(__GNUC__) || defined(__clang__) || __GNUC__*100 + __GNUC_MINOR__ >= 500 { -/* [Phong-usage-colored1] */ +/* [PhongGL-usage-colored1] */ struct Vertex { Vector3 position; Vector3 normal; @@ -479,27 +479,27 @@ vertices.setData(data, GL::BufferUsage::StaticDraw); GL::Mesh mesh; mesh.addVertexBuffer(vertices, 0, - Shaders::Phong::Position{}, - Shaders::Phong::Normal{}); -/* [Phong-usage-colored1] */ + Shaders::PhongGL::Position{}, + Shaders::PhongGL::Normal{}); +/* [PhongGL-usage-colored1] */ -/* [Phong-usage-colored2] */ +/* [PhongGL-usage-colored2] */ Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f)); Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); -Shaders::Phong shader; +Shaders::PhongGL shader; shader.setDiffuseColor(0x2f83cc_rgbf) .setShininess(200.0f) .setTransformationMatrix(transformationMatrix) .setNormalMatrix(transformationMatrix.normalMatrix()) .setProjectionMatrix(projectionMatrix) .draw(mesh); -/* [Phong-usage-colored2] */ +/* [PhongGL-usage-colored2] */ } { -/* [Phong-usage-texture1] */ +/* [PhongGL-usage-texture1] */ struct Vertex { Vector3 position; Vector3 normal; @@ -514,31 +514,31 @@ vertices.setData(data, GL::BufferUsage::StaticDraw); GL::Mesh mesh; mesh.addVertexBuffer(vertices, 0, - Shaders::Phong::Position{}, - Shaders::Phong::Normal{}, - Shaders::Phong::TextureCoordinates{}); -/* [Phong-usage-texture1] */ + Shaders::PhongGL::Position{}, + Shaders::PhongGL::Normal{}, + Shaders::PhongGL::TextureCoordinates{}); +/* [PhongGL-usage-texture1] */ -/* [Phong-usage-texture2] */ +/* [PhongGL-usage-texture2] */ Matrix4 transformationMatrix, projectionMatrix; GL::Texture2D diffuseTexture, specularTexture; -Shaders::Phong shader{Shaders::Phong::Flag::DiffuseTexture| - Shaders::Phong::Flag::SpecularTexture}; +Shaders::PhongGL shader{Shaders::PhongGL::Flag::DiffuseTexture| + Shaders::PhongGL::Flag::SpecularTexture}; shader.bindTextures(nullptr, &diffuseTexture, &specularTexture, nullptr) .setTransformationMatrix(transformationMatrix) .setNormalMatrix(transformationMatrix.normalMatrix()) .setProjectionMatrix(projectionMatrix) .draw(mesh); -/* [Phong-usage-texture2] */ +/* [PhongGL-usage-texture2] */ } #endif { -/* [Phong-usage-lights] */ +/* [PhongGL-usage-lights] */ Matrix4 directionalLight, pointLight1, pointLight2; // camera-relative -Shaders::Phong shader{{}, 3}; // 3 lights +Shaders::PhongGL shader{{}, 3}; // 3 lights shader .setLightPositions({Vector4{directionalLight.up(), 0.0f}, Vector4{pointLight1.translation(), 1.0f}, @@ -550,39 +550,39 @@ shader .setLightRanges({Constants::inf(), 2.0f, 2.0f}); -/* [Phong-usage-lights] */ +/* [PhongGL-usage-lights] */ } { Color3 ambientColor; GL::Texture2D diffuseTexture; -/* [Phong-usage-lights-ambient] */ +/* [PhongGL-usage-lights-ambient] */ Trade::LightData ambientLight = DOXYGEN_IGNORE(Trade::LightData{{}, {}, {}}); -Shaders::Phong shader{Shaders::Phong::Flag::AmbientTexture|DOXYGEN_IGNORE(Shaders::Phong::Flag::DiffuseTexture), DOXYGEN_IGNORE(3)}; +Shaders::PhongGL shader{Shaders::PhongGL::Flag::AmbientTexture|DOXYGEN_IGNORE(Shaders::PhongGL::Flag::DiffuseTexture), DOXYGEN_IGNORE(3)}; shader .setAmbientColor(ambientColor + ambientLight.color()*ambientLight.intensity()) .bindAmbientTexture(diffuseTexture) .bindDiffuseTexture(diffuseTexture); -/* [Phong-usage-lights-ambient] */ +/* [PhongGL-usage-lights-ambient] */ } { GL::Texture2D diffuseAlphaTexture; Color3 diffuseRgb, specularRgb; -/* [Phong-usage-alpha] */ -Shaders::Phong shader{Shaders::Phong::Flag::AmbientTexture| - Shaders::Phong::Flag::DiffuseTexture}; +/* [PhongGL-usage-alpha] */ +Shaders::PhongGL shader{Shaders::PhongGL::Flag::AmbientTexture| + Shaders::PhongGL::Flag::DiffuseTexture}; shader.bindTextures(&diffuseAlphaTexture, &diffuseAlphaTexture, nullptr, nullptr) .setAmbientColor(0x000000ff_rgbaf) .setDiffuseColor(Color4{diffuseRgb, 0.0f}) .setSpecularColor(Color4{specularRgb, 0.0f}); -/* [Phong-usage-alpha] */ +/* [PhongGL-usage-alpha] */ } #if !defined(__GNUC__) || defined(__clang__) || __GNUC__*100 + __GNUC_MINOR__ >= 500 { -/* [Vector-usage1] */ +/* [VectorGL-usage1] */ struct Vertex { Vector2 position; Vector2 textureCoordinates; @@ -596,24 +596,24 @@ vertices.setData(data, GL::BufferUsage::StaticDraw); GL::Mesh mesh; mesh.addVertexBuffer(vertices, 0, - Shaders::Vector2D::Position{}, - Shaders::Vector2D::TextureCoordinates{}); -/* [Vector-usage1] */ + Shaders::VectorGL2D::Position{}, + Shaders::VectorGL2D::TextureCoordinates{}); +/* [VectorGL-usage1] */ -/* [Vector-usage2] */ +/* [VectorGL-usage2] */ Matrix3 transformationMatrix, projectionMatrix; GL::Texture2D texture; -Shaders::Vector2D shader; +Shaders::VectorGL2D shader; shader.setColor(0x2f83cc_rgbf) .bindVectorTexture(texture) .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix) .draw(mesh); -/* [Vector-usage2] */ +/* [VectorGL-usage2] */ } { -/* [VertexColor-usage1] */ +/* [VertexColorGL-usage1] */ struct Vertex { Vector3 position; Color3 color; @@ -627,19 +627,19 @@ vertices.setData(data, GL::BufferUsage::StaticDraw); GL::Mesh mesh; mesh.addVertexBuffer(vertices, 0, - Shaders::VertexColor3D::Position{}, - Shaders::VertexColor3D::Color3{}); -/* [VertexColor-usage1] */ + Shaders::VertexColorGL3D::Position{}, + Shaders::VertexColorGL3D::Color3{}); +/* [VertexColorGL-usage1] */ -/* [VertexColor-usage2] */ +/* [VertexColorGL-usage2] */ Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f)); Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); -Shaders::VertexColor3D shader; +Shaders::VertexColorGL3D shader; shader.setTransformationProjectionMatrix(projectionMatrix*transformationMatrix) .draw(mesh); -/* [VertexColor-usage2] */ +/* [VertexColorGL-usage2] */ } #endif diff --git a/doc/snippets/MagnumText.cpp b/doc/snippets/MagnumText.cpp index d614a2a61..5f4d4675d 100644 --- a/doc/snippets/MagnumText.cpp +++ b/doc/snippets/MagnumText.cpp @@ -32,7 +32,7 @@ #include "Magnum/FileCallback.h" #include "Magnum/Math/Color.h" #include "Magnum/Math/Matrix3.h" -#include "Magnum/Shaders/Vector.h" +#include "Magnum/Shaders/VectorGL.h" #include "Magnum/Text/AbstractFont.h" #include "Magnum/Text/DistanceFieldGlyphCache.h" #include "Magnum/Text/Renderer.h" @@ -144,7 +144,7 @@ font->fillGlyphCache(cache, "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789?!:;,. "); -Shaders::Vector2D shader; +Shaders::VectorGL2D shader; GL::Buffer vertexBuffer, indexBuffer; GL::Mesh mesh; diff --git a/doc/snippets/MagnumTrade.cpp b/doc/snippets/MagnumTrade.cpp index a944f7eaf..e101b52f5 100644 --- a/doc/snippets/MagnumTrade.cpp +++ b/doc/snippets/MagnumTrade.cpp @@ -54,7 +54,7 @@ #include "Magnum/GL/TextureFormat.h" #include "Magnum/GL/Mesh.h" #include "Magnum/MeshTools/Compile.h" -#include "Magnum/Shaders/Phong.h" +#include "Magnum/Shaders/PhongGL.h" #endif #ifdef MAGNUM_TARGET_VK #include "Magnum/Vk/Vulkan.h" @@ -544,7 +544,7 @@ GL::Buffer vertices; vertices.setData(MeshTools::interleave(data.positions3DAsArray(), data.normalsAsArray())); mesh.addVertexBuffer(std::move(vertices), 0, - Shaders::Phong::Position{}, Shaders::Phong::Normal{}); + Shaders::PhongGL::Position{}, Shaders::PhongGL::Normal{}); /* Set up an index buffer, if the mesh is indexed*/ if(data.isIndexed()) { @@ -568,12 +568,12 @@ vertices.setData(data.vertexData()); mesh.addVertexBuffer(vertices, data.attributeOffset(Trade::MeshAttribute::Position), data.attributeStride(Trade::MeshAttribute::Position), - GL::DynamicAttribute{Shaders::Phong::Position{}, + GL::DynamicAttribute{Shaders::PhongGL::Position{}, data.attributeFormat(Trade::MeshAttribute::Position)}); mesh.addVertexBuffer(vertices, data.attributeOffset(Trade::MeshAttribute::Normal), data.attributeStride(Trade::MeshAttribute::Normal), - GL::DynamicAttribute{Shaders::Phong::Normal{}, + GL::DynamicAttribute{Shaders::PhongGL::Normal{}, data.attributeFormat(Trade::MeshAttribute::Normal)}); // Set up other attributes ... diff --git a/src/Magnum/DebugTools/ForceRenderer.cpp b/src/Magnum/DebugTools/ForceRenderer.cpp index 49b0b39bb..2cfabcf08 100644 --- a/src/Magnum/DebugTools/ForceRenderer.cpp +++ b/src/Magnum/DebugTools/ForceRenderer.cpp @@ -28,7 +28,7 @@ #include "Magnum/GL/Mesh.h" #include "Magnum/DebugTools/ResourceManager.h" #include "Magnum/SceneGraph/Camera.h" -#include "Magnum/Shaders/Flat.h" +#include "Magnum/Shaders/FlatGL.h" #include "Magnum/DebugTools/Implementation/ForceRendererTransformation.h" @@ -57,8 +57,8 @@ constexpr UnsignedByte indices[]{ template ForceRenderer::ForceRenderer(ResourceManager& manager, SceneGraph::AbstractObject& object, const VectorTypeFor& forcePosition, const VectorTypeFor& force, ResourceKey options, SceneGraph::DrawableGroup* drawables): SceneGraph::Drawable(object, drawables), _forcePosition(forcePosition), _force(force), _options(manager.get(options)) { /* Shader */ - _shader = manager.get>(shaderKey()); - if(!_shader) manager.set(_shader.key(), new Shaders::Flat); + _shader = manager.get>(shaderKey()); + if(!_shader) manager.set(_shader.key(), new Shaders::FlatGL); /* Mesh and vertex buffer */ _mesh = manager.get("force"); @@ -72,7 +72,7 @@ template ForceRenderer::ForceRenderer(Resour GL::Mesh mesh{GL::MeshPrimitive::Lines}; mesh.setCount(Containers::arraySize(indices)) .addVertexBuffer(std::move(vertexBuffer), 0, - typename Shaders::Flat::Position(Shaders::Flat::Position::Components::Two)) + typename Shaders::FlatGL::Position(Shaders::FlatGL::Position::Components::Two)) .setIndexBuffer(std::move(indexBuffer), 0, GL::MeshIndexType::UnsignedByte, 0, Containers::arraySize(positions)); manager.set(_mesh.key(), std::move(mesh), ResourceDataState::Final, ResourcePolicy::Manual); } diff --git a/src/Magnum/DebugTools/ForceRenderer.h b/src/Magnum/DebugTools/ForceRenderer.h index c78482e36..2b59950a9 100644 --- a/src/Magnum/DebugTools/ForceRenderer.h +++ b/src/Magnum/DebugTools/ForceRenderer.h @@ -162,7 +162,7 @@ template class ForceRenderer: public SceneGraph::Drawabl const VectorTypeFor& _force; Resource _options; - Resource> _shader; + Resource> _shader; Resource _mesh; }; diff --git a/src/Magnum/DebugTools/ObjectRenderer.cpp b/src/Magnum/DebugTools/ObjectRenderer.cpp index 12a829626..73e4bbc4c 100644 --- a/src/Magnum/DebugTools/ObjectRenderer.cpp +++ b/src/Magnum/DebugTools/ObjectRenderer.cpp @@ -30,7 +30,7 @@ #include "Magnum/MeshTools/Compile.h" #include "Magnum/Primitives/Axis.h" #include "Magnum/SceneGraph/Camera.h" -#include "Magnum/Shaders/VertexColor.h" +#include "Magnum/Shaders/VertexColorGL.h" #include "Magnum/Trade/MeshData.h" namespace Magnum { namespace DebugTools { @@ -56,8 +56,8 @@ template<> struct Renderer<3> { /* Doxygen gets confused when using {} to initialize parent object */ template ObjectRenderer::ObjectRenderer(ResourceManager& manager, SceneGraph::AbstractObject& object, ResourceKey options, SceneGraph::DrawableGroup* drawables): SceneGraph::Drawable(object, drawables), _options{manager.get(options)} { /* Shader */ - _shader = manager.get>(Renderer::shader()); - if(!_shader) manager.set(_shader.key(), new Shaders::VertexColor); + _shader = manager.get>(Renderer::shader()); + if(!_shader) manager.set(_shader.key(), new Shaders::VertexColorGL); /* Mesh */ _mesh = manager.get(Renderer::mesh()); diff --git a/src/Magnum/DebugTools/ObjectRenderer.h b/src/Magnum/DebugTools/ObjectRenderer.h index af1d7bfdf..bd6d3310c 100644 --- a/src/Magnum/DebugTools/ObjectRenderer.h +++ b/src/Magnum/DebugTools/ObjectRenderer.h @@ -121,7 +121,7 @@ template class ObjectRenderer: public SceneGraph::Drawab void draw(const MatrixTypeFor& transformationMatrix, SceneGraph::Camera& camera) override; Resource _options; - Resource> _shader; + Resource> _shader; Resource _mesh; }; diff --git a/src/Magnum/DebugTools/Test/FrameProfilerGLTest.cpp b/src/Magnum/DebugTools/Test/FrameProfilerGLTest.cpp index 6347e5ba2..0b85d9646 100644 --- a/src/Magnum/DebugTools/Test/FrameProfilerGLTest.cpp +++ b/src/Magnum/DebugTools/Test/FrameProfilerGLTest.cpp @@ -36,7 +36,7 @@ #include "Magnum/GL/RenderbufferFormat.h" #include "Magnum/MeshTools/Compile.h" #include "Magnum/Primitives/Cube.h" -#include "Magnum/Shaders/Flat.h" +#include "Magnum/Shaders/FlatGL.h" #include "Magnum/Trade/MeshData.h" namespace Magnum { namespace DebugTools { namespace Test { namespace { @@ -109,7 +109,7 @@ void FrameProfilerGLTest::test() { fb.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, color) .bind(); - Shaders::Flat3D shader; + Shaders::FlatGL3D shader; GL::Mesh mesh = MeshTools::compile(Primitives::cubeSolid()); FrameProfilerGL profiler{data.values, 4}; diff --git a/src/Magnum/GL/Framebuffer.h b/src/Magnum/GL/Framebuffer.h index 9fee9e0fb..879ba11f1 100644 --- a/src/Magnum/GL/Framebuffer.h +++ b/src/Magnum/GL/Framebuffer.h @@ -85,8 +85,8 @@ macOS / iOS. In a deferred rendering setup for example, a shader usually has more than one output. That's finally where non-zero @ref ColorAttachment and @ref mapForDraw() gets used. In builtin shaders this is also how the -@ref Shaders::Flat::ColorOutput / @ref Shaders::Flat::ObjectIdOutput etc. get -used: +@ref Shaders::FlatGL::ColorOutput / @ref Shaders::FlatGL::ObjectIdOutput etc. +get used: @snippet MagnumGL.cpp Framebuffer-usage-deferred diff --git a/src/Magnum/GL/Mesh.h b/src/Magnum/GL/Mesh.h index e236b523c..ce5f329f5 100644 --- a/src/Magnum/GL/Mesh.h +++ b/src/Magnum/GL/Mesh.h @@ -697,7 +697,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * buffer with 76 bytes of some other data at the beginning (possibly * material configuration) and then the interleaved vertex array. Each * vertex consists of a weight, position, texture coordinate and - * a normal. You want to draw it with @ref Shaders::Phong, but it + * a normal. You want to draw it with @ref Shaders::PhongGL, but it * accepts only a position and a normal, so you have to skip the weight * and the texture coordinate in each vertex: * diff --git a/src/Magnum/GL/Renderer.h b/src/Magnum/GL/Renderer.h index 64669b254..ec7433992 100644 --- a/src/Magnum/GL/Renderer.h +++ b/src/Magnum/GL/Renderer.h @@ -1674,9 +1674,10 @@ class MAGNUM_GL_EXPORT Renderer { * * Note that in 3D you need to sort and render transparent objects * back-to-front after all opaque objects in order for them to appear - * correctly. Alternatively, builtin shaders such as @ref Shaders::Flat - * or @ref Shaders::Phong support alpha masking, which works without - * alpha blending enabled and doesn't require depth sorting. + * correctly. Alternatively, builtin shaders such as + * @ref Shaders::FlatGL or @ref Shaders::PhongGL support alpha masking, + * which works without alpha blending enabled and doesn't require depth + * sorting. * @see @ref Feature::Blending, @ref setBlendFunction(BlendFunction, BlendFunction, BlendFunction, BlendFunction), * @ref setBlendEquation(), @ref setBlendColor(), * @fn_gl_keyword{BlendFunc} diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index 238afa9b9..1b911666a 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -674,7 +674,12 @@ template class Vector { T _data[size]; private: + #ifndef DOXYGEN_GENERATING_OUTPUT + /* Since I added deprecated aliases to Shaders::VectorGL, this FUCKING + DUMPSTER FIRE DOXYGEN CRAP thinks this refers to Shaders::Vector or + whatever fucking insane thing. WHAT THE FUCK. */ template friend class Vector; + #endif /* These three needed to access _data to speed up debug builds */ template friend class RectangularMatrix; template friend class Matrix; diff --git a/src/Magnum/MeshTools/Compile.cpp b/src/Magnum/MeshTools/Compile.cpp index 4326c417a..7dec471a3 100644 --- a/src/Magnum/MeshTools/Compile.cpp +++ b/src/Magnum/MeshTools/Compile.cpp @@ -48,7 +48,7 @@ /* This header is included only privately and doesn't introduce any linker dependency, thus it's completely safe */ -#include "Magnum/Shaders/Generic.h" +#include "Magnum/Shaders/GenericGL.h" namespace Magnum { namespace MeshTools { @@ -88,34 +88,34 @@ GL::Mesh compileInternal(const Trade::MeshData& meshData, GL::Buffer&& indices, case Trade::MeshAttribute::Position: /* Pick 3D position always, the format will properly reduce it to a 2-component version if needed */ - attribute.emplace(Shaders::Generic3D::Position{}, format); + attribute.emplace(Shaders::GenericGL3D::Position{}, format); break; case Trade::MeshAttribute::TextureCoordinates: /** @todo have Generic2D derived from Generic that has all attribute definitions common for 2D and 3D */ - attribute.emplace(Shaders::Generic2D::TextureCoordinates{}, format); + attribute.emplace(Shaders::GenericGL2D::TextureCoordinates{}, format); break; case Trade::MeshAttribute::Color: /** @todo have Generic2D derived from Generic that has all attribute definitions common for 2D and 3D */ /* Pick Color4 always, the format will properly reduce it to a 3-component version if needed */ - attribute.emplace(Shaders::Generic2D::Color4{}, format); + attribute.emplace(Shaders::GenericGL2D::Color4{}, format); break; case Trade::MeshAttribute::Tangent: /* Pick Tangent4 always, the format will properly reduce it to a 3-component version if needed */ - attribute.emplace(Shaders::Generic3D::Tangent4{}, format); + attribute.emplace(Shaders::GenericGL3D::Tangent4{}, format); break; case Trade::MeshAttribute::Bitangent: - attribute.emplace(Shaders::Generic3D::Bitangent{}, format); + attribute.emplace(Shaders::GenericGL3D::Bitangent{}, format); break; case Trade::MeshAttribute::Normal: - attribute.emplace(Shaders::Generic3D::Normal{}, format); + attribute.emplace(Shaders::GenericGL3D::Normal{}, format); break; #ifndef MAGNUM_TARGET_GLES2 case Trade::MeshAttribute::ObjectId: - attribute.emplace(Shaders::Generic3D::ObjectId{}, format); + attribute.emplace(Shaders::GenericGL3D::ObjectId{}, format); break; #endif diff --git a/src/Magnum/MeshTools/Compile.h b/src/Magnum/MeshTools/Compile.h index 0cea50534..ab53b02f0 100644 --- a/src/Magnum/MeshTools/Compile.h +++ b/src/Magnum/MeshTools/Compile.h @@ -95,22 +95,22 @@ typedef Containers::EnumSet CompileFlags; CORRADE_ENUMSET_OPERATORS(CompileFlags) /** -@brief Compile mesh data +@brief Compile OpenGL mesh data @m_since{2020,06} -Configures a mesh for a @ref Shaders::Generic shader with a vertex buffer and +Configures a mesh for a @ref Shaders::GenericGL shader with a vertex buffer and possibly also an index buffer, if the mesh is indexed. - If the mesh contains positions, these are bound to the - @ref Shaders::Generic2D::Position attribute if they are 2D or to - @ref Shaders::Generic3D::Position if they are 3D. + @ref Shaders::GenericGL2D::Position attribute if they are 2D or to + @ref Shaders::GenericGL3D::Position if they are 3D. - If the mesh contains normals or if @ref CompileFlag::GenerateFlatNormals / @ref CompileFlag::GenerateSmoothNormals is set, these are bound to - @ref Shaders::Generic3D::Normal. + @ref Shaders::GenericGL3D::Normal. - If the mesh contains texture coordinates, these are bound to - @ref Shaders::Generic::TextureCoordinates. + @ref Shaders::GenericGL::TextureCoordinates. - If the mesh contains colors, these are bound to - @ref Shaders::Generic::Color3 / @ref Shaders::Generic::Color4 based on + @ref Shaders::GenericGL::Color3 / @ref Shaders::GenericGL::Color4 based on their type. - Custom attributes and known attributes of implementation-specific types are ignored with a warning. See the @ref compile(const Trade::MeshData&, GL::Buffer&, GL::Buffer&) @@ -200,11 +200,11 @@ MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& meshData, GL::Bu @m_deprecated_since{2020,06} Use @ref compile(const Trade::MeshData&, CompileFlags) instead. -Configures a mesh for @ref Shaders::Generic2D shader with vertex buffer and +Configures a mesh for @ref Shaders::GenericGL2D shader with vertex buffer and possibly also an index buffer, if the mesh is indexed. Positions are bound to -@ref Shaders::Generic2D::Position attribute. If the mesh contains texture -coordinates, these are bound to @ref Shaders::Generic2D::TextureCoordinates -attribute. If the mesh contains colors, these are bound to @ref Shaders::Generic3D::Color4 +@ref Shaders::GenericGL2D::Position attribute. If the mesh contains texture +coordinates, these are bound to @ref Shaders::GenericGL2D::TextureCoordinates +attribute. If the mesh contains colors, these are bound to @ref Shaders::GenericGL3D::Color4 attribute. No data compression or index optimization (except for index buffer packing) is done, both the vertex buffer and the index buffer (if any) is owned by the mesh, both created with @ref GL::BufferUsage::StaticDraw. @@ -230,15 +230,16 @@ CORRADE_IGNORE_DEPRECATED_POP @m_deprecated_since{2020,06} Use @ref compile(const Trade::MeshData&, CompileFlags) instead. -Configures mesh for @ref Shaders::Generic3D shader with vertex buffer and +Configures mesh for @ref Shaders::GenericGL3D shader with vertex buffer and possibly also index buffer, if the mesh is indexed. Positions are bound to -@ref Shaders::Generic3D::Position attribute. If the mesh contains normals, they -are bound to @ref Shaders::Generic3D::Normal attribute, texture coordinates are -bound to @ref Shaders::Generic3D::TextureCoordinates attribute. If the mesh -contains colors, they are bound to @ref Shaders::Generic3D::Color4 attribute. -No data compression or index optimization (except for index buffer packing) is -done, both the vertex buffer and the index buffer (if any) is owned by the mesh, -both created with @ref GL::BufferUsage::StaticDraw. +@ref Shaders::GenericGL3D::Position attribute. If the mesh contains normals, +they are bound to @ref Shaders::GenericGL3D::Normal attribute, texture +coordinates are bound to @ref Shaders::GenericGL3D::TextureCoordinates +attribute. If the mesh contains colors, they are bound to +@ref Shaders::GenericGL3D::Color4 attribute. No data compression or index +optimization (except for index buffer packing) is done, both the vertex buffer +and the index buffer (if any) is owned by the mesh, both created with +@ref GL::BufferUsage::StaticDraw. This is just a convenience function for creating generic meshes, you might want to use @ref interleave() and @ref compressIndices() functions together with diff --git a/src/Magnum/MeshTools/Test/CompileGLTest.cpp b/src/Magnum/MeshTools/Test/CompileGLTest.cpp index ab7c939c0..c5838c51c 100644 --- a/src/Magnum/MeshTools/Test/CompileGLTest.cpp +++ b/src/Magnum/MeshTools/Test/CompileGLTest.cpp @@ -48,10 +48,10 @@ #include "Magnum/Math/Matrix4.h" #include "Magnum/MeshTools/Compile.h" #include "Magnum/MeshTools/Duplicate.h" -#include "Magnum/Shaders/Flat.h" -#include "Magnum/Shaders/Phong.h" -#include "Magnum/Shaders/VertexColor.h" -#include "Magnum/Shaders/MeshVisualizer.h" +#include "Magnum/Shaders/FlatGL.h" +#include "Magnum/Shaders/PhongGL.h" +#include "Magnum/Shaders/VertexColorGL.h" +#include "Magnum/Shaders/MeshVisualizerGL.h" #include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/MeshData.h" @@ -118,22 +118,22 @@ struct CompileGLTest: GL::OpenGLTester { private: PluginManager::Manager _manager{"nonexistent"}; - Shaders::Flat2D _flat2D; - Shaders::Flat2D _flatTextured2D{Shaders::Flat2D::Flag::Textured}; + Shaders::FlatGL2D _flat2D; + Shaders::FlatGL2D _flatTextured2D{Shaders::FlatGL2D::Flag::Textured}; #ifndef MAGNUM_TARGET_GLES2 - Shaders::Flat2D _flatObjectId2D{NoCreate}; + Shaders::FlatGL2D _flatObjectId2D{NoCreate}; #endif - Shaders::Flat3D _flat3D; - Shaders::Flat3D _flatTextured3D{Shaders::Flat3D::Flag::Textured}; + Shaders::FlatGL3D _flat3D; + Shaders::FlatGL3D _flatTextured3D{Shaders::FlatGL3D::Flag::Textured}; #ifndef MAGNUM_TARGET_GLES2 - Shaders::Flat3D _flatObjectId3D{NoCreate}; + Shaders::FlatGL3D _flatObjectId3D{NoCreate}; #endif - Shaders::VertexColor2D _color2D; - Shaders::VertexColor3D _color3D; - Shaders::Phong _phong; + Shaders::VertexColorGL2D _color2D; + Shaders::VertexColorGL3D _color3D; + Shaders::PhongGL _phong; #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - Shaders::MeshVisualizer3D _meshVisualizer3D{NoCreate}; - Shaders::MeshVisualizer3D _meshVisualizerBitangentsFromTangents3D{NoCreate}; + Shaders::MeshVisualizerGL3D _meshVisualizer3D{NoCreate}; + Shaders::MeshVisualizerGL3D _meshVisualizerBitangentsFromTangents3D{NoCreate}; #endif GL::Renderbuffer _color; @@ -315,14 +315,14 @@ CompileGLTest::CompileGLTest() { if(GL::Context::current().isExtensionSupported()) #endif { - _flatObjectId2D = Shaders::Flat2D{Shaders::Flat2D::Flag::InstancedObjectId}; - _flatObjectId3D = Shaders::Flat3D{Shaders::Flat3D::Flag::InstancedObjectId}; + _flatObjectId2D = Shaders::FlatGL2D{Shaders::FlatGL2D::Flag::InstancedObjectId}; + _flatObjectId3D = Shaders::FlatGL3D{Shaders::FlatGL3D::Flag::InstancedObjectId}; _objectId.setStorage(GL::RenderbufferFormat::R32UI, {32, 32}); _framebuffer .attachRenderbuffer(GL::Framebuffer::ColorAttachment{1}, _objectId) .mapForDraw({ - {Shaders::Generic3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, - {Shaders::Generic3D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}} + {Shaders::GenericGL3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, + {Shaders::GenericGL3D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}} }); } #endif @@ -335,14 +335,14 @@ CompileGLTest::CompileGLTest() { if(GL::Context::current().isExtensionSupported()) #endif { - _meshVisualizer3D = Shaders::MeshVisualizer3D{ - Shaders::MeshVisualizer3D::Flag::TangentDirection| - Shaders::MeshVisualizer3D::Flag::BitangentDirection| - Shaders::MeshVisualizer3D::Flag::NormalDirection}; - _meshVisualizerBitangentsFromTangents3D = Shaders::MeshVisualizer3D{ - Shaders::MeshVisualizer3D::Flag::TangentDirection| - Shaders::MeshVisualizer3D::Flag::BitangentFromTangentDirection| - Shaders::MeshVisualizer3D::Flag::NormalDirection}; + _meshVisualizer3D = Shaders::MeshVisualizerGL3D{ + Shaders::MeshVisualizerGL3D::Flag::TangentDirection| + Shaders::MeshVisualizerGL3D::Flag::BitangentDirection| + Shaders::MeshVisualizerGL3D::Flag::NormalDirection}; + _meshVisualizerBitangentsFromTangents3D = Shaders::MeshVisualizerGL3D{ + Shaders::MeshVisualizerGL3D::Flag::TangentDirection| + Shaders::MeshVisualizerGL3D::Flag::BitangentFromTangentDirection| + Shaders::MeshVisualizerGL3D::Flag::NormalDirection}; } #endif } diff --git a/src/Magnum/SceneGraph/Drawable.h b/src/Magnum/SceneGraph/Drawable.h index 4cacb2e22..f6f6603fc 100644 --- a/src/Magnum/SceneGraph/Drawable.h +++ b/src/Magnum/SceneGraph/Drawable.h @@ -55,8 +55,8 @@ by multiple objects, and pass only references around. The @p transformationMatrix parameter in the @ref draw() function contains transformation of the object (to which the drawable is attached) relative to @p camera. The camera contains the projection matrix. Some shaders (like the -@ref Shaders::Phong used in the snippet) have separate functions for setting -transformation and projection matrix, but some (such as @ref Shaders::Flat) +@ref Shaders::PhongGL used in the snippet) have separate functions for setting +transformation and projection matrix, but some (such as @ref Shaders::FlatGL) have a single function to set composite transformation and projection matrix. In that case you need to combine the two matrices manually like in the following code. Some shaders might have additional requirements, see their diff --git a/src/Magnum/Shaders/AbstractVector.h b/src/Magnum/Shaders/AbstractVector.h index 98fd36a38..192371879 100644 --- a/src/Magnum/Shaders/AbstractVector.h +++ b/src/Magnum/Shaders/AbstractVector.h @@ -25,94 +25,46 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef MAGNUM_BUILD_DEPRECATED /** @file - * @brief Class @ref Magnum::Shaders::AbstractVector, typedef @ref Magnum::Shaders::AbstractVector2D, @ref Magnum::Shaders::AbstractVector3D + * @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/GL/AbstractShaderProgram.h" -#include "Magnum/Shaders/Generic.h" - -namespace Magnum { namespace Shaders { - -/** -@brief Base for vector shaders - -See @ref DistanceFieldVector and @ref Vector for more information. -@see @ref shaders, @ref AbstractVector2D, @ref AbstractVector3D -*/ -template class AbstractVector: 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 Generic::Position Position; - - /** - * @brief 2D texture coordinates - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector2 "Vector2". - */ - typedef typename Generic::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 = Generic::ColorOutput - }; - - /** @brief Copying is not allowed */ - AbstractVector(const AbstractVector&) = delete; - - /** @brief Move constructor */ - AbstractVector(AbstractVector&&) noexcept = default; +#include "Magnum/configure.h" - /** @brief Copying is not allowed */ - AbstractVector& operator=(const AbstractVector&) = delete; +#ifdef MAGNUM_BUILD_DEPRECATED +#include - /** @brief Move assignment */ - AbstractVector& operator=(AbstractVector&&) noexcept = default; +#include "Magnum/Shaders/AbstractVectorGL.h" - /** - * @brief Bind vector texture - * @return Reference to self (for method chaining) - * - * @see @ref DistanceFieldVector::Flag::TextureTransformation, - * @ref Vector::Flag::TextureTransformation, - * @ref DistanceFieldVector::setTextureMatrix(), - * @ref Vector::setTextureMatrix() - */ - AbstractVector& bindVectorTexture(GL::Texture2D& texture); +CORRADE_DEPRECATED_FILE("use Magnum/Shaders/AbstractVectorGL.h, the AbstractVectorGL class and related typedefs instead") - #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 }; +namespace Magnum { namespace Shaders { - explicit AbstractVector(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {} - explicit AbstractVector() = default; - ~AbstractVector() = default; -}; +/** @brief @copybrief AbstractVectorGL + * @m_deprecated_since_latest Use @ref AbstractVectorGL instead. + */ +#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Multiple definitions still broken */ +template using AbstractVector CORRADE_DEPRECATED_ALIAS("use AbstractVectorGL instead") = AbstractVectorGL; +#endif -/** @brief Base for two-dimensional text shaders */ -typedef AbstractVector<2> AbstractVector2D; +/** @brief @copybrief AbstractVectorGL2D + * @m_deprecated_since_latest Use @ref AbstractVectorGL2D instead. + */ +typedef CORRADE_DEPRECATED("use AbstractVectorGL2D instead") AbstractVectorGL2D AbstractVector2D; -/** @brief Base for three-dimensional text shader */ -typedef AbstractVector<3> AbstractVector3D; +/** @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 diff --git a/src/Magnum/Shaders/AbstractVector.cpp b/src/Magnum/Shaders/AbstractVectorGL.cpp similarity index 83% rename from src/Magnum/Shaders/AbstractVector.cpp rename to src/Magnum/Shaders/AbstractVectorGL.cpp index 8361e1641..e02251094 100644 --- a/src/Magnum/Shaders/AbstractVector.cpp +++ b/src/Magnum/Shaders/AbstractVectorGL.cpp @@ -23,21 +23,21 @@ DEALINGS IN THE SOFTWARE. */ -#include "AbstractVector.h" +#include "AbstractVectorGL.h" #include "Magnum/GL/Texture.h" #include "Magnum/Shaders/visibility.h" namespace Magnum { namespace Shaders { -template AbstractVector& AbstractVector::bindVectorTexture(GL::Texture2D& texture) { +template AbstractVectorGL& AbstractVectorGL::bindVectorTexture(GL::Texture2D& texture) { texture.bind(VectorTextureUnit); return *this; } #ifndef DOXYGEN_GENERATING_OUTPUT -template class MAGNUM_SHADERS_EXPORT AbstractVector<2>; -template class MAGNUM_SHADERS_EXPORT AbstractVector<3>; +template class MAGNUM_SHADERS_EXPORT AbstractVectorGL<2>; +template class MAGNUM_SHADERS_EXPORT AbstractVectorGL<3>; #endif }} diff --git a/src/Magnum/Shaders/AbstractVectorGL.h b/src/Magnum/Shaders/AbstractVectorGL.h new file mode 100644 index 000000000..c6b8a0c01 --- /dev/null +++ b/src/Magnum/Shaders/AbstractVectorGL.h @@ -0,0 +1,126 @@ +#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š + + 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 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::Position Position; + + /** + * @brief 2D texture coordinates + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector2 "Vector2". + */ + typedef typename GenericGL::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::ColorOutput + }; + + /** @brief Copying is not allowed */ + AbstractVectorGL(const AbstractVectorGL&) = delete; + + /** @brief Move constructor */ + AbstractVectorGL(AbstractVectorGL&&) noexcept = default; + + /** @brief Copying is not allowed */ + AbstractVectorGL& operator=(const AbstractVectorGL&) = delete; + + /** @brief Move assignment */ + AbstractVectorGL& operator=(AbstractVectorGL&&) noexcept = default; + + /** + * @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& 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 diff --git a/src/Magnum/Shaders/CMakeLists.txt b/src/Magnum/Shaders/CMakeLists.txt index 3a940b774..b5b55947b 100644 --- a/src/Magnum/Shaders/CMakeLists.txt +++ b/src/Magnum/Shaders/CMakeLists.txt @@ -27,35 +27,47 @@ if(NOT WITH_GL) message(SEND_ERROR "Shaders are available only if WITH_GL is enabled") endif() -corrade_add_resource(MagnumShaders_RCS resources.conf) -set_target_properties(MagnumShaders_RCS-dependencies PROPERTIES FOLDER "Magnum/Shaders") +corrade_add_resource(MagnumShaders_RESOURCES_GL resources-gl.conf) +set_target_properties(MagnumShaders_RESOURCES_GL-dependencies PROPERTIES FOLDER "Magnum/Shaders") set(MagnumShaders_SRCS - AbstractVector.cpp - VertexColor.cpp + AbstractVectorGL.cpp + VertexColorGL.cpp - ${MagnumShaders_RCS}) + ${MagnumShaders_RESOURCES_GL}) set(MagnumShaders_GracefulAssert_SRCS - DistanceFieldVector.cpp - Flat.cpp - MeshVisualizer.cpp - Phong.cpp - Vector.cpp) + DistanceFieldVectorGL.cpp + FlatGL.cpp + MeshVisualizerGL.cpp + PhongGL.cpp + VectorGL.cpp) set(MagnumShaders_HEADERS - DistanceFieldVector.h - AbstractVector.h - Flat.h - Generic.h - MeshVisualizer.h - Phong.h + DistanceFieldVectorGL.h + AbstractVectorGL.h + FlatGL.h + GenericGL.h + MeshVisualizerGL.h + PhongGL.h Shaders.h - Vector.h - VertexColor.h + VectorGL.h + VertexColorGL.h visibility.h) +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() + # Header files to display in project view of IDEs only set(MagnumShaders_PRIVATE_HEADERS Implementation/CreateCompatibilityShader.h) diff --git a/src/Magnum/Shaders/DistanceFieldVector.h b/src/Magnum/Shaders/DistanceFieldVector.h index a64eca957..c3b15183c 100644 --- a/src/Magnum/Shaders/DistanceFieldVector.h +++ b/src/Magnum/Shaders/DistanceFieldVector.h @@ -25,243 +25,46 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef MAGNUM_BUILD_DEPRECATED /** @file - * @brief Class @ref Magnum::Shaders::DistanceFieldVector, typedef @ref Magnum::Shaders::DistanceFieldVector2D, @ref Magnum::Shaders::DistanceFieldVector3D + * @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. */ +#endif -#include "Magnum/DimensionTraits.h" -#include "Magnum/Shaders/AbstractVector.h" -#include "Magnum/Shaders/visibility.h" - -namespace Magnum { namespace Shaders { - -namespace Implementation { - enum class DistanceFieldVectorFlag: UnsignedByte { - TextureTransformation = 1 << 0 - }; - typedef Containers::EnumSet DistanceFieldVectorFlags; -} - -/** -@brief Distance field vector shader - -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 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 -@ref setTransformationProjectionMatrix(), @ref setColor() and others to -configure the shader. - -Alpha / transparency is supported by the shader implicitly, but to have it -working on the framebuffer, you need to enable -@ref GL::Renderer::Feature::Blending and set up the blending function. See -@ref GL::Renderer::setBlendFunction() for details. - -@image html shaders-distancefieldvector.png width=256px - -@section Shaders-DistanceFieldVector-usage Example usage - -Common mesh setup: - -@snippet MagnumShaders.cpp DistanceFieldVector-usage1 - -Common rendering setup: - -@snippet MagnumShaders.cpp DistanceFieldVector-usage2 - -@see @ref shaders, @ref DistanceFieldVector2D, @ref DistanceFieldVector3D -@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 class MAGNUM_SHADERS_EXPORT DistanceFieldVector: public AbstractVector { - public: - #ifdef DOXYGEN_GENERATING_OUTPUT - /** - * @brief Flag - * @m_since{2020,06} - * - * @see @ref Flags, @ref flags() - */ - enum class Flag: UnsignedByte { - /** - * Enable texture coordinate transformation. - * @see @ref setTextureMatrix() - * @m_since{2020,06} - */ - TextureTransformation = 1 << 0 - }; - - /** - * @brief Flags - * @m_since{2020,06} - * - * @see @ref flags() - */ - typedef Containers::EnumSet Flags; - #else - /* Done this way to be prepared for possible future diversion of 2D - and 3D flags (e.g. introducing 3D-specific features) */ - typedef Implementation::DistanceFieldVectorFlag Flag; - typedef Implementation::DistanceFieldVectorFlags Flags; - #endif - - /** - * @brief Constructor - * @param flags Flags - */ - explicit DistanceFieldVector(Flags flags = {}); - - /** - * @brief Construct without creating the underlying OpenGL object - * - * The constructed instance is equivalent to a moved-from state. Useful - * in cases where you will overwrite the instance later anyway. Move - * another object over it to make it useful. - * - * This function can be safely used for constructing (and later - * destructing) objects even without any OpenGL context being active. - * However note that this is a low-level and a potentially dangerous - * API, see the documentation of @ref NoCreate for alternatives. - */ - explicit DistanceFieldVector(NoCreateT) noexcept - /** @todoc remove workaround when doxygen is sane */ - #ifndef DOXYGEN_GENERATING_OUTPUT - : AbstractVector{NoCreate} - #endif - {} - - /** @brief Copying is not allowed */ - DistanceFieldVector(const DistanceFieldVector&) = delete; - - /** @brief Move constructor */ - DistanceFieldVector(DistanceFieldVector&&) noexcept = default; - - /** @brief Copying is not allowed */ - DistanceFieldVector& operator=(const DistanceFieldVector&) = delete; - - /** @brief Move assignment */ - DistanceFieldVector& operator=(DistanceFieldVector&&) noexcept = default; - - /** - * @brief Flags - * @m_since{2020,06} - */ - Flags flags() const { return _flags; } - - /** - * @brief Set transformation and projection matrix - * @return Reference to self (for method chaining) - * - * Initial value is an identity matrix. - */ - DistanceFieldVector& setTransformationProjectionMatrix(const MatrixTypeFor& matrix); - - /** - * @brief Set texture coordinate transformation matrix - * @return Reference to self (for method chaining) - * @m_since{2020,06} - * - * Expects that the shader was created with - * @ref Flag::TextureTransformation enabled. Initial value is an - * identity matrix. - */ - DistanceFieldVector& setTextureMatrix(const Matrix3& matrix); - - /** - * @brief Set fill color - * @return Reference to self (for method chaining) - * - * Initial value is @cpp 0xffffffff_rgbaf @ce. - * @see @ref setOutlineColor() - */ - DistanceFieldVector& setColor(const Color4& color); - - /** - * @brief Set outline color - * @return Reference to self (for method chaining) - * - * Initial value is @cpp 0x00000000_rgbaf @ce and the outline is not - * drawn --- see @ref setOutlineRange() for more information. - * @see @ref setOutlineRange(), @ref setColor() - */ - DistanceFieldVector& setOutlineColor(const Color4& color); - - /** - * @brief Set outline range - * @return Reference to self (for method chaining) - * - * The @p start parameter describes where fill ends and possible - * outline starts. Initial value is @cpp 0.5f @ce, larger values will - * make the vector art look thinner, smaller will make it look thicker. - * - * The @p end parameter describes where outline ends. If set to value - * larger than @p start the outline is not drawn. Initial value is - * @cpp 1.0f @ce. - * - * @see @ref setOutlineColor() - */ - DistanceFieldVector& setOutlineRange(Float start, Float end); +#include "Magnum/configure.h" - /** - * @brief Set smoothness radius - * @return Reference to self (for method chaining) - * - * 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. - */ - DistanceFieldVector& setSmoothness(Float value); +#ifdef MAGNUM_BUILD_DEPRECATED +#include - #ifndef DOXYGEN_GENERATING_OUTPUT - /* Overloads to remove WTF-factor from method chaining order */ - DistanceFieldVector& bindVectorTexture(GL::Texture2D& texture) { - AbstractVector::bindVectorTexture(texture); - return *this; - } - #endif +#include "Magnum/Shaders/DistanceFieldVectorGL.h" - private: - /* Prevent accidentally calling irrelevant functions */ - #ifndef MAGNUM_TARGET_GLES - using GL::AbstractShaderProgram::drawTransformFeedback; - #endif - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - using GL::AbstractShaderProgram::dispatchCompute; - #endif +CORRADE_DEPRECATED_FILE("use Magnum/Shaders/DistanceFieldVectorGL.h, the DistanceFieldVectorGL class and related typedefs instead") - Flags _flags; - Int _transformationProjectionMatrixUniform{0}, - _textureMatrixUniform{1}, - _colorUniform{2}, - _outlineColorUniform{3}, - _outlineRangeUniform{4}, - _smoothnessUniform{5}; -}; +namespace Magnum { namespace Shaders { -/** @brief Two-dimensional distance field vector shader */ -typedef DistanceFieldVector<2> DistanceFieldVector2D; +/** @brief @copybrief DistanceFieldVectorGL + * @m_deprecated_since_latest Use @ref DistanceFieldVectorGL instead. + */ +#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Multiple definitions still broken */ +template using DistanceFieldVector CORRADE_DEPRECATED_ALIAS("use DistanceFieldVectorGL instead") = DistanceFieldVectorGL; +#endif -/** @brief Three-dimensional distance field vector shader */ -typedef DistanceFieldVector<3> DistanceFieldVector3D; +/** @brief @copybrief DistanceFieldVectorGL2D + * @m_deprecated_since_latest Use @ref DistanceFieldVectorGL2D instead. + */ +typedef CORRADE_DEPRECATED("use DistanceFieldVectorGL2D instead") DistanceFieldVectorGL2D DistanceFieldVector2D; -#ifdef DOXYGEN_GENERATING_OUTPUT -/** @debugoperatorclassenum{DistanceFieldVector,DistanceFieldVector::Flag} */ -template Debug& operator<<(Debug& debug, DistanceFieldVector::Flag value); +/** @brief @copybrief DistanceFieldVectorGL3D + * @m_deprecated_since_latest Use @ref DistanceFieldVectorGL3D instead. + */ +typedef CORRADE_DEPRECATED("use DistanceFieldVectorGL3D instead") DistanceFieldVectorGL3D DistanceFieldVector3D; -/** @debugoperatorclassenum{DistanceFieldVector,DistanceFieldVector::Flags} */ -template Debug& operator<<(Debug& debug, DistanceFieldVector::Flags value); +}} #else -namespace Implementation { - MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, DistanceFieldVectorFlag value); - MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, DistanceFieldVectorFlags value); - CORRADE_ENUMSET_OPERATORS(DistanceFieldVectorFlags) -} +#error use Magnum/Shaders/DistanceFieldVectorGL.h, the DistanceFieldVectorGL class and related typedefs instead #endif -}} - #endif diff --git a/src/Magnum/Shaders/DistanceFieldVector.cpp b/src/Magnum/Shaders/DistanceFieldVectorGL.cpp similarity index 75% rename from src/Magnum/Shaders/DistanceFieldVector.cpp rename to src/Magnum/Shaders/DistanceFieldVectorGL.cpp index ca34c98bc..19c50301f 100644 --- a/src/Magnum/Shaders/DistanceFieldVector.cpp +++ b/src/Magnum/Shaders/DistanceFieldVectorGL.cpp @@ -23,7 +23,7 @@ DEALINGS IN THE SOFTWARE. */ -#include "DistanceFieldVector.h" +#include "DistanceFieldVectorGL.h" #include #include @@ -40,13 +40,13 @@ namespace Magnum { namespace Shaders { -template DistanceFieldVector::DistanceFieldVector(const Flags flags): _flags{flags} { +template DistanceFieldVectorGL::DistanceFieldVectorGL(const Flags flags): _flags{flags} { #ifdef MAGNUM_BUILD_STATIC /* Import resources on static build, if not already */ - if(!Utility::Resource::hasGroup("MagnumShaders")) + if(!Utility::Resource::hasGroup("MagnumShadersGL")) importShaderResources(); #endif - Utility::Resource rs("MagnumShaders"); + Utility::Resource rs("MagnumShadersGL"); #ifndef MAGNUM_TARGET_GLES const GL::Version version = GL::Context::current().supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); @@ -74,8 +74,8 @@ template DistanceFieldVector::DistanceFieldV if(!GL::Context::current().isExtensionSupported(version)) #endif { - GL::AbstractShaderProgram::bindAttributeLocation(AbstractVector::Position::Location, "position"); - GL::AbstractShaderProgram::bindAttributeLocation(AbstractVector::TextureCoordinates::Location, "textureCoordinates"); + GL::AbstractShaderProgram::bindAttributeLocation(AbstractVectorGL::Position::Location, "position"); + GL::AbstractShaderProgram::bindAttributeLocation(AbstractVectorGL::TextureCoordinates::Location, "textureCoordinates"); } #endif @@ -99,7 +99,7 @@ template DistanceFieldVector::DistanceFieldV #endif { GL::AbstractShaderProgram::setUniform(GL::AbstractShaderProgram::uniformLocation("vectorTexture"), - AbstractVector::VectorTextureUnit); + AbstractVectorGL::VectorTextureUnit); } /* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */ @@ -113,49 +113,49 @@ template DistanceFieldVector::DistanceFieldV #endif } -template DistanceFieldVector& DistanceFieldVector::setTransformationProjectionMatrix(const MatrixTypeFor& matrix) { +template DistanceFieldVectorGL& DistanceFieldVectorGL::setTransformationProjectionMatrix(const MatrixTypeFor& matrix) { GL::AbstractShaderProgram::setUniform(_transformationProjectionMatrixUniform, matrix); return *this; } -template DistanceFieldVector& DistanceFieldVector::setTextureMatrix(const Matrix3& matrix) { +template DistanceFieldVectorGL& DistanceFieldVectorGL::setTextureMatrix(const Matrix3& matrix) { CORRADE_ASSERT(_flags & Flag::TextureTransformation, - "Shaders::DistanceFieldVector::setTextureMatrix(): the shader was not created with texture transformation enabled", *this); + "Shaders::DistanceFieldVectorGL::setTextureMatrix(): the shader was not created with texture transformation enabled", *this); GL::AbstractShaderProgram::setUniform(_textureMatrixUniform, matrix); return *this; } -template DistanceFieldVector& DistanceFieldVector::setColor(const Color4& color) { +template DistanceFieldVectorGL& DistanceFieldVectorGL::setColor(const Color4& color) { GL::AbstractShaderProgram::setUniform(_colorUniform, color); return *this; } -template DistanceFieldVector& DistanceFieldVector::setOutlineColor(const Color4& color) { +template DistanceFieldVectorGL& DistanceFieldVectorGL::setOutlineColor(const Color4& color) { GL::AbstractShaderProgram::setUniform(_outlineColorUniform, color); return *this; } -template DistanceFieldVector& DistanceFieldVector::setOutlineRange(Float start, Float end) { +template DistanceFieldVectorGL& DistanceFieldVectorGL::setOutlineRange(Float start, Float end) { GL::AbstractShaderProgram::setUniform(_outlineRangeUniform, Vector2(start, end)); return *this; } -template DistanceFieldVector& DistanceFieldVector::setSmoothness(Float value) { +template DistanceFieldVectorGL& DistanceFieldVectorGL::setSmoothness(Float value) { GL::AbstractShaderProgram::setUniform(_smoothnessUniform, value); return *this; } -template class DistanceFieldVector<2>; -template class DistanceFieldVector<3>; +template class DistanceFieldVectorGL<2>; +template class DistanceFieldVectorGL<3>; namespace Implementation { -Debug& operator<<(Debug& debug, const DistanceFieldVectorFlag value) { - debug << "Shaders::DistanceFieldVector::Flag" << Debug::nospace; +Debug& operator<<(Debug& debug, const DistanceFieldVectorGLFlag value) { + debug << "Shaders::DistanceFieldVectorGL::Flag" << Debug::nospace; switch(value) { /* LCOV_EXCL_START */ - #define _c(v) case DistanceFieldVectorFlag::v: return debug << "::" #v; + #define _c(v) case DistanceFieldVectorGLFlag::v: return debug << "::" #v; _c(TextureTransformation) #undef _c /* LCOV_EXCL_STOP */ @@ -164,9 +164,9 @@ Debug& operator<<(Debug& debug, const DistanceFieldVectorFlag value) { return debug << "(" << Debug::nospace << reinterpret_cast(UnsignedByte(value)) << Debug::nospace << ")"; } -Debug& operator<<(Debug& debug, const DistanceFieldVectorFlags value) { - return Containers::enumSetDebugOutput(debug, value, "Shaders::DistanceFieldVector::Flags{}", { - DistanceFieldVectorFlag::TextureTransformation +Debug& operator<<(Debug& debug, const DistanceFieldVectorGLFlags value) { + return Containers::enumSetDebugOutput(debug, value, "Shaders::DistanceFieldVectorGL::Flags{}", { + DistanceFieldVectorGLFlag::TextureTransformation }); } diff --git a/src/Magnum/Shaders/DistanceFieldVectorGL.h b/src/Magnum/Shaders/DistanceFieldVectorGL.h new file mode 100644 index 000000000..92ede2175 --- /dev/null +++ b/src/Magnum/Shaders/DistanceFieldVectorGL.h @@ -0,0 +1,275 @@ +#ifndef Magnum_Shaders_DistanceFieldVectorGL_h +#define Magnum_Shaders_DistanceFieldVectorGL_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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::DistanceFieldVectorGL, typedef @ref Magnum::Shaders::DistanceFieldVectorGL2D, @ref Magnum::Shaders::DistanceFieldVectorGL3D + * @m_since_latest + */ + +#include "Magnum/DimensionTraits.h" +#include "Magnum/Shaders/AbstractVectorGL.h" +#include "Magnum/Shaders/visibility.h" + +namespace Magnum { namespace Shaders { + +namespace Implementation { + enum class DistanceFieldVectorGLFlag: UnsignedByte { + TextureTransformation = 1 << 0 + }; + typedef Containers::EnumSet DistanceFieldVectorGLFlags; +} + +/** +@brief Distance field vector OpenGL shader +@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 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 +@ref setTransformationProjectionMatrix(), @ref setColor() and others to +configure the shader. + +Alpha / transparency is supported by the shader implicitly, but to have it +working on the framebuffer, you need to enable +@ref GL::Renderer::Feature::Blending and set up the blending function. See +@ref GL::Renderer::setBlendFunction() for details. + +@image html shaders-distancefieldvector.png width=256px + +@section Shaders-DistanceFieldVectorGL-usage Example usage + +Common mesh setup: + +@snippet MagnumShaders-gl.cpp DistanceFieldVectorGL-usage1 + +Common rendering setup: + +@snippet MagnumShaders-gl.cpp DistanceFieldVectorGL-usage2 + +@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 class MAGNUM_SHADERS_EXPORT DistanceFieldVectorGL: public AbstractVectorGL { + public: + #ifdef DOXYGEN_GENERATING_OUTPUT + /** + * @brief Flag + * @m_since{2020,06} + * + * @see @ref Flags, @ref flags() + */ + enum class Flag: UnsignedByte { + /** + * Enable texture coordinate transformation. + * @see @ref setTextureMatrix() + * @m_since{2020,06} + */ + TextureTransformation = 1 << 0 + }; + + /** + * @brief Flags + * @m_since{2020,06} + * + * @see @ref flags() + */ + typedef Containers::EnumSet Flags; + #else + /* Done this way to be prepared for possible future diversion of 2D + and 3D flags (e.g. introducing 3D-specific features) */ + typedef Implementation::DistanceFieldVectorGLFlag Flag; + typedef Implementation::DistanceFieldVectorGLFlags Flags; + #endif + + /** + * @brief Constructor + * @param flags Flags + */ + explicit DistanceFieldVectorGL(Flags flags = {}); + + /** + * @brief Construct without creating the underlying OpenGL object + * + * The constructed instance is equivalent to a moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + * + * This function can be safely used for constructing (and later + * destructing) objects even without any OpenGL context being active. + * 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{NoCreate} + #endif + {} + + /** @brief Copying is not allowed */ + DistanceFieldVectorGL(const DistanceFieldVectorGL&) = delete; + + /** @brief Move constructor */ + DistanceFieldVectorGL(DistanceFieldVectorGL&&) noexcept = default; + + /** @brief Copying is not allowed */ + DistanceFieldVectorGL& operator=(const DistanceFieldVectorGL&) = delete; + + /** @brief Move assignment */ + DistanceFieldVectorGL& operator=(DistanceFieldVectorGL&&) noexcept = default; + + /** + * @brief Flags + * @m_since{2020,06} + */ + Flags flags() const { return _flags; } + + /** + * @brief Set transformation and projection matrix + * @return Reference to self (for method chaining) + * + * Initial value is an identity matrix. + */ + DistanceFieldVectorGL& setTransformationProjectionMatrix(const MatrixTypeFor& matrix); + + /** + * @brief Set texture coordinate transformation matrix + * @return Reference to self (for method chaining) + * @m_since{2020,06} + * + * Expects that the shader was created with + * @ref Flag::TextureTransformation enabled. Initial value is an + * identity matrix. + */ + DistanceFieldVectorGL& setTextureMatrix(const Matrix3& matrix); + + /** + * @brief Set fill color + * @return Reference to self (for method chaining) + * + * Initial value is @cpp 0xffffffff_rgbaf @ce. + * @see @ref setOutlineColor() + */ + DistanceFieldVectorGL& setColor(const Color4& color); + + /** + * @brief Set outline color + * @return Reference to self (for method chaining) + * + * Initial value is @cpp 0x00000000_rgbaf @ce and the outline is not + * drawn --- see @ref setOutlineRange() for more information. + * @see @ref setOutlineRange(), @ref setColor() + */ + DistanceFieldVectorGL& setOutlineColor(const Color4& color); + + /** + * @brief Set outline range + * @return Reference to self (for method chaining) + * + * The @p start parameter describes where fill ends and possible + * outline starts. Initial value is @cpp 0.5f @ce, larger values will + * make the vector art look thinner, smaller will make it look thicker. + * + * The @p end parameter describes where outline ends. If set to value + * larger than @p start the outline is not drawn. Initial value is + * @cpp 1.0f @ce. + * + * @see @ref setOutlineColor() + */ + DistanceFieldVectorGL& setOutlineRange(Float start, Float end); + + /** + * @brief Set smoothness radius + * @return Reference to self (for method chaining) + * + * 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. + */ + DistanceFieldVectorGL& setSmoothness(Float value); + + #ifndef DOXYGEN_GENERATING_OUTPUT + /* Overloads to remove WTF-factor from method chaining order */ + DistanceFieldVectorGL& bindVectorTexture(GL::Texture2D& texture) { + AbstractVectorGL::bindVectorTexture(texture); + return *this; + } + #endif + + private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + + Flags _flags; + Int _transformationProjectionMatrixUniform{0}, + _textureMatrixUniform{1}, + _colorUniform{2}, + _outlineColorUniform{3}, + _outlineRangeUniform{4}, + _smoothnessUniform{5}; +}; + +/** +@brief Two-dimensional distance field vector OpenGL shader +@m_since_latest +*/ +typedef DistanceFieldVectorGL<2> DistanceFieldVectorGL2D; + +/** +@brief Three-dimensional distance field vector OpenGL shader +@m_since_latest +*/ +typedef DistanceFieldVectorGL<3> DistanceFieldVectorGL3D; + +#ifdef DOXYGEN_GENERATING_OUTPUT +/** @debugoperatorclassenum{DistanceFieldVectorGL,DistanceFieldVectorGL::Flag} */ +template Debug& operator<<(Debug& debug, DistanceFieldVector::Flag value); + +/** @debugoperatorclassenum{DistanceFieldVectorGL,DistanceFieldVectorGL::Flags} */ +template Debug& operator<<(Debug& debug, DistanceFieldVector::Flags value); +#else +namespace Implementation { + MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, DistanceFieldVectorGLFlag value); + MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, DistanceFieldVectorGLFlags value); + CORRADE_ENUMSET_OPERATORS(DistanceFieldVectorGLFlags) +} +#endif + +}} + +#endif diff --git a/src/Magnum/Shaders/Flat.h b/src/Magnum/Shaders/Flat.h index 1a5d4ab0a..70311e465 100644 --- a/src/Magnum/Shaders/Flat.h +++ b/src/Magnum/Shaders/Flat.h @@ -25,507 +25,46 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef MAGNUM_BUILD_DEPRECATED /** @file - * @brief Class @ref Magnum::Shaders::Flat, typedef @ref Magnum::Shaders::Flat2D, @ref Magnum::Shaders::Flat3D + * @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. */ +#endif -#include "Magnum/DimensionTraits.h" -#include "Magnum/GL/AbstractShaderProgram.h" -#include "Magnum/Shaders/Generic.h" -#include "Magnum/Shaders/visibility.h" - -namespace Magnum { namespace Shaders { - -namespace Implementation { - enum class FlatFlag: UnsignedByte { - Textured = 1 << 0, - AlphaMask = 1 << 1, - VertexColor = 1 << 2, - TextureTransformation = 1 << 3, - #ifndef MAGNUM_TARGET_GLES2 - ObjectId = 1 << 4, - InstancedObjectId = (1 << 5)|ObjectId, - #endif - InstancedTransformation = 1 << 6, - InstancedTextureOffset = (1 << 7)|TextureTransformation - }; - typedef Containers::EnumSet FlatFlags; -} - -/** -@brief Flat shader - -Draws the whole mesh with given color or texture. For a colored mesh you need -to provide the @ref Position attribute in your triangle mesh. By default, the -shader renders the mesh with a white color in an identity transformation. -Use @ref setTransformationProjectionMatrix(), @ref setColor() and others to -configure the shader. - -@image html shaders-flat.png width=256px - -@section Shaders-Flat-colored Colored rendering - -Common mesh setup: - -@snippet MagnumShaders.cpp Flat-usage-colored1 - -Common rendering setup: - -@snippet MagnumShaders.cpp Flat-usage-colored2 - -@section Shaders-Flat-textured Textured rendering - -If you want to use a texture, you need to provide also the -@ref TextureCoordinates attribute. Pass @ref Flag::Textured to the constructor -and then at render time don't forget to bind also the texture via -@ref bindTexture(). The texture is multipled by the color, which is by default -set to @cpp 0xffffffff_rgbaf @ce. Common mesh setup: - -@snippet MagnumShaders.cpp Flat-usage-textured1 - -Common rendering setup: - -@snippet MagnumShaders.cpp Flat-usage-textured2 - -For coloring the texture based on intensity you can use the @ref Vector shader. -The 3D version of this shader is equivalent to @ref Phong with zero lights, -however this implementation is much simpler and thus likely also faster. See -@ref Shaders-Phong-lights-zero "its documentation" for more information. -Conversely, enabling @ref Flag::VertexColor and using a default color with no -texturing makes this shader equivalent to @ref VertexColor. - -@section Shaders-Flat-alpha Alpha blending and masking - -Alpha / transparency is supported by the shader implicitly, but to have it -working on the framebuffer, you need to enable -@ref GL::Renderer::Feature::Blending and set up the blending function. See -@ref GL::Renderer::setBlendFunction() for details. - -An alternative is to enable @ref Flag::AlphaMask and tune @ref setAlphaMask() -for simple binary alpha-masked drawing that doesn't require depth sorting or -blending enabled. Note that this feature is implemented using the GLSL -@glsl discard @ce operation which is known to have considerable performance -impact on some platforms. With proper depth sorting and blending you'll usually -get much better performance and output quality. - -@section Shaders-Flat-object-id Object ID output - -The shader supports writing object ID to the framebuffer for object picking or -other annotation purposes. Enable it using @ref Flag::ObjectId and set up an -integer buffer attached to the @ref ObjectIdOutput attachment. Note that for -portability you should use @ref GL::Framebuffer::clearColor() instead of -@ref GL::Framebuffer::clear() as the former usually emits GL errors when called -on framebuffers with integer attachments. - -@snippet MagnumShaders.cpp Flat-usage-object-id - -If you have a batch of meshes with different object IDs, enable -@ref Flag::InstancedObjectId and supply per-vertex IDs to the @ref ObjectId -attribute. The output will contain a sum of the per-vertex ID and ID coming -from @ref setObjectId(). - -@requires_gles30 Object ID output requires integer buffer attachments, which - are not available in OpenGL ES 2.0 or WebGL 1.0. - -@section Shaders-Flat-instancing Instanced rendering - -Enabling @ref Flag::InstancedTransformation will turn the shader into an -instanced one. It'll take per-instance transformation from the -@ref TransformationMatrix attribute, applying it before the matrix set by -@ref setTransformationProjectionMatrix(). Besides that, @ref Flag::VertexColor -(and the @ref Color3 / @ref Color4) attributes can work as both per-vertex and -per-instance, and for texturing it's possible to have per-instance texture -offset taken from @ref TextureOffset when @ref Flag::InstancedTextureOffset is -enabled (similarly to transformation, applied before @ref setTextureMatrix()). -The snippet below shows adding a buffer with per-instance transformation and -color to a mesh: - -@snippet MagnumShaders.cpp Flat-usage-instancing - -@requires_gl33 Extension @gl_extension{ARB,instanced_arrays} -@requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - @gl_extension{EXT,instanced_arrays} or @gl_extension{NV,instanced_arrays} - in OpenGL ES 2.0. -@requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} in WebGL - 1.0. - -@see @ref shaders, @ref Flat2D, @ref Flat3D -*/ -template class MAGNUM_SHADERS_EXPORT Flat: 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 Generic::Position Position; - - /** - * @brief 2D texture coordinates - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector2 "Vector2". Used only if @ref Flag::Textured is - * set. - */ - typedef typename Generic::TextureCoordinates TextureCoordinates; - - /** - * @brief Three-component vertex color - * @m_since{2019,10} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Color3. Use - * either this or the @ref Color4 attribute. Used only if - * @ref Flag::VertexColor is set. - */ - typedef typename Generic::Color3 Color3; - - /** - * @brief Four-component vertex color - * @m_since{2019,10} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Color4. Use - * either this or the @ref Color3 attribute. Used only if - * @ref Flag::VertexColor is set. - */ - typedef typename Generic::Color4 Color4; - - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief (Instanced) object ID - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt. - * Used only if @ref Flag::InstancedObjectId is set. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. - */ - typedef typename Generic::ObjectId ObjectId; - #endif - - /** - * @brief (Instanced) transformation matrix - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Matrix3 in - * 2D, @ref Magnum::Matrix4 in 3D. Used only if - * @ref Flag::InstancedTransformation is set. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - */ - typedef typename Generic::TransformationMatrix TransformationMatrix; - - /** - * @brief (Instanced) texture offset - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Vector2. Used - * only if @ref Flag::InstancedTextureOffset is set. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - */ - typedef typename Generic::TextureOffset TextureOffset; - - enum: UnsignedInt { - /** - * Color shader output. Present always, expects three- or - * four-component floating-point or normalized buffer attachment. - * @m_since{2019,10} - */ - ColorOutput = Generic::ColorOutput, - - #ifndef MAGNUM_TARGET_GLES2 - /** - * Object ID shader output. @ref shaders-generic "Generic output", - * present only if @ref Flag::ObjectId is set. Expects a - * single-component unsigned integral attachment. Writes the value - * set in @ref setObjectId() there, see - * @ref Shaders-Phong-object-id for more information. - * @requires_gl30 Extension @gl_extension{EXT,texture_integer} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL - * 1.0. - * @m_since{2019,10} - */ - ObjectIdOutput = Generic::ObjectIdOutput - #endif - }; - - #ifdef DOXYGEN_GENERATING_OUTPUT - /** - * @brief Flag - * - * @see @ref Flags, @ref flags() - */ - enum class Flag: UnsignedByte { - /** - * Multiply color with a texture. - * @see @ref setColor(), @ref bindTexture() - */ - Textured = 1 << 0, - - /** - * Enable alpha masking. If the combined fragment color has an - * alpha less than the value specified with @ref setAlphaMask(), - * given fragment is discarded. - * - * This uses the @glsl discard @ce operation which is known to have - * considerable performance impact on some platforms. While useful - * for cheap alpha masking that doesn't require depth sorting, - * with proper depth sorting and blending you'll usually get much - * better performance and output quality. - */ - AlphaMask = 1 << 1, - - /** - * Multiply diffuse color with a vertex color. Requires either - * the @ref Color3 or @ref Color4 attribute to be present. - * @m_since{2019,10} - */ - VertexColor = 1 << 2, - - /** - * Enable texture coordinate transformation. If this flag is set, - * the shader expects that @ref Flag::Textured is enabled as well. - * @see @ref setTextureMatrix() - * @m_since{2020,06} - */ - TextureTransformation = 1 << 3, - - #ifndef MAGNUM_TARGET_GLES2 - /** - * Enable object ID output. See @ref Shaders-Flat-object-id for - * more information. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL - * 1.0. - * @m_since{2019,10} - */ - ObjectId = 1 << 4, - - /** - * Instanced object ID. Retrieves a per-instance / per-vertex - * object ID from the @ref ObjectId attribute, outputting a sum of - * the per-vertex ID and ID coming from @ref setObjectId(). - * Implicitly enables @ref Flag::ObjectId. See - * @ref Shaders-Flat-object-id for more information. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL - * 1.0. - * @m_since{2020,06} - */ - InstancedObjectId = (1 << 5)|ObjectId, - #endif - - /** - * Instanced transformation. Retrieves a per-instance - * transformation matrix from the @ref TransformationMatrix - * attribute and uses it together with the matrix coming from - * @ref setTransformationProjectionMatrix() (first the - * per-instance, then the uniform matrix). See - * @ref Shaders-Flat-instancing for more information. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - * @m_since{2020,06} - */ - InstancedTransformation = 1 << 6, - - /** - * Instanced texture offset. Retrieves a per-instance offset vector - * from the @ref TextureOffset attribute and uses it together with - * the matrix coming from @ref setTextureMatrix() (first the - * per-instance vector, then the uniform matrix). Instanced texture - * scaling and rotation is not supported at the moment, you can - * specify that only via the uniform @ref setTextureMatrix(). - * Implicitly enables @ref Flag::TextureTransformation. See - * @ref Shaders-Flat-instancing for more information. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - * @m_since{2020,06} - */ - InstancedTextureOffset = (1 << 7)|TextureTransformation - }; - - /** - * @brief Flags - * - * @see @ref flags() - */ - typedef Containers::EnumSet Flags; - #else - /* Done this way to be prepared for possible future diversion of 2D - and 3D flags (e.g. introducing 3D-specific features) */ - typedef Implementation::FlatFlag Flag; - typedef Implementation::FlatFlags Flags; - #endif - - /** - * @brief Constructor - * @param flags Flags - */ - explicit Flat(Flags flags = {}); - - /** - * @brief Construct without creating the underlying OpenGL object - * - * The constructed instance is equivalent to a moved-from state. Useful - * in cases where you will overwrite the instance later anyway. Move - * another object over it to make it useful. - * - * This function can be safely used for constructing (and later - * destructing) objects even without any OpenGL context being active. - * However note that this is a low-level and a potentially dangerous - * API, see the documentation of @ref NoCreate for alternatives. - */ - explicit Flat(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {} - - /** @brief Copying is not allowed */ - Flat(const Flat&) = delete; - - /** @brief Move constructor */ - Flat(Flat&&) noexcept = default; - - /** @brief Copying is not allowed */ - Flat& operator=(const Flat&) = delete; - - /** @brief Move assignment */ - Flat& operator=(Flat&&) noexcept = default; - - /** @brief Flags */ - Flags flags() const { return _flags; } - - /** - * @brief Set transformation and projection matrix - * @return Reference to self (for method chaining) - * - * Initial value is an identity matrix. - */ - Flat& setTransformationProjectionMatrix(const MatrixTypeFor& matrix); - - /** - * @brief Set texture coordinate transformation matrix - * @return Reference to self (for method chaining) - * @m_since{2020,06} - * - * Expects that the shader was created with - * @ref Flag::TextureTransformation enabled. Initial value is an - * identity matrix. - */ - Flat& setTextureMatrix(const Matrix3& matrix); - - /** - * @brief Set color - * @return Reference to self (for method chaining) - * - * If @ref Flag::Textured is set, initial value is - * @cpp 0xffffffff_rgbaf @ce and the color will be multiplied with the - * texture. - * @see @ref bindTexture() - */ - Flat& setColor(const Magnum::Color4& color); - - /** - * @brief Bind a color texture - * @return Reference to self (for method chaining) - * - * Expects that the shader was created with @ref Flag::Textured - * enabled. - * @see @ref setColor(), @ref Flag::TextureTransformation, - * @ref setTextureMatrix() - */ - Flat& bindTexture(GL::Texture2D& texture); +#include "Magnum/configure.h" - /** - * @brief Set alpha mask value - * @return Reference to self (for method chaining) - * - * Expects that the shader was created with @ref Flag::AlphaMask - * enabled. Fragments with alpha values smaller than the mask value - * will be discarded. Initial value is @cpp 0.5f @ce. See the flag - * documentation for further information. - * - * This corresponds to @m_class{m-doc-external} [glAlphaFunc()](https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glAlphaFunc.xml) - * in classic OpenGL. - * @m_keywords{glAlphaFunc()} - */ - Flat& setAlphaMask(Float mask); +#ifdef MAGNUM_BUILD_DEPRECATED +#include - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief Set object ID - * @return Reference to self (for method chaining) - * - * Expects that the shader was created with @ref Flag::ObjectId - * enabled. Value set here is written to the @ref ObjectIdOutput, see - * @ref Shaders-Flat-object-id for more information. Default is - * @cpp 0 @ce. If @ref Flag::InstancedObjectId is enabled as well, this - * value is combined with ID coming from the @ref ObjectId attribute. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. - */ - Flat& setObjectId(UnsignedInt id); - #endif +#include "Magnum/Shaders/FlatGL.h" - private: - /* Prevent accidentally calling irrelevant functions */ - #ifndef MAGNUM_TARGET_GLES - using GL::AbstractShaderProgram::drawTransformFeedback; - #endif - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - using GL::AbstractShaderProgram::dispatchCompute; - #endif +CORRADE_DEPRECATED_FILE("use Magnum/Shaders/FlatGL.h, the FlatGL class and related typedefs instead") - Flags _flags; - Int _transformationProjectionMatrixUniform{0}, - _textureMatrixUniform{1}, - _colorUniform{2}, - _alphaMaskUniform{3}; - #ifndef MAGNUM_TARGET_GLES2 - Int _objectIdUniform{4}; - #endif -}; +namespace Magnum { namespace Shaders { -/** @brief 2D flat shader */ -typedef Flat<2> Flat2D; +/** @brief @copybrief FlatGL + * @m_deprecated_since_latest Use @ref FlatGL instead. + */ +#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Multiple definitions still broken */ +template using Flat CORRADE_DEPRECATED_ALIAS("use FlatGL instead") = FlatGL; +#endif -/** @brief 3D flat shader */ -typedef Flat<3> Flat3D; +/** @brief @copybrief FlatGL2D + * @m_deprecated_since_latest Use @ref FlatGL2D instead. + */ +typedef CORRADE_DEPRECATED("use FlatGL2D instead") FlatGL2D Flat2D; -#ifdef DOXYGEN_GENERATING_OUTPUT -/** @debugoperatorclassenum{Flat,Flat::Flag} */ -template Debug& operator<<(Debug& debug, Flat::Flag value); +/** @brief @copybrief FlatGL3D + * @m_deprecated_since_latest Use @ref FlatGL3D instead. + */ +typedef CORRADE_DEPRECATED("use FlatGL3D instead") FlatGL3D Flat3D; -/** @debugoperatorclassenum{Flat,Flat::Flags} */ -template Debug& operator<<(Debug& debug, Flat::Flags value); +}} #else -namespace Implementation { - MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, FlatFlag value); - MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, FlatFlags value); - CORRADE_ENUMSET_OPERATORS(FlatFlags) -} +#error use Magnum/Shaders/FlatGL.h, the FlatGL class and related typedefs instead #endif -}} - #endif diff --git a/src/Magnum/Shaders/Flat.cpp b/src/Magnum/Shaders/FlatGL.cpp similarity index 78% rename from src/Magnum/Shaders/Flat.cpp rename to src/Magnum/Shaders/FlatGL.cpp index f55ca547f..3d9b1c79e 100644 --- a/src/Magnum/Shaders/Flat.cpp +++ b/src/Magnum/Shaders/FlatGL.cpp @@ -23,7 +23,7 @@ DEALINGS IN THE SOFTWARE. */ -#include "Flat.h" +#include "FlatGL.h" #include #include @@ -45,16 +45,16 @@ namespace { enum: Int { TextureUnit = 0 }; } -template Flat::Flat(const Flags flags): _flags(flags) { +template FlatGL::FlatGL(const Flags flags): _flags(flags) { CORRADE_ASSERT(!(flags & Flag::TextureTransformation) || (flags & Flag::Textured), - "Shaders::Flat: texture transformation enabled but the shader is not textured", ); + "Shaders::FlatGL: texture transformation enabled but the shader is not textured", ); #ifdef MAGNUM_BUILD_STATIC /* Import resources on static build, if not already */ - if(!Utility::Resource::hasGroup("MagnumShaders")) + if(!Utility::Resource::hasGroup("MagnumShadersGL")) importShaderResources(); #endif - Utility::Resource rs("MagnumShaders"); + Utility::Resource rs("MagnumShadersGL"); #ifndef MAGNUM_TARGET_GLES const GL::Version version = GL::Context::current().supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); @@ -151,57 +151,57 @@ template Flat::Flat(const Flags flags): _fla #endif } -template Flat& Flat::setTransformationProjectionMatrix(const MatrixTypeFor& matrix) { +template FlatGL& FlatGL::setTransformationProjectionMatrix(const MatrixTypeFor& matrix) { setUniform(_transformationProjectionMatrixUniform, matrix); return *this; } -template Flat& Flat::setTextureMatrix(const Matrix3& matrix) { +template FlatGL& FlatGL::setTextureMatrix(const Matrix3& matrix) { CORRADE_ASSERT(_flags & Flag::TextureTransformation, - "Shaders::Flat::setTextureMatrix(): the shader was not created with texture transformation enabled", *this); + "Shaders::FlatGL::setTextureMatrix(): the shader was not created with texture transformation enabled", *this); setUniform(_textureMatrixUniform, matrix); return *this; } -template Flat& Flat::setColor(const Magnum::Color4& color) { +template FlatGL& FlatGL::setColor(const Magnum::Color4& color) { setUniform(_colorUniform, color); return *this; } -template Flat& Flat::bindTexture(GL::Texture2D& texture) { +template FlatGL& FlatGL::bindTexture(GL::Texture2D& texture) { CORRADE_ASSERT(_flags & Flag::Textured, - "Shaders::Flat::bindTexture(): the shader was not created with texturing enabled", *this); + "Shaders::FlatGL::bindTexture(): the shader was not created with texturing enabled", *this); texture.bind(TextureUnit); return *this; } -template Flat& Flat::setAlphaMask(Float mask) { +template FlatGL& FlatGL::setAlphaMask(Float mask) { CORRADE_ASSERT(_flags & Flag::AlphaMask, - "Shaders::Flat::setAlphaMask(): the shader was not created with alpha mask enabled", *this); + "Shaders::FlatGL::setAlphaMask(): the shader was not created with alpha mask enabled", *this); setUniform(_alphaMaskUniform, mask); return *this; } #ifndef MAGNUM_TARGET_GLES2 -template Flat& Flat::setObjectId(UnsignedInt id) { +template FlatGL& FlatGL::setObjectId(UnsignedInt id) { CORRADE_ASSERT(_flags & Flag::ObjectId, - "Shaders::Flat::setObjectId(): the shader was not created with object ID enabled", *this); + "Shaders::FlatGL::setObjectId(): the shader was not created with object ID enabled", *this); setUniform(_objectIdUniform, id); return *this; } #endif -template class Flat<2>; -template class Flat<3>; +template class FlatGL<2>; +template class FlatGL<3>; namespace Implementation { -Debug& operator<<(Debug& debug, const FlatFlag value) { - debug << "Shaders::Flat::Flag" << Debug::nospace; +Debug& operator<<(Debug& debug, const FlatGLFlag value) { + debug << "Shaders::FlatGL::Flag" << Debug::nospace; switch(value) { /* LCOV_EXCL_START */ - #define _c(v) case FlatFlag::v: return debug << "::" #v; + #define _c(v) case FlatGLFlag::v: return debug << "::" #v; _c(Textured) _c(AlphaMask) _c(VertexColor) @@ -219,18 +219,18 @@ Debug& operator<<(Debug& debug, const FlatFlag value) { return debug << "(" << Debug::nospace << reinterpret_cast(UnsignedByte(value)) << Debug::nospace << ")"; } -Debug& operator<<(Debug& debug, const FlatFlags value) { - return Containers::enumSetDebugOutput(debug, value, "Shaders::Flat::Flags{}", { - FlatFlag::Textured, - FlatFlag::AlphaMask, - FlatFlag::VertexColor, - FlatFlag::InstancedTextureOffset, /* Superset of TextureTransformation */ - FlatFlag::TextureTransformation, +Debug& operator<<(Debug& debug, const FlatGLFlags value) { + return Containers::enumSetDebugOutput(debug, value, "Shaders::FlatGL::Flags{}", { + FlatGLFlag::Textured, + FlatGLFlag::AlphaMask, + FlatGLFlag::VertexColor, + FlatGLFlag::InstancedTextureOffset, /* Superset of TextureTransformation */ + FlatGLFlag::TextureTransformation, #ifndef MAGNUM_TARGET_GLES2 - FlatFlag::InstancedObjectId, /* Superset of ObjectId */ - FlatFlag::ObjectId, + FlatGLFlag::InstancedObjectId, /* Superset of ObjectId */ + FlatGLFlag::ObjectId, #endif - FlatFlag::InstancedTransformation}); + FlatGLFlag::InstancedTransformation}); } } diff --git a/src/Magnum/Shaders/FlatGL.h b/src/Magnum/Shaders/FlatGL.h new file mode 100644 index 000000000..7256bf3cf --- /dev/null +++ b/src/Magnum/Shaders/FlatGL.h @@ -0,0 +1,539 @@ +#ifndef Magnum_Shaders_FlatGL_h +#define Magnum_Shaders_FlatGL_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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::FlatGL, typedef @ref Magnum::Shaders::FlatGL2D, @ref Magnum::Shaders::FlatGL3D + * @m_since_latest + */ + +#include "Magnum/DimensionTraits.h" +#include "Magnum/GL/AbstractShaderProgram.h" +#include "Magnum/Shaders/GenericGL.h" +#include "Magnum/Shaders/visibility.h" + +namespace Magnum { namespace Shaders { + +namespace Implementation { + enum class FlatGLFlag: UnsignedByte { + Textured = 1 << 0, + AlphaMask = 1 << 1, + VertexColor = 1 << 2, + TextureTransformation = 1 << 3, + #ifndef MAGNUM_TARGET_GLES2 + ObjectId = 1 << 4, + InstancedObjectId = (1 << 5)|ObjectId, + #endif + InstancedTransformation = 1 << 6, + InstancedTextureOffset = (1 << 7)|TextureTransformation + }; + typedef Containers::EnumSet FlatGLFlags; +} + +/** +@brief Flat OpenGL shader +@m_since_latest + +Draws the whole mesh with given color or texture. For a colored mesh you need +to provide the @ref Position attribute in your triangle mesh. By default, the +shader renders the mesh with a white color in an identity transformation. +Use @ref setTransformationProjectionMatrix(), @ref setColor() and others to +configure the shader. + +@image html shaders-flat.png width=256px + +@section Shaders-FlatGL-colored Colored rendering + +Common mesh setup: + +@snippet MagnumShaders-gl.cpp FlatGL-usage-colored1 + +Common rendering setup: + +@snippet MagnumShaders-gl.cpp FlatGL-usage-colored2 + +@section Shaders-FlatGL-textured Textured rendering + +If you want to use a texture, you need to provide also the +@ref TextureCoordinates attribute. Pass @ref Flag::Textured to the constructor +and then at render time don't forget to bind also the texture via +@ref bindTexture(). The texture is multipled by the color, which is by default +set to @cpp 0xffffffff_rgbaf @ce. Common mesh setup: + +@snippet MagnumShaders-gl.cpp FlatGL-usage-textured1 + +Common rendering setup: + +@snippet MagnumShaders-gl.cpp FlatGL-usage-textured2 + +For coloring the texture based on intensity you can use the @ref VectorGL +shader. The 3D version of this shader is equivalent to @ref PhongGL with zero +lights, however this implementation is much simpler and thus likely also +faster. See @ref Shaders-PhongGL-lights-zero "its documentation" for more +information. Conversely, enabling @ref Flag::VertexColor and using a default +color with no texturing makes this shader equivalent to @ref VertexColorGL. + +@section Shaders-FlatGL-alpha Alpha blending and masking + +Alpha / transparency is supported by the shader implicitly, but to have it +working on the framebuffer, you need to enable +@ref GL::Renderer::Feature::Blending and set up the blending function. See +@ref GL::Renderer::setBlendFunction() for details. + +An alternative is to enable @ref Flag::AlphaMask and tune @ref setAlphaMask() +for simple binary alpha-masked drawing that doesn't require depth sorting or +blending enabled. Note that this feature is implemented using the GLSL +@glsl discard @ce operation which is known to have considerable performance +impact on some platforms. With proper depth sorting and blending you'll usually +get much better performance and output quality. + +@section Shaders-FlatGL-object-id Object ID output + +The shader supports writing object ID to the framebuffer for object picking or +other annotation purposes. Enable it using @ref Flag::ObjectId and set up an +integer buffer attached to the @ref ObjectIdOutput attachment. Note that for +portability you should use @ref GL::Framebuffer::clearColor() instead of +@ref GL::Framebuffer::clear() as the former usually emits GL errors when called +on framebuffers with integer attachments. + +@snippet MagnumShaders-gl.cpp FlatGL-usage-object-id + +If you have a batch of meshes with different object IDs, enable +@ref Flag::InstancedObjectId and supply per-vertex IDs to the @ref ObjectId +attribute. The output will contain a sum of the per-vertex ID and ID coming +from @ref setObjectId(). + +@requires_gles30 Object ID output requires integer buffer attachments, which + are not available in OpenGL ES 2.0 or WebGL 1.0. + +@section Shaders-FlatGL-instancing Instanced rendering + +Enabling @ref Flag::InstancedTransformation will turn the shader into an +instanced one. It'll take per-instance transformation from the +@ref TransformationMatrix attribute, applying it before the matrix set by +@ref setTransformationProjectionMatrix(). Besides that, @ref Flag::VertexColor +(and the @ref Color3 / @ref Color4) attributes can work as both per-vertex and +per-instance, and for texturing it's possible to have per-instance texture +offset taken from @ref TextureOffset when @ref Flag::InstancedTextureOffset is +enabled (similarly to transformation, applied before @ref setTextureMatrix()). +The snippet below shows adding a buffer with per-instance transformation and +color to a mesh: + +@snippet MagnumShaders-gl.cpp FlatGL-usage-instancing + +@requires_gl33 Extension @gl_extension{ARB,instanced_arrays} +@requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + @gl_extension{EXT,instanced_arrays} or @gl_extension{NV,instanced_arrays} + in OpenGL ES 2.0. +@requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} in WebGL + 1.0. + +@see @ref shaders, @ref FlatGL2D, @ref FlatGL3D +*/ +template class MAGNUM_SHADERS_EXPORT FlatGL: 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::Position Position; + + /** + * @brief 2D texture coordinates + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector2 "Vector2". Used only if @ref Flag::Textured is + * set. + */ + typedef typename GenericGL::TextureCoordinates TextureCoordinates; + + /** + * @brief Three-component vertex color + * @m_since{2019,10} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Color3. Use + * either this or the @ref Color4 attribute. Used only if + * @ref Flag::VertexColor is set. + */ + typedef typename GenericGL::Color3 Color3; + + /** + * @brief Four-component vertex color + * @m_since{2019,10} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Color4. Use + * either this or the @ref Color3 attribute. Used only if + * @ref Flag::VertexColor is set. + */ + typedef typename GenericGL::Color4 Color4; + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief (Instanced) object ID + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt. + * Used only if @ref Flag::InstancedObjectId is set. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. + */ + typedef typename GenericGL::ObjectId ObjectId; + #endif + + /** + * @brief (Instanced) transformation matrix + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Matrix3 in + * 2D, @ref Magnum::Matrix4 in 3D. Used only if + * @ref Flag::InstancedTransformation is set. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + */ + typedef typename GenericGL::TransformationMatrix TransformationMatrix; + + /** + * @brief (Instanced) texture offset + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Vector2. Used + * only if @ref Flag::InstancedTextureOffset is set. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + */ + typedef typename GenericGL::TextureOffset TextureOffset; + + enum: UnsignedInt { + /** + * Color shader output. Present always, expects three- or + * four-component floating-point or normalized buffer attachment. + * @m_since{2019,10} + */ + ColorOutput = GenericGL::ColorOutput, + + #ifndef MAGNUM_TARGET_GLES2 + /** + * Object ID shader output. @ref shaders-generic "Generic output", + * present only if @ref Flag::ObjectId is set. Expects a + * single-component unsigned integral attachment. Writes the value + * set in @ref setObjectId() there, see + * @ref Shaders-FlatGL-object-id for more information. + * @requires_gl30 Extension @gl_extension{EXT,texture_integer} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL + * 1.0. + * @m_since{2019,10} + */ + ObjectIdOutput = GenericGL::ObjectIdOutput + #endif + }; + + #ifdef DOXYGEN_GENERATING_OUTPUT + /** + * @brief Flag + * + * @see @ref Flags, @ref flags() + */ + enum class Flag: UnsignedByte { + /** + * Multiply color with a texture. + * @see @ref setColor(), @ref bindTexture() + */ + Textured = 1 << 0, + + /** + * Enable alpha masking. If the combined fragment color has an + * alpha less than the value specified with @ref setAlphaMask(), + * given fragment is discarded. + * + * This uses the @glsl discard @ce operation which is known to have + * considerable performance impact on some platforms. While useful + * for cheap alpha masking that doesn't require depth sorting, + * with proper depth sorting and blending you'll usually get much + * better performance and output quality. + */ + AlphaMask = 1 << 1, + + /** + * Multiply diffuse color with a vertex color. Requires either + * the @ref Color3 or @ref Color4 attribute to be present. + * @m_since{2019,10} + */ + VertexColor = 1 << 2, + + /** + * Enable texture coordinate transformation. If this flag is set, + * the shader expects that @ref Flag::Textured is enabled as well. + * @see @ref setTextureMatrix() + * @m_since{2020,06} + */ + TextureTransformation = 1 << 3, + + #ifndef MAGNUM_TARGET_GLES2 + /** + * Enable object ID output. See @ref Shaders-FlatGL-object-id for + * more information. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL + * 1.0. + * @m_since{2019,10} + */ + ObjectId = 1 << 4, + + /** + * Instanced object ID. Retrieves a per-instance / per-vertex + * object ID from the @ref ObjectId attribute, outputting a sum of + * the per-vertex ID and ID coming from @ref setObjectId(). + * Implicitly enables @ref Flag::ObjectId. See + * @ref Shaders-FlatGL-object-id for more information. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL + * 1.0. + * @m_since{2020,06} + */ + InstancedObjectId = (1 << 5)|ObjectId, + #endif + + /** + * Instanced transformation. Retrieves a per-instance + * transformation matrix from the @ref TransformationMatrix + * attribute and uses it together with the matrix coming from + * @ref setTransformationProjectionMatrix() (first the + * per-instance, then the uniform matrix). See + * @ref Shaders-FlatGL-instancing for more information. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + * @m_since{2020,06} + */ + InstancedTransformation = 1 << 6, + + /** + * Instanced texture offset. Retrieves a per-instance offset vector + * from the @ref TextureOffset attribute and uses it together with + * the matrix coming from @ref setTextureMatrix() (first the + * per-instance vector, then the uniform matrix). Instanced texture + * scaling and rotation is not supported at the moment, you can + * specify that only via the uniform @ref setTextureMatrix(). + * Implicitly enables @ref Flag::TextureTransformation. See + * @ref Shaders-FlatGL-instancing for more information. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + * @m_since{2020,06} + */ + InstancedTextureOffset = (1 << 7)|TextureTransformation + }; + + /** + * @brief Flags + * + * @see @ref flags() + */ + typedef Containers::EnumSet Flags; + #else + /* Done this way to be prepared for possible future diversion of 2D + and 3D flags (e.g. introducing 3D-specific features) */ + typedef Implementation::FlatGLFlag Flag; + typedef Implementation::FlatGLFlags Flags; + #endif + + /** + * @brief Constructor + * @param flags Flags + */ + explicit FlatGL(Flags flags = {}); + + /** + * @brief Construct without creating the underlying OpenGL object + * + * The constructed instance is equivalent to a moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + * + * This function can be safely used for constructing (and later + * destructing) objects even without any OpenGL context being active. + * However note that this is a low-level and a potentially dangerous + * API, see the documentation of @ref NoCreate for alternatives. + */ + explicit FlatGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {} + + /** @brief Copying is not allowed */ + FlatGL(const FlatGL&) = delete; + + /** @brief Move constructor */ + FlatGL(FlatGL&&) noexcept = default; + + /** @brief Copying is not allowed */ + FlatGL& operator=(const FlatGL&) = delete; + + /** @brief Move assignment */ + FlatGL& operator=(FlatGL&&) noexcept = default; + + /** @brief Flags */ + Flags flags() const { return _flags; } + + /** + * @brief Set transformation and projection matrix + * @return Reference to self (for method chaining) + * + * Initial value is an identity matrix. + */ + FlatGL& setTransformationProjectionMatrix(const MatrixTypeFor& matrix); + + /** + * @brief Set texture coordinate transformation matrix + * @return Reference to self (for method chaining) + * @m_since{2020,06} + * + * Expects that the shader was created with + * @ref Flag::TextureTransformation enabled. Initial value is an + * identity matrix. + */ + FlatGL& setTextureMatrix(const Matrix3& matrix); + + /** + * @brief Set color + * @return Reference to self (for method chaining) + * + * If @ref Flag::Textured is set, initial value is + * @cpp 0xffffffff_rgbaf @ce and the color will be multiplied with the + * texture. + * @see @ref bindTexture() + */ + FlatGL& setColor(const Magnum::Color4& color); + + /** + * @brief Bind a color texture + * @return Reference to self (for method chaining) + * + * Expects that the shader was created with @ref Flag::Textured + * enabled. + * @see @ref setColor(), @ref Flag::TextureTransformation, + * @ref setTextureMatrix() + */ + FlatGL& bindTexture(GL::Texture2D& texture); + + /** + * @brief Set alpha mask value + * @return Reference to self (for method chaining) + * + * Expects that the shader was created with @ref Flag::AlphaMask + * enabled. Fragments with alpha values smaller than the mask value + * will be discarded. Initial value is @cpp 0.5f @ce. See the flag + * documentation for further information. + * + * This corresponds to @m_class{m-doc-external} [glAlphaFunc()](https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glAlphaFunc.xml) + * in classic OpenGL. + * @m_keywords{glAlphaFunc()} + */ + FlatGL& setAlphaMask(Float mask); + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Set object ID + * @return Reference to self (for method chaining) + * + * Expects that the shader was created with @ref Flag::ObjectId + * enabled. Value set here is written to the @ref ObjectIdOutput, see + * @ref Shaders-FlatGL-object-id for more information. Default is + * @cpp 0 @ce. If @ref Flag::InstancedObjectId is enabled as well, this + * value is combined with ID coming from the @ref ObjectId attribute. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. + */ + FlatGL& setObjectId(UnsignedInt id); + #endif + + private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + + Flags _flags; + Int _transformationProjectionMatrixUniform{0}, + _textureMatrixUniform{1}, + _colorUniform{2}, + _alphaMaskUniform{3}; + #ifndef MAGNUM_TARGET_GLES2 + Int _objectIdUniform{4}; + #endif +}; + +/** +@brief 2D flat OpenGL shader +@m_since_latest +*/ +typedef FlatGL<2> FlatGL2D; + +/** +@brief 3D flat OpenGL shader +@m_since_latest +*/ +typedef FlatGL<3> FlatGL3D; + +#ifdef DOXYGEN_GENERATING_OUTPUT +/** @debugoperatorclassenum{FlatGL,FlatGL::Flag} */ +template Debug& operator<<(Debug& debug, FlatGL::Flag value); + +/** @debugoperatorclassenum{FlatGL,FlatGL::Flags} */ +template Debug& operator<<(Debug& debug, FlatGL::Flags value); +#else +namespace Implementation { + MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, FlatGLFlag value); + MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, FlatGLFlags value); + CORRADE_ENUMSET_OPERATORS(FlatGLFlags) +} +#endif + +}} + +#endif diff --git a/src/Magnum/Shaders/Generic.h b/src/Magnum/Shaders/Generic.h index 149e6f5b1..e588298ec 100644 --- a/src/Magnum/Shaders/Generic.h +++ b/src/Magnum/Shaders/Generic.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Shaders_GenericShader_h -#define Magnum_Shaders_GenericShader_h +#ifndef Magnum_Shaders_Generic_h +#define Magnum_Shaders_Generic_h /* This file is part of Magnum. @@ -25,462 +25,32 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef MAGNUM_BUILD_DEPRECATED /** @file - * @brief Struct @ref Magnum::Shaders::Generic, typedef @ref Magnum::Shaders::Generic2D, @ref Magnum::Shaders::Generic3D + * @brief Typedef @ref Magnum::Shaders::Generic, alias @ref Magnum::Shaders::Generic2D, @ref Magnum::Shaders::Generic3D + * @m_deprecated_since_latest Use @ref Magnum/Shaders/GenericGL.h, the + * @ref Magnum::Shaders::GenericGL "GenericGL" class and + * related typedefs instead. */ - -#include "Magnum/GL/Attribute.h" - -namespace Magnum { namespace Shaders { - -/** -@brief Generic shader definition - -Definitions common for majority of shaders in the @ref Shaders namespace, -allowing mesh or a framebuffer configured for a generic shader to be used with -any of them. See @ref shaders-generic for more information. - -@section Shaders-Generic-allocation Attribute allocation - -The attribute locations are allocated like shown below, with various tradeoffs -as GPUs commonly support only 16 attribtes at most, while the mandated minimum -on OpenGL ES2 and WebGL 1 being only 8. Some locations are only reserved for -future use, with no attribute definition implemented yet. - -@m_class{m-row m-container-inflate} - -@parblock - -@m_class{m-fullwidth} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\#AttributeAlternativeAlternative 2
0 -@ref Position -
1 -@ref TextureCoordinates - -* *Reserved* --- third component for a layer -
2 -@ref Color3 / @ref Color4 (per-vertex or instanced) -
3 -@ref Tangent / @ref Tangent4 - -@ref Tangent - -* *Reserved* --- TBN as a @ref Magnum::Quaternion "Quaternion" -
4 -@ref ObjectId (instanced) - -* *Reserved* --- additional components could \n -represent material ID and other indices, which \n -could then be used to fetch additional \n -per-instance properties that wouldn't fit into \n -vertex attributes. - -@ref Bitangent - -Provided only as a convenience for models that \n -don't encode bitangent orientation in the last \n -component of @ref Tangent4. If a model needs \n -both bitangents and object ID for instancing, \n -@ref Tangent4 has to be used. -
5 -@ref Normal -
6 -* *Reserved* --- vertex weights -
7 -* *Reserved* --- bone indices -
8 -@ref TransformationMatrix (instanced) - -* *Reserved* --- instanced @ref Magnum::DualQuaternion "DualQuaternion" \n transformation for positions and normals -
9
10 -* *Reserved* --- 2nd vertex weights -
11 -* *Reserved* --- 2nd bone indices -
12 -@ref NormalMatrix (instanced) - -* *Reserved* --- instanced scale for positions -
13 -* *Reserved* --- instanced texture \n -rotation and scale - -* *Reserved* --- 2nd vertex colors -
14 -* *Reserved* --- 3rd texture coords -
15 -@ref TextureOffset (instanced) - -* *Reserved* --- third component for a layer - -* *Reserved* --- a single component \n -representing instanced texture layer \n -index, UVs being the same always - -* *Reserved* --- 2nd texture coords -
- -@endparblock - -The three alternative allocations can be mixed freely as long as the locations -don't conflict --- so it's possible to have for example a mesh with two sets of -texture coordinates, weights and colors, as each of those occupies a different -attribute range; but instancing then has to be done using smaller types as full -matrices would occupy the locations used by the secondary sets. Additional -guarantees of the above: - -- @ref Tangent, @ref Bitangent and @ref Normal is in consecutive locations to - allow those being passed as a single TBN @ref Magnum::Matrix3x3 "Matrix3x3" - attribute as well. -- @ref Normal and TBN represented as a quaternion use different locations in - order to allow a mesh to contain both -- Similarly, texture rotation/scale and offset is in consecutive locations to - allow passing a single @ref Matrix3 attribute there. -- Tnstanced texture transformation is available if and only if there's - exactly one set of texture coordinates (as the additional sets would need - additional transformations as well). - -@section Shaders-Generic-custom Generic attributes and custom shaders - -Note that while custom shaders don't *have to* follow the above, it's -recommended to so. If the custom shader diverges from predefined locations of -common attributes, meshes configured for the builtin shaders (for example with -@ref MeshTools::compile()) won't work with it and the mesh attribute -configuration has to be done manually. It also becomes impossible to render a -mesh configured for a custom shader with for example @ref MeshVisualizer. - -If you're using @ref GL::AbstractShaderProgram::bindAttributeLocation(), it's -rather easy, as you can simply use the @ref GL::Attribute::Location of given -attribute: - -@snippet MagnumShaders.cpp Generic-custom-bind - -For attribute location defined directly in shader code (which is the -recommended way unless you need compatibility with WebGL 1.0 and OpenGL ES -2.0), the attribute locations can be propagated using a preprocessor define. -For example: - -@snippet MagnumShaders.cpp Generic-custom-preprocessor - -Then, the attribute definition in a shader will look like this: - -@code{.glsl} -layout(location = POSITION_ATTRIBUTE_LOCATION) in vec3 position; -layout(location = NORMAL_ATTRIBUTE_LOCATION) in vec3 normal; -@endcode - -@see @ref shaders, @ref Generic2D, @ref Generic3D -*/ -#ifndef DOXYGEN_GENERATING_OUTPUT -template struct Generic; -#else -template struct Generic { - /* Keep consistent with generic.glsl and the real definitions below */ - - enum: UnsignedInt { - /** - * Color shader output. Present always, expects three- or - * four-component floating-point or normalized buffer attachment. - */ - ColorOutput = 0, - - #ifndef MAGNUM_TARGET_GLES2 - /** - * Object ID shader output. Expects a single-component unsigned - * integral attachment. - * @requires_gl30 Extension @gl_extension{EXT,texture_integer} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. - */ - ObjectIdOutput = 1 - #endif - }; - - /** - * @brief Vertex position - * - * @ref Magnum::Vector2 "Vector2" in 2D and @ref Magnum::Vector3 "Vector3" - * in 3D. Corresponds to @ref Trade::MeshAttribute::Position. - */ - typedef GL::Attribute<0, T> Position; - - /** - * @brief 2D texture coordinates - * - * @ref Magnum::Vector2 "Vector2". Corresponds to - * @ref Trade::MeshAttribute::TextureCoordinates. - */ - typedef GL::Attribute<1, Vector2> TextureCoordinates; - - /** - * @brief Three-component vertex color - * - * @ref Magnum::Color3. Use either this or the @ref Color4 attribute. - * Corresponds to @ref Trade::MeshAttribute::Color. - */ - typedef GL::Attribute<2, Magnum::Color3> Color3; - - /** - * @brief Four-component vertex color - * - * @ref Magnum::Color4. Use either this or the @ref Color3 attribute. - * Corresponds to @ref Trade::MeshAttribute::Color. - */ - typedef GL::Attribute<2, Magnum::Color4> Color4; - - /** - * @brief Vertex tangent - * @m_since{2019,10} - * - * @ref Magnum::Vector3 "Vector3", defined only in 3D. Use either this or - * the @ref Tangent4 attribute. Corresponds to - * @ref Trade::MeshAttribute::Tangent. - */ - typedef GL::Attribute<3, Vector3> Tangent; - - /** - * @brief Vertex tangent with a bitangent sign - * @m_since{2020,06} - * - * @ref Magnum::Vector4 "Vector4", defined only in 3D. The last component - * is a sign value (@cpp -1.0f @ce or @cpp +1.0f @ce) defining handedness - * of the tangent basis. Reconstructing the @ref Bitangent attribute can be - * then done like this: - * - * @snippet MagnumTrade.cpp MeshAttribute-bitangent-from-tangent - * - * Use either this or the @ref Tangent attribute. Corresponds to - * @ref Trade::MeshAttribute::Tangent. - */ - typedef GL::Attribute<3, Vector4> Tangent4; - - /** - * @brief Vertex bitangent - * @m_since{2020,06} - * - * @ref Magnum::Vector3 "Vector3", defined only in 3D. For better storage - * efficiency, the bitangent can be also reconstructed from the normal and - * tangent, see @ref Tangent4 for more information. Corresponds to - * @ref Trade::MeshAttribute::Bitangent. - * - * This attribute conflicts with @ref ObjectId, if you want to use both - * instanced object ID and bitangents, you need to reconstruct them from - * @ref Tangent4 instead. - */ - typedef GL::Attribute<4, Vector3> Bitangent; - - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief (Instanced) object ID - * @m_since{2020,06} - * - * @ref Magnum::UnsignedInt "UnsignedInt". Corresponds to - * @ref Trade::MeshAttribute::ObjectId. - * - * This attribute conflicts with @ref Bitangent, if you want to use both - * instanced object ID and bitangents, you need to reconstruct them from - * @ref Tangent4 instead. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in shaders, - * which is not available in OpenGL ES 2.0 or WebGL 1.0. - */ - typedef GL::Attribute<4, UnsignedInt> ObjectId; - #endif - - /* Index 4 also used by MeshVisualizer::VertexIndex (reusing ObjectId). Not - making it generic yet, as its use case is limited to a single shader, - and even there it's just a fallback for platforms w/o gl_VertexID. */ - - /** - * @brief Vertex normal - * - * @ref Magnum::Vector3 "Vector3", defined only in 3D. Corresponds to - * @ref Trade::MeshAttribute::Normal. - */ - typedef GL::Attribute<5, Vector3> Normal; - - /* 6, 7 reserved for vertex weights / bone IDs */ - - /** - * @brief (Instanced) transformation matrix - * @m_since{2020,06} - * - * @ref Magnum::Matrix3 "Matrix3" in 2D and @ref Magnum::Matrix4 "Matrix4" - * in 3D. Currently doesn't have a corresponding @ref Trade::MeshAttribute. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - */ - typedef GL::Attribute<8, T> TransformationMatrix; - - /* 9, 10, 11 occupied by TransformationMatrix */ - - /** - * @brief (Instanced) normal matrix - * @m_since{2020,06} - * - * @ref Magnum::Matrix3 "Matrix3x3", defined only in 3D. Currently doesn't - * have a corresponding @ref Trade::MeshAttribute. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - */ - typedef GL::Attribute<12, Matrix3x3> NormalMatrix; - - /* 13, 14 occupied by NormalMatrix */ - - /** - * @brief (Instanced) texture offset - * @m_since{2020,06} - * - * @ref Magnum::Vector2 "Vector2". Currently doesn't have a corresponding - * @ref Trade::MeshAttribute. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - */ - typedef GL::Attribute<15, Vector2> TextureOffset; -}; #endif -/** @brief Generic 2D shader definition */ -typedef Generic<2> Generic2D; +#include "Magnum/configure.h" -/** @brief Generic 3D shader definition */ -typedef Generic<3> Generic3D; +#ifdef MAGNUM_BUILD_DEPRECATED +#include -#ifndef DOXYGEN_GENERATING_OUTPUT -struct BaseGeneric { - enum: UnsignedInt { - ColorOutput = 0, - #ifndef MAGNUM_TARGET_GLES2 - ObjectIdOutput = 1 - #endif - }; +#include "Magnum/Shaders/GenericGL.h" - typedef GL::Attribute<1, Vector2> TextureCoordinates; - typedef GL::Attribute<2, Magnum::Color3> Color3; - typedef GL::Attribute<2, Magnum::Color4> Color4; - #ifndef MAGNUM_TARGET_GLES2 - typedef GL::Attribute<4, UnsignedInt> ObjectId; - #endif +CORRADE_DEPRECATED_FILE("use Magnum/Shaders/GenericGL.h, the GenericGL class and related typedefs instead") - typedef GL::Attribute<15, Vector2> TextureOffset; -}; - -template<> struct Generic<2>: BaseGeneric { - typedef GL::Attribute<0, Vector2> Position; - /* 1, 2 used by TextureCoordinates and Color */ - - typedef GL::Attribute<8, Matrix3> TransformationMatrix; - /* 9, 10 occupied by TransformationMatrix */ - /* 15 used by TextureOffset */ -}; - -template<> struct Generic<3>: BaseGeneric { - typedef GL::Attribute<0, Vector3> Position; - /* 1, 2 used by TextureCoordinates and Color */ - typedef GL::Attribute<3, Vector3> Tangent; - typedef GL::Attribute<3, Vector4> Tangent4; - typedef GL::Attribute<4, Vector3> Bitangent; /* also ObjectId */ - typedef GL::Attribute<5, Vector3> Normal; - /* 6, 7 reserved for vertex weights / bone IDs */ - - typedef GL::Attribute<8, Matrix4> TransformationMatrix; - /* 9, 10, 11 occupied by TransformationMatrix */ - typedef GL::Attribute<12, Matrix3x3> NormalMatrix; - /* 13, 14 occupied by NormalMatrix */ - /* 15 used by TextureOffset */ -}; +/* Deprecated aliases not present here but in GenericGL.h instead, as a lot of + existing code relies on these being transitively included from Phong.h etc., + and there are no forward declarations in Shaders.h as the type is never used + like that. While we *could* include Generic.h from Phong.h, we'd have to + also temporarily disable the CORRADE_DEPRECATED_FILE() macro there and it's + more pain than it's worth. */ +#else +#error use Magnum/Shaders/GenericGL.h, the GenericGL class and related typedefs instead #endif -}} - #endif diff --git a/src/Magnum/Shaders/GenericGL.h b/src/Magnum/Shaders/GenericGL.h new file mode 100644 index 000000000..d40318ae3 --- /dev/null +++ b/src/Magnum/Shaders/GenericGL.h @@ -0,0 +1,521 @@ +#ifndef Magnum_Shaders_GenericGL_h +#define Magnum_Shaders_GenericGL_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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 Struct @ref Magnum::Shaders::GenericGL, typedef @ref Magnum::Shaders::GenericGL2D, @ref Magnum::Shaders::GenericGL3D + * @m_since_latest + */ + +#include "Magnum/GL/Attribute.h" +#include "Magnum/Shaders/Shaders.h" + +namespace Magnum { namespace Shaders { + +/** +@brief Generic OpenGL shader definition +@m_since_latest + +Definitions common for majority of OpenGL shaders in the @ref Shaders +namespace, allowing mesh or a framebuffer configured for a generic shader to be +used with any of them. See @ref shaders-generic for more information. + +@section Shaders-GenericGL-allocation Attribute allocation + +The attribute locations are allocated like shown below, with various tradeoffs +as GPUs commonly support only 16 attribtes at most, while the mandated minimum +on OpenGL ES2 and WebGL 1 being only 8. Some locations are only reserved for +future use, with no attribute definition implemented yet. + +@m_class{m-row m-container-inflate} + +@parblock + +@m_class{m-fullwidth} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\#AttributeAlternativeAlternative 2
0 +@ref Position +
1 +@ref TextureCoordinates + +* *Reserved* --- third component for a layer +
2 +@ref Color3 / @ref Color4 (per-vertex or instanced) +
3 +@ref Tangent / @ref Tangent4 + +@ref Tangent + +* *Reserved* --- TBN as a @ref Magnum::Quaternion "Quaternion" +
4 +@ref ObjectId (instanced) + +* *Reserved* --- additional components could \n +represent material ID and other indices, which \n +could then be used to fetch additional \n +per-instance properties that wouldn't fit into \n +vertex attributes. + +@ref Bitangent + +Provided only as a convenience for models that \n +don't encode bitangent orientation in the last \n +component of @ref Tangent4. If a model needs \n +both bitangents and object ID for instancing, \n +@ref Tangent4 has to be used. +
5 +@ref Normal +
6 +* *Reserved* --- vertex weights +
7 +* *Reserved* --- bone indices +
8 +@ref TransformationMatrix (instanced) + +* *Reserved* --- instanced @ref Magnum::DualQuaternion "DualQuaternion" \n transformation for positions and normals +
9
10 +* *Reserved* --- 2nd vertex weights +
11 +* *Reserved* --- 2nd bone indices +
12 +@ref NormalMatrix (instanced) + +* *Reserved* --- instanced scale for positions +
13 +* *Reserved* --- instanced texture \n +rotation and scale + +* *Reserved* --- 2nd vertex colors +
14 +* *Reserved* --- 3rd texture coords +
15 +@ref TextureOffset (instanced) + +* *Reserved* --- third component for a layer + +* *Reserved* --- a single component \n +representing instanced texture layer \n +index, UVs being the same always + +* *Reserved* --- 2nd texture coords +
+ +@endparblock + +The three alternative allocations can be mixed freely as long as the locations +don't conflict --- so it's possible to have for example a mesh with two sets of +texture coordinates, weights and colors, as each of those occupies a different +attribute range; but instancing then has to be done using smaller types as full +matrices would occupy the locations used by the secondary sets. Additional +guarantees of the above: + +- @ref Tangent, @ref Bitangent and @ref Normal is in consecutive locations to + allow those being passed as a single TBN @ref Magnum::Matrix3x3 "Matrix3x3" + attribute as well. +- @ref Normal and TBN represented as a quaternion use different locations in + order to allow a mesh to contain both +- Similarly, texture rotation/scale and offset is in consecutive locations to + allow passing a single @ref Matrix3 attribute there. +- Tnstanced texture transformation is available if and only if there's + exactly one set of texture coordinates (as the additional sets would need + additional transformations as well). + +@section Shaders-GenericGL-custom Generic attributes and custom shaders + +Note that while custom shaders don't *have to* follow the above, it's +recommended to so. If the custom shader diverges from predefined locations of +common attributes, meshes configured for the builtin shaders (for example with +@ref MeshTools::compile()) won't work with it and the mesh attribute +configuration has to be done manually. It also becomes impossible to render a +mesh configured for a custom shader with for example @ref MeshVisualizer. + +If you're using @ref GL::AbstractShaderProgram::bindAttributeLocation(), it's +rather easy, as you can simply use the @ref GL::Attribute::Location of given +attribute: + +@snippet MagnumShaders-gl.cpp GenericGL-custom-bind + +For attribute location defined directly in shader code (which is the +recommended way unless you need compatibility with WebGL 1.0 and OpenGL ES +2.0), the attribute locations can be propagated using a preprocessor define. +For example: + +@snippet MagnumShaders-gl.cpp GenericGL-custom-preprocessor + +Then, the attribute definition in a shader will look like this: + +@code{.glsl} +layout(location = POSITION_ATTRIBUTE_LOCATION) in vec3 position; +layout(location = NORMAL_ATTRIBUTE_LOCATION) in vec3 normal; +@endcode + +@see @ref shaders, @ref GenericGL2D, @ref GenericGL3D +*/ +#ifndef DOXYGEN_GENERATING_OUTPUT +template struct GenericGL; +#else +template struct GenericGL { + /* Keep consistent with generic.glsl and the real definitions below */ + + enum: UnsignedInt { + /** + * Color shader output. Present always, expects three- or + * four-component floating-point or normalized buffer attachment. + */ + ColorOutput = 0, + + #ifndef MAGNUM_TARGET_GLES2 + /** + * Object ID shader output. Expects a single-component unsigned + * integral attachment. + * @requires_gl30 Extension @gl_extension{EXT,texture_integer} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. + */ + ObjectIdOutput = 1 + #endif + }; + + /** + * @brief Vertex position + * + * @ref Magnum::Vector2 "Vector2" in 2D and @ref Magnum::Vector3 "Vector3" + * in 3D. Corresponds to @ref Trade::MeshAttribute::Position. + */ + typedef GL::Attribute<0, T> Position; + + /** + * @brief 2D texture coordinates + * + * @ref Magnum::Vector2 "Vector2". Corresponds to + * @ref Trade::MeshAttribute::TextureCoordinates. + */ + typedef GL::Attribute<1, Vector2> TextureCoordinates; + + /** + * @brief Three-component vertex color + * + * @ref Magnum::Color3. Use either this or the @ref Color4 attribute. + * Corresponds to @ref Trade::MeshAttribute::Color. + */ + typedef GL::Attribute<2, Magnum::Color3> Color3; + + /** + * @brief Four-component vertex color + * + * @ref Magnum::Color4. Use either this or the @ref Color3 attribute. + * Corresponds to @ref Trade::MeshAttribute::Color. + */ + typedef GL::Attribute<2, Magnum::Color4> Color4; + + /** + * @brief Vertex tangent + * @m_since{2019,10} + * + * @ref Magnum::Vector3 "Vector3", defined only in 3D. Use either this or + * the @ref Tangent4 attribute. Corresponds to + * @ref Trade::MeshAttribute::Tangent. + */ + typedef GL::Attribute<3, Vector3> Tangent; + + /** + * @brief Vertex tangent with a bitangent sign + * @m_since{2020,06} + * + * @ref Magnum::Vector4 "Vector4", defined only in 3D. The last component + * is a sign value (@cpp -1.0f @ce or @cpp +1.0f @ce) defining handedness + * of the tangent basis. Reconstructing the @ref Bitangent attribute can be + * then done like this: + * + * @snippet MagnumTrade.cpp MeshAttribute-bitangent-from-tangent + * + * Use either this or the @ref Tangent attribute. Corresponds to + * @ref Trade::MeshAttribute::Tangent. + */ + typedef GL::Attribute<3, Vector4> Tangent4; + + /** + * @brief Vertex bitangent + * @m_since{2020,06} + * + * @ref Magnum::Vector3 "Vector3", defined only in 3D. For better storage + * efficiency, the bitangent can be also reconstructed from the normal and + * tangent, see @ref Tangent4 for more information. Corresponds to + * @ref Trade::MeshAttribute::Bitangent. + * + * This attribute conflicts with @ref ObjectId, if you want to use both + * instanced object ID and bitangents, you need to reconstruct them from + * @ref Tangent4 instead. + */ + typedef GL::Attribute<4, Vector3> Bitangent; + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief (Instanced) object ID + * @m_since{2020,06} + * + * @ref Magnum::UnsignedInt "UnsignedInt". Corresponds to + * @ref Trade::MeshAttribute::ObjectId. + * + * This attribute conflicts with @ref Bitangent, if you want to use both + * instanced object ID and bitangents, you need to reconstruct them from + * @ref Tangent4 instead. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in shaders, + * which is not available in OpenGL ES 2.0 or WebGL 1.0. + */ + typedef GL::Attribute<4, UnsignedInt> ObjectId; + #endif + + /* Index 4 also used by MeshVisualizer::VertexIndex (reusing ObjectId). Not + making it generic yet, as its use case is limited to a single shader, + and even there it's just a fallback for platforms w/o gl_VertexID. */ + + /** + * @brief Vertex normal + * + * @ref Magnum::Vector3 "Vector3", defined only in 3D. Corresponds to + * @ref Trade::MeshAttribute::Normal. + */ + typedef GL::Attribute<5, Vector3> Normal; + + /* 6, 7 reserved for vertex weights / bone IDs */ + + /** + * @brief (Instanced) transformation matrix + * @m_since{2020,06} + * + * @ref Magnum::Matrix3 "Matrix3" in 2D and @ref Magnum::Matrix4 "Matrix4" + * in 3D. Currently doesn't have a corresponding @ref Trade::MeshAttribute. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + */ + typedef GL::Attribute<8, T> TransformationMatrix; + + /* 9, 10, 11 occupied by TransformationMatrix */ + + /** + * @brief (Instanced) normal matrix + * @m_since{2020,06} + * + * @ref Magnum::Matrix3 "Matrix3x3", defined only in 3D. Currently doesn't + * have a corresponding @ref Trade::MeshAttribute. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + */ + typedef GL::Attribute<12, Matrix3x3> NormalMatrix; + + /* 13, 14 occupied by NormalMatrix */ + + /** + * @brief (Instanced) texture offset + * @m_since{2020,06} + * + * @ref Magnum::Vector2 "Vector2". Currently doesn't have a corresponding + * @ref Trade::MeshAttribute. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + */ + typedef GL::Attribute<15, Vector2> TextureOffset; +}; +#endif + +/** +@brief Generic 2D OpenGL shader definition +@m_since_latest +*/ +typedef GenericGL<2> GenericGL2D; + +/** +@brief Generic 3D OpenGL shader definition +@m_since_latest +*/ +typedef GenericGL<3> GenericGL3D; + +#ifndef DOXYGEN_GENERATING_OUTPUT +struct BaseGenericGL { + enum: UnsignedInt { + ColorOutput = 0, + #ifndef MAGNUM_TARGET_GLES2 + ObjectIdOutput = 1 + #endif + }; + + typedef GL::Attribute<1, Vector2> TextureCoordinates; + typedef GL::Attribute<2, Magnum::Color3> Color3; + typedef GL::Attribute<2, Magnum::Color4> Color4; + #ifndef MAGNUM_TARGET_GLES2 + typedef GL::Attribute<4, UnsignedInt> ObjectId; + #endif + + typedef GL::Attribute<15, Vector2> TextureOffset; +}; + +template<> struct GenericGL<2>: BaseGenericGL { + typedef GL::Attribute<0, Vector2> Position; + /* 1, 2 used by TextureCoordinates and Color */ + + typedef GL::Attribute<8, Matrix3> TransformationMatrix; + /* 9, 10 occupied by TransformationMatrix */ + /* 15 used by TextureOffset */ +}; + +template<> struct GenericGL<3>: BaseGenericGL { + typedef GL::Attribute<0, Vector3> Position; + /* 1, 2 used by TextureCoordinates and Color */ + typedef GL::Attribute<3, Vector3> Tangent; + typedef GL::Attribute<3, Vector4> Tangent4; + typedef GL::Attribute<4, Vector3> Bitangent; /* also ObjectId */ + typedef GL::Attribute<5, Vector3> Normal; + /* 6, 7 reserved for vertex weights / bone IDs */ + + typedef GL::Attribute<8, Matrix4> TransformationMatrix; + /* 9, 10, 11 occupied by TransformationMatrix */ + typedef GL::Attribute<12, Matrix3x3> NormalMatrix; + /* 13, 14 occupied by NormalMatrix */ + /* 15 used by TextureOffset */ +}; +#endif + +#ifdef MAGNUM_BUILD_DEPRECATED +/* Deprecated aliases present here instead of GenericGL.h, as a lot of existing + code relies on these being transitively included from Phong.h etc., and + there are no forward declarations in Shaders.h as the type is never used + like that. While we *could* include Generic.h from Phong.h, we'd have to + also temporarily disable the CORRADE_DEPRECATED_FILE() macro there and it's + more pain than it's worth. */ + +/** @brief @copybrief GenericGL + * @m_deprecated_since_latest Use @ref GenericGL instead. + */ +#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Multiple definitions still broken */ +template using Generic CORRADE_DEPRECATED_ALIAS("use GenericGL instead") = GenericGL; +#endif + +/** @brief @copybrief GenericGL2D + * @m_deprecated_since_latest Use @ref GenericGL2D instead. + */ +typedef CORRADE_DEPRECATED("use GenericGL2D instead") GenericGL2D Generic2D; + +/** @brief @copybrief GenericGL3D + * @m_deprecated_since_latest Use @ref GenericGL3D instead. + */ +typedef CORRADE_DEPRECATED("use GenericGL3D instead") GenericGL3D Generic3D; +#endif + +}} + +#endif diff --git a/src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h b/src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h index 2802e4d0b..a96613ab4 100644 --- a/src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h +++ b/src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h @@ -35,7 +35,7 @@ "static symbol not used" warning when using this file for TextureTools */ #if defined(MAGNUM_BUILD_STATIC) && defined(MAGNUM_SHADERS_EXPORT) static void importShaderResources() { - CORRADE_RESOURCE_INITIALIZE(MagnumShaders_RCS) + CORRADE_RESOURCE_INITIALIZE(MagnumShaders_RESOURCES_GL) } #endif diff --git a/src/Magnum/Shaders/MeshVisualizer.h b/src/Magnum/Shaders/MeshVisualizer.h index e66bca3a1..3a725bdef 100644 --- a/src/Magnum/Shaders/MeshVisualizer.h +++ b/src/Magnum/Shaders/MeshVisualizer.h @@ -25,1019 +25,45 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef MAGNUM_BUILD_DEPRECATED /** @file - * @brief Class @ref Magnum::Shaders::MeshVisualizer2D, @ref Magnum::Shaders::MeshVisualizer3D + * @brief Typedef @ref Magnum::Shaders::MeshVisualizer2D, @ref Magnum::Shaders::MeshVisualizer3D + * @m_deprecated_since_latest Use @ref Magnum/Shaders/MeshVisualizerGL.h and + * the @ref Magnum::Shaders::MeshVisualizerGL2D "MeshVisualizerGL2D" / + * @ref Magnum::Shaders::MeshVisualizerGL3D "MeshVisualizerGL3D" class + * instead */ +#endif -#include - -#include "Magnum/DimensionTraits.h" -#include "Magnum/GL/AbstractShaderProgram.h" -#include "Magnum/Shaders/Generic.h" -#include "Magnum/Shaders/visibility.h" - -namespace Magnum { namespace Shaders { - -namespace Implementation { - -class MAGNUM_SHADERS_EXPORT MeshVisualizerBase: public GL::AbstractShaderProgram { - protected: - enum class FlagBase: UnsignedShort { - /* Unlike the public Wireframe flag, this one doesn't include - NoGeometryShader on ES2 as that would make the checks too - complex */ - Wireframe = 1 << 0, - NoGeometryShader = 1 << 1, - #ifndef MAGNUM_TARGET_GLES2 - InstancedObjectId = 1 << 2, - VertexId = 1 << 3, - PrimitiveId = 1 << 4, - PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId - #endif - }; - typedef Containers::EnumSet FlagsBase; - - CORRADE_ENUMSET_FRIEND_OPERATORS(FlagsBase) - - explicit MeshVisualizerBase(FlagsBase flags); - explicit MeshVisualizerBase(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {} - - MAGNUM_SHADERS_LOCAL GL::Version setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs) const; - - MeshVisualizerBase& setColor(const Color4& color); - MeshVisualizerBase& setWireframeColor(const Color4& color); - MeshVisualizerBase& setWireframeWidth(Float width); - #ifndef MAGNUM_TARGET_GLES2 - MeshVisualizerBase& setColorMapTransformation(Float offset, Float scale); - MeshVisualizerBase& bindColorMapTexture(GL::Texture2D& texture); - #endif - - /* Prevent accidentally calling irrelevant functions */ - #ifndef MAGNUM_TARGET_GLES - using GL::AbstractShaderProgram::drawTransformFeedback; - #endif - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - using GL::AbstractShaderProgram::dispatchCompute; - #endif - - FlagsBase _flags; - Int _colorUniform{1}, - _wireframeColorUniform{2}, - _wireframeWidthUniform{3}, - _smoothnessUniform{4}, - _viewportSizeUniform{5}; - #ifndef MAGNUM_TARGET_GLES2 - Int _colorMapOffsetScaleUniform{6}; - #endif -}; - -} - -/** -@brief 2D mesh visualization shader -@m_since{2020,06} - -Visualizes wireframe, per-vertex/per-instance object ID or primitive ID of 2D -meshes. You need to provide the @ref Position attribute in your triangle mesh. -Use @ref setTransformationProjectionMatrix(), @ref setColor() and others to -configure the shader. - -@m_class{m-row} - -@parblock - -@m_div{m-col-m-4 m-col-t-6 m-push-m-2 m-nopadt m-nopadx} -@image html shaders-meshvisualizer2d.png width=256px -@m_enddiv - -@m_div{m-col-m-4 m-col-t-6 m-push-m-2 m-nopadt m-nopadx} -@image html shaders-meshvisualizer2d-primitiveid.png width=256px -@m_enddiv - -@endparblock - -The shader expects that you enable wireframe visualization by passing an -appropriate @ref Flag to the constructor --- there's no default behavior with -nothing enabled. The shader is a 2D variant of @ref MeshVisualizer3D with -mostly identical workflow. See its documentation for more information. -*/ -class MAGNUM_SHADERS_EXPORT MeshVisualizer2D: public Implementation::MeshVisualizerBase { - public: - /** - * @brief Vertex position - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector2 "Vector2". - */ - typedef typename Generic2D::Position Position; - - /** - * @brief Vertex index - * - * See @ref MeshVisualizer3D::VertexIndex for more information. - */ - typedef GL::Attribute<4, Float> VertexIndex; - - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief (Instanced) object ID - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt. - * Used only if @ref Flag::InstancedObjectId is set. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. - */ - typedef Generic3D::ObjectId ObjectId; - #endif - - enum: UnsignedInt { - /** - * Color shader output. @ref shaders-generic "Generic output", - * present always. Expects three- or four-component floating-point - * or normalized buffer attachment. - */ - ColorOutput = Generic2D::ColorOutput - }; - - /** - * @brief Flag - * - * @see @ref Flags, @ref MeshVisualizer2D() - */ - enum class Flag: UnsignedShort { - /** - * Visualize wireframe. On OpenGL ES 2.0 and WebGL this also - * enables @ref Flag::NoGeometryShader. - */ - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - Wireframe = 1 << 0, - #else - Wireframe = (1 << 0) | (1 << 1), - #endif - - /** - * Don't use a geometry shader for wireframe visualization. If - * enabled, you might need to provide also the @ref VertexIndex - * attribute in the mesh. On OpenGL ES 2.0 and WebGL enabled - * alongside @ref Flag::Wireframe. - */ - NoGeometryShader = 1 << 1, - - #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc MeshVisualizer3D::Flag::InstancedObjectId */ - InstancedObjectId = 1 << 2, - - /** @copydoc MeshVisualizer3D::Flag::VertexId */ - VertexId = 1 << 3, - - #ifndef MAGNUM_TARGET_WEBGL - /** @copydoc MeshVisualizer3D::Flag::PrimitiveId */ - PrimitiveId = 1 << 4, - #endif - - /** @copydoc MeshVisualizer3D::Flag::PrimitiveIdFromVertexId */ - #ifndef MAGNUM_TARGET_WEBGL - PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId - #else - PrimitiveIdFromVertexId = (1 << 5)|(1 << 4) - #endif - #endif - }; - - /** @brief Flags */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param flags Flags - * - * At least @ref Flag::Wireframe is expected to be enabled. - */ - explicit MeshVisualizer2D(Flags flags); - - /** - * @brief Construct without creating the underlying OpenGL object - * - * The constructed instance is equivalent to a moved-from state. Useful - * in cases where you will overwrite the instance later anyway. Move - * another object over it to make it useful. - * - * This function can be safely used for constructing (and later - * destructing) objects even without any OpenGL context being active. - * However note that this is a low-level and a potentially dangerous - * API, see the documentation of @ref NoCreate for alternatives. - */ - explicit MeshVisualizer2D(NoCreateT) noexcept: Implementation::MeshVisualizerBase{NoCreate} {} - - /** @brief Copying is not allowed */ - MeshVisualizer2D(const MeshVisualizer2D&) = delete; - - /** @brief Move constructor */ - MeshVisualizer2D(MeshVisualizer2D&&) noexcept = default; - - /** @brief Copying is not allowed */ - MeshVisualizer2D& operator=(const MeshVisualizer2D&) = delete; - - /** @brief Move assignment */ - MeshVisualizer2D& operator=(MeshVisualizer2D&&) noexcept = default; - - /** @brief Flags */ - Flags flags() const { - return Flag(UnsignedShort(Implementation::MeshVisualizerBase::_flags)); - } - - /** - * @brief Set transformation and projection matrix - * @return Reference to self (for method chaining) - * - * Initial value is an identity matrix. - */ - MeshVisualizer2D& setTransformationProjectionMatrix(const Matrix3& matrix); - - /** - * @brief Set viewport size - * @return Reference to self (for method chaining) - * - * Has effect only if @ref Flag::Wireframe is enabled and geometry - * shaders are used, otherwise it does nothing. Initial value is a zero - * vector. - */ - MeshVisualizer2D& setViewportSize(const Vector2& size); - - /** - * @brief Set base object color - * @return Reference to self (for method chaining) - * - * Initial value is @cpp 0xffffffff_rgbaf @ce. Expects that either - * @ref Flag::Wireframe or @ref Flag::InstancedObjectId / - * @ref Flag::PrimitiveId is enabled. In case of the latter, the color - * is multiplied with the color map coming from - * @ref bindColorMapTexture(). - */ - MeshVisualizer2D& setColor(const Color4& color) { - return static_cast(Implementation::MeshVisualizerBase::setColor(color)); - } - - /** - * @brief Set wireframe color - * @return Reference to self (for method chaining) - * - * Initial value is @cpp 0x000000ff_rgbaf @ce. Expects that - * @ref Flag::Wireframe is enabled. - */ - MeshVisualizer2D& setWireframeColor(const Color4& color) { - return static_cast(Implementation::MeshVisualizerBase::setWireframeColor(color)); - } - - /** - * @brief Set wireframe width - * @return Reference to self (for method chaining) - * - * Value is in screen space (depending on @ref setViewportSize()), - * initial value is @cpp 1.0f @ce. Expects that @ref Flag::Wireframe is - * enabled. - */ - MeshVisualizer2D& setWireframeWidth(Float width) { - return static_cast(Implementation::MeshVisualizerBase::setWireframeWidth(width)); - } - - #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc MeshVisualizer3D::setColorMapTransformation() */ - MeshVisualizer2D& setColorMapTransformation(Float offset, Float scale) { - return static_cast(Implementation::MeshVisualizerBase::setColorMapTransformation(offset, scale)); - } - - /** @copydoc MeshVisualizer3D::bindColorMapTexture() */ - MeshVisualizer2D& bindColorMapTexture(GL::Texture2D& texture) { - return static_cast(Implementation::MeshVisualizerBase::bindColorMapTexture(texture)); - } - #endif - - /** - * @brief Set line smoothness - * @return Reference to self (for method chaining) - * - * Value is in screen space (depending on @ref setViewportSize()), - * initial value is @cpp 2.0f @ce. Expects that @ref Flag::Wireframe is - * enabled. - */ - MeshVisualizer2D& setSmoothness(Float smoothness); - - private: - Int _transformationProjectionMatrixUniform{0}; -}; - -/** -@brief 3D mesh visualization shader - -Visualizes wireframe, per-vertex/per-instance object ID, primitive ID or -tangent space of 3D meshes. You need to provide the @ref Position attribute in -your triangle mesh at the very least. Use @ref setTransformationProjectionMatrix(), -@ref setColor() and others to configure the shader. - -@m_class{m-row} - -@parblock - -@m_div{m-col-m-4 m-col-t-6 m-push-m-2 m-text-center m-nopadt m-nopadx} -@image html shaders-meshvisualizer3d.png width=256px -@ref Shaders-MeshVisualizer-wireframe, \n -@ref Shaders-MeshVisualizer-tbn -@m_enddiv - -@m_div{m-col-m-4 m-col-t-6 m-push-m-2 m-text-center m-nopadt m-nopadx} -@image html shaders-meshvisualizer3d-primitiveid.png width=256px -@ref Shaders-MeshVisualizer-object-id -@m_enddiv - -@endparblock - -The shader expects that you enable wireframe visualization, tangent space -visualization or object/primitive ID visualization by passing an appropriate -@ref Flag to the constructor --- there's no default behavior with nothing -enabled. - -@section Shaders-MeshVisualizer-wireframe Wireframe visualization - -Wireframe visualization is done by enabling @ref Flag::Wireframe. It is done -either using geometry shaders or with help of additional vertex information. If -you have geometry shaders available, you don't need to do anything else except -calling @ref setViewportSize() to correctly size the wireframe --- without -this, the mesh will be rendered in a single color. - -@requires_gl32 Extension @gl_extension{ARB,geometry_shader4} for wireframe - rendering using geometry shaders. -@requires_es_extension Extension @gl_extension{EXT,geometry_shader} for - wireframe rendering using geometry shaders. - -If you don't have geometry shaders, you need to enable @ref Flag::NoGeometryShader -(done by default in OpenGL ES 2.0) and use only **non-indexed** triangle meshes -(see @ref MeshTools::duplicate() for a possible solution). Additionaly, if you -have OpenGL < 3.1 or OpenGL ES 2.0, you need to provide also the -@ref VertexIndex attribute. - -@requires_gles30 Extension @gl_extension{OES,standard_derivatives} for - wireframe rendering without geometry shaders. - -If using geometry shaders on OpenGL ES, @gl_extension{NV,shader_noperspective_interpolation} -is optionally used for improving line appearance. On desktop OpenGL this is -done implicitly. - -If you want to render just the wireframe on top of an existing mesh, call -@ref setColor() with @cpp 0x00000000_rgbaf @ce. Alpha / transparency is -supported by the shader implicitly, but to have it working on the framebuffer, -you need to enable @ref GL::Renderer::Feature::Blending and set up the blending -function. See @ref GL::Renderer::setBlendFunction() for details. - -@subsection Shaders-MeshVisualizer-wireframe-geom Example setup with a geometry shader (desktop GL, OpenGL ES 3.2) - -Common mesh setup: - -@snippet MagnumShaders.cpp MeshVisualizer-usage-geom1 - -Common rendering setup: - -@snippet MagnumShaders.cpp MeshVisualizer-usage-geom2 - -@subsection Shaders-MeshVisualizer-wireframe-no-geom Example setup for indexed meshes without a geometry shader - -The vertices have to be converted to a non-indexed array first. Mesh setup: - -@snippet MagnumShaders.cpp MeshVisualizer-usage-no-geom1 - -Rendering setup: - -@snippet MagnumShaders.cpp MeshVisualizer-usage-no-geom2 - -@subsection Shaders-MeshVisualizer-usage-wireframe-no-geom-old Wireframe visualization of non-indexed meshes without a geometry shader on older hardware - -You need to provide also the @ref VertexIndex attribute. Mesh setup *in -addition to the above*: - -@snippet MagnumShaders.cpp MeshVisualizer-usage-no-geom-old - -Rendering setup the same as above. - -@section Shaders-MeshVisualizer-tbn Tangent space visualization - -On platforms with geometry shaders (desktop GL, OpenGL ES 3.2), the shader is -able to visualize tangents, bitangent and normal direction via colored lines -coming out of vertices (red, green and blue for tangent, bitangent and normal, respectively). This can be enabled together with wireframe visualization, -however note that when both are enabled, the lines are not antialiased to avoid -depth ordering artifacts. - -For tangents and normals, you need to provide the @ref Tangent and @ref Normal -attributes and enable @ref Flag::TangentDirection and -@ref Flag::NormalDirection, respectively. If any of the attributes isn't -present, its data are implicitly zero and thus the direction isn't shown --- -which means you don't need to worry about having two active variants of the -shader and switching between either depending on whether tangents are present -or not. - -For bitangents however, there are two possible representations --- the more -efficient one is via a fourth component in the tangent attribute that -indicates tangent space handedness, in which case you'll be using the -@ref Tangent4 attribute instead of @ref Tangent, and enable -@ref Flag::BitangentFromTangentDirection. The other, more obvious but less -efficient representation, is a dedicated @ref Bitangent attribute (in which -case you'll enable @ref Flag::BitangentDirection). Note that these two are -mutually exclusive, so you need to choose either of them based on what given -mesh contains. Example for the first case: - -@snippet MagnumShaders.cpp MeshVisualizer-usage-tbn1 - -Rendering setup: - -@snippet MagnumShaders.cpp MeshVisualizer-usage-tbn2 - -@section Shaders-MeshVisualizer-object-id Object, vertex and primitive ID visualization - -If the mesh contains a per-vertex (or instanced) @ref ObjectId, it can be -visualized by enabling @ref Flag::InstancedObjectId. For the actual -visualization you need to provide a color map using @ref bindColorMapTexture() -and use @ref setColorMapTransformation() to map given range of discrete IDs to -the @f$ [0, 1] @f$ texture range. Various colormap presets are in the -@ref DebugTools::ColorMap namespace. Example usage: - -@snippet MagnumShaders.cpp MeshVisualizer-usage-object-id - -If you enable @ref Flag::VertexId, the shader will use the color map to -visualize how are vertices shared among primitives. That's useful for -inspecting mesh connectivity --- primitives sharing vertices will have a smooth -color map transition while duplicated vertices will cause a sharp edge. This -relies on the @glsl gl_VertexID @ce GLSL builtin. - -The @ref Flag::PrimitiveId then visualizes the order in which primitives are -drawn. That's useful for example to see to see how well is the mesh optimized -for a post-transform vertex cache. This by default relies on the @glsl gl_PrimitiveID @ce GLSL builtin; with @ref Flag::PrimitiveIdFromVertexId it's -emulated using @glsl gl_VertexID @ce, expecting you to draw a non-indexed -triangle mesh. You can use @ref MeshTools::duplicate() (and potentially -@ref MeshTools::generateIndices()) to conveniently convert the mesh to a -non-indexed @ref MeshPrimitive::Triangles. - -@requires_gl32 The `gl_PrimitiveID` shader variable is not available on OpenGL - 3.1 and lower. -@requires_gl30 The `gl_VertexID` shader variable is not available on OpenGL - 2.1. -@requires_gles32 The `gl_PrimitiveID` shader variable is not available on - OpenGL ES 3.1 and lower. -@requires_gles30 The `gl_VertexID` shader variable is not available on OpenGL - ES 2.0. -@requires_gles `gl_PrimitiveID` is not available in WebGL. -@requires_webgl20 `gl_VertexID` is not available in WebGL 1.0. - -@see @ref shaders, @ref MeshVisualizer2D -@todo Understand and add support wireframe width/smoothness without GS -*/ -class MAGNUM_SHADERS_EXPORT MeshVisualizer3D: public Implementation::MeshVisualizerBase { - public: - /** - * @brief Vertex position - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector3 "Vector3". - */ - typedef typename Generic3D::Position Position; - - /** - * @brief Tangent direction - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector3 "Vector3". Use either this or the @ref Tangent4 - * attribute. Used only if @ref Flag::TangentDirection is enabled. - */ - typedef typename Generic3D::Tangent Tangent; - - /** - * @brief Tangent direction with a bitangent sign - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector4 "Vector4". Use either this or the @ref Tangent - * attribute. Used only if @ref Flag::TangentDirection or - * @ref Flag::BitangentFromTangentDirection is enabled. - */ - typedef typename Generic3D::Tangent4 Tangent4; - - /** - * @brief Bitangent direction - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector3 "Vector3". Use either this or the @ref Tangent4 - * attribute. Used only if @ref Flag::BitangentDirection is enabled. - */ - typedef typename Generic3D::Bitangent Bitangent; - - /** - * @brief Normal direction - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector3 "Vector3". Used only if - * @ref Flag::NormalDirection is enabled. - */ - typedef typename Generic3D::Normal Normal; - - /** - * @brief Vertex index - * - * @ref Magnum::Float "Float", used only in OpenGL < 3.1 and OpenGL ES - * 2.0 if @ref Flag::Wireframe is enabled. This attribute (modulo 3) - * specifies index of given vertex in triangle, i.e. @cpp 0.0f @ce for - * first, @cpp 1.0f @ce for second, @cpp 2.0f @ce for third. In OpenGL - * 3.1, OpenGL ES 3.0 and newer this value is provided via the - * @cb{.glsl} gl_VertexID @ce shader builtin, so the attribute is not - * needed. - * - * @note This attribute uses the same slot as @ref Generic::ObjectId, - * but since Object ID is available only on ES3+ and vertex index - * is used only on ES2 contexts without @glsl gl_VertexID @ce, - * there should be no conflict between these two. - */ - typedef GL::Attribute<4, Float> VertexIndex; - - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief (Instanced) object ID - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt. - * Used only if @ref Flag::InstancedObjectId is set. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. - */ - typedef Generic3D::ObjectId ObjectId; - #endif - - enum: UnsignedInt { - /** - * Color shader output. @ref shaders-generic "Generic output", - * present always. Expects three- or four-component floating-point - * or normalized buffer attachment. - */ - ColorOutput = Generic3D::ColorOutput - }; - - /** - * @brief Flag - * - * @see @ref Flags, @ref MeshVisualizer() - */ - enum class Flag: UnsignedShort { - /** - * Visualize wireframe. On OpenGL ES 2.0 and WebGL this also - * enables @ref Flag::NoGeometryShader. - */ - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - Wireframe = 1 << 0, - #else - Wireframe = (1 << 0) | (1 << 1), - #endif - - /** - * Don't use a geometry shader for wireframe visualization. If - * enabled, you might need to provide also the @ref VertexIndex - * attribute in the mesh. On OpenGL ES 2.0 and WebGL enabled - * alongside @ref Flag::Wireframe. - * - * Mutually exclusive with @ref Flag::TangentDirection, - * @ref Flag::BitangentFromTangentDirection, - * @ref Flag::BitangentDirection and @ref Flag::NormalDirection --- - * those need a geometry shader always. - */ - NoGeometryShader = 1 << 1, - - #ifndef MAGNUM_TARGET_GLES2 - /** - * Visualize instanced object ID. You need to provide the - * @ref ObjectId attribute in the mesh. Mutually exclusive with - * @ref Flag::VertexId and @ref Flag::PrimitiveId. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL - * 1.0. - * @m_since{2020,06} - */ - InstancedObjectId = 1 << 2, - - /** - * Visualize vertex ID (@cpp gl_VertexID @ce). Useful for - * visualizing mesh connectivity --- primitives sharing vertices - * will have a smooth color map transition while duplicated - * vertices will cause a sharp edge. Mutually exclusive with - * @ref Flag::InstancedObjectId and @ref Flag::PrimitiveId. - * @requires_gl30 The `gl_VertexID` shader variable is not - * available on OpenGL 2.1. - * @requires_gles30 The `gl_VertexID` shader variable is not - * available on OpenGL ES 2.0. - * @requires_webgl20 `gl_VertexID` is not available in WebGL 1.0. - * @m_since{2020,06} - */ - VertexId = 1 << 3, - - #ifndef MAGNUM_TARGET_WEBGL - /** - * Visualize primitive ID (@cpp gl_PrimitiveID @ce). Useful for - * visualizing how well is the mesh optimized for a post-transform - * vertex cache. Mutually exclusive with - * @ref Flag::InstancedObjectId and @ref Flag::VertexId. See also - * @ref Flag::PrimitiveIdFromVertexId. - * @requires_gl32 The `gl_PrimitiveID` shader variable is not - * available on OpenGL 3.1 and lower. - * @requires_gles30 Not defined in OpenGL ES 2.0. - * @requires_gles32 The `gl_PrimitiveID` shader variable is not - * available on OpenGL ES 3.1 and lower. - * @requires_gles `gl_PrimitiveID` is not available in WebGL. - * @m_since{2020,06} - */ - PrimitiveId = 1 << 4, - #endif - - /** - * Visualize primitive ID on a non-indexed triangle mesh using - * @cpp gl_VertexID/3 @ce. Implicitly enables - * @ref Flag::PrimitiveId, mutually exclusive with - * @ref Flag::InstancedObjectId. Usable on OpenGL < 3.2, - * OpenGL ES < 3.2 and WebGL where @cpp gl_PrimitiveID @ce is not - * available. - * @requires_gl30 The `gl_VertexID` shader variable is not - * available on OpenGL 2.1. - * @requires_gles30 The `gl_VertexID` shader variable is not - * available on OpenGL ES 2.0. - * @requires_webgl20 `gl_VertexID` is not available in WebGL 1.0. - * @m_since{2020,06} - */ - #ifndef MAGNUM_TARGET_WEBGL - PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId, - #else - PrimitiveIdFromVertexId = (1 << 5)|(1 << 4), - #endif - #endif - - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - /** - * Visualize tangent direction with red lines pointing out of - * vertices. You need to provide the @ref Tangent or @ref Tangent4 - * attribute in the mesh. Mutually exclusive with - * @ref Flag::NoGeometryShader (as this needs a geometry shader - * always). - * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} - * @requires_gles30 Not defined in OpenGL ES 2.0. - * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / - * @gl_extension{EXT,geometry_shader} - * @requires_gles Geometry shaders are not available in WebGL. - * @m_since{2020,06} - */ - TangentDirection = 1 << 6, - - /** - * Visualize bitangent direction with green lines pointing out of - * vertices. You need to provide both @ref Normal and @ref Tangent4 - * attributes in the mesh, alternatively you can provide the - * @ref Bitangent attribute and enable - * @ref Flag::BitangentDirection instead. Mutually exclusive with - * @ref Flag::NoGeometryShader (as this needs a geometry shader - * always). - * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} - * @requires_gles30 Not defined in OpenGL ES 2.0. - * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / - * @gl_extension{EXT,geometry_shader} - * @requires_gles Geometry shaders are not available in WebGL. - * @m_since{2020,06} - */ - BitangentFromTangentDirection = 1 << 7, - - /** - * Visualize bitangent direction with green lines pointing out of - * vertices. You need to provide the @ref Bitangent attribute in - * the mesh, alternatively you can provide both @ref Normal and - * @ref Tangent4 attributes and enable - * @ref Flag::BitangentFromTangentDirection instead. Mutually - * exclusive with @ref Flag::NoGeometryShader (as this needs a - * geometry shader always). - * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} - * @requires_gles30 Not defined in OpenGL ES 2.0. - * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / - * @gl_extension{EXT,geometry_shader} - * @requires_gles Geometry shaders are not available in WebGL. - * @m_since{2020,06} - */ - BitangentDirection = 1 << 8, - - /** - * Visualize normal direction with blue lines pointing out of - * vertices. You need to provide the @ref Normal attribute in the - * mesh. Mutually exclusive with @ref Flag::NoGeometryShader (as - * this needs a geometry shader always). - * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} - * @requires_gles30 Not defined in OpenGL ES 2.0. - * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / - * @gl_extension{EXT,geometry_shader} - * @requires_gles Geometry shaders are not available in WebGL. - * @m_since{2020,06} - */ - NormalDirection = 1 << 9 - #endif - }; - - /** @brief Flags */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param flags Flags - * - * At least @ref Flag::Wireframe or one of @ref Flag::TangentDirection, - * @ref Flag::BitangentFromTangentDirection, - * @ref Flag::BitangentDirection, @ref Flag::NormalDirection is - * expected to be enabled. - */ - explicit MeshVisualizer3D(Flags flags); - - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @brief Constructor - * @m_deprecated_since{2020,06} Use @ref MeshVisualizer3D(Flags) instead. - */ - explicit CORRADE_DEPRECATED("use MeshVisualizer3D(Flags) instead") MeshVisualizer3D(): MeshVisualizer3D{{}} {} - #endif - - /** - * @brief Construct without creating the underlying OpenGL object - * - * The constructed instance is equivalent to a moved-from state. Useful - * in cases where you will overwrite the instance later anyway. Move - * another object over it to make it useful. - * - * This function can be safely used for constructing (and later - * destructing) objects even without any OpenGL context being active. - * However note that this is a low-level and a potentially dangerous - * API, see the documentation of @ref NoCreate for alternatives. - */ - explicit MeshVisualizer3D(NoCreateT) noexcept: Implementation::MeshVisualizerBase{NoCreate} {} - - /** @brief Copying is not allowed */ - MeshVisualizer3D(const MeshVisualizer3D&) = delete; - - /** @brief Move constructor */ - MeshVisualizer3D(MeshVisualizer3D&&) noexcept = default; - - /** @brief Copying is not allowed */ - MeshVisualizer3D& operator=(const MeshVisualizer3D&) = delete; - - /** @brief Move assignment */ - MeshVisualizer3D& operator=(MeshVisualizer3D&&) noexcept = default; - - /** @brief Flags */ - Flags flags() const { - return Flag(UnsignedShort(Implementation::MeshVisualizerBase::_flags)); - } - - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @brief Set transformation and projection matrix - * @m_deprecated_since{2020,06} Use @ref setTransformationMatrix() and - * @ref setProjectionMatrix() instead. - */ - CORRADE_DEPRECATED("use setTransformationMatrix() and setProjectionMatrix() instead") MeshVisualizer3D& setTransformationProjectionMatrix(const Matrix4& matrix) { - /* Keep projection at identity, which should still work for - wireframe (but of course not for TBN visualization) */ - return setTransformationMatrix(matrix); - } - #endif - - /** - * @brief Set transformation matrix - * @return Reference to self (for method chaining) - * - * Initial value is an identity matrix. - */ - MeshVisualizer3D& setTransformationMatrix(const Matrix4& matrix); - - /** - * @brief Set projection matrix - * @return Reference to self (for method chaining) - * - * Initial value is an identity matrix. (i.e., an orthographic - * projection of the default @f$ [ -\boldsymbol{1} ; \boldsymbol{1} ] @f$ - * cube). - */ - MeshVisualizer3D& setProjectionMatrix(const Matrix4& matrix); - - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - /** - * @brief Set transformation matrix - * @return Reference to self (for method chaining) - * @m_since{2020,06} - * - * Expects that @ref Flag::TangentDirection, - * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is - * enabled. The matrix doesn't need to be normalized, as - * renormalization is done per-fragment anyway. - * Initial value is an identity matrix. - * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} - * @requires_gles30 Not defined in OpenGL ES 2.0. - * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / - * @gl_extension{EXT,geometry_shader} - * @requires_gles Geometry shaders are not available in WebGL. - */ - MeshVisualizer3D& setNormalMatrix(const Matrix3x3& matrix); - #endif - - /** - * @brief Set viewport size - * @return Reference to self (for method chaining) - * - * Has effect only if @ref Flag::Wireframe is enabled and geometry - * shaders are used; or if @ref Flag::TangentDirection, - * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is - * enabled, otherwise it does nothing. Initial value is a zero vector. - */ - MeshVisualizer3D& setViewportSize(const Vector2& size); - - /** - * @brief Set base object color - * @return Reference to self (for method chaining) - * - * Initial value is @cpp 0xffffffff_rgbaf @ce. Expects that either - * @ref Flag::Wireframe or @ref Flag::InstancedObjectId / - * @ref Flag::PrimitiveId is enabled. In case of the latter, the color - * is multiplied with the color map coming from - * @ref bindColorMapTexture(). - */ - MeshVisualizer3D& setColor(const Color4& color) { - return static_cast(Implementation::MeshVisualizerBase::setColor(color)); - } - - /** - * @brief Set wireframe color - * @return Reference to self (for method chaining) - * - * Initial value is @cpp 0x000000ff_rgbaf @ce. Expects that - * @ref Flag::Wireframe is enabled. - */ - MeshVisualizer3D& setWireframeColor(const Color4& color) { - return static_cast(Implementation::MeshVisualizerBase::setWireframeColor(color)); - } - - /** - * @brief Set wireframe width - * @return Reference to self (for method chaining) - * - * Value is in screen space (depending on @ref setViewportSize()), - * initial value is @cpp 1.0f @ce. Expects that @ref Flag::Wireframe is - * enabled. - */ - MeshVisualizer3D& setWireframeWidth(Float width) { - return static_cast(Implementation::MeshVisualizerBase::setWireframeWidth(width)); - } - - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief Set color map transformation - * @return Reference to self (for method chaining) - * @m_since{2020,06} - * - * Offset and scale applied to the input value coming either from the - * @ref ObjectId attribute or @glsl gl_PrimitiveID @ce, resulting value - * is then used to fetch a color from a color map bound with - * @ref bindColorMapTexture(). Initial value is @cpp 1.0f/512.0f @ce - * and @cpp 1.0/256.0f @ce, meaning that for a 256-entry colormap the - * first 256 values get an exact color from it and the next values will - * be either clamped to last color or repeated depending on the color - * map texture wrapping mode. Expects that either - * @ref Flag::InstancedObjectId or @ref Flag::PrimitiveId / - * @ref Flag::PrimitiveIdFromVertexId is enabled. - * - * Note that this shader doesn't directly offer a - * @ref Flat::setObjectId() "setObjectId()" uniform that's used to - * offset the per-vertex / per-instance ID. Instead, you need to encode - * the base offset into the @p offset parameter. - * @requires_gles30 Object ID visualization requires integer attributes - * while primitive ID visualization requires the `gl_VertexID` / - * `gl_PrimitiveID` builtins, neither of which is available in - * OpenGL ES 2.0. - * @requires_webgl20 Object ID visualization requires integer - * attributes while primitive ID visualization requires at least - * the `gl_VertexID` builtin, neither of which is available in - * WebGL 1. - */ - MeshVisualizer3D& setColorMapTransformation(Float offset, Float scale) { - return static_cast(Implementation::MeshVisualizerBase::setColorMapTransformation(offset, scale)); - } - - /** - * @brief Bind a color map texture - * @return Reference to self (for method chaining) - * @m_since{2020,06} - * - * See also @ref setColorMapTransformation(). Expects that either - * @ref Flag::InstancedObjectId or @ref Flag::PrimitiveId / - * @ref Flag::PrimitiveIdFromVertexId is enabled. - * @requires_gles30 Object ID visualization requires integer attributes - * while primitive ID visualization requires the `gl_VertexID` / - * `gl_PrimitiveID` builtins, neither of which is available in - * OpenGL ES 2.0. - * @requires_webgl20 Object ID visualization requires integer - * attributes while primitive ID visualization requires at least - * the `gl_VertexID` builtin, neither of which is available in - * WebGL 1. - */ - MeshVisualizer3D& bindColorMapTexture(GL::Texture2D& texture) { - return static_cast(Implementation::MeshVisualizerBase::bindColorMapTexture(texture)); - } - #endif - - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - /** - * @brief Set line width - * @return Reference to self (for method chaining) - * @m_since{2020,06} - * - * Value is in screen space (depending on @ref setViewportSize()), - * initial value is @cpp 1.0f @ce. Expects that - * @ref Flag::TangentDirection, - * @ref Flag::BitangentFromTangentDirection, - * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is - * enabled. - * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} - * @requires_gles30 Not defined in OpenGL ES 2.0. - * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / - * @gl_extension{EXT,geometry_shader} - * @requires_gles Geometry shaders are not available in WebGL. - */ - MeshVisualizer3D& setLineWidth(Float width); - - /** - * @brief Set line length - * @return Reference to self (for method chaining) - * @m_since{2020,06} - * - * Value is in object space, initial value is @cpp 1.0f @ce. Expects - * that @ref Flag::TangentDirection, - * @ref Flag::BitangentFromTangentDirection, - * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is - * enabled. - * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} - * @requires_gles30 Not defined in OpenGL ES 2.0. - * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / - * @gl_extension{EXT,geometry_shader} - * @requires_gles Geometry shaders are not available in WebGL. - */ - MeshVisualizer3D& setLineLength(Float length); - #endif - - /** - * @brief Set line smoothness - * @return Reference to self (for method chaining) - * - * Value is in screen space (depending on @ref setViewportSize()), - * initial value is @cpp 2.0f @ce. Expects that @ref Flag::Wireframe, - * @ref Flag::TangentDirection, - * @ref Flag::BitangentFromTangentDirection, - * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is - * enabled. - */ - MeshVisualizer3D& setSmoothness(Float smoothness); - - private: - Int _transformationMatrixUniform{0}, - _projectionMatrixUniform{7}; - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - Int _normalMatrixUniform{8}, - _lineWidthUniform{9}, - _lineLengthUniform{10}; - #endif -}; +#include "Magnum/configure.h" #ifdef MAGNUM_BUILD_DEPRECATED -/** -@brief 3D mesh visualizer shader -@m_deprecated_since{2020,06} Use @ref MeshVisualizer3D instead. -*/ -typedef CORRADE_DEPRECATED("use MeshVisualizer3D instead") MeshVisualizer3D MeshVisualizer; -#endif +#include -/** @debugoperatorclassenum{MeshVisualizer2D,MeshVisualizer2D::Flag} */ -MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizer2D::Flag value); +#include "Magnum/Shaders/MeshVisualizerGL.h" -/** @debugoperatorclassenum{MeshVisualizer3D,MeshVisualizer3D::Flag} */ -MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizer3D::Flag value); +CORRADE_DEPRECATED_FILE("use Magnum/Shaders/MeshVisualizerGL.h and the MeshVisualizerGL2D / MeshVisualizer3D class instead") + +namespace Magnum { namespace Shaders { -/** @debugoperatorclassenum{MeshVisualizer2D,MeshVisualizer2D::Flags} */ -MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizer2D::Flags value); +/** @brief @copybrief MeshVisualizerGL2D + * @m_deprecated_since_latest Use @ref MeshVisualizerGL2D instead. + */ +typedef CORRADE_DEPRECATED("use MeshVisualizerGL2D instead") MeshVisualizerGL2D MeshVisualizer2D; -/** @debugoperatorclassenum{MeshVisualizer3D,MeshVisualizer3D::Flags} */ -MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizer3D::Flags value); +/** @brief @copybrief MeshVisualizerGL3D + * @m_deprecated_since_latest Use @ref MeshVisualizerGL3D instead. + */ +typedef CORRADE_DEPRECATED("use MeshVisualizerGL3D instead") MeshVisualizerGL3D MeshVisualizer3D; -CORRADE_ENUMSET_OPERATORS(MeshVisualizer2D::Flags) -CORRADE_ENUMSET_OPERATORS(MeshVisualizer3D::Flags) +/** @brief @copybrief MeshVisualizerGL3D + * @m_deprecated_since{2020,06} Use @ref MeshVisualizerGL3D instead. + */ +typedef CORRADE_DEPRECATED("use MeshVisualizerGL3D instead") MeshVisualizerGL3D MeshVisualizer; }} +#else +#error use Magnum/Shaders/MeshVisualizerGL.h and the MeshVisualizerGL2D / MeshVisualizer3D class instead +#endif #endif diff --git a/src/Magnum/Shaders/MeshVisualizer.cpp b/src/Magnum/Shaders/MeshVisualizerGL.cpp similarity index 83% rename from src/Magnum/Shaders/MeshVisualizer.cpp rename to src/Magnum/Shaders/MeshVisualizerGL.cpp index f02e055bf..2319626f5 100644 --- a/src/Magnum/Shaders/MeshVisualizer.cpp +++ b/src/Magnum/Shaders/MeshVisualizerGL.cpp @@ -23,7 +23,7 @@ DEALINGS IN THE SOFTWARE. */ -#include "MeshVisualizer.h" +#include "MeshVisualizerGL.h" #include #include @@ -52,7 +52,7 @@ namespace { namespace Implementation { -MeshVisualizerBase::MeshVisualizerBase(FlagsBase flags): _flags{flags} { +MeshVisualizerGLBase::MeshVisualizerGLBase(FlagsBase flags): _flags{flags} { #ifndef MAGNUM_TARGET_GLES2 #ifndef CORRADE_NO_ASSERT Int countMutuallyExclusive = 0; @@ -61,7 +61,7 @@ MeshVisualizerBase::MeshVisualizerBase(FlagsBase flags): _flags{flags} { if(flags & FlagBase::PrimitiveIdFromVertexId) ++countMutuallyExclusive; #endif CORRADE_ASSERT(countMutuallyExclusive <= 1, - "Shaders::MeshVisualizer: Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive", ); + "Shaders::MeshVisualizerGL: Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive", ); #endif #ifndef MAGNUM_TARGET_GLES2 @@ -90,12 +90,12 @@ MeshVisualizerBase::MeshVisualizerBase(FlagsBase flags): _flags{flags} { #ifdef MAGNUM_BUILD_STATIC /* Import resources on static build, if not already */ - if(!Utility::Resource::hasGroup("MagnumShaders")) + if(!Utility::Resource::hasGroup("MagnumShadersGL")) importShaderResources(); #endif } -GL::Version MeshVisualizerBase::setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs) const { +GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs) const { #ifndef MAGNUM_TARGET_GLES const GL::Version version = GL::Context::current().supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); /* Extended in MeshVisualizer3D for TBN visualization */ @@ -138,43 +138,43 @@ GL::Version MeshVisualizerBase::setupShaders(GL::Shader& vert, GL::Shader& frag, return version; } -MeshVisualizerBase& MeshVisualizerBase::setColor(const Color4& color) { +MeshVisualizerGLBase& MeshVisualizerGLBase::setColor(const Color4& color) { #ifndef MAGNUM_TARGET_GLES2 CORRADE_ASSERT(_flags & (FlagBase::Wireframe|FlagBase::InstancedObjectId|FlagBase::VertexId|FlagBase::PrimitiveId), - "Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled", *this); + "Shaders::MeshVisualizerGL::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled", *this); #else CORRADE_ASSERT(_flags & FlagBase::Wireframe, - "Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe enabled", *this); + "Shaders::MeshVisualizerGL::setColor(): the shader was not created with wireframe enabled", *this); #endif setUniform(_colorUniform, color); return *this; } -MeshVisualizerBase& MeshVisualizerBase::setWireframeColor(const Color4& color) { +MeshVisualizerGLBase& MeshVisualizerGLBase::setWireframeColor(const Color4& color) { CORRADE_ASSERT(_flags & FlagBase::Wireframe, - "Shaders::MeshVisualizer::setWireframeColor(): the shader was not created with wireframe enabled", *this); + "Shaders::MeshVisualizerGL::setWireframeColor(): the shader was not created with wireframe enabled", *this); setUniform(_wireframeColorUniform, color); return *this; } -MeshVisualizerBase& MeshVisualizerBase::setWireframeWidth(const Float width) { +MeshVisualizerGLBase& MeshVisualizerGLBase::setWireframeWidth(const Float width) { CORRADE_ASSERT(_flags & FlagBase::Wireframe, - "Shaders::MeshVisualizer::setWireframeWidth(): the shader was not created with wireframe enabled", *this); + "Shaders::MeshVisualizerGL::setWireframeWidth(): the shader was not created with wireframe enabled", *this); setUniform(_wireframeWidthUniform, width); return *this; } #ifndef MAGNUM_TARGET_GLES2 -MeshVisualizerBase& MeshVisualizerBase::setColorMapTransformation(const Float offset, const Float scale) { +MeshVisualizerGLBase& MeshVisualizerGLBase::setColorMapTransformation(const Float offset, const Float scale) { CORRADE_ASSERT(_flags & (FlagBase::InstancedObjectId|FlagBase::VertexId|FlagBase::PrimitiveId), - "Shaders::MeshVisualizer::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled", *this); + "Shaders::MeshVisualizerGL::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled", *this); setUniform(_colorMapOffsetScaleUniform, Vector2{offset, scale}); return *this; } -MeshVisualizerBase& MeshVisualizerBase::bindColorMapTexture(GL::Texture2D& texture) { +MeshVisualizerGLBase& MeshVisualizerGLBase::bindColorMapTexture(GL::Texture2D& texture) { CORRADE_ASSERT(_flags & (FlagBase::InstancedObjectId|FlagBase::VertexId|FlagBase::PrimitiveId), - "Shaders::MeshVisualizer::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled", *this); + "Shaders::MeshVisualizerGL::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled", *this); texture.bind(ColorMapTextureUnit); return *this; } @@ -182,16 +182,16 @@ MeshVisualizerBase& MeshVisualizerBase::bindColorMapTexture(GL::Texture2D& textu } -MeshVisualizer2D::MeshVisualizer2D(const Flags flags): Implementation::MeshVisualizerBase{Implementation::MeshVisualizerBase::FlagBase(UnsignedShort(flags))} { +MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags): Implementation::MeshVisualizerGLBase{Implementation::MeshVisualizerGLBase::FlagBase(UnsignedShort(flags))} { #ifndef MAGNUM_TARGET_GLES2 CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader), - "Shaders::MeshVisualizer2D: at least one visualization feature has to be enabled", ); + "Shaders::MeshVisualizerGL2D: at least one visualization feature has to be enabled", ); #else CORRADE_ASSERT(flags & (Flag::Wireframe & ~Flag::NoGeometryShader), - "Shaders::MeshVisualizer2D: at least Flag::Wireframe has to be enabled", ); + "Shaders::MeshVisualizerGL2D: at least Flag::Wireframe has to be enabled", ); #endif - Utility::Resource rs{"MagnumShaders"}; + Utility::Resource rs{"MagnumShadersGL"}; GL::Shader vert{NoCreate}; GL::Shader frag{NoCreate}; const GL::Version version = setupShaders(vert, frag, rs); @@ -314,7 +314,7 @@ MeshVisualizer2D::MeshVisualizer2D(const Flags flags): Implementation::MeshVisua #endif } -MeshVisualizer2D& MeshVisualizer2D::setViewportSize(const Vector2& size) { +MeshVisualizerGL2D& MeshVisualizerGL2D::setViewportSize(const Vector2& size) { /* Not asserting here, since the relation to wireframe is a bit vague. Also it's an ugly hack that should be removed, ideally. */ if(flags() & Flag::Wireframe && !(flags() & Flag::NoGeometryShader)) @@ -322,37 +322,37 @@ MeshVisualizer2D& MeshVisualizer2D::setViewportSize(const Vector2& size) { return *this; } -MeshVisualizer2D& MeshVisualizer2D::setTransformationProjectionMatrix(const Matrix3& matrix) { +MeshVisualizerGL2D& MeshVisualizerGL2D::setTransformationProjectionMatrix(const Matrix3& matrix) { setUniform(_transformationProjectionMatrixUniform, matrix); return *this; } -MeshVisualizer2D& MeshVisualizer2D::setSmoothness(const Float smoothness) { +MeshVisualizerGL2D& MeshVisualizerGL2D::setSmoothness(const Float smoothness) { /* This is a bit vaguely related but less vague than setViewportSize() so asserting in this case. */ CORRADE_ASSERT(flags() & Flag::Wireframe, - "Shaders::MeshVisualizer2D::setSmoothness(): the shader was not created with wireframe enabled", *this); + "Shaders::MeshVisualizerGL2D::setSmoothness(): the shader was not created with wireframe enabled", *this); setUniform(_smoothnessUniform, smoothness); return *this; } -MeshVisualizer3D::MeshVisualizer3D(const Flags flags): Implementation::MeshVisualizerBase{Implementation::MeshVisualizerBase::FlagBase(UnsignedShort(flags))} { +MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags): Implementation::MeshVisualizerGLBase{Implementation::MeshVisualizerGLBase::FlagBase(UnsignedShort(flags))} { #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader), - "Shaders::MeshVisualizer3D: at least one visualization feature has to be enabled", ); + "Shaders::MeshVisualizerGL3D: at least one visualization feature has to be enabled", ); CORRADE_ASSERT(!(flags & Flag::NoGeometryShader && flags & (Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection)), - "Shaders::MeshVisualizer3D: geometry shader has to be enabled when rendering TBN direction", ); + "Shaders::MeshVisualizerGL3D: geometry shader has to be enabled when rendering TBN direction", ); CORRADE_ASSERT(!(flags & Flag::BitangentDirection && flags & Flag::BitangentFromTangentDirection), - "Shaders::MeshVisualizer3D: Flag::BitangentDirection and Flag::BitangentFromTangentDirection are mutually exclusive", ); + "Shaders::MeshVisualizerGL3D: Flag::BitangentDirection and Flag::BitangentFromTangentDirection are mutually exclusive", ); #elif !defined(MAGNUM_TARGET_GLES2) CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader), - "Shaders::MeshVisualizer3D: at least one visualization feature has to be enabled", ); + "Shaders::MeshVisualizerGL3D: at least one visualization feature has to be enabled", ); #else CORRADE_ASSERT(flags & (Flag::Wireframe & ~Flag::NoGeometryShader), - "Shaders::MeshVisualizer3D: at least Flag::Wireframe has to be enabled", ); + "Shaders::MeshVisualizerGL3D: at least Flag::Wireframe has to be enabled", ); #endif - Utility::Resource rs{"MagnumShaders"}; + Utility::Resource rs{"MagnumShadersGL"}; GL::Shader vert{NoCreate}; GL::Shader frag{NoCreate}; const GL::Version version = setupShaders(vert, frag, rs); @@ -547,26 +547,26 @@ MeshVisualizer3D::MeshVisualizer3D(const Flags flags): Implementation::MeshVisua #endif } -MeshVisualizer3D& MeshVisualizer3D::setTransformationMatrix(const Matrix4& matrix) { +MeshVisualizerGL3D& MeshVisualizerGL3D::setTransformationMatrix(const Matrix4& matrix) { setUniform(_transformationMatrixUniform, matrix); return *this; } -MeshVisualizer3D& MeshVisualizer3D::setProjectionMatrix(const Matrix4& matrix) { +MeshVisualizerGL3D& MeshVisualizerGL3D::setProjectionMatrix(const Matrix4& matrix) { setUniform(_projectionMatrixUniform, matrix); return *this; } #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) -MeshVisualizer3D& MeshVisualizer3D::setNormalMatrix(const Matrix3x3& matrix) { +MeshVisualizerGL3D& MeshVisualizerGL3D::setNormalMatrix(const Matrix3x3& matrix) { CORRADE_ASSERT(flags() & (Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection), - "Shaders::MeshVisualizer3D::setNormalMatrix(): the shader was not created with TBN direction enabled", *this); + "Shaders::MeshVisualizerGL3D::setNormalMatrix(): the shader was not created with TBN direction enabled", *this); setUniform(_normalMatrixUniform, matrix); return *this; } #endif -MeshVisualizer3D& MeshVisualizer3D::setViewportSize(const Vector2& size) { +MeshVisualizerGL3D& MeshVisualizerGL3D::setViewportSize(const Vector2& size) { /* Not asserting here, since the relation to wireframe is a bit vague. Also it's an ugly hack that should be removed, ideally. */ if((flags() & Flag::Wireframe && !(flags() & Flag::NoGeometryShader)) @@ -579,22 +579,22 @@ MeshVisualizer3D& MeshVisualizer3D::setViewportSize(const Vector2& size) { } #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) -MeshVisualizer3D& MeshVisualizer3D::setLineWidth(const Float width) { +MeshVisualizerGL3D& MeshVisualizerGL3D::setLineWidth(const Float width) { CORRADE_ASSERT(flags() & (Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection), - "Shaders::MeshVisualizer3D::setLineWidth(): the shader was not created with TBN direction enabled", *this); + "Shaders::MeshVisualizerGL3D::setLineWidth(): the shader was not created with TBN direction enabled", *this); setUniform(_lineWidthUniform, width); return *this; } -MeshVisualizer3D& MeshVisualizer3D::setLineLength(const Float length) { +MeshVisualizerGL3D& MeshVisualizerGL3D::setLineLength(const Float length) { CORRADE_ASSERT(flags() & (Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection), - "Shaders::MeshVisualizer3D::setLineLength(): the shader was not created with TBN direction enabled", *this); + "Shaders::MeshVisualizerGL3D::setLineLength(): the shader was not created with TBN direction enabled", *this); setUniform(_lineLengthUniform, length); return *this; } #endif -MeshVisualizer3D& MeshVisualizer3D::setSmoothness(const Float smoothness) { +MeshVisualizerGL3D& MeshVisualizerGL3D::setSmoothness(const Float smoothness) { #ifndef CORRADE_NO_ASSERT /* This is a bit vaguely related but less vague than setViewportSize() so asserting in this case. */ @@ -604,18 +604,18 @@ MeshVisualizer3D& MeshVisualizer3D::setSmoothness(const Float smoothness) { constexpr Flags allowed = Flag::Wireframe; #endif CORRADE_ASSERT(flags() & allowed, - "Shaders::MeshVisualizer3D::setSmoothness(): the shader was not created with wireframe or TBN direction enabled", *this); + "Shaders::MeshVisualizerGL3D::setSmoothness(): the shader was not created with wireframe or TBN direction enabled", *this); #endif setUniform(_smoothnessUniform, smoothness); return *this; } -Debug& operator<<(Debug& debug, const MeshVisualizer2D::Flag value) { - debug << "Shaders::MeshVisualizer2D::Flag" << Debug::nospace; +Debug& operator<<(Debug& debug, const MeshVisualizerGL2D::Flag value) { + debug << "Shaders::MeshVisualizerGL2D::Flag" << Debug::nospace; switch(value) { /* LCOV_EXCL_START */ - #define _c(v) case MeshVisualizer2D::Flag::v: return debug << "::" #v; + #define _c(v) case MeshVisualizerGL2D::Flag::v: return debug << "::" #v; _c(NoGeometryShader) _c(Wireframe) #ifndef MAGNUM_TARGET_GLES2 @@ -633,12 +633,12 @@ Debug& operator<<(Debug& debug, const MeshVisualizer2D::Flag value) { return debug << "(" << Debug::nospace << reinterpret_cast(UnsignedByte(value)) << Debug::nospace << ")"; } -Debug& operator<<(Debug& debug, const MeshVisualizer3D::Flag value) { - debug << "Shaders::MeshVisualizer3D::Flag" << Debug::nospace; +Debug& operator<<(Debug& debug, const MeshVisualizerGL3D::Flag value) { + debug << "Shaders::MeshVisualizerGL3D::Flag" << Debug::nospace; switch(value) { /* LCOV_EXCL_START */ - #define _c(v) case MeshVisualizer3D::Flag::v: return debug << "::" #v; + #define _c(v) case MeshVisualizerGL3D::Flag::v: return debug << "::" #v; _c(NoGeometryShader) _c(Wireframe) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) @@ -662,41 +662,41 @@ Debug& operator<<(Debug& debug, const MeshVisualizer3D::Flag value) { return debug << "(" << Debug::nospace << reinterpret_cast(UnsignedByte(value)) << Debug::nospace << ")"; } -Debug& operator<<(Debug& debug, const MeshVisualizer2D::Flags value) { - return Containers::enumSetDebugOutput(debug, value, "Shaders::MeshVisualizer2D::Flags{}", { - MeshVisualizer2D::Flag::Wireframe, +Debug& operator<<(Debug& debug, const MeshVisualizerGL2D::Flags value) { + return Containers::enumSetDebugOutput(debug, value, "Shaders::MeshVisualizerGL2D::Flags{}", { + MeshVisualizerGL2D::Flag::Wireframe, /* Wireframe contains this on ES2 and WebGL 1 so it's not reported there */ - MeshVisualizer2D::Flag::NoGeometryShader, + MeshVisualizerGL2D::Flag::NoGeometryShader, #ifndef MAGNUM_TARGET_GLES2 - MeshVisualizer2D::Flag::InstancedObjectId, - MeshVisualizer2D::Flag::VertexId, - MeshVisualizer2D::Flag::PrimitiveIdFromVertexId, /* Superset of PrimitiveId */ + MeshVisualizerGL2D::Flag::InstancedObjectId, + MeshVisualizerGL2D::Flag::VertexId, + MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId, /* Superset of PrimitiveId */ #ifndef MAGNUM_TARGET_WEBGL - MeshVisualizer2D::Flag::PrimitiveId + MeshVisualizerGL2D::Flag::PrimitiveId #endif #endif }); } -Debug& operator<<(Debug& debug, const MeshVisualizer3D::Flags value) { - return Containers::enumSetDebugOutput(debug, value, "Shaders::MeshVisualizer3D::Flags{}", { - MeshVisualizer3D::Flag::Wireframe, +Debug& operator<<(Debug& debug, const MeshVisualizerGL3D::Flags value) { + return Containers::enumSetDebugOutput(debug, value, "Shaders::MeshVisualizerGL3D::Flags{}", { + MeshVisualizerGL3D::Flag::Wireframe, /* Wireframe contains this on ES2 and WebGL 1 so it's not reported there */ - MeshVisualizer3D::Flag::NoGeometryShader, + MeshVisualizerGL3D::Flag::NoGeometryShader, #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - MeshVisualizer3D::Flag::TangentDirection, - MeshVisualizer3D::Flag::BitangentFromTangentDirection, - MeshVisualizer3D::Flag::BitangentDirection, - MeshVisualizer3D::Flag::NormalDirection, + MeshVisualizerGL3D::Flag::TangentDirection, + MeshVisualizerGL3D::Flag::BitangentFromTangentDirection, + MeshVisualizerGL3D::Flag::BitangentDirection, + MeshVisualizerGL3D::Flag::NormalDirection, #endif #ifndef MAGNUM_TARGET_GLES2 - MeshVisualizer3D::Flag::InstancedObjectId, - MeshVisualizer3D::Flag::VertexId, - MeshVisualizer3D::Flag::PrimitiveIdFromVertexId, /* Superset of PrimitiveId */ + MeshVisualizerGL3D::Flag::InstancedObjectId, + MeshVisualizerGL3D::Flag::VertexId, + MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId, /* Superset of PrimitiveId */ #ifndef MAGNUM_TARGET_WEBGL - MeshVisualizer3D::Flag::PrimitiveId + MeshVisualizerGL3D::Flag::PrimitiveId #endif #endif }); diff --git a/src/Magnum/Shaders/MeshVisualizerGL.h b/src/Magnum/Shaders/MeshVisualizerGL.h new file mode 100644 index 000000000..c0997486e --- /dev/null +++ b/src/Magnum/Shaders/MeshVisualizerGL.h @@ -0,0 +1,1038 @@ +#ifndef Magnum_Shaders_MeshVisualizerGL_h +#define Magnum_Shaders_MeshVisualizerGL_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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::MeshVisualizerGL2D, @ref Magnum::Shaders::MeshVisualizerGL3D + * @m_since_latest + */ + +#include + +#include "Magnum/DimensionTraits.h" +#include "Magnum/GL/AbstractShaderProgram.h" +#include "Magnum/Shaders/GenericGL.h" +#include "Magnum/Shaders/visibility.h" + +namespace Magnum { namespace Shaders { + +namespace Implementation { + +class MAGNUM_SHADERS_EXPORT MeshVisualizerGLBase: public GL::AbstractShaderProgram { + protected: + enum class FlagBase: UnsignedShort { + /* Unlike the public Wireframe flag, this one doesn't include + NoGeometryShader on ES2 as that would make the checks too + complex */ + Wireframe = 1 << 0, + NoGeometryShader = 1 << 1, + #ifndef MAGNUM_TARGET_GLES2 + InstancedObjectId = 1 << 2, + VertexId = 1 << 3, + PrimitiveId = 1 << 4, + PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId + #endif + }; + typedef Containers::EnumSet FlagsBase; + + CORRADE_ENUMSET_FRIEND_OPERATORS(FlagsBase) + + explicit MeshVisualizerGLBase(FlagsBase flags); + explicit MeshVisualizerGLBase(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {} + + MAGNUM_SHADERS_LOCAL GL::Version setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs) const; + + MeshVisualizerGLBase& setColor(const Color4& color); + MeshVisualizerGLBase& setWireframeColor(const Color4& color); + MeshVisualizerGLBase& setWireframeWidth(Float width); + #ifndef MAGNUM_TARGET_GLES2 + MeshVisualizerGLBase& setColorMapTransformation(Float offset, Float scale); + MeshVisualizerGLBase& bindColorMapTexture(GL::Texture2D& texture); + #endif + + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + + FlagsBase _flags; + Int _colorUniform{1}, + _wireframeColorUniform{2}, + _wireframeWidthUniform{3}, + _smoothnessUniform{4}, + _viewportSizeUniform{5}; + #ifndef MAGNUM_TARGET_GLES2 + Int _colorMapOffsetScaleUniform{6}; + #endif +}; + +} + +/** +@brief 2D mesh visualization OpenGL shader +@m_since_latest + +Visualizes wireframe, per-vertex/per-instance object ID or primitive ID of 2D +meshes. You need to provide the @ref Position attribute in your triangle mesh. +Use @ref setTransformationProjectionMatrix(), @ref setColor() and others to +configure the shader. + +@m_class{m-row} + +@parblock + +@m_div{m-col-m-4 m-col-t-6 m-push-m-2 m-nopadt m-nopadx} +@image html shaders-meshvisualizer2d.png width=256px +@m_enddiv + +@m_div{m-col-m-4 m-col-t-6 m-push-m-2 m-nopadt m-nopadx} +@image html shaders-meshvisualizer2d-primitiveid.png width=256px +@m_enddiv + +@endparblock + +The shader expects that you enable wireframe visualization by passing an +appropriate @ref Flag to the constructor --- there's no default behavior with +nothing enabled. The shader is a 2D variant of @ref MeshVisualizerGL3D with +mostly identical workflow. See its documentation for more information. +*/ +class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisualizerGLBase { + public: + /** + * @brief Vertex position + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector2 "Vector2". + */ + typedef typename GenericGL2D::Position Position; + + /** + * @brief Vertex index + * + * See @ref MeshVisualizerGL3D::VertexIndex for more information. + */ + typedef GL::Attribute<4, Float> VertexIndex; + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief (Instanced) object ID + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt. + * Used only if @ref Flag::InstancedObjectId is set. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. + */ + typedef GenericGL3D::ObjectId ObjectId; + #endif + + enum: UnsignedInt { + /** + * Color shader output. @ref shaders-generic "Generic output", + * present always. Expects three- or four-component floating-point + * or normalized buffer attachment. + */ + ColorOutput = GenericGL2D::ColorOutput + }; + + /** + * @brief Flag + * + * @see @ref Flags, @ref MeshVisualizerGL2D() + */ + enum class Flag: UnsignedShort { + /** + * Visualize wireframe. On OpenGL ES 2.0 and WebGL this also + * enables @ref Flag::NoGeometryShader. + */ + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + Wireframe = 1 << 0, + #else + Wireframe = (1 << 0) | (1 << 1), + #endif + + /** + * Don't use a geometry shader for wireframe visualization. If + * enabled, you might need to provide also the @ref VertexIndex + * attribute in the mesh. On OpenGL ES 2.0 and WebGL enabled + * alongside @ref Flag::Wireframe. + */ + NoGeometryShader = 1 << 1, + + #ifndef MAGNUM_TARGET_GLES2 + /** @copydoc MeshVisualizerGL3D::Flag::InstancedObjectId */ + InstancedObjectId = 1 << 2, + + /** @copydoc MeshVisualizerGL3D::Flag::VertexId */ + VertexId = 1 << 3, + + #ifndef MAGNUM_TARGET_WEBGL + /** @copydoc MeshVisualizerGL3D::Flag::PrimitiveId */ + PrimitiveId = 1 << 4, + #endif + + /** @copydoc MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId */ + #ifndef MAGNUM_TARGET_WEBGL + PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId + #else + PrimitiveIdFromVertexId = (1 << 5)|(1 << 4) + #endif + #endif + }; + + /** @brief Flags */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param flags Flags + * + * At least @ref Flag::Wireframe is expected to be enabled. + */ + explicit MeshVisualizerGL2D(Flags flags); + + /** + * @brief Construct without creating the underlying OpenGL object + * + * The constructed instance is equivalent to a moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + * + * This function can be safely used for constructing (and later + * destructing) objects even without any OpenGL context being active. + * However note that this is a low-level and a potentially dangerous + * API, see the documentation of @ref NoCreate for alternatives. + */ + explicit MeshVisualizerGL2D(NoCreateT) noexcept: Implementation::MeshVisualizerGLBase{NoCreate} {} + + /** @brief Copying is not allowed */ + MeshVisualizerGL2D(const MeshVisualizerGL2D&) = delete; + + /** @brief Move constructor */ + MeshVisualizerGL2D(MeshVisualizerGL2D&&) noexcept = default; + + /** @brief Copying is not allowed */ + MeshVisualizerGL2D& operator=(const MeshVisualizerGL2D&) = delete; + + /** @brief Move assignment */ + MeshVisualizerGL2D& operator=(MeshVisualizerGL2D&&) noexcept = default; + + /** @brief Flags */ + Flags flags() const { + return Flag(UnsignedShort(Implementation::MeshVisualizerGLBase::_flags)); + } + + /** + * @brief Set transformation and projection matrix + * @return Reference to self (for method chaining) + * + * Initial value is an identity matrix. + */ + MeshVisualizerGL2D& setTransformationProjectionMatrix(const Matrix3& matrix); + + /** + * @brief Set viewport size + * @return Reference to self (for method chaining) + * + * Has effect only if @ref Flag::Wireframe is enabled and geometry + * shaders are used, otherwise it does nothing. Initial value is a zero + * vector. + */ + MeshVisualizerGL2D& setViewportSize(const Vector2& size); + + /** + * @brief Set base object color + * @return Reference to self (for method chaining) + * + * Initial value is @cpp 0xffffffff_rgbaf @ce. Expects that either + * @ref Flag::Wireframe or @ref Flag::InstancedObjectId / + * @ref Flag::PrimitiveId is enabled. In case of the latter, the color + * is multiplied with the color map coming from + * @ref bindColorMapTexture(). + */ + MeshVisualizerGL2D& setColor(const Color4& color) { + return static_cast(Implementation::MeshVisualizerGLBase::setColor(color)); + } + + /** + * @brief Set wireframe color + * @return Reference to self (for method chaining) + * + * Initial value is @cpp 0x000000ff_rgbaf @ce. Expects that + * @ref Flag::Wireframe is enabled. + */ + MeshVisualizerGL2D& setWireframeColor(const Color4& color) { + return static_cast(Implementation::MeshVisualizerGLBase::setWireframeColor(color)); + } + + /** + * @brief Set wireframe width + * @return Reference to self (for method chaining) + * + * Value is in screen space (depending on @ref setViewportSize()), + * initial value is @cpp 1.0f @ce. Expects that @ref Flag::Wireframe is + * enabled. + */ + MeshVisualizerGL2D& setWireframeWidth(Float width) { + return static_cast(Implementation::MeshVisualizerGLBase::setWireframeWidth(width)); + } + + #ifndef MAGNUM_TARGET_GLES2 + /** @copydoc MeshVisualizerGL3D::setColorMapTransformation() */ + MeshVisualizerGL2D& setColorMapTransformation(Float offset, Float scale) { + return static_cast(Implementation::MeshVisualizerGLBase::setColorMapTransformation(offset, scale)); + } + + /** @copydoc MeshVisualizerGL3D::bindColorMapTexture() */ + MeshVisualizerGL2D& bindColorMapTexture(GL::Texture2D& texture) { + return static_cast(Implementation::MeshVisualizerGLBase::bindColorMapTexture(texture)); + } + #endif + + /** + * @brief Set line smoothness + * @return Reference to self (for method chaining) + * + * Value is in screen space (depending on @ref setViewportSize()), + * initial value is @cpp 2.0f @ce. Expects that @ref Flag::Wireframe is + * enabled. + */ + MeshVisualizerGL2D& setSmoothness(Float smoothness); + + private: + Int _transformationProjectionMatrixUniform{0}; +}; + +/** +@brief 3D mesh visualization OpenGL shader +@m_since_latest + +Visualizes wireframe, per-vertex/per-instance object ID, primitive ID or +tangent space of 3D meshes. You need to provide the @ref Position attribute in +your triangle mesh at the very least. Use @ref setTransformationProjectionMatrix(), +@ref setColor() and others to configure the shader. + +@m_class{m-row} + +@parblock + +@m_div{m-col-m-4 m-col-t-6 m-push-m-2 m-text-center m-nopadt m-nopadx} +@image html shaders-meshvisualizer3d.png width=256px +@ref Shaders-MeshVisualizerGL3D-wireframe, \n +@ref Shaders-MeshVisualizerGL3D-tbn +@m_enddiv + +@m_div{m-col-m-4 m-col-t-6 m-push-m-2 m-text-center m-nopadt m-nopadx} +@image html shaders-meshvisualizer3d-primitiveid.png width=256px +@ref Shaders-MeshVisualizerGL3D-object-id +@m_enddiv + +@endparblock + +The shader expects that you enable wireframe visualization, tangent space +visualization or object/primitive ID visualization by passing an appropriate +@ref Flag to the constructor --- there's no default behavior with nothing +enabled. + +@section Shaders-MeshVisualizerGL3D-wireframe Wireframe visualization + +Wireframe visualization is done by enabling @ref Flag::Wireframe. It is done +either using geometry shaders or with help of additional vertex information. If +you have geometry shaders available, you don't need to do anything else except +calling @ref setViewportSize() to correctly size the wireframe --- without +this, the mesh will be rendered in a single color. + +@requires_gl32 Extension @gl_extension{ARB,geometry_shader4} for wireframe + rendering using geometry shaders. +@requires_es_extension Extension @gl_extension{EXT,geometry_shader} for + wireframe rendering using geometry shaders. + +If you don't have geometry shaders, you need to enable @ref Flag::NoGeometryShader +(done by default in OpenGL ES 2.0) and use only **non-indexed** triangle meshes +(see @ref MeshTools::duplicate() for a possible solution). Additionaly, if you +have OpenGL < 3.1 or OpenGL ES 2.0, you need to provide also the +@ref VertexIndex attribute. + +@requires_gles30 Extension @gl_extension{OES,standard_derivatives} for + wireframe rendering without geometry shaders. + +If using geometry shaders on OpenGL ES, @gl_extension{NV,shader_noperspective_interpolation} +is optionally used for improving line appearance. On desktop OpenGL this is +done implicitly. + +If you want to render just the wireframe on top of an existing mesh, call +@ref setColor() with @cpp 0x00000000_rgbaf @ce. Alpha / transparency is +supported by the shader implicitly, but to have it working on the framebuffer, +you need to enable @ref GL::Renderer::Feature::Blending and set up the blending +function. See @ref GL::Renderer::setBlendFunction() for details. + +@subsection Shaders-MeshVisualizerGL3D-wireframe-geom Example setup with a geometry shader (desktop GL, OpenGL ES 3.2) + +Common mesh setup: + +@snippet MagnumShaders-gl.cpp MeshVisualizerGL3D-usage-geom1 + +Common rendering setup: + +@snippet MagnumShaders-gl.cpp MeshVisualizerGL3D-usage-geom2 + +@subsection Shaders-MeshVisualizerGL3D-wireframe-no-geom Example setup for indexed meshes without a geometry shader + +The vertices have to be converted to a non-indexed array first. Mesh setup: + +@snippet MagnumShaders-gl.cpp MeshVisualizerGL3D-usage-no-geom1 + +Rendering setup: + +@snippet MagnumShaders-gl.cpp MeshVisualizerGL3D-usage-no-geom2 + +@subsection Shaders-MeshVisualizerGL3D-usage-wireframe-no-geom-old Wireframe visualization of non-indexed meshes without a geometry shader on older hardware + +You need to provide also the @ref VertexIndex attribute. Mesh setup *in +addition to the above*: + +@snippet MagnumShaders-gl.cpp MeshVisualizerGL3D-usage-no-geom-old + +Rendering setup the same as above. + +@section Shaders-MeshVisualizerGL3D-tbn Tangent space visualization + +On platforms with geometry shaders (desktop GL, OpenGL ES 3.2), the shader is +able to visualize tangents, bitangent and normal direction via colored lines +coming out of vertices (red, green and blue for tangent, bitangent and normal, respectively). This can be enabled together with wireframe visualization, +however note that when both are enabled, the lines are not antialiased to avoid +depth ordering artifacts. + +For tangents and normals, you need to provide the @ref Tangent and @ref Normal +attributes and enable @ref Flag::TangentDirection and +@ref Flag::NormalDirection, respectively. If any of the attributes isn't +present, its data are implicitly zero and thus the direction isn't shown --- +which means you don't need to worry about having two active variants of the +shader and switching between either depending on whether tangents are present +or not. + +For bitangents however, there are two possible representations --- the more +efficient one is via a fourth component in the tangent attribute that +indicates tangent space handedness, in which case you'll be using the +@ref Tangent4 attribute instead of @ref Tangent, and enable +@ref Flag::BitangentFromTangentDirection. The other, more obvious but less +efficient representation, is a dedicated @ref Bitangent attribute (in which +case you'll enable @ref Flag::BitangentDirection). Note that these two are +mutually exclusive, so you need to choose either of them based on what given +mesh contains. Example for the first case: + +@snippet MagnumShaders-gl.cpp MeshVisualizerGL3D-usage-tbn1 + +Rendering setup: + +@snippet MagnumShaders-gl.cpp MeshVisualizerGL3D-usage-tbn2 + +@section Shaders-MeshVisualizerGL3D-object-id Object, vertex and primitive ID visualization + +If the mesh contains a per-vertex (or instanced) @ref ObjectId, it can be +visualized by enabling @ref Flag::InstancedObjectId. For the actual +visualization you need to provide a color map using @ref bindColorMapTexture() +and use @ref setColorMapTransformation() to map given range of discrete IDs to +the @f$ [0, 1] @f$ texture range. Various colormap presets are in the +@ref DebugTools::ColorMap namespace. Example usage: + +@snippet MagnumShaders-gl.cpp MeshVisualizerGL3D-usage-object-id + +If you enable @ref Flag::VertexId, the shader will use the color map to +visualize how are vertices shared among primitives. That's useful for +inspecting mesh connectivity --- primitives sharing vertices will have a smooth +color map transition while duplicated vertices will cause a sharp edge. This +relies on the @glsl gl_VertexID @ce GLSL builtin. + +The @ref Flag::PrimitiveId then visualizes the order in which primitives are +drawn. That's useful for example to see to see how well is the mesh optimized +for a post-transform vertex cache. This by default relies on the @glsl gl_PrimitiveID @ce GLSL builtin; with @ref Flag::PrimitiveIdFromVertexId it's +emulated using @glsl gl_VertexID @ce, expecting you to draw a non-indexed +triangle mesh. You can use @ref MeshTools::duplicate() (and potentially +@ref MeshTools::generateIndices()) to conveniently convert the mesh to a +non-indexed @ref MeshPrimitive::Triangles. + +@requires_gl32 The `gl_PrimitiveID` shader variable is not available on OpenGL + 3.1 and lower. +@requires_gl30 The `gl_VertexID` shader variable is not available on OpenGL + 2.1. +@requires_gles32 The `gl_PrimitiveID` shader variable is not available on + OpenGL ES 3.1 and lower. +@requires_gles30 The `gl_VertexID` shader variable is not available on OpenGL + ES 2.0. +@requires_gles `gl_PrimitiveID` is not available in WebGL. +@requires_webgl20 `gl_VertexID` is not available in WebGL 1.0. + +@see @ref shaders, @ref MeshVisualizerGL2D +@todo Understand and add support wireframe width/smoothness without GS +*/ +class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisualizerGLBase { + public: + /** + * @brief Vertex position + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector3 "Vector3". + */ + typedef typename GenericGL3D::Position Position; + + /** + * @brief Tangent direction + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector3 "Vector3". Use either this or the @ref Tangent4 + * attribute. Used only if @ref Flag::TangentDirection is enabled. + */ + typedef typename GenericGL3D::Tangent Tangent; + + /** + * @brief Tangent direction with a bitangent sign + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector4 "Vector4". Use either this or the @ref Tangent + * attribute. Used only if @ref Flag::TangentDirection or + * @ref Flag::BitangentFromTangentDirection is enabled. + */ + typedef typename GenericGL3D::Tangent4 Tangent4; + + /** + * @brief Bitangent direction + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector3 "Vector3". Use either this or the @ref Tangent4 + * attribute. Used only if @ref Flag::BitangentDirection is enabled. + */ + typedef typename GenericGL3D::Bitangent Bitangent; + + /** + * @brief Normal direction + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector3 "Vector3". Used only if + * @ref Flag::NormalDirection is enabled. + */ + typedef typename GenericGL3D::Normal Normal; + + /** + * @brief Vertex index + * + * @ref Magnum::Float "Float", used only in OpenGL < 3.1 and OpenGL ES + * 2.0 if @ref Flag::Wireframe is enabled. This attribute (modulo 3) + * specifies index of given vertex in triangle, i.e. @cpp 0.0f @ce for + * first, @cpp 1.0f @ce for second, @cpp 2.0f @ce for third. In OpenGL + * 3.1, OpenGL ES 3.0 and newer this value is provided via the + * @cb{.glsl} gl_VertexID @ce shader builtin, so the attribute is not + * needed. + * + * @note This attribute uses the same slot as @ref GenericGL::ObjectId, + * but since Object ID is available only on ES3+ and vertex index + * is used only on ES2 contexts without @glsl gl_VertexID @ce, + * there should be no conflict between these two. + */ + typedef GL::Attribute<4, Float> VertexIndex; + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief (Instanced) object ID + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt. + * Used only if @ref Flag::InstancedObjectId is set. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. + */ + typedef GenericGL3D::ObjectId ObjectId; + #endif + + enum: UnsignedInt { + /** + * Color shader output. @ref shaders-generic "Generic output", + * present always. Expects three- or four-component floating-point + * or normalized buffer attachment. + */ + ColorOutput = GenericGL3D::ColorOutput + }; + + /** + * @brief Flag + * + * @see @ref Flags, @ref MeshVisualizer() + */ + enum class Flag: UnsignedShort { + /** + * Visualize wireframe. On OpenGL ES 2.0 and WebGL this also + * enables @ref Flag::NoGeometryShader. + */ + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + Wireframe = 1 << 0, + #else + Wireframe = (1 << 0) | (1 << 1), + #endif + + /** + * Don't use a geometry shader for wireframe visualization. If + * enabled, you might need to provide also the @ref VertexIndex + * attribute in the mesh. On OpenGL ES 2.0 and WebGL enabled + * alongside @ref Flag::Wireframe. + * + * Mutually exclusive with @ref Flag::TangentDirection, + * @ref Flag::BitangentFromTangentDirection, + * @ref Flag::BitangentDirection and @ref Flag::NormalDirection --- + * those need a geometry shader always. + */ + NoGeometryShader = 1 << 1, + + #ifndef MAGNUM_TARGET_GLES2 + /** + * Visualize instanced object ID. You need to provide the + * @ref ObjectId attribute in the mesh. Mutually exclusive with + * @ref Flag::VertexId and @ref Flag::PrimitiveId. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL + * 1.0. + * @m_since{2020,06} + */ + InstancedObjectId = 1 << 2, + + /** + * Visualize vertex ID (@cpp gl_VertexID @ce). Useful for + * visualizing mesh connectivity --- primitives sharing vertices + * will have a smooth color map transition while duplicated + * vertices will cause a sharp edge. Mutually exclusive with + * @ref Flag::InstancedObjectId and @ref Flag::PrimitiveId. + * @requires_gl30 The `gl_VertexID` shader variable is not + * available on OpenGL 2.1. + * @requires_gles30 The `gl_VertexID` shader variable is not + * available on OpenGL ES 2.0. + * @requires_webgl20 `gl_VertexID` is not available in WebGL 1.0. + * @m_since{2020,06} + */ + VertexId = 1 << 3, + + #ifndef MAGNUM_TARGET_WEBGL + /** + * Visualize primitive ID (@cpp gl_PrimitiveID @ce). Useful for + * visualizing how well is the mesh optimized for a post-transform + * vertex cache. Mutually exclusive with + * @ref Flag::InstancedObjectId and @ref Flag::VertexId. See also + * @ref Flag::PrimitiveIdFromVertexId. + * @requires_gl32 The `gl_PrimitiveID` shader variable is not + * available on OpenGL 3.1 and lower. + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles32 The `gl_PrimitiveID` shader variable is not + * available on OpenGL ES 3.1 and lower. + * @requires_gles `gl_PrimitiveID` is not available in WebGL. + * @m_since{2020,06} + */ + PrimitiveId = 1 << 4, + #endif + + /** + * Visualize primitive ID on a non-indexed triangle mesh using + * @cpp gl_VertexID/3 @ce. Implicitly enables + * @ref Flag::PrimitiveId, mutually exclusive with + * @ref Flag::InstancedObjectId. Usable on OpenGL < 3.2, + * OpenGL ES < 3.2 and WebGL where @cpp gl_PrimitiveID @ce is not + * available. + * @requires_gl30 The `gl_VertexID` shader variable is not + * available on OpenGL 2.1. + * @requires_gles30 The `gl_VertexID` shader variable is not + * available on OpenGL ES 2.0. + * @requires_webgl20 `gl_VertexID` is not available in WebGL 1.0. + * @m_since{2020,06} + */ + #ifndef MAGNUM_TARGET_WEBGL + PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId, + #else + PrimitiveIdFromVertexId = (1 << 5)|(1 << 4), + #endif + #endif + + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + /** + * Visualize tangent direction with red lines pointing out of + * vertices. You need to provide the @ref Tangent or @ref Tangent4 + * attribute in the mesh. Mutually exclusive with + * @ref Flag::NoGeometryShader (as this needs a geometry shader + * always). + * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / + * @gl_extension{EXT,geometry_shader} + * @requires_gles Geometry shaders are not available in WebGL. + * @m_since{2020,06} + */ + TangentDirection = 1 << 6, + + /** + * Visualize bitangent direction with green lines pointing out of + * vertices. You need to provide both @ref Normal and @ref Tangent4 + * attributes in the mesh, alternatively you can provide the + * @ref Bitangent attribute and enable + * @ref Flag::BitangentDirection instead. Mutually exclusive with + * @ref Flag::NoGeometryShader (as this needs a geometry shader + * always). + * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / + * @gl_extension{EXT,geometry_shader} + * @requires_gles Geometry shaders are not available in WebGL. + * @m_since{2020,06} + */ + BitangentFromTangentDirection = 1 << 7, + + /** + * Visualize bitangent direction with green lines pointing out of + * vertices. You need to provide the @ref Bitangent attribute in + * the mesh, alternatively you can provide both @ref Normal and + * @ref Tangent4 attributes and enable + * @ref Flag::BitangentFromTangentDirection instead. Mutually + * exclusive with @ref Flag::NoGeometryShader (as this needs a + * geometry shader always). + * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / + * @gl_extension{EXT,geometry_shader} + * @requires_gles Geometry shaders are not available in WebGL. + * @m_since{2020,06} + */ + BitangentDirection = 1 << 8, + + /** + * Visualize normal direction with blue lines pointing out of + * vertices. You need to provide the @ref Normal attribute in the + * mesh. Mutually exclusive with @ref Flag::NoGeometryShader (as + * this needs a geometry shader always). + * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / + * @gl_extension{EXT,geometry_shader} + * @requires_gles Geometry shaders are not available in WebGL. + * @m_since{2020,06} + */ + NormalDirection = 1 << 9 + #endif + }; + + /** @brief Flags */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param flags Flags + * + * At least @ref Flag::Wireframe or one of @ref Flag::TangentDirection, + * @ref Flag::BitangentFromTangentDirection, + * @ref Flag::BitangentDirection, @ref Flag::NormalDirection is + * expected to be enabled. + */ + explicit MeshVisualizerGL3D(Flags flags); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Constructor + * @m_deprecated_since{2020,06} Use @ref MeshVisualizerGL3D(Flags) + * instead. + */ + explicit CORRADE_DEPRECATED("use MeshVisualizerGL3D(Flags) instead") MeshVisualizerGL3D(): MeshVisualizerGL3D{{}} {} + #endif + + /** + * @brief Construct without creating the underlying OpenGL object + * + * The constructed instance is equivalent to a moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + * + * This function can be safely used for constructing (and later + * destructing) objects even without any OpenGL context being active. + * However note that this is a low-level and a potentially dangerous + * API, see the documentation of @ref NoCreate for alternatives. + */ + explicit MeshVisualizerGL3D(NoCreateT) noexcept: Implementation::MeshVisualizerGLBase{NoCreate} {} + + /** @brief Copying is not allowed */ + MeshVisualizerGL3D(const MeshVisualizerGL3D&) = delete; + + /** @brief Move constructor */ + MeshVisualizerGL3D(MeshVisualizerGL3D&&) noexcept = default; + + /** @brief Copying is not allowed */ + MeshVisualizerGL3D& operator=(const MeshVisualizerGL3D&) = delete; + + /** @brief Move assignment */ + MeshVisualizerGL3D& operator=(MeshVisualizerGL3D&&) noexcept = default; + + /** @brief Flags */ + Flags flags() const { + return Flag(UnsignedShort(Implementation::MeshVisualizerGLBase::_flags)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Set transformation and projection matrix + * @m_deprecated_since{2020,06} Use @ref setTransformationMatrix() and + * @ref setProjectionMatrix() instead. + */ + CORRADE_DEPRECATED("use setTransformationMatrix() and setProjectionMatrix() instead") MeshVisualizerGL3D& setTransformationProjectionMatrix(const Matrix4& matrix) { + /* Keep projection at identity, which should still work for + wireframe (but of course not for TBN visualization) */ + return setTransformationMatrix(matrix); + } + #endif + + /** + * @brief Set transformation matrix + * @return Reference to self (for method chaining) + * + * Initial value is an identity matrix. + */ + MeshVisualizerGL3D& setTransformationMatrix(const Matrix4& matrix); + + /** + * @brief Set projection matrix + * @return Reference to self (for method chaining) + * + * Initial value is an identity matrix. (i.e., an orthographic + * projection of the default @f$ [ -\boldsymbol{1} ; \boldsymbol{1} ] @f$ + * cube). + */ + MeshVisualizerGL3D& setProjectionMatrix(const Matrix4& matrix); + + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + /** + * @brief Set transformation matrix + * @return Reference to self (for method chaining) + * @m_since{2020,06} + * + * Expects that @ref Flag::TangentDirection, + * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is + * enabled. The matrix doesn't need to be normalized, as + * renormalization is done per-fragment anyway. + * Initial value is an identity matrix. + * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / + * @gl_extension{EXT,geometry_shader} + * @requires_gles Geometry shaders are not available in WebGL. + */ + MeshVisualizerGL3D& setNormalMatrix(const Matrix3x3& matrix); + #endif + + /** + * @brief Set viewport size + * @return Reference to self (for method chaining) + * + * Has effect only if @ref Flag::Wireframe is enabled and geometry + * shaders are used; or if @ref Flag::TangentDirection, + * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is + * enabled, otherwise it does nothing. Initial value is a zero vector. + */ + MeshVisualizerGL3D& setViewportSize(const Vector2& size); + + /** + * @brief Set base object color + * @return Reference to self (for method chaining) + * + * Initial value is @cpp 0xffffffff_rgbaf @ce. Expects that either + * @ref Flag::Wireframe or @ref Flag::InstancedObjectId / + * @ref Flag::PrimitiveId is enabled. In case of the latter, the color + * is multiplied with the color map coming from + * @ref bindColorMapTexture(). + */ + MeshVisualizerGL3D& setColor(const Color4& color) { + return static_cast(Implementation::MeshVisualizerGLBase::setColor(color)); + } + + /** + * @brief Set wireframe color + * @return Reference to self (for method chaining) + * + * Initial value is @cpp 0x000000ff_rgbaf @ce. Expects that + * @ref Flag::Wireframe is enabled. + */ + MeshVisualizerGL3D& setWireframeColor(const Color4& color) { + return static_cast(Implementation::MeshVisualizerGLBase::setWireframeColor(color)); + } + + /** + * @brief Set wireframe width + * @return Reference to self (for method chaining) + * + * Value is in screen space (depending on @ref setViewportSize()), + * initial value is @cpp 1.0f @ce. Expects that @ref Flag::Wireframe is + * enabled. + */ + MeshVisualizerGL3D& setWireframeWidth(Float width) { + return static_cast(Implementation::MeshVisualizerGLBase::setWireframeWidth(width)); + } + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Set color map transformation + * @return Reference to self (for method chaining) + * @m_since{2020,06} + * + * Offset and scale applied to the input value coming either from the + * @ref ObjectId attribute or @glsl gl_PrimitiveID @ce, resulting value + * is then used to fetch a color from a color map bound with + * @ref bindColorMapTexture(). Initial value is @cpp 1.0f/512.0f @ce + * and @cpp 1.0/256.0f @ce, meaning that for a 256-entry colormap the + * first 256 values get an exact color from it and the next values will + * be either clamped to last color or repeated depending on the color + * map texture wrapping mode. Expects that either + * @ref Flag::InstancedObjectId or @ref Flag::PrimitiveId / + * @ref Flag::PrimitiveIdFromVertexId is enabled. + * + * Note that this shader doesn't directly offer a + * @ref FlatGL::setObjectId() "setObjectId()" uniform that's used to + * offset the per-vertex / per-instance ID. Instead, you need to encode + * the base offset into the @p offset parameter. + * @requires_gles30 Object ID visualization requires integer attributes + * while primitive ID visualization requires the `gl_VertexID` / + * `gl_PrimitiveID` builtins, neither of which is available in + * OpenGL ES 2.0. + * @requires_webgl20 Object ID visualization requires integer + * attributes while primitive ID visualization requires at least + * the `gl_VertexID` builtin, neither of which is available in + * WebGL 1. + */ + MeshVisualizerGL3D& setColorMapTransformation(Float offset, Float scale) { + return static_cast(Implementation::MeshVisualizerGLBase::setColorMapTransformation(offset, scale)); + } + + /** + * @brief Bind a color map texture + * @return Reference to self (for method chaining) + * @m_since{2020,06} + * + * See also @ref setColorMapTransformation(). Expects that either + * @ref Flag::InstancedObjectId or @ref Flag::PrimitiveId / + * @ref Flag::PrimitiveIdFromVertexId is enabled. + * @requires_gles30 Object ID visualization requires integer attributes + * while primitive ID visualization requires the `gl_VertexID` / + * `gl_PrimitiveID` builtins, neither of which is available in + * OpenGL ES 2.0. + * @requires_webgl20 Object ID visualization requires integer + * attributes while primitive ID visualization requires at least + * the `gl_VertexID` builtin, neither of which is available in + * WebGL 1. + */ + MeshVisualizerGL3D& bindColorMapTexture(GL::Texture2D& texture) { + return static_cast(Implementation::MeshVisualizerGLBase::bindColorMapTexture(texture)); + } + #endif + + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + /** + * @brief Set line width + * @return Reference to self (for method chaining) + * @m_since{2020,06} + * + * Value is in screen space (depending on @ref setViewportSize()), + * initial value is @cpp 1.0f @ce. Expects that + * @ref Flag::TangentDirection, + * @ref Flag::BitangentFromTangentDirection, + * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is + * enabled. + * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / + * @gl_extension{EXT,geometry_shader} + * @requires_gles Geometry shaders are not available in WebGL. + */ + MeshVisualizerGL3D& setLineWidth(Float width); + + /** + * @brief Set line length + * @return Reference to self (for method chaining) + * @m_since{2020,06} + * + * Value is in object space, initial value is @cpp 1.0f @ce. Expects + * that @ref Flag::TangentDirection, + * @ref Flag::BitangentFromTangentDirection, + * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is + * enabled. + * @requires_gl32 Extension @gl_extension{ARB,geometry_shader4} + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} / + * @gl_extension{EXT,geometry_shader} + * @requires_gles Geometry shaders are not available in WebGL. + */ + MeshVisualizerGL3D& setLineLength(Float length); + #endif + + /** + * @brief Set line smoothness + * @return Reference to self (for method chaining) + * + * Value is in screen space (depending on @ref setViewportSize()), + * initial value is @cpp 2.0f @ce. Expects that @ref Flag::Wireframe, + * @ref Flag::TangentDirection, + * @ref Flag::BitangentFromTangentDirection, + * @ref Flag::BitangentDirection or @ref Flag::NormalDirection is + * enabled. + */ + MeshVisualizerGL3D& setSmoothness(Float smoothness); + + private: + Int _transformationMatrixUniform{0}, + _projectionMatrixUniform{7}; + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + Int _normalMatrixUniform{8}, + _lineWidthUniform{9}, + _lineLengthUniform{10}; + #endif +}; + +/** @debugoperatorclassenum{MeshVisualizerGL2D,MeshVisualizerGL2D::Flag} */ +MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizerGL2D::Flag value); + +/** @debugoperatorclassenum{MeshVisualizerGL3D,MeshVisualizerGL3D::Flag} */ +MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizerGL3D::Flag value); + +/** @debugoperatorclassenum{MeshVisualizerGL2D,MeshVisualizerGL2D::Flags} */ +MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizerGL2D::Flags value); + +/** @debugoperatorclassenum{MeshVisualizerGL3D,MeshVisualizerGL3D::Flags} */ +MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizerGL3D::Flags value); + +CORRADE_ENUMSET_OPERATORS(MeshVisualizerGL2D::Flags) +CORRADE_ENUMSET_OPERATORS(MeshVisualizerGL3D::Flags) + +}} + +#endif diff --git a/src/Magnum/Shaders/Phong.h b/src/Magnum/Shaders/Phong.h index b59537083..24a5cd9af 100644 --- a/src/Magnum/Shaders/Phong.h +++ b/src/Magnum/Shaders/Phong.h @@ -25,1026 +25,33 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef MAGNUM_BUILD_DEPRECATED /** @file - * @brief Class @ref Magnum::Shaders::Phong + * @brief Typedef @ref Magnum::Shaders::Phong + * @m_deprecated_since_latest Use @ref Magnum/Shaders/PhongGL.h and the + * @ref Magnum::Shaders::PhongGL "PhongGL" class instead */ +#endif -#include "Magnum/GL/AbstractShaderProgram.h" -#include "Magnum/Shaders/Generic.h" -#include "Magnum/Shaders/visibility.h" - -namespace Magnum { namespace Shaders { - -/** -@brief Phong shader - -Uses ambient, diffuse and specular color or texture. For a colored mesh you -need to provide the @ref Position and @ref Normal attributes in your triangle -mesh. By default, the shader renders the mesh with a white color in an identity -transformation. Use @ref setTransformationMatrix(), @ref setNormalMatrix(), -@ref setProjectionMatrix(), @ref setLightPosition() and others to configure -the shader. - -@image html shaders-phong.png width=256px - -@section Shaders-Phong-colored Colored rendering - -Common mesh setup: - -@snippet MagnumShaders.cpp Phong-usage-colored1 - -Common rendering setup: - -@snippet MagnumShaders.cpp Phong-usage-colored2 - -@section Shaders-Phong-texture Textured rendering - -If you want to use textures, you need to provide also the -@ref TextureCoordinates attribute. Pass appropriate @ref Flag combination to -the constructor and then at render time don't forget to also call appropriate -subset of @ref bindAmbientTexture(), @ref bindDiffuseTexture() and -@ref bindSpecularTexture() (or the combined @ref bindTextures()). The texture -is multipled by the color, which is by default set to fully opaque white for -enabled textures. Mesh setup with a diffuse and a specular texture: - -@snippet MagnumShaders.cpp Phong-usage-texture1 - -Common rendering setup: - -@snippet MagnumShaders.cpp Phong-usage-texture2 - -@section Shaders-Phong-lights Light specification - -By default, the shader provides a single directional "fill" light, coming from -the center of the camera. Using the @p lightCount parameter in constructor, you -can specify how many lights you want, and then control light parameters using -@ref setLightPositions(), @ref setLightColors(), @ref setLightSpecularColors() -and @ref setLightRanges(). Light positions are specified as four-component -vectors, the last component distinguishing between directional and point -lights. - -
  • -Point lights are specified with camera-relative position and the last component -set to @cpp 1.0f @ce together with @ref setLightRanges() describing the -attenuation. The range corresponds to the @ref Trade::LightData::range() and -the attenuation is calculated as the following --- see -@ref Trade-LightData-attenuation for more information: @f[ - F_{att} = \frac{\operatorname{clamp}(1 - (\frac{d}{\color{m-info} R})^4, 0, 1)^2}{1 + d^2} -@f] - -If you use @ref Constants::inf() as a range (which is also the default), the -equation reduces down to a simple inverse square: @f[ - F_{att} = \lim_{{\color{m-info} R} \to \infty} \frac{{\color{m-dim} \operatorname{clamp}(} 1 \mathbin{\color{m-dim} -} {\color{m-dim} (\frac{d}{R})^4, 0, 1)^2}}{1 + d^2} = \frac{1}{1 + d^2} -@f] -
  • -Directional lights are specified with a camera-relative direction *to* the -light with the last component set to @cpp 0.0f @ce --- which effectively makes -@f$ d = 0 @f$ --- and are not affected by values from @ref setLightRanges() in -any way: @f[ - F_{att} = \lim_{d \to 0} \frac{{\color{m-dim} \operatorname{clamp}(} 1 \mathbin{\color{m-dim} -} {\color{m-dim} (\frac{d}{R})^4, 0, 1)^2}}{1 \mathbin{\color{m-dim} +} {\color{m-dim} d^2}} = 1 -@f] -
- -Light color and intensity, corresponding to @ref Trade::LightData::color() and -@ref Trade::LightData::intensity(), is meant to be multiplied together and -passed to @ref setLightColors() and @ref setLightSpecularColors(). - -The following example shows a three-light setup with one dim directional light -shining from the top and two stronger but range-limited point lights: - -@snippet MagnumShaders.cpp Phong-usage-lights - -@subsection Shaders-Phong-lights-ambient Ambient lights - -In order to avoid redundant uniform inputs, there's no dedicated way to specify -ambient lights. Instead, they are handled by the ambient color input, as the -math for ambient color and lights is equivalent. Add the ambient colors -together and reuse the diffuse texture in the @ref bindAmbientTexture() slot to -have it affected by the ambient as well: - -@snippet MagnumShaders.cpp Phong-usage-lights-ambient - -@subsection Shaders-Phong-lights-zero Zero lights - -As a special case, creating this shader with zero lights makes its output -equivalent to the @ref Flat3D shader --- only @ref setAmbientColor() and -@ref bindAmbientTexture() (if @ref Flag::AmbientTexture is enabled) are taken -into account, which corresponds to @ref Flat::setColor() and -@ref Flat::bindTexture(). This is useful to reduce complexity in apps that -render models with pre-baked lights. For instanced workflows using zero lights -means the @ref NormalMatrix instance attribute doesn't need to be supplied -either. In addition, enabling @ref Flag::VertexColor and using a default -ambient color with no texturing makes this shader equivalent to -@ref VertexColor. - -@see @ref Trade::MaterialType::Flat - - - -@m_class{m-note m-dim} - -@par - Attenuation based on constant/linear/quadratic factors (the - @ref Trade::LightData::attenuation() property) and spot lights - (@ref Trade::LightData::innerConeAngle(), - @ref Trade::LightData::outerConeAngle() "outerConeAngle()") are not - implemented at the moment. - -@section Shaders-Phong-alpha Alpha blending and masking - -Alpha / transparency is supported by the shader implicitly, but to have it -working on the framebuffer, you need to enable -@ref GL::Renderer::Feature::Blending and set up the blending function. See -@ref GL::Renderer::setBlendFunction() for details. - -To avoid specular highlights on transparent areas, specular alpha should be -always set to @cpp 0.0f @ce. On the other hand, non-zero specular alpha can be -for example used to render transparent materials which are still expected to -have specular highlights such as glass or soap bubbles. - -An alternative is to enable @ref Flag::AlphaMask and tune @ref setAlphaMask() -for simple binary alpha-masked drawing that doesn't require depth sorting or -blending enabled. Note that this feature is implemented using the GLSL -@glsl discard @ce operation which is known to have considerable performance -impact on some platforms. With proper depth sorting and blending you'll usually -get much better performance and output quality. - -For general alpha-masked drawing you need to provide an ambient texture with -alpha channel and set alpha channel of the diffuse/specular color to @cpp 0.0f @ce -so only ambient alpha will be taken into account. If you have a diffuse texture -combined with the alpha mask, you can use that texture for both ambient and -diffuse part and then separate the alpha like this: - -@snippet MagnumShaders.cpp Phong-usage-alpha - -@section Shaders-Phong-normal-mapping Normal mapping - -If you want to use normal textures, enable @ref Flag::NormalTexture and call -@ref bindNormalTexture(). In addition you need to supply per-vertex tangent and -bitangent direction: - -- either using a four-component @ref Tangent4 attribute, where the sign of - the fourth component defines handedness of tangent basis, as described in - @ref Trade::MeshAttribute::Tangent; -- or a using pair of three-component @ref Tangent and @ref Bitangent - attributes together with enabling @ref Flag::Bitangent - -If you supply just a three-component @ref Tangent attribute and no bitangents, -the shader will implicitly assume the fourth component to be @cpp 1.0f @ce, -forming a right-handed tangent space. This is a valid optimization when you -have full control over the bitangent orientation, but won't work with general -meshes. - -@m_class{m-note m-success} - -@par - You can also use the @ref MeshVisualizer3D shader to visualize and debug - per-vertex normal, tangent and binormal direction, among other things. - -The strength of the effect can be controlled by -@ref setNormalTextureScale(). See -@ref Trade::MaterialAttribute::NormalTextureScale for a description of the -factor is used. - -@section Shaders-Phong-object-id Object ID output - -The shader supports writing object ID to the framebuffer for object picking or -other annotation purposes. Enable it using @ref Flag::ObjectId and set up an -integer buffer attached to the @ref ObjectIdOutput attachment. If you have a -batch of meshes with different object IDs, enable @ref Flag::InstancedObjectId -and supply per-vertex IDs to the @ref ObjectId attribute. The output will -contain a sum of the per-vertex ID and ID coming from @ref setObjectId(). - -The functionality is practically the same as in the @ref Flat shader, see -@ref Shaders-Flat-object-id "its documentation" for more information and usage -example. - -@requires_gles30 Object ID output requires integer buffer attachments, which - are not available in OpenGL ES 2.0 or WebGL 1.0. - -@section Shaders-Phong-instancing Instanced rendering - -Enabling @ref Flag::InstancedTransformation will turn the shader into an -instanced one. It'll take per-instance transformation and normal matrix from -the @ref TransformationMatrix and @ref NormalMatrix attributes, applying those -before the matrix set by @ref setTransformationMatrix() and -@ref setNormalMatrix(). Besides that, @ref Flag::VertexColor (and the -@ref Color3 / @ref Color4) attributes can work as both per-vertex and -per-instance, and for texturing it's possible to have per-instance texture -offset taken from @ref TextureOffset when @ref Flag::InstancedTextureOffset is -enabled (similarly to transformation, applied before @ref setTextureMatrix()). -The snippet below shows adding a buffer with per-instance transformation to a -mesh --- note how a normal matrix attribute has to be populated and supplied as -well to ensure lighting works: - -@snippet MagnumShaders.cpp Phong-usage-instancing - -@requires_gl33 Extension @gl_extension{ARB,instanced_arrays} -@requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - @gl_extension{EXT,instanced_arrays} or @gl_extension{NV,instanced_arrays} - in OpenGL ES 2.0. -@requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} in WebGL - 1.0. - -@see @ref shaders -*/ -class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram { - public: - /** - * @brief Vertex position - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector3 "Vector3". - */ - typedef Generic3D::Position Position; - - /** - * @brief Normal direction - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector3 "Vector3". - */ - typedef Generic3D::Normal Normal; - - /** - * @brief Tangent direction - * @m_since{2019,10} - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector3 "Vector3". Use either this or the @ref Tangent4 - * attribute. If only a three-component attribute is used and - * @ref Flag::Bitangent is not enabled, it's the same as if - * @ref Tangent4 was specified with the fourth component always being - * @cpp 1.0f @ce. Used only if @ref Flag::NormalTexture is set. - * @see @ref Shaders-Phong-normal-mapping - */ - typedef Generic3D::Tangent Tangent; - - /** - * @brief Tangent direction with a bitangent sign - * @m_since_latest - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector4 "Vector4". Use either this or the @ref Tangent - * attribute. If @ref Flag::Bitangent is set, the fourth component is - * ignored and bitangents are taken from the @ref Bitangent attribute - * instead. Used only if @ref Flag::NormalTexture is set. - * @see @ref Shaders-Phong-normal-mapping - */ - typedef typename Generic3D::Tangent4 Tangent4; - - /** - * @brief Bitangent direction - * @m_since_latest - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector3 "Vector3". Use either this or the @ref Tangent4 - * attribute. Used only if both @ref Flag::NormalTexture and - * @ref Flag::Bitangent are set. - * @see @ref Shaders-Phong-normal-mapping - */ - typedef typename Generic3D::Bitangent Bitangent; - - /** - * @brief 2D texture coordinates - * - * @ref shaders-generic "Generic attribute", - * @ref Magnum::Vector2 "Vector2", used only if at least one of - * @ref Flag::AmbientTexture, @ref Flag::DiffuseTexture and - * @ref Flag::SpecularTexture is set. - */ - typedef Generic3D::TextureCoordinates TextureCoordinates; - - /** - * @brief Three-component vertex color - * @m_since{2019,10} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Color3. Use - * either this or the @ref Color4 attribute. Used only if - * @ref Flag::VertexColor is set. - */ - typedef Generic3D::Color3 Color3; - - /** - * @brief Four-component vertex color - * @m_since{2019,10} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Color4. Use - * either this or the @ref Color3 attribute. Used only if - * @ref Flag::VertexColor is set. - */ - typedef Generic3D::Color4 Color4; - - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief (Instanced) object ID - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt. - * Used only if @ref Flag::InstancedObjectId is set. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. - */ - typedef Generic3D::ObjectId ObjectId; - #endif - - /** - * @brief (Instanced) transformation matrix - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Matrix4. - * Used only if @ref Flag::InstancedTransformation is set. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - */ - typedef Generic3D::TransformationMatrix TransformationMatrix; - - /** - * @brief (Instanced) normal matrix - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Matrix3x3. - * Used only if @ref Flag::InstancedTransformation is set. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - */ - typedef Generic3D::NormalMatrix NormalMatrix; - - /** - * @brief (Instanced) texture offset - * @m_since{2020,06} - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Vector2. Used - * only if @ref Flag::InstancedTextureOffset is set. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - */ - typedef typename Generic3D::TextureOffset TextureOffset; - - enum: UnsignedInt { - /** - * Color shader output. @ref shaders-generic "Generic output", - * present always. Expects three- or four-component floating-point - * or normalized buffer attachment. - * @m_since{2019,10} - */ - ColorOutput = Generic3D::ColorOutput, - - #ifndef MAGNUM_TARGET_GLES2 - /** - * Object ID shader output. @ref shaders-generic "Generic output", - * present only if @ref Flag::ObjectId is set. Expects a - * single-component unsigned integral attachment. Writes the value - * set in @ref setObjectId() there, see - * @ref Shaders-Phong-object-id for more information. - * @requires_gl30 Extension @gl_extension{EXT,texture_integer} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL - * 1.0. - * @m_since{2019,10} - */ - ObjectIdOutput = Generic3D::ObjectIdOutput - #endif - }; - - /** - * @brief Flag - * - * @see @ref Flags, @ref flags() - */ - enum class Flag: UnsignedShort { - /** - * Multiply ambient color with a texture. - * @see @ref setAmbientColor(), @ref bindAmbientTexture() - */ - AmbientTexture = 1 << 0, - - /** - * Multiply diffuse color with a texture. - * @see @ref setDiffuseColor(), @ref bindDiffuseTexture() - */ - DiffuseTexture = 1 << 1, - - /** - * Multiply specular color with a texture. - * @see @ref setSpecularColor(), @ref bindSpecularTexture() - */ - SpecularTexture = 1 << 2, - - /** - * Modify normals according to a texture. Requires the - * @ref Tangent attribute to be present. - * @m_since{2019,10} - */ - NormalTexture = 1 << 4, - - /** - * Enable alpha masking. If the combined fragment color has an - * alpha less than the value specified with @ref setAlphaMask(), - * given fragment is discarded. - * - * This uses the @glsl discard @ce operation which is known to have - * considerable performance impact on some platforms. While useful - * for cheap alpha masking that doesn't require depth sorting, - * with proper depth sorting and blending you'll usually get much - * better performance and output quality. - */ - AlphaMask = 1 << 3, - - /** - * Multiply diffuse color with a vertex color. Requires either - * the @ref Color3 or @ref Color4 attribute to be present. - * @m_since{2019,10} - */ - VertexColor = 1 << 5, - - /** - * Use the separate @ref Bitangent attribute for retrieving vertex - * bitangents. If this flag is not present, the last component of - * @ref Tangent4 is used to calculate bitangent direction. See - * @ref Shaders-Phong-normal-mapping for more information. - * @m_since_latest - */ - Bitangent = 1 << 11, - - /** - * Enable texture coordinate transformation. If this flag is set, - * the shader expects that at least one of - * @ref Flag::AmbientTexture, @ref Flag::DiffuseTexture, - * @ref Flag::SpecularTexture or @ref Flag::NormalTexture is - * enabled as well. - * @see @ref setTextureMatrix() - * @m_since{2020,06} - */ - TextureTransformation = 1 << 6, - - #ifndef MAGNUM_TARGET_GLES2 - /** - * Enable object ID output. See @ref Shaders-Phong-object-id - * for more information. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL - * 1.0. - * @m_since{2019,10} - */ - ObjectId = 1 << 7, - - /** - * Instanced object ID. Retrieves a per-instance / per-vertex - * object ID from the @ref ObjectId attribute, outputting a sum of - * the per-vertex ID and ID coming from @ref setObjectId(). - * Implicitly enables @ref Flag::ObjectId. See - * @ref Shaders-Phong-object-id for more information. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL - * 1.0. - * @m_since{2020,06} - */ - InstancedObjectId = (1 << 8)|ObjectId, - #endif - - /** - * Instanced transformation. Retrieves a per-instance - * transformation and normal matrix from the - * @ref TransformationMatrix / @ref NormalMatrix attributes and - * uses them together with matrices coming from - * @ref setTransformationMatrix() and @ref setNormalMatrix() (first - * the per-instance, then the uniform matrix). See - * @ref Shaders-Phong-instancing for more information. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - * @m_since{2020,06} - */ - InstancedTransformation = 1 << 9, - - /** - * Instanced texture offset. Retrieves a per-instance offset vector - * from the @ref TextureOffset attribute and uses it together with - * the matrix coming from @ref setTextureMatrix() (first the - * per-instance vector, then the uniform matrix). Instanced texture - * scaling and rotation is not supported at the moment, you can - * specify that only via the uniform @ref setTextureMatrix(). - * Implicitly enables @ref Flag::TextureTransformation. See - * @ref Shaders-Phong-instancing for more information. - * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} - * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, - * @gl_extension{EXT,instanced_arrays} or - * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. - * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} - * in WebGL 1.0. - * @m_since{2020,06} - */ - InstancedTextureOffset = (1 << 10)|TextureTransformation - }; - - /** - * @brief Flags - * - * @see @ref flags() - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param flags Flags - * @param lightCount Count of light sources - */ - explicit Phong(Flags flags = {}, UnsignedInt lightCount = 1); - - /** - * @brief Construct without creating the underlying OpenGL object - * - * The constructed instance is equivalent to a moved-from state. Useful - * in cases where you will overwrite the instance later anyway. Move - * another object over it to make it useful. - * - * This function can be safely used for constructing (and later - * destructing) objects even without any OpenGL context being active. - * However note that this is a low-level and a potentially dangerous - * API, see the documentation of @ref NoCreate for alternatives. - */ - explicit Phong(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {} - - /** @brief Copying is not allowed */ - Phong(const Phong&) = delete; - - /** @brief Move constructor */ - Phong(Phong&&) noexcept = default; - - /** @brief Copying is not allowed */ - Phong& operator=(const Phong&) = delete; - - /** @brief Move assignment */ - Phong& operator=(Phong&&) noexcept = default; - - /** @brief Flags */ - Flags flags() const { return _flags; } - - /** @brief Light count */ - UnsignedInt lightCount() const { return _lightCount; } - - /** - * @brief Set ambient color - * @return Reference to self (for method chaining) - * - * If @ref Flag::AmbientTexture is set, default value is - * @cpp 0xffffffff_rgbaf @ce and the color will be multiplied with - * ambient texture, otherwise default value is @cpp 0x00000000_rgbaf @ce. - * @see @ref bindAmbientTexture(), @ref Shaders-Phong-lights-ambient - */ - Phong& setAmbientColor(const Magnum::Color4& color); - - /** - * @brief Bind an ambient texture - * @return Reference to self (for method chaining) - * - * Expects that the shader was created with @ref Flag::AmbientTexture - * enabled. - * @see @ref bindTextures(), @ref setAmbientColor(), - * @ref Shaders-Phong-lights-ambient - */ - Phong& bindAmbientTexture(GL::Texture2D& texture); - - /** - * @brief Set diffuse color - * @return Reference to self (for method chaining) - * - * Initial value is @cpp 0xffffffff_rgbaf @ce. If @ref lightCount() is - * zero, this function is a no-op, as diffuse color doesn't contribute - * to the output in that case. - * @see @ref bindDiffuseTexture() - */ - Phong& setDiffuseColor(const Magnum::Color4& color); - - /** - * @brief Bind a diffuse texture - * @return Reference to self (for method chaining) - * - * Expects that the shader was created with @ref Flag::DiffuseTexture - * enabled. If @ref lightCount() is zero, this function is a no-op, as - * diffuse color doesn't contribute to the output in that case. - * @see @ref bindTextures(), @ref setDiffuseColor() - */ - Phong& bindDiffuseTexture(GL::Texture2D& texture); - - /** - * @brief Set normal texture scale - * @return Reference to self (for method chaining) - * @m_since_latest - * - * Affects strength of the normal mapping. Initial value is - * @cpp 1.0f @ce, meaning the normal texture is not changed in any way; - * a value of @cpp 0.0f @ce disables the normal texture effect - * altogether. - * - * Expects that the shader was created with @ref Flag::NormalTexture - * enabled. If @ref lightCount() is zero, this function is a no-op, as - * normals don't contribute to the output in that case. - * @see @ref Shaders-Phong-normal-mapping, @ref bindNormalTexture(), - * @ref Trade::MaterialAttribute::NormalTextureScale - */ - Phong& setNormalTextureScale(Float scale); - - /** - * @brief Bind a normal texture - * @return Reference to self (for method chaining) - * @m_since{2019,10} - * - * Expects that the shader was created with @ref Flag::NormalTexture - * enabled and the @ref Tangent attribute was supplied. If - * @ref lightCount() is zero, this function is a no-op, as normals - * don't contribute to the output in that case. - * @see @ref Shaders-Phong-normal-mapping, - * @ref bindTextures(), @ref setNormalTextureScale() - */ - Phong& bindNormalTexture(GL::Texture2D& texture); - - /** - * @brief Set specular color - * @return Reference to self (for method chaining) - * - * Initial value is @cpp 0xffffff00_rgbaf @ce. Color will be multiplied - * with specular texture if @ref Flag::SpecularTexture is set. If you - * want to have a fully diffuse material, set specular color to - * @cpp 0x00000000_rgbaf @ce. If @ref lightCount() is zero, this - * function is a no-op, as specular color doesn't contribute to the - * output in that case. - * @see @ref bindSpecularTexture() - */ - Phong& setSpecularColor(const Magnum::Color4& color); - - /** - * @brief Bind a specular texture - * @return Reference to self (for method chaining) - * - * Expects that the shader was created with @ref Flag::SpecularTexture - * enabled. If @ref lightCount() is zero, this function is a no-op, as - * specular color doesn't contribute to the output in that case. - * @see @ref bindTextures(), @ref setSpecularColor() - */ - Phong& bindSpecularTexture(GL::Texture2D& texture); - - /** - * @brief Bind textures - * @return Reference to self (for method chaining) - * - * A particular texture has effect only if particular texture flag from - * @ref Phong::Flag "Flag" is set, you can use @cpp nullptr @ce for the - * rest. Expects that the shader was created with at least one of - * @ref Flag::AmbientTexture, @ref Flag::DiffuseTexture, - * @ref Flag::SpecularTexture or @ref Flag::NormalTexture enabled. More - * efficient than setting each texture separately. - * @see @ref bindAmbientTexture(), @ref bindDiffuseTexture(), - * @ref bindSpecularTexture(), @ref bindNormalTexture() - */ - Phong& bindTextures(GL::Texture2D* ambient, GL::Texture2D* diffuse, GL::Texture2D* specular, GL::Texture2D* normal - #ifdef MAGNUM_BUILD_DEPRECATED - = nullptr - #endif - ); - - /** - * @brief Set shininess - * @return Reference to self (for method chaining) - * - * The larger value, the harder surface (smaller specular highlight). - * Initial value is @cpp 80.0f @ce. If @ref lightCount() is zero, this - * function is a no-op, as specular color doesn't contribute to the - * output in that case. - */ - Phong& setShininess(Float shininess); - - /** - * @brief Set alpha mask value - * @return Reference to self (for method chaining) - * - * Expects that the shader was created with @ref Flag::AlphaMask - * enabled. Fragments with alpha values smaller than the mask value - * will be discarded. Initial value is @cpp 0.5f @ce. See the flag - * documentation for further information. - * - * This corresponds to @m_class{m-doc-external} [glAlphaFunc()](https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glAlphaFunc.xml) - * in classic OpenGL. - * @m_keywords{glAlphaFunc()} - */ - Phong& setAlphaMask(Float mask); - - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief Set object ID - * @return Reference to self (for method chaining) - * - * Expects that the shader was created with @ref Flag::ObjectId - * enabled. Value set here is written to the @ref ObjectIdOutput, see - * @ref Shaders-Phong-object-id for more information. Default is - * @cpp 0 @ce. - * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} - * @requires_gles30 Object ID output requires integer support in - * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. - */ - Phong& setObjectId(UnsignedInt id); - #endif - - /** - * @brief Set transformation matrix - * @return Reference to self (for method chaining) - * - * You need to set also @ref setNormalMatrix() with a corresponding - * value. Initial value is an identity matrix. - */ - Phong& setTransformationMatrix(const Matrix4& matrix); - - /** - * @brief Set normal matrix - * @return Reference to self (for method chaining) - * - * The matrix doesn't need to be normalized, as renormalization is done - * per-fragment anyway. You need to set also - * @ref setTransformationMatrix() with a corresponding value. Initial - * value is an identity matrix. If @ref lightCount() is zero, this - * function is a no-op, as normals don't contribute to the output in - * that case. - * @see @ref Math::Matrix4::normalMatrix() - */ - Phong& setNormalMatrix(const Matrix3x3& matrix); - - /** - * @brief Set projection matrix - * @return Reference to self (for method chaining) - * - * Initial value is an identity matrix (i.e., an orthographic - * projection of the default @f$ [ -\boldsymbol{1} ; \boldsymbol{1} ] @f$ - * cube). - */ - Phong& setProjectionMatrix(const Matrix4& matrix); - - /** - * @brief Set texture coordinate transformation matrix - * @return Reference to self (for method chaining) - * @m_since{2020,06} - * - * Expects that the shader was created with - * @ref Flag::TextureTransformation enabled. Initial value is an - * identity matrix. - */ - Phong& setTextureMatrix(const Matrix3& matrix); - - /** - * @brief Set light positions - * @return Reference to self (for method chaining) - * @m_since_latest - * - * Depending on the fourth component, the value is treated as either a - *camera-relative position of a point light, if the fourth component is - * @cpp 1.0f @ce; or a direction *to* a directional light, if the - * fourth component is @cpp 0.0f @ce. Expects that the size of the - * @p positions array is the same as @ref lightCount(). Initial values - * are @cpp {0.0f, 0.0f, 1.0f, 0.0f} @ce --- a directional "fill" light - * coming from the camera. - * @see @ref Shaders-Phong-lights, @ref setLightPosition() - */ - Phong& setLightPositions(Containers::ArrayView positions); - - /** - * @overload - * @m_since_latest - */ - Phong& setLightPositions(std::initializer_list positions); - - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @brief @copybrief setLightPositions(Containers::ArrayView) - * @m_deprecated_since_latest Use @ref setLightPositions(Containers::ArrayView) - * instead. This function sets the fourth component to - * @cpp 0.0f @ce to preserve the original behavior as close as - * possible. - */ - CORRADE_DEPRECATED("use setLightPositions(Containers::ArrayView) instead") Phong& setLightPositions(Containers::ArrayView positions); - - /** - * @brief @copybrief setLightPositions(std::initializer_list) - * @m_deprecated_since_latest Use @ref setLightPositions(std::initializer_list) - * instead. This function sets the fourth component to - * @cpp 0.0f @ce to preserve the original behavior as close as - * possible. - */ - CORRADE_DEPRECATED("use setLightPositions(std::initializer_list) instead") Phong& setLightPositions(std::initializer_list positions); - #endif - - /** - * @brief Set position for given light - * @return Reference to self (for method chaining) - * @m_since_latest - * - * Unlike @ref setLightPositions() updates just a single light - * position. If updating more than one light, prefer the batch function - * instead to reduce the count of GL API calls. Expects that @p id is - * less than @ref lightCount(). - */ - Phong& setLightPosition(UnsignedInt id, const Vector4& position); - - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @brief @copybrief setLightPosition(UnsignedInt, const Vector4&) - * @m_deprecated_since_latest Use @ref setLightPosition(UnsignedInt, const Vector4&) - * instead. This function sets the fourth component to - * @cpp 0.0f @ce to preserve the original behavior as close as - * possible. - */ - CORRADE_DEPRECATED("use setLightPosition(UnsignedInt, const Vector4&) instead") Phong& setLightPosition(UnsignedInt id, const Vector3& position); - - /** - * @brief Set light position - * @m_deprecated_since_latest Use @ref setLightPositions(std::initializer_list) - * with a single item instead --- it's short enough to not warrant - * the existence of a dedicated overload. This function sets the - * fourth component to @cpp 0.0f @ce to preserve the original - * behavior as close as possible. - */ - CORRADE_DEPRECATED("use setLightPositions(std::initializer_list) instead") Phong& setLightPosition(const Vector3& position); - #endif - - /** - * @brief Set light colors - * @return Reference to self (for method chaining) - * @m_since_latest - * - * Initial values are @cpp 0xffffff_rgbf @ce. Expects that the size - * of the @p colors array is the same as @ref lightCount(). - * @see @ref Shaders-Phong-lights, @ref setLightColor() - */ - Phong& setLightColors(Containers::ArrayView colors); - - /** - * @overload - * @m_since_latest - */ - Phong& setLightColors(std::initializer_list colors); - - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @brief @copybrief setLightColors(Containers::ArrayView) - * @m_deprecated_since_latest Use @ref setLightColors(Containers::ArrayView) - * instead. The alpha channel isn't used in any way. - */ - CORRADE_DEPRECATED("use setLightColors(Containers::ArrayView) instead") Phong& setLightColors(Containers::ArrayView colors); - - /** - * @brief @copybrief setLightColors(std::initializer_list) - * @m_deprecated_since_latest Use @ref setLightColors(std::initializer_list) - * instead. The alpha channel isn't used in any way. - */ - CORRADE_DEPRECATED("use setLightColors(std::initializer_list) instead") Phong& setLightColors(std::initializer_list colors); - #endif - - /** - * @brief Set color for given light - * @return Reference to self (for method chaining) - * @m_since_latest - * - * Unlike @ref setLightColors() updates just a single light color. If - * updating more than one light, prefer the batch function instead to - * reduce the count of GL API calls. Expects that @p id is less than - * @ref lightCount(). - */ - Phong& setLightColor(UnsignedInt id, const Magnum::Color3& color); - - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @brief @copybrief setLightColor(UnsignedInt, const Magnum::Color3&) - * @m_deprecated_since_latest Use @ref setLightColor(UnsignedInt, const Magnum::Color3&) - * instead. The alpha channel isn't used in any way. - */ - CORRADE_DEPRECATED("use setLightColor(UnsignedInt, const Magnum::Color3&) instead") Phong& setLightColor(UnsignedInt id, const Magnum::Color4& color); - - /** - * @brief Set light color - * @m_deprecated_since_latest Use @ref setLightColors(std::initializer_list) - * with a single item instead --- it's short enough to not warrant - * the existence of a dedicated overload. The alpha channel isn't - * used in any way. - */ - CORRADE_DEPRECATED("use setLightColor(std::initializer_list) instead") Phong& setLightColor(const Magnum::Color4& color); - #endif - - /** - * @brief Set light specular colors - * @return Reference to self (for method chaining) - * @m_since_latest - * - * Usually you'd set this value to the same as @ref setLightColors(), - * but it allows for greater flexibility such as disabling specular - * highlights on certain lights. Initial values are - * @cpp 0xffffff_rgbf @ce. Expects that the size of the @p colors array - * is the same as @ref lightCount(). - * @see @ref Shaders-Phong-lights, @ref setLightColor() - */ - Phong& setLightSpecularColors(Containers::ArrayView colors); - - /** - * @overload - * @m_since_latest - */ - Phong& setLightSpecularColors(std::initializer_list colors); - - /** - * @brief Set specular color for given light - * @return Reference to self (for method chaining) - * @m_since_latest - * - * Unlike @ref setLightSpecularColors() updates just a single light - * color. If updating more than one light, prefer the batch function - * instead to reduce the count of GL API calls. Expects that @p id is - * less than @ref lightCount(). - */ - Phong& setLightSpecularColor(UnsignedInt id, const Magnum::Color3& color); - - /** - * @brief Set light attenuation ranges - * @return Reference to self (for method chaining) - * @m_since_latest - * - * Initial values are @ref Constants::inf(). Expects that the size of - * the @p ranges array is the same as @ref lightCount(). - * @see @ref Shaders-Phong-lights, @ref setLightRange() - */ - Phong& setLightRanges(Containers::ArrayView ranges); - - /** - * @overload - * @m_since_latest - */ - Phong& setLightRanges(std::initializer_list ranges); - - /** - * @brief Set attenuation range for given light - * @return Reference to self (for method chaining) - * @m_since_latest - * - * Unlike @ref setLightRanges() updates just a single light range. If - * updating more than one light, prefer the batch function instead to - * reduce the count of GL API calls. Expects that @p id is less than - * @ref lightCount(). - */ - Phong& setLightRange(UnsignedInt id, Float range); +#include "Magnum/configure.h" - private: - /* Prevent accidentally calling irrelevant functions */ - #ifndef MAGNUM_TARGET_GLES - using GL::AbstractShaderProgram::drawTransformFeedback; - #endif - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - using GL::AbstractShaderProgram::dispatchCompute; - #endif +#ifdef MAGNUM_BUILD_DEPRECATED +#include - Flags _flags; - UnsignedInt _lightCount{}; - Int _transformationMatrixUniform{0}, - _projectionMatrixUniform{1}, - _normalMatrixUniform{2}, - _textureMatrixUniform{3}, - _ambientColorUniform{4}, - _diffuseColorUniform{5}, - _specularColorUniform{6}, - _shininessUniform{7}, - _normalTextureScaleUniform{8}, - _alphaMaskUniform{9}; - #ifndef MAGNUM_TARGET_GLES2 - Int _objectIdUniform{10}; - #endif - Int _lightPositionsUniform{11}, - _lightColorsUniform, /* 11 + lightCount, set in the constructor */ - _lightSpecularColorsUniform, /* 11 + 2*lightCount */ - _lightRangesUniform; /* 11 + 3*lightCount */ -}; +#include "Magnum/Shaders/PhongGL.h" -/** @debugoperatorclassenum{Phong,Phong::Flag} */ -MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, Phong::Flag value); +CORRADE_DEPRECATED_FILE("use Magnum/Shaders/PhongGL.h and the PhongGL class instead") -/** @debugoperatorclassenum{Phong,Phong::Flags} */ -MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, Phong::Flags value); +namespace Magnum { namespace Shaders { -CORRADE_ENUMSET_OPERATORS(Phong::Flags) +/** @brief @copybrief PhongGL + * @m_deprecated_since_latest Use @ref PhongGL instead. + */ +typedef CORRADE_DEPRECATED("use PhongGL instead") PhongGL Phong; }} +#else +#error use Magnum/Shaders/PhongGL.h and the PhongGL class instead +#endif #endif diff --git a/src/Magnum/Shaders/Phong.cpp b/src/Magnum/Shaders/PhongGL.cpp similarity index 75% rename from src/Magnum/Shaders/Phong.cpp rename to src/Magnum/Shaders/PhongGL.cpp index 6cb4505a0..4dfa76ae3 100644 --- a/src/Magnum/Shaders/Phong.cpp +++ b/src/Magnum/Shaders/PhongGL.cpp @@ -23,7 +23,7 @@ DEALINGS IN THE SOFTWARE. */ -#include "Phong.h" +#include "PhongGL.h" #if defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_BUILD_DEPRECATED) #include @@ -55,16 +55,16 @@ namespace { }; } -Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _lightCount{lightCount}, _lightColorsUniform{_lightPositionsUniform + Int(lightCount)}, _lightSpecularColorsUniform{_lightPositionsUniform + 2*Int(lightCount)}, _lightRangesUniform{_lightPositionsUniform + 3*Int(lightCount)} { +PhongGL::PhongGL(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _lightCount{lightCount}, _lightColorsUniform{_lightPositionsUniform + Int(lightCount)}, _lightSpecularColorsUniform{_lightPositionsUniform + 2*Int(lightCount)}, _lightRangesUniform{_lightPositionsUniform + 3*Int(lightCount)} { CORRADE_ASSERT(!(flags & Flag::TextureTransformation) || (flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture)), - "Shaders::Phong: texture transformation enabled but the shader is not textured", ); + "Shaders::PhongGL: texture transformation enabled but the shader is not textured", ); #ifdef MAGNUM_BUILD_STATIC /* Import resources on static build, if not already */ - if(!Utility::Resource::hasGroup("MagnumShaders")) + if(!Utility::Resource::hasGroup("MagnumShadersGL")) importShaderResources(); #endif - Utility::Resource rs("MagnumShaders"); + Utility::Resource rs("MagnumShadersGL"); #ifndef MAGNUM_TARGET_GLES const GL::Version version = GL::Context::current().supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); @@ -275,121 +275,121 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l #endif } -Phong& Phong::setAmbientColor(const Magnum::Color4& color) { +PhongGL& PhongGL::setAmbientColor(const Magnum::Color4& color) { setUniform(_ambientColorUniform, color); return *this; } -Phong& Phong::bindAmbientTexture(GL::Texture2D& texture) { +PhongGL& PhongGL::bindAmbientTexture(GL::Texture2D& texture) { CORRADE_ASSERT(_flags & Flag::AmbientTexture, - "Shaders::Phong::bindAmbientTexture(): the shader was not created with ambient texture enabled", *this); + "Shaders::PhongGL::bindAmbientTexture(): the shader was not created with ambient texture enabled", *this); texture.bind(AmbientTextureUnit); return *this; } -Phong& Phong::setDiffuseColor(const Magnum::Color4& color) { +PhongGL& PhongGL::setDiffuseColor(const Magnum::Color4& color) { if(_lightCount) setUniform(_diffuseColorUniform, color); return *this; } -Phong& Phong::bindDiffuseTexture(GL::Texture2D& texture) { +PhongGL& PhongGL::bindDiffuseTexture(GL::Texture2D& texture) { CORRADE_ASSERT(_flags & Flag::DiffuseTexture, - "Shaders::Phong::bindDiffuseTexture(): the shader was not created with diffuse texture enabled", *this); + "Shaders::PhongGL::bindDiffuseTexture(): the shader was not created with diffuse texture enabled", *this); if(_lightCount) texture.bind(DiffuseTextureUnit); return *this; } -Phong& Phong::setSpecularColor(const Magnum::Color4& color) { +PhongGL& PhongGL::setSpecularColor(const Magnum::Color4& color) { if(_lightCount) setUniform(_specularColorUniform, color); return *this; } -Phong& Phong::bindSpecularTexture(GL::Texture2D& texture) { +PhongGL& PhongGL::bindSpecularTexture(GL::Texture2D& texture) { CORRADE_ASSERT(_flags & Flag::SpecularTexture, - "Shaders::Phong::bindSpecularTexture(): the shader was not created with specular texture enabled", *this); + "Shaders::PhongGL::bindSpecularTexture(): the shader was not created with specular texture enabled", *this); if(_lightCount) texture.bind(SpecularTextureUnit); return *this; } -Phong& Phong::bindNormalTexture(GL::Texture2D& texture) { +PhongGL& PhongGL::bindNormalTexture(GL::Texture2D& texture) { CORRADE_ASSERT(_flags & Flag::NormalTexture, - "Shaders::Phong::bindNormalTexture(): the shader was not created with normal texture enabled", *this); + "Shaders::PhongGL::bindNormalTexture(): the shader was not created with normal texture enabled", *this); if(_lightCount) texture.bind(NormalTextureUnit); return *this; } -Phong& Phong::bindTextures(GL::Texture2D* ambient, GL::Texture2D* diffuse, GL::Texture2D* specular, GL::Texture2D* normal) { +PhongGL& PhongGL::bindTextures(GL::Texture2D* ambient, GL::Texture2D* diffuse, GL::Texture2D* specular, GL::Texture2D* normal) { CORRADE_ASSERT(_flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture), - "Shaders::Phong::bindTextures(): the shader was not created with any textures enabled", *this); + "Shaders::PhongGL::bindTextures(): the shader was not created with any textures enabled", *this); GL::AbstractTexture::bind(AmbientTextureUnit, {ambient, diffuse, specular, normal}); return *this; } -Phong& Phong::setShininess(Float shininess) { +PhongGL& PhongGL::setShininess(Float shininess) { if(_lightCount) setUniform(_shininessUniform, shininess); return *this; } -Phong& Phong::setNormalTextureScale(const Float scale) { +PhongGL& PhongGL::setNormalTextureScale(const Float scale) { CORRADE_ASSERT(_flags & Flag::NormalTexture, - "Shaders::Phong::setNormalTextureScale(): the shader was not created with normal texture enabled", *this); + "Shaders::PhongGL::setNormalTextureScale(): the shader was not created with normal texture enabled", *this); if(_lightCount) setUniform(_normalTextureScaleUniform, scale); return *this; } -Phong& Phong::setAlphaMask(Float mask) { +PhongGL& PhongGL::setAlphaMask(Float mask) { CORRADE_ASSERT(_flags & Flag::AlphaMask, - "Shaders::Phong::setAlphaMask(): the shader was not created with alpha mask enabled", *this); + "Shaders::PhongGL::setAlphaMask(): the shader was not created with alpha mask enabled", *this); setUniform(_alphaMaskUniform, mask); return *this; } #ifndef MAGNUM_TARGET_GLES2 -Phong& Phong::setObjectId(UnsignedInt id) { +PhongGL& PhongGL::setObjectId(UnsignedInt id) { CORRADE_ASSERT(_flags & Flag::ObjectId, - "Shaders::Phong::setObjectId(): the shader was not created with object ID enabled", *this); + "Shaders::PhongGL::setObjectId(): the shader was not created with object ID enabled", *this); setUniform(_objectIdUniform, id); return *this; } #endif -Phong& Phong::setTransformationMatrix(const Matrix4& matrix) { +PhongGL& PhongGL::setTransformationMatrix(const Matrix4& matrix) { setUniform(_transformationMatrixUniform, matrix); return *this; } -Phong& Phong::setNormalMatrix(const Matrix3x3& matrix) { +PhongGL& PhongGL::setNormalMatrix(const Matrix3x3& matrix) { if(_lightCount) setUniform(_normalMatrixUniform, matrix); return *this; } -Phong& Phong::setProjectionMatrix(const Matrix4& matrix) { +PhongGL& PhongGL::setProjectionMatrix(const Matrix4& matrix) { setUniform(_projectionMatrixUniform, matrix); return *this; } -Phong& Phong::setTextureMatrix(const Matrix3& matrix) { +PhongGL& PhongGL::setTextureMatrix(const Matrix3& matrix) { CORRADE_ASSERT(_flags & Flag::TextureTransformation, - "Shaders::Phong::setTextureMatrix(): the shader was not created with texture transformation enabled", *this); + "Shaders::PhongGL::setTextureMatrix(): the shader was not created with texture transformation enabled", *this); setUniform(_textureMatrixUniform, matrix); return *this; } -Phong& Phong::setLightPositions(const Containers::ArrayView positions) { +PhongGL& PhongGL::setLightPositions(const Containers::ArrayView positions) { CORRADE_ASSERT(_lightCount == positions.size(), - "Shaders::Phong::setLightPositions(): expected" << _lightCount << "items but got" << positions.size(), *this); + "Shaders::PhongGL::setLightPositions(): expected" << _lightCount << "items but got" << positions.size(), *this); if(_lightCount) setUniform(_lightPositionsUniform, positions); return *this; } /* It's light, but can't be in the header because MSVC needs to know the size of Vector3 for the initializer list use */ -Phong& Phong::setLightPositions(const std::initializer_list positions) { +PhongGL& PhongGL::setLightPositions(const std::initializer_list positions) { return setLightPositions(Containers::arrayView(positions)); } #ifdef MAGNUM_BUILD_DEPRECATED -Phong& Phong::setLightPositions(const Containers::ArrayView positions) { +PhongGL& PhongGL::setLightPositions(const Containers::ArrayView positions) { Containers::Array fourComponent{NoInit, positions.size()}; for(std::size_t i = 0; i != positions.size(); ++i) fourComponent[i] = Vector4{positions[i], 0.0f}; @@ -397,40 +397,40 @@ Phong& Phong::setLightPositions(const Containers::ArrayView posit return *this; } -Phong& Phong::setLightPositions(const std::initializer_list positions) { +PhongGL& PhongGL::setLightPositions(const std::initializer_list positions) { CORRADE_IGNORE_DEPRECATED_PUSH return setLightPositions(Containers::arrayView(positions)); CORRADE_IGNORE_DEPRECATED_POP } #endif -Phong& Phong::setLightPosition(const UnsignedInt id, const Vector4& position) { +PhongGL& PhongGL::setLightPosition(const UnsignedInt id, const Vector4& position) { CORRADE_ASSERT(id < _lightCount, - "Shaders::Phong::setLightPosition(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); + "Shaders::PhongGL::setLightPosition(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); setUniform(_lightPositionsUniform + id, position); return *this; } #ifdef MAGNUM_BUILD_DEPRECATED -Phong& Phong::setLightPosition(UnsignedInt id, const Vector3& position) { +PhongGL& PhongGL::setLightPosition(UnsignedInt id, const Vector3& position) { return setLightPosition(id, Vector4{position, 0.0f}); } -Phong& Phong::setLightPosition(const Vector3& position) { +PhongGL& PhongGL::setLightPosition(const Vector3& position) { /* Use the list variant to check the shader really has just one light */ return setLightPositions({Vector4{position, 0.0f}}); } #endif -Phong& Phong::setLightColors(const Containers::ArrayView colors) { +PhongGL& PhongGL::setLightColors(const Containers::ArrayView colors) { CORRADE_ASSERT(_lightCount == colors.size(), - "Shaders::Phong::setLightColors(): expected" << _lightCount << "items but got" << colors.size(), *this); + "Shaders::PhongGL::setLightColors(): expected" << _lightCount << "items but got" << colors.size(), *this); if(_lightCount) setUniform(_lightColorsUniform, colors); return *this; } #ifdef MAGNUM_BUILD_DEPRECATED -Phong& Phong::setLightColors(const Containers::ArrayView colors) { +PhongGL& PhongGL::setLightColors(const Containers::ArrayView colors) { Containers::Array threeComponent{NoInit, colors.size()}; for(std::size_t i = 0; i != colors.size(); ++i) threeComponent[i] = colors[i].rgb(); @@ -438,77 +438,77 @@ Phong& Phong::setLightColors(const Containers::ArrayView c return *this; } -Phong& Phong::setLightColors(const std::initializer_list colors) { +PhongGL& PhongGL::setLightColors(const std::initializer_list colors) { CORRADE_IGNORE_DEPRECATED_PUSH return setLightColors(Containers::arrayView(colors)); CORRADE_IGNORE_DEPRECATED_POP } #endif -Phong& Phong::setLightColors(const std::initializer_list colors) { +PhongGL& PhongGL::setLightColors(const std::initializer_list colors) { return setLightColors(Containers::arrayView(colors)); } -Phong& Phong::setLightColor(const UnsignedInt id, const Magnum::Color3& color) { +PhongGL& PhongGL::setLightColor(const UnsignedInt id, const Magnum::Color3& color) { CORRADE_ASSERT(id < _lightCount, - "Shaders::Phong::setLightColor(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); + "Shaders::PhongGL::setLightColor(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); setUniform(_lightColorsUniform + id, color); return *this; } #ifdef MAGNUM_BUILD_DEPRECATED -Phong& Phong::setLightColor(UnsignedInt id, const Magnum::Color4& color) { +PhongGL& PhongGL::setLightColor(UnsignedInt id, const Magnum::Color4& color) { return setLightColor(id, color.rgb()); } -Phong& Phong::setLightColor(const Magnum::Color4& color) { +PhongGL& PhongGL::setLightColor(const Magnum::Color4& color) { /* Use the list variant to check the shader really has just one light */ return setLightColors({color.rgb()}); } #endif -Phong& Phong::setLightSpecularColors(const Containers::ArrayView colors) { +PhongGL& PhongGL::setLightSpecularColors(const Containers::ArrayView colors) { CORRADE_ASSERT(_lightCount == colors.size(), - "Shaders::Phong::setLightSpecularColors(): expected" << _lightCount << "items but got" << colors.size(), *this); + "Shaders::PhongGL::setLightSpecularColors(): expected" << _lightCount << "items but got" << colors.size(), *this); if(_lightCount) setUniform(_lightSpecularColorsUniform, colors); return *this; } -Phong& Phong::setLightSpecularColors(const std::initializer_list colors) { +PhongGL& PhongGL::setLightSpecularColors(const std::initializer_list colors) { return setLightSpecularColors(Containers::arrayView(colors)); } -Phong& Phong::setLightSpecularColor(const UnsignedInt id, const Magnum::Color3& color) { +PhongGL& PhongGL::setLightSpecularColor(const UnsignedInt id, const Magnum::Color3& color) { CORRADE_ASSERT(id < _lightCount, - "Shaders::Phong::setLightSpecularColor(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); + "Shaders::PhongGL::setLightSpecularColor(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); setUniform(_lightSpecularColorsUniform + id, color); return *this; } -Phong& Phong::setLightRanges(const Containers::ArrayView ranges) { +PhongGL& PhongGL::setLightRanges(const Containers::ArrayView ranges) { CORRADE_ASSERT(_lightCount == ranges.size(), - "Shaders::Phong::setLightRanges(): expected" << _lightCount << "items but got" << ranges.size(), *this); + "Shaders::PhongGL::setLightRanges(): expected" << _lightCount << "items but got" << ranges.size(), *this); if(_lightCount) setUniform(_lightRangesUniform, ranges); return *this; } -Phong& Phong::setLightRanges(const std::initializer_list ranges) { +PhongGL& PhongGL::setLightRanges(const std::initializer_list ranges) { return setLightRanges(Containers::arrayView(ranges)); } -Phong& Phong::setLightRange(const UnsignedInt id, const Float range) { +PhongGL& PhongGL::setLightRange(const UnsignedInt id, const Float range) { CORRADE_ASSERT(id < _lightCount, - "Shaders::Phong::setLightRange(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); + "Shaders::PhongGL::setLightRange(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); setUniform(_lightRangesUniform + id, range); return *this; } -Debug& operator<<(Debug& debug, const Phong::Flag value) { - debug << "Shaders::Phong::Flag" << Debug::nospace; +Debug& operator<<(Debug& debug, const PhongGL::Flag value) { + debug << "Shaders::PhongGL::Flag" << Debug::nospace; switch(value) { /* LCOV_EXCL_START */ - #define _c(v) case Phong::Flag::v: return debug << "::" #v; + #define _c(v) case PhongGL::Flag::v: return debug << "::" #v; _c(AmbientTexture) _c(DiffuseTexture) _c(SpecularTexture) @@ -530,22 +530,22 @@ Debug& operator<<(Debug& debug, const Phong::Flag value) { return debug << "(" << Debug::nospace << reinterpret_cast(UnsignedByte(value)) << Debug::nospace << ")"; } -Debug& operator<<(Debug& debug, const Phong::Flags value) { - return Containers::enumSetDebugOutput(debug, value, "Shaders::Phong::Flags{}", { - Phong::Flag::AmbientTexture, - Phong::Flag::DiffuseTexture, - Phong::Flag::SpecularTexture, - Phong::Flag::NormalTexture, - Phong::Flag::Bitangent, - Phong::Flag::AlphaMask, - Phong::Flag::VertexColor, - Phong::Flag::InstancedTextureOffset, /* Superset of TextureTransformation */ - Phong::Flag::TextureTransformation, +Debug& operator<<(Debug& debug, const PhongGL::Flags value) { + return Containers::enumSetDebugOutput(debug, value, "Shaders::PhongGL::Flags{}", { + PhongGL::Flag::AmbientTexture, + PhongGL::Flag::DiffuseTexture, + PhongGL::Flag::SpecularTexture, + PhongGL::Flag::NormalTexture, + PhongGL::Flag::Bitangent, + PhongGL::Flag::AlphaMask, + PhongGL::Flag::VertexColor, + PhongGL::Flag::InstancedTextureOffset, /* Superset of TextureTransformation */ + PhongGL::Flag::TextureTransformation, #ifndef MAGNUM_TARGET_GLES2 - Phong::Flag::InstancedObjectId, /* Superset of ObjectId */ - Phong::Flag::ObjectId, + PhongGL::Flag::InstancedObjectId, /* Superset of ObjectId */ + PhongGL::Flag::ObjectId, #endif - Phong::Flag::InstancedTransformation}); + PhongGL::Flag::InstancedTransformation}); } }} diff --git a/src/Magnum/Shaders/PhongGL.h b/src/Magnum/Shaders/PhongGL.h new file mode 100644 index 000000000..65d4990bc --- /dev/null +++ b/src/Magnum/Shaders/PhongGL.h @@ -0,0 +1,1052 @@ +#ifndef Magnum_Shaders_PhongGL_h +#define Magnum_Shaders_PhongGL_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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::PhongGL + * @m_since_latest + */ + +#include "Magnum/GL/AbstractShaderProgram.h" +#include "Magnum/Shaders/GenericGL.h" +#include "Magnum/Shaders/visibility.h" + +namespace Magnum { namespace Shaders { + +/** +@brief Phong OpenGL shader +@m_since_latest + +Uses ambient, diffuse and specular color or texture. For a colored mesh you +need to provide the @ref Position and @ref Normal attributes in your triangle +mesh. By default, the shader renders the mesh with a white color in an identity +transformation. Use @ref setTransformationMatrix(), @ref setNormalMatrix(), +@ref setProjectionMatrix(), @ref setLightPosition() and others to configure +the shader. + +@image html shaders-phong.png width=256px + +@section Shaders-PhongGL-colored Colored rendering + +Common mesh setup: + +@snippet MagnumShaders-gl.cpp PhongGL-usage-colored1 + +Common rendering setup: + +@snippet MagnumShaders-gl.cpp PhongGL-usage-colored2 + +@section Shaders-PhongGL-texture Textured rendering + +If you want to use textures, you need to provide also the +@ref TextureCoordinates attribute. Pass appropriate @ref Flag combination to +the constructor and then at render time don't forget to also call appropriate +subset of @ref bindAmbientTexture(), @ref bindDiffuseTexture() and +@ref bindSpecularTexture() (or the combined @ref bindTextures()). The texture +is multipled by the color, which is by default set to fully opaque white for +enabled textures. Mesh setup with a diffuse and a specular texture: + +@snippet MagnumShaders-gl.cpp PhongGL-usage-texture1 + +Common rendering setup: + +@snippet MagnumShaders-gl.cpp PhongGL-usage-texture2 + +@section Shaders-PhongGL-lights Light specification + +By default, the shader provides a single directional "fill" light, coming from +the center of the camera. Using the @p lightCount parameter in constructor, you +can specify how many lights you want, and then control light parameters using +@ref setLightPositions(), @ref setLightColors(), @ref setLightSpecularColors() +and @ref setLightRanges(). Light positions are specified as four-component +vectors, the last component distinguishing between directional and point +lights. + +
  • +Point lights are specified with camera-relative position and the last component +set to @cpp 1.0f @ce together with @ref setLightRanges() describing the +attenuation. The range corresponds to the @ref Trade::LightData::range() and +the attenuation is calculated as the following --- see +@ref Trade-LightData-attenuation for more information: @f[ + F_{att} = \frac{\operatorname{clamp}(1 - (\frac{d}{\color{m-info} R})^4, 0, 1)^2}{1 + d^2} +@f] + +If you use @ref Constants::inf() as a range (which is also the default), the +equation reduces down to a simple inverse square: @f[ + F_{att} = \lim_{{\color{m-info} R} \to \infty} \frac{{\color{m-dim} \operatorname{clamp}(} 1 \mathbin{\color{m-dim} -} {\color{m-dim} (\frac{d}{R})^4, 0, 1)^2}}{1 + d^2} = \frac{1}{1 + d^2} +@f] +
  • +Directional lights are specified with a camera-relative direction *to* the +light with the last component set to @cpp 0.0f @ce --- which effectively makes +@f$ d = 0 @f$ --- and are not affected by values from @ref setLightRanges() in +any way: @f[ + F_{att} = \lim_{d \to 0} \frac{{\color{m-dim} \operatorname{clamp}(} 1 \mathbin{\color{m-dim} -} {\color{m-dim} (\frac{d}{R})^4, 0, 1)^2}}{1 \mathbin{\color{m-dim} +} {\color{m-dim} d^2}} = 1 +@f] +
+ +Light color and intensity, corresponding to @ref Trade::LightData::color() and +@ref Trade::LightData::intensity(), is meant to be multiplied together and +passed to @ref setLightColors() and @ref setLightSpecularColors(). + +The following example shows a three-light setup with one dim directional light +shining from the top and two stronger but range-limited point lights: + +@snippet MagnumShaders-gl.cpp PhongGL-usage-lights + +@subsection Shaders-PhongGL-lights-ambient Ambient lights + +In order to avoid redundant uniform inputs, there's no dedicated way to specify +ambient lights. Instead, they are handled by the ambient color input, as the +math for ambient color and lights is equivalent. Add the ambient colors +together and reuse the diffuse texture in the @ref bindAmbientTexture() slot to +have it affected by the ambient as well: + +@snippet MagnumShaders-gl.cpp PhongGL-usage-lights-ambient + +@subsection Shaders-PhongGL-lights-zero Zero lights + +As a special case, creating this shader with zero lights makes its output +equivalent to the @ref FlatGL3D shader --- only @ref setAmbientColor() and +@ref bindAmbientTexture() (if @ref Flag::AmbientTexture is enabled) are taken +into account, which corresponds to @ref FlatGL::setColor() and +@ref FlatGL::bindTexture(). This is useful to reduce complexity in apps that +render models with pre-baked lights. For instanced workflows using zero lights +means the @ref NormalMatrix instance attribute doesn't need to be supplied +either. In addition, enabling @ref Flag::VertexColor and using a default +ambient color with no texturing makes this shader equivalent to +@ref VertexColorGL. + +@see @ref Trade::MaterialType::Flat + + + +@m_class{m-note m-dim} + +@par + Attenuation based on constant/linear/quadratic factors (the + @ref Trade::LightData::attenuation() property) and spot lights + (@ref Trade::LightData::innerConeAngle(), + @ref Trade::LightData::outerConeAngle() "outerConeAngle()") are not + implemented at the moment. + +@section Shaders-PhongGL-alpha Alpha blending and masking + +Alpha / transparency is supported by the shader implicitly, but to have it +working on the framebuffer, you need to enable +@ref GL::Renderer::Feature::Blending and set up the blending function. See +@ref GL::Renderer::setBlendFunction() for details. + +To avoid specular highlights on transparent areas, specular alpha should be +always set to @cpp 0.0f @ce. On the other hand, non-zero specular alpha can be +for example used to render transparent materials which are still expected to +have specular highlights such as glass or soap bubbles. + +An alternative is to enable @ref Flag::AlphaMask and tune @ref setAlphaMask() +for simple binary alpha-masked drawing that doesn't require depth sorting or +blending enabled. Note that this feature is implemented using the GLSL +@glsl discard @ce operation which is known to have considerable performance +impact on some platforms. With proper depth sorting and blending you'll usually +get much better performance and output quality. + +For general alpha-masked drawing you need to provide an ambient texture with +alpha channel and set alpha channel of the diffuse/specular color to @cpp 0.0f @ce +so only ambient alpha will be taken into account. If you have a diffuse texture +combined with the alpha mask, you can use that texture for both ambient and +diffuse part and then separate the alpha like this: + +@snippet MagnumShaders-gl.cpp PhongGL-usage-alpha + +@section Shaders-PhongGL-normal-mapping Normal mapping + +If you want to use normal textures, enable @ref Flag::NormalTexture and call +@ref bindNormalTexture(). In addition you need to supply per-vertex tangent and +bitangent direction: + +- either using a four-component @ref Tangent4 attribute, where the sign of + the fourth component defines handedness of tangent basis, as described in + @ref Trade::MeshAttribute::Tangent; +- or a using pair of three-component @ref Tangent and @ref Bitangent + attributes together with enabling @ref Flag::Bitangent + +If you supply just a three-component @ref Tangent attribute and no bitangents, +the shader will implicitly assume the fourth component to be @cpp 1.0f @ce, +forming a right-handed tangent space. This is a valid optimization when you +have full control over the bitangent orientation, but won't work with general +meshes. + +@m_class{m-note m-success} + +@par + You can also use the @ref MeshVisualizerGL3D shader to visualize and debug + per-vertex normal, tangent and binormal direction, among other things. + +The strength of the effect can be controlled by +@ref setNormalTextureScale(). See +@ref Trade::MaterialAttribute::NormalTextureScale for a description of the +factor is used. + +@section Shaders-PhongGL-object-id Object ID output + +The shader supports writing object ID to the framebuffer for object picking or +other annotation purposes. Enable it using @ref Flag::ObjectId and set up an +integer buffer attached to the @ref ObjectIdOutput attachment. If you have a +batch of meshes with different object IDs, enable @ref Flag::InstancedObjectId +and supply per-vertex IDs to the @ref ObjectId attribute. The output will +contain a sum of the per-vertex ID and ID coming from @ref setObjectId(). + +The functionality is practically the same as in the @ref FlatGL shader, see +@ref Shaders-FlatGL-object-id "its documentation" for more information and usage +example. + +@requires_gles30 Object ID output requires integer buffer attachments, which + are not available in OpenGL ES 2.0 or WebGL 1.0. + +@section Shaders-PhongGL-instancing Instanced rendering + +Enabling @ref Flag::InstancedTransformation will turn the shader into an +instanced one. It'll take per-instance transformation and normal matrix from +the @ref TransformationMatrix and @ref NormalMatrix attributes, applying those +before the matrix set by @ref setTransformationMatrix() and +@ref setNormalMatrix(). Besides that, @ref Flag::VertexColor (and the +@ref Color3 / @ref Color4) attributes can work as both per-vertex and +per-instance, and for texturing it's possible to have per-instance texture +offset taken from @ref TextureOffset when @ref Flag::InstancedTextureOffset is +enabled (similarly to transformation, applied before @ref setTextureMatrix()). +The snippet below shows adding a buffer with per-instance transformation to a +mesh --- note how a normal matrix attribute has to be populated and supplied as +well to ensure lighting works: + +@snippet MagnumShaders-gl.cpp PhongGL-usage-instancing + +@requires_gl33 Extension @gl_extension{ARB,instanced_arrays} +@requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + @gl_extension{EXT,instanced_arrays} or @gl_extension{NV,instanced_arrays} + in OpenGL ES 2.0. +@requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} in WebGL + 1.0. + +@see @ref shaders +*/ +class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram { + public: + /** + * @brief Vertex position + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector3 "Vector3". + */ + typedef GenericGL3D::Position Position; + + /** + * @brief Normal direction + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector3 "Vector3". + */ + typedef GenericGL3D::Normal Normal; + + /** + * @brief Tangent direction + * @m_since{2019,10} + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector3 "Vector3". Use either this or the @ref Tangent4 + * attribute. If only a three-component attribute is used and + * @ref Flag::Bitangent is not enabled, it's the same as if + * @ref Tangent4 was specified with the fourth component always being + * @cpp 1.0f @ce. Used only if @ref Flag::NormalTexture is set. + * @see @ref Shaders-PhongGL-normal-mapping + */ + typedef GenericGL3D::Tangent Tangent; + + /** + * @brief Tangent direction with a bitangent sign + * @m_since_latest + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector4 "Vector4". Use either this or the @ref Tangent + * attribute. If @ref Flag::Bitangent is set, the fourth component is + * ignored and bitangents are taken from the @ref Bitangent attribute + * instead. Used only if @ref Flag::NormalTexture is set. + * @see @ref Shaders-PhongGL-normal-mapping + */ + typedef GenericGL3D::Tangent4 Tangent4; + + /** + * @brief Bitangent direction + * @m_since_latest + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector3 "Vector3". Use either this or the @ref Tangent4 + * attribute. Used only if both @ref Flag::NormalTexture and + * @ref Flag::Bitangent are set. + * @see @ref Shaders-PhongGL-normal-mapping + */ + typedef GenericGL3D::Bitangent Bitangent; + + /** + * @brief 2D texture coordinates + * + * @ref shaders-generic "Generic attribute", + * @ref Magnum::Vector2 "Vector2", used only if at least one of + * @ref Flag::AmbientTexture, @ref Flag::DiffuseTexture and + * @ref Flag::SpecularTexture is set. + */ + typedef GenericGL3D::TextureCoordinates TextureCoordinates; + + /** + * @brief Three-component vertex color + * @m_since{2019,10} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Color3. Use + * either this or the @ref Color4 attribute. Used only if + * @ref Flag::VertexColor is set. + */ + typedef GenericGL3D::Color3 Color3; + + /** + * @brief Four-component vertex color + * @m_since{2019,10} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Color4. Use + * either this or the @ref Color3 attribute. Used only if + * @ref Flag::VertexColor is set. + */ + typedef GenericGL3D::Color4 Color4; + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief (Instanced) object ID + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt. + * Used only if @ref Flag::InstancedObjectId is set. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. + */ + typedef GenericGL3D::ObjectId ObjectId; + #endif + + /** + * @brief (Instanced) transformation matrix + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Matrix4. + * Used only if @ref Flag::InstancedTransformation is set. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + */ + typedef GenericGL3D::TransformationMatrix TransformationMatrix; + + /** + * @brief (Instanced) normal matrix + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Matrix3x3. + * Used only if @ref Flag::InstancedTransformation is set. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + */ + typedef GenericGL3D::NormalMatrix NormalMatrix; + + /** + * @brief (Instanced) texture offset + * @m_since{2020,06} + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Vector2. Used + * only if @ref Flag::InstancedTextureOffset is set. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + */ + typedef typename GenericGL3D::TextureOffset TextureOffset; + + enum: UnsignedInt { + /** + * Color shader output. @ref shaders-generic "Generic output", + * present always. Expects three- or four-component floating-point + * or normalized buffer attachment. + * @m_since{2019,10} + */ + ColorOutput = GenericGL3D::ColorOutput, + + #ifndef MAGNUM_TARGET_GLES2 + /** + * Object ID shader output. @ref shaders-generic "Generic output", + * present only if @ref Flag::ObjectId is set. Expects a + * single-component unsigned integral attachment. Writes the value + * set in @ref setObjectId() there, see + * @ref Shaders-PhongGL-object-id for more information. + * @requires_gl30 Extension @gl_extension{EXT,texture_integer} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL + * 1.0. + * @m_since{2019,10} + */ + ObjectIdOutput = GenericGL3D::ObjectIdOutput + #endif + }; + + /** + * @brief Flag + * + * @see @ref Flags, @ref flags() + */ + enum class Flag: UnsignedShort { + /** + * Multiply ambient color with a texture. + * @see @ref setAmbientColor(), @ref bindAmbientTexture() + */ + AmbientTexture = 1 << 0, + + /** + * Multiply diffuse color with a texture. + * @see @ref setDiffuseColor(), @ref bindDiffuseTexture() + */ + DiffuseTexture = 1 << 1, + + /** + * Multiply specular color with a texture. + * @see @ref setSpecularColor(), @ref bindSpecularTexture() + */ + SpecularTexture = 1 << 2, + + /** + * Modify normals according to a texture. Requires the + * @ref Tangent attribute to be present. + * @m_since{2019,10} + */ + NormalTexture = 1 << 4, + + /** + * Enable alpha masking. If the combined fragment color has an + * alpha less than the value specified with @ref setAlphaMask(), + * given fragment is discarded. + * + * This uses the @glsl discard @ce operation which is known to have + * considerable performance impact on some platforms. While useful + * for cheap alpha masking that doesn't require depth sorting, + * with proper depth sorting and blending you'll usually get much + * better performance and output quality. + */ + AlphaMask = 1 << 3, + + /** + * Multiply diffuse color with a vertex color. Requires either + * the @ref Color3 or @ref Color4 attribute to be present. + * @m_since{2019,10} + */ + VertexColor = 1 << 5, + + /** + * Use the separate @ref Bitangent attribute for retrieving vertex + * bitangents. If this flag is not present, the last component of + * @ref Tangent4 is used to calculate bitangent direction. See + * @ref Shaders-PhongGL-normal-mapping for more information. + * @m_since_latest + */ + Bitangent = 1 << 11, + + /** + * Enable texture coordinate transformation. If this flag is set, + * the shader expects that at least one of + * @ref Flag::AmbientTexture, @ref Flag::DiffuseTexture, + * @ref Flag::SpecularTexture or @ref Flag::NormalTexture is + * enabled as well. + * @see @ref setTextureMatrix() + * @m_since{2020,06} + */ + TextureTransformation = 1 << 6, + + #ifndef MAGNUM_TARGET_GLES2 + /** + * Enable object ID output. See @ref Shaders-PhongGL-object-id + * for more information. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL + * 1.0. + * @m_since{2019,10} + */ + ObjectId = 1 << 7, + + /** + * Instanced object ID. Retrieves a per-instance / per-vertex + * object ID from the @ref ObjectId attribute, outputting a sum of + * the per-vertex ID and ID coming from @ref setObjectId(). + * Implicitly enables @ref Flag::ObjectId. See + * @ref Shaders-PhongGL-object-id for more information. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL + * 1.0. + * @m_since{2020,06} + */ + InstancedObjectId = (1 << 8)|ObjectId, + #endif + + /** + * Instanced transformation. Retrieves a per-instance + * transformation and normal matrix from the + * @ref TransformationMatrix / @ref NormalMatrix attributes and + * uses them together with matrices coming from + * @ref setTransformationMatrix() and @ref setNormalMatrix() (first + * the per-instance, then the uniform matrix). See + * @ref Shaders-PhongGL-instancing for more information. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + * @m_since{2020,06} + */ + InstancedTransformation = 1 << 9, + + /** + * Instanced texture offset. Retrieves a per-instance offset vector + * from the @ref TextureOffset attribute and uses it together with + * the matrix coming from @ref setTextureMatrix() (first the + * per-instance vector, then the uniform matrix). Instanced texture + * scaling and rotation is not supported at the moment, you can + * specify that only via the uniform @ref setTextureMatrix(). + * Implicitly enables @ref Flag::TextureTransformation. See + * @ref Shaders-PhongGL-instancing for more information. + * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} + * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, + * @gl_extension{EXT,instanced_arrays} or + * @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0. + * @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} + * in WebGL 1.0. + * @m_since{2020,06} + */ + InstancedTextureOffset = (1 << 10)|TextureTransformation + }; + + /** + * @brief Flags + * + * @see @ref flags() + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param flags Flags + * @param lightCount Count of light sources + */ + explicit PhongGL(Flags flags = {}, UnsignedInt lightCount = 1); + + /** + * @brief Construct without creating the underlying OpenGL object + * + * The constructed instance is equivalent to a moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + * + * This function can be safely used for constructing (and later + * destructing) objects even without any OpenGL context being active. + * However note that this is a low-level and a potentially dangerous + * API, see the documentation of @ref NoCreate for alternatives. + */ + explicit PhongGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {} + + /** @brief Copying is not allowed */ + PhongGL(const PhongGL&) = delete; + + /** @brief Move constructor */ + PhongGL(PhongGL&&) noexcept = default; + + /** @brief Copying is not allowed */ + PhongGL& operator=(const PhongGL&) = delete; + + /** @brief Move assignment */ + PhongGL& operator=(PhongGL&&) noexcept = default; + + /** @brief Flags */ + Flags flags() const { return _flags; } + + /** @brief Light count */ + UnsignedInt lightCount() const { return _lightCount; } + + /** + * @brief Set ambient color + * @return Reference to self (for method chaining) + * + * If @ref Flag::AmbientTexture is set, default value is + * @cpp 0xffffffff_rgbaf @ce and the color will be multiplied with + * ambient texture, otherwise default value is @cpp 0x00000000_rgbaf @ce. + * @see @ref bindAmbientTexture(), @ref Shaders-PhongGL-lights-ambient + */ + PhongGL& setAmbientColor(const Magnum::Color4& color); + + /** + * @brief Bind an ambient texture + * @return Reference to self (for method chaining) + * + * Expects that the shader was created with @ref Flag::AmbientTexture + * enabled. + * @see @ref bindTextures(), @ref setAmbientColor(), + * @ref Shaders-PhongGL-lights-ambient + */ + PhongGL& bindAmbientTexture(GL::Texture2D& texture); + + /** + * @brief Set diffuse color + * @return Reference to self (for method chaining) + * + * Initial value is @cpp 0xffffffff_rgbaf @ce. If @ref lightCount() is + * zero, this function is a no-op, as diffuse color doesn't contribute + * to the output in that case. + * @see @ref bindDiffuseTexture() + */ + PhongGL& setDiffuseColor(const Magnum::Color4& color); + + /** + * @brief Bind a diffuse texture + * @return Reference to self (for method chaining) + * + * Expects that the shader was created with @ref Flag::DiffuseTexture + * enabled. If @ref lightCount() is zero, this function is a no-op, as + * diffuse color doesn't contribute to the output in that case. + * @see @ref bindTextures(), @ref setDiffuseColor() + */ + PhongGL& bindDiffuseTexture(GL::Texture2D& texture); + + /** + * @brief Set normal texture scale + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Affects strength of the normal mapping. Initial value is + * @cpp 1.0f @ce, meaning the normal texture is not changed in any way; + * a value of @cpp 0.0f @ce disables the normal texture effect + * altogether. + * + * Expects that the shader was created with @ref Flag::NormalTexture + * enabled. If @ref lightCount() is zero, this function is a no-op, as + * normals don't contribute to the output in that case. + * @see @ref Shaders-PhongGL-normal-mapping, @ref bindNormalTexture(), + * @ref Trade::MaterialAttribute::NormalTextureScale + */ + PhongGL& setNormalTextureScale(Float scale); + + /** + * @brief Bind a normal texture + * @return Reference to self (for method chaining) + * @m_since{2019,10} + * + * Expects that the shader was created with @ref Flag::NormalTexture + * enabled and the @ref Tangent attribute was supplied. If + * @ref lightCount() is zero, this function is a no-op, as normals + * don't contribute to the output in that case. + * @see @ref Shaders-PhongGL-normal-mapping, + * @ref bindTextures(), @ref setNormalTextureScale() + */ + PhongGL& bindNormalTexture(GL::Texture2D& texture); + + /** + * @brief Set specular color + * @return Reference to self (for method chaining) + * + * Initial value is @cpp 0xffffff00_rgbaf @ce. Color will be multiplied + * with specular texture if @ref Flag::SpecularTexture is set. If you + * want to have a fully diffuse material, set specular color to + * @cpp 0x00000000_rgbaf @ce. If @ref lightCount() is zero, this + * function is a no-op, as specular color doesn't contribute to the + * output in that case. + * @see @ref bindSpecularTexture() + */ + PhongGL& setSpecularColor(const Magnum::Color4& color); + + /** + * @brief Bind a specular texture + * @return Reference to self (for method chaining) + * + * Expects that the shader was created with @ref Flag::SpecularTexture + * enabled. If @ref lightCount() is zero, this function is a no-op, as + * specular color doesn't contribute to the output in that case. + * @see @ref bindTextures(), @ref setSpecularColor() + */ + PhongGL& bindSpecularTexture(GL::Texture2D& texture); + + /** + * @brief Bind textures + * @return Reference to self (for method chaining) + * + * A particular texture has effect only if particular texture flag from + * @ref PhongGL::Flag "Flag" is set, you can use @cpp nullptr @ce for + * the rest. Expects that the shader was created with at least one of + * @ref Flag::AmbientTexture, @ref Flag::DiffuseTexture, + * @ref Flag::SpecularTexture or @ref Flag::NormalTexture enabled. More + * efficient than setting each texture separately. + * @see @ref bindAmbientTexture(), @ref bindDiffuseTexture(), + * @ref bindSpecularTexture(), @ref bindNormalTexture() + */ + PhongGL& bindTextures(GL::Texture2D* ambient, GL::Texture2D* diffuse, GL::Texture2D* specular, GL::Texture2D* normal + #ifdef MAGNUM_BUILD_DEPRECATED + = nullptr + #endif + ); + + /** + * @brief Set shininess + * @return Reference to self (for method chaining) + * + * The larger value, the harder surface (smaller specular highlight). + * Initial value is @cpp 80.0f @ce. If @ref lightCount() is zero, this + * function is a no-op, as specular color doesn't contribute to the + * output in that case. + */ + PhongGL& setShininess(Float shininess); + + /** + * @brief Set alpha mask value + * @return Reference to self (for method chaining) + * + * Expects that the shader was created with @ref Flag::AlphaMask + * enabled. Fragments with alpha values smaller than the mask value + * will be discarded. Initial value is @cpp 0.5f @ce. See the flag + * documentation for further information. + * + * This corresponds to @m_class{m-doc-external} [glAlphaFunc()](https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glAlphaFunc.xml) + * in classic OpenGL. + * @m_keywords{glAlphaFunc()} + */ + PhongGL& setAlphaMask(Float mask); + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Set object ID + * @return Reference to self (for method chaining) + * + * Expects that the shader was created with @ref Flag::ObjectId + * enabled. Value set here is written to the @ref ObjectIdOutput, see + * @ref Shaders-PhongGL-object-id for more information. Default is + * @cpp 0 @ce. + * @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} + * @requires_gles30 Object ID output requires integer support in + * shaders, which is not available in OpenGL ES 2.0 or WebGL 1.0. + */ + PhongGL& setObjectId(UnsignedInt id); + #endif + + /** + * @brief Set transformation matrix + * @return Reference to self (for method chaining) + * + * You need to set also @ref setNormalMatrix() with a corresponding + * value. Initial value is an identity matrix. + */ + PhongGL& setTransformationMatrix(const Matrix4& matrix); + + /** + * @brief Set normal matrix + * @return Reference to self (for method chaining) + * + * The matrix doesn't need to be normalized, as renormalization is done + * per-fragment anyway. You need to set also + * @ref setTransformationMatrix() with a corresponding value. Initial + * value is an identity matrix. If @ref lightCount() is zero, this + * function is a no-op, as normals don't contribute to the output in + * that case. + * @see @ref Math::Matrix4::normalMatrix() + */ + PhongGL& setNormalMatrix(const Matrix3x3& matrix); + + /** + * @brief Set projection matrix + * @return Reference to self (for method chaining) + * + * Initial value is an identity matrix (i.e., an orthographic + * projection of the default @f$ [ -\boldsymbol{1} ; \boldsymbol{1} ] @f$ + * cube). + */ + PhongGL& setProjectionMatrix(const Matrix4& matrix); + + /** + * @brief Set texture coordinate transformation matrix + * @return Reference to self (for method chaining) + * @m_since{2020,06} + * + * Expects that the shader was created with + * @ref Flag::TextureTransformation enabled. Initial value is an + * identity matrix. + */ + PhongGL& setTextureMatrix(const Matrix3& matrix); + + /** + * @brief Set light positions + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Depending on the fourth component, the value is treated as either a + *camera-relative position of a point light, if the fourth component is + * @cpp 1.0f @ce; or a direction *to* a directional light, if the + * fourth component is @cpp 0.0f @ce. Expects that the size of the + * @p positions array is the same as @ref lightCount(). Initial values + * are @cpp {0.0f, 0.0f, 1.0f, 0.0f} @ce --- a directional "fill" light + * coming from the camera. + * @see @ref Shaders-PhongGL-lights, @ref setLightPosition() + */ + PhongGL& setLightPositions(Containers::ArrayView positions); + + /** + * @overload + * @m_since_latest + */ + PhongGL& setLightPositions(std::initializer_list positions); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief setLightPositions(Containers::ArrayView) + * @m_deprecated_since_latest Use @ref setLightPositions(Containers::ArrayView) + * instead. This function sets the fourth component to + * @cpp 0.0f @ce to preserve the original behavior as close as + * possible. + */ + CORRADE_DEPRECATED("use setLightPositions(Containers::ArrayView) instead") PhongGL& setLightPositions(Containers::ArrayView positions); + + /** + * @brief @copybrief setLightPositions(std::initializer_list) + * @m_deprecated_since_latest Use @ref setLightPositions(std::initializer_list) + * instead. This function sets the fourth component to + * @cpp 0.0f @ce to preserve the original behavior as close as + * possible. + */ + CORRADE_DEPRECATED("use setLightPositions(std::initializer_list) instead") PhongGL& setLightPositions(std::initializer_list positions); + #endif + + /** + * @brief Set position for given light + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Unlike @ref setLightPositions() updates just a single light + * position. If updating more than one light, prefer the batch function + * instead to reduce the count of GL API calls. Expects that @p id is + * less than @ref lightCount(). + */ + PhongGL& setLightPosition(UnsignedInt id, const Vector4& position); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief setLightPosition(UnsignedInt, const Vector4&) + * @m_deprecated_since_latest Use @ref setLightPosition(UnsignedInt, const Vector4&) + * instead. This function sets the fourth component to + * @cpp 0.0f @ce to preserve the original behavior as close as + * possible. + */ + CORRADE_DEPRECATED("use setLightPosition(UnsignedInt, const Vector4&) instead") PhongGL& setLightPosition(UnsignedInt id, const Vector3& position); + + /** + * @brief Set light position + * @m_deprecated_since_latest Use @ref setLightPositions(std::initializer_list) + * with a single item instead --- it's short enough to not warrant + * the existence of a dedicated overload. This function sets the + * fourth component to @cpp 0.0f @ce to preserve the original + * behavior as close as possible. + */ + CORRADE_DEPRECATED("use setLightPositions(std::initializer_list) instead") PhongGL& setLightPosition(const Vector3& position); + #endif + + /** + * @brief Set light colors + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Initial values are @cpp 0xffffff_rgbf @ce. Expects that the size + * of the @p colors array is the same as @ref lightCount(). + * @see @ref Shaders-PhongGL-lights, @ref setLightColor() + */ + PhongGL& setLightColors(Containers::ArrayView colors); + + /** + * @overload + * @m_since_latest + */ + PhongGL& setLightColors(std::initializer_list colors); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief setLightColors(Containers::ArrayView) + * @m_deprecated_since_latest Use @ref setLightColors(Containers::ArrayView) + * instead. The alpha channel isn't used in any way. + */ + CORRADE_DEPRECATED("use setLightColors(Containers::ArrayView) instead") PhongGL& setLightColors(Containers::ArrayView colors); + + /** + * @brief @copybrief setLightColors(std::initializer_list) + * @m_deprecated_since_latest Use @ref setLightColors(std::initializer_list) + * instead. The alpha channel isn't used in any way. + */ + CORRADE_DEPRECATED("use setLightColors(std::initializer_list) instead") PhongGL& setLightColors(std::initializer_list colors); + #endif + + /** + * @brief Set color for given light + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Unlike @ref setLightColors() updates just a single light color. If + * updating more than one light, prefer the batch function instead to + * reduce the count of GL API calls. Expects that @p id is less than + * @ref lightCount(). + */ + PhongGL& setLightColor(UnsignedInt id, const Magnum::Color3& color); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief setLightColor(UnsignedInt, const Magnum::Color3&) + * @m_deprecated_since_latest Use @ref setLightColor(UnsignedInt, const Magnum::Color3&) + * instead. The alpha channel isn't used in any way. + */ + CORRADE_DEPRECATED("use setLightColor(UnsignedInt, const Magnum::Color3&) instead") PhongGL& setLightColor(UnsignedInt id, const Magnum::Color4& color); + + /** + * @brief Set light color + * @m_deprecated_since_latest Use @ref setLightColors(std::initializer_list) + * with a single item instead --- it's short enough to not warrant + * the existence of a dedicated overload. The alpha channel isn't + * used in any way. + */ + CORRADE_DEPRECATED("use setLightColor(std::initializer_list) instead") PhongGL& setLightColor(const Magnum::Color4& color); + #endif + + /** + * @brief Set light specular colors + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Usually you'd set this value to the same as @ref setLightColors(), + * but it allows for greater flexibility such as disabling specular + * highlights on certain lights. Initial values are + * @cpp 0xffffff_rgbf @ce. Expects that the size of the @p colors array + * is the same as @ref lightCount(). + * @see @ref Shaders-PhongGL-lights, @ref setLightColor() + */ + PhongGL& setLightSpecularColors(Containers::ArrayView colors); + + /** + * @overload + * @m_since_latest + */ + PhongGL& setLightSpecularColors(std::initializer_list colors); + + /** + * @brief Set specular color for given light + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Unlike @ref setLightSpecularColors() updates just a single light + * color. If updating more than one light, prefer the batch function + * instead to reduce the count of GL API calls. Expects that @p id is + * less than @ref lightCount(). + */ + PhongGL& setLightSpecularColor(UnsignedInt id, const Magnum::Color3& color); + + /** + * @brief Set light attenuation ranges + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Initial values are @ref Constants::inf(). Expects that the size of + * the @p ranges array is the same as @ref lightCount(). + * @see @ref Shaders-PhongGL-lights, @ref setLightRange() + */ + PhongGL& setLightRanges(Containers::ArrayView ranges); + + /** + * @overload + * @m_since_latest + */ + PhongGL& setLightRanges(std::initializer_list ranges); + + /** + * @brief Set attenuation range for given light + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Unlike @ref setLightRanges() updates just a single light range. If + * updating more than one light, prefer the batch function instead to + * reduce the count of GL API calls. Expects that @p id is less than + * @ref lightCount(). + */ + PhongGL& setLightRange(UnsignedInt id, Float range); + + private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + + Flags _flags; + UnsignedInt _lightCount{}; + Int _transformationMatrixUniform{0}, + _projectionMatrixUniform{1}, + _normalMatrixUniform{2}, + _textureMatrixUniform{3}, + _ambientColorUniform{4}, + _diffuseColorUniform{5}, + _specularColorUniform{6}, + _shininessUniform{7}, + _normalTextureScaleUniform{8}, + _alphaMaskUniform{9}; + #ifndef MAGNUM_TARGET_GLES2 + Int _objectIdUniform{10}; + #endif + Int _lightPositionsUniform{11}, + _lightColorsUniform, /* 11 + lightCount, set in the constructor */ + _lightSpecularColorsUniform, /* 11 + 2*lightCount */ + _lightRangesUniform; /* 11 + 3*lightCount */ +}; + +/** @debugoperatorclassenum{PhongGL,PhongGL::Flag} */ +MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, PhongGL::Flag value); + +/** @debugoperatorclassenum{PhongGL,PhongGL::Flags} */ +MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, PhongGL::Flags value); + +CORRADE_ENUMSET_OPERATORS(PhongGL::Flags) + +}} + +#endif diff --git a/src/Magnum/Shaders/Shaders.h b/src/Magnum/Shaders/Shaders.h index d5d556bce..5e353add8 100644 --- a/src/Magnum/Shaders/Shaders.h +++ b/src/Magnum/Shaders/Shaders.h @@ -38,35 +38,65 @@ namespace Magnum { namespace Shaders { #ifndef DOXYGEN_GENERATING_OUTPUT -template class DistanceFieldVector; -typedef DistanceFieldVector<2> DistanceFieldVector2D; -typedef DistanceFieldVector<3> DistanceFieldVector3D; +template class AbstractVectorGL; +typedef AbstractVectorGL<2> AbstractVectorGL2D; +typedef AbstractVectorGL<3> AbstractVectorGL3D; +#ifdef MAGNUM_BUILD_DEPRECATED +template using AbstractVector CORRADE_DEPRECATED_ALIAS("use AbstractVectorGL instead") = AbstractVectorGL; +typedef CORRADE_DEPRECATED("use AbstractVectorGL2D instead") AbstractVectorGL2D AbstractVector2D; +typedef CORRADE_DEPRECATED("use AbstractVectorGL3D instead") AbstractVectorGL3D AbstractVector3D; +#endif -template class AbstractVector; -typedef AbstractVector<2> AbstractVector2D; -typedef AbstractVector<3> AbstractVector3D; +template class DistanceFieldVectorGL; +typedef DistanceFieldVectorGL<2> DistanceFieldVectorGL2D; +typedef DistanceFieldVectorGL<3> DistanceFieldVectorGL3D; +#ifdef MAGNUM_BUILD_DEPRECATED +template using DistanceFieldVector CORRADE_DEPRECATED_ALIAS("use DistanceFieldVectorGL instead") = DistanceFieldVectorGL; +typedef CORRADE_DEPRECATED("use DistanceFieldVectorGL2D instead") DistanceFieldVectorGL2D DistanceFieldVector2D; +typedef CORRADE_DEPRECATED("use DistanceFieldVectorGL3D instead") DistanceFieldVectorGL3D DistanceFieldVector3D; +#endif -template class Flat; -typedef Flat<2> Flat2D; -typedef Flat<3> Flat3D; +template class FlatGL; +typedef FlatGL<2> FlatGL2D; +typedef FlatGL<3> FlatGL3D; +#ifdef MAGNUM_BUILD_DEPRECATED +template using Flat CORRADE_DEPRECATED_ALIAS("use FlatGL instead") = FlatGL; +typedef CORRADE_DEPRECATED("use FlatGL2D instead") FlatGL2D Flat2D; +typedef CORRADE_DEPRECATED("use FlatGL3D instead") FlatGL3D Flat3D; +#endif /* Generic is used only statically */ -class MeshVisualizer2D; -class MeshVisualizer3D; +class MeshVisualizerGL2D; +class MeshVisualizerGL3D; #ifdef MAGNUM_BUILD_DEPRECATED -typedef CORRADE_DEPRECATED("use MeshVisualizer3D instead") MeshVisualizer3D MeshVisualizer; +typedef CORRADE_DEPRECATED("use MeshVisualizerGL2D instead") MeshVisualizerGL2D MeshVisualizer2D; +typedef CORRADE_DEPRECATED("use MeshVisualizerGL3D instead") MeshVisualizerGL3D MeshVisualizer3D; +typedef CORRADE_DEPRECATED("use MeshVisualizerGL3D instead") MeshVisualizerGL3D MeshVisualizer; #endif -class Phong; +class PhongGL; +#ifdef MAGNUM_BUILD_DEPRECATED +typedef CORRADE_DEPRECATED("use PhongGL instead") PhongGL Phong; +#endif -template class Vector; -typedef Vector<2> Vector2D; -typedef Vector<3> Vector3D; +template class VectorGL; +typedef VectorGL<2> VectorGL2D; +typedef VectorGL<3> VectorGL3D; +#ifdef MAGNUM_BUILD_DEPRECATED +template using Vector CORRADE_DEPRECATED_ALIAS("use VectorGL instead") = VectorGL; +typedef CORRADE_DEPRECATED("use VectorGL2D instead") VectorGL2D Vector2D; +typedef CORRADE_DEPRECATED("use VectorGL3D instead") VectorGL3D Vector3D; +#endif -template class VertexColor; -typedef VertexColor<2> VertexColor2D; -typedef VertexColor<3> VertexColor3D; +template class VertexColorGL; +typedef VertexColorGL<2> VertexColorGL2D; +typedef VertexColorGL<3> VertexColorGL3D; +#ifdef MAGNUM_BUILD_DEPRECATED +template using VertexColor CORRADE_DEPRECATED_ALIAS("use VertexColorGL instead") = VertexColorGL; +typedef CORRADE_DEPRECATED("use VertexColorGL2D instead") VertexColorGL2D VertexColor2D; +typedef CORRADE_DEPRECATED("use VertexColorGL3D instead") VertexColorGL3D VertexColor3D; +#endif #endif }} diff --git a/src/Magnum/Shaders/Test/CMakeLists.txt b/src/Magnum/Shaders/Test/CMakeLists.txt index f2cb31c5c..5e90c28f9 100644 --- a/src/Magnum/Shaders/Test/CMakeLists.txt +++ b/src/Magnum/Shaders/Test/CMakeLists.txt @@ -23,21 +23,23 @@ # DEALINGS IN THE SOFTWARE. # -corrade_add_test(ShadersDistanceFieldVectorTest DistanceFieldVectorTest.cpp LIBRARIES MagnumShaders) -corrade_add_test(ShadersFlatTest FlatTest.cpp LIBRARIES MagnumShaders) -corrade_add_test(ShadersGenericTest GenericTest.cpp LIBRARIES MagnumShaders) -corrade_add_test(ShadersMeshVisualizerTest MeshVisualizerTest.cpp LIBRARIES MagnumShaders) -corrade_add_test(ShadersPhongTest PhongTest.cpp LIBRARIES MagnumShaders) -corrade_add_test(ShadersVectorTest VectorTest.cpp LIBRARIES MagnumShaders) -corrade_add_test(ShadersVertexColorTest VertexColorTest.cpp LIBRARIES MagnumShaders) +# There's an underscore between GL and Test to disambiguate from GLTest, which +# is a common suffix used to mark tests that need a GL context. Ugly, I know. +corrade_add_test(ShadersDistanceFieldVectorGL_Test DistanceFieldVectorGL_Test.cpp LIBRARIES MagnumShaders) +corrade_add_test(ShadersFlatGL_Test FlatGL_Test.cpp LIBRARIES MagnumShaders) +corrade_add_test(ShadersGenericGL_Test GenericGL_Test.cpp LIBRARIES MagnumShaders) +corrade_add_test(ShadersMeshVisualizerGL_Test MeshVisualizerGL_Test.cpp LIBRARIES MagnumShaders) +corrade_add_test(ShadersPhongGL_Test PhongGL_Test.cpp LIBRARIES MagnumShaders) +corrade_add_test(ShadersVectorGL_Test VectorGL_Test.cpp LIBRARIES MagnumShaders) +corrade_add_test(ShadersVertexColorGL_Test VertexColorGL_Test.cpp LIBRARIES MagnumShaders) set_target_properties( - ShadersDistanceFieldVectorTest - ShadersFlatTest - ShadersMeshVisualizerTest - ShadersPhongTest - ShadersVectorTest - ShadersVertexColorTest + ShadersDistanceFieldVectorGL_Test + ShadersFlatGL_Test + ShadersMeshVisualizerGL_Test + ShadersPhongGL_Test + ShadersVectorGL_Test + ShadersVertexColorGL_Test PROPERTIES FOLDER "Magnum/Shaders/Test") if(BUILD_GL_TESTS) diff --git a/src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp b/src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp index 117bc45a6..e9aeaee0a 100644 --- a/src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp +++ b/src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp @@ -47,7 +47,7 @@ #include "Magnum/MeshTools/Compile.h" #include "Magnum/Primitives/Plane.h" #include "Magnum/Primitives/Square.h" -#include "Magnum/Shaders/DistanceFieldVector.h" +#include "Magnum/Shaders/DistanceFieldVectorGL.h" #include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/ImageData.h" #include "Magnum/Trade/MeshData.h" @@ -99,15 +99,15 @@ using namespace Math::Literals; constexpr struct { const char* name; - DistanceFieldVector2D::Flags flags; + DistanceFieldVectorGL2D::Flags flags; } ConstructData[]{ {"", {}}, - {"texture transformation", DistanceFieldVector2D::Flag::TextureTransformation} + {"texture transformation", DistanceFieldVectorGL2D::Flag::TextureTransformation} }; const struct { const char* name; - DistanceFieldVector2D::Flags flags; + DistanceFieldVectorGL2D::Flags flags; Matrix3 textureTransformation; Color4 color, outlineColor; Float outlineRangeStart, outlineRangeEnd, smoothness; @@ -115,7 +115,7 @@ const struct { const char* file3D; bool flip; } RenderData[] { - {"texture transformation", DistanceFieldVector2D::Flag::TextureTransformation, + {"texture transformation", DistanceFieldVectorGL2D::Flag::TextureTransformation, Matrix3::translation(Vector2{1.0f})*Matrix3::scaling(Vector2{-1.0f}), 0xffffff_rgbf, 0x00000000_rgbaf, 0.5f, 1.0f, 0.04f, "defaults-distancefield.tga", "defaults-distancefield.tga", true}, @@ -181,7 +181,7 @@ template void DistanceFieldVectorGLTest::construct() { auto&& data = ConstructData[testCaseInstanceId()]; setTestCaseDescription(data.name); - DistanceFieldVector shader{data.flags}; + DistanceFieldVectorGL shader{data.flags}; CORRADE_COMPARE(shader.flags(), data.flags); CORRADE_VERIFY(shader.id()); { @@ -197,21 +197,21 @@ template void DistanceFieldVectorGLTest::construct() { template void DistanceFieldVectorGLTest::constructMove() { setTestCaseTemplateName(std::to_string(dimensions)); - DistanceFieldVector a{DistanceFieldVector::Flag::TextureTransformation}; + DistanceFieldVectorGL a{DistanceFieldVectorGL::Flag::TextureTransformation}; const GLuint id = a.id(); CORRADE_VERIFY(id); MAGNUM_VERIFY_NO_GL_ERROR(); - DistanceFieldVector b{std::move(a)}; + DistanceFieldVectorGL b{std::move(a)}; CORRADE_COMPARE(b.id(), id); - CORRADE_COMPARE(b.flags(), DistanceFieldVector::Flag::TextureTransformation); + CORRADE_COMPARE(b.flags(), DistanceFieldVectorGL::Flag::TextureTransformation); CORRADE_VERIFY(!a.id()); - DistanceFieldVector c{NoCreate}; + DistanceFieldVectorGL c{NoCreate}; c = std::move(b); CORRADE_COMPARE(c.id(), id); - CORRADE_COMPARE(c.flags(), DistanceFieldVector::Flag::TextureTransformation); + CORRADE_COMPARE(c.flags(), DistanceFieldVectorGL::Flag::TextureTransformation); CORRADE_VERIFY(!b.id()); } @@ -225,11 +225,11 @@ template void DistanceFieldVectorGLTest::setTextureMatri std::ostringstream out; Error redirectError{&out}; - DistanceFieldVector shader; + DistanceFieldVectorGL shader; shader.setTextureMatrix({}); CORRADE_COMPARE(out.str(), - "Shaders::DistanceFieldVector::setTextureMatrix(): the shader was not created with texture transformation enabled\n"); + "Shaders::DistanceFieldVectorGL::setTextureMatrix(): the shader was not created with texture transformation enabled\n"); } constexpr Vector2i RenderSize{80, 80}; @@ -293,7 +293,7 @@ void DistanceFieldVectorGLTest::renderDefaults2D() { .setSubImage(0, {}, *image); #endif - DistanceFieldVector2D{} + DistanceFieldVectorGL2D{} .bindVectorTexture(texture) .draw(square); @@ -349,7 +349,7 @@ void DistanceFieldVectorGLTest::renderDefaults3D() { .setSubImage(0, {}, *image); #endif - DistanceFieldVector2D{} + DistanceFieldVectorGL2D{} .bindVectorTexture(texture) .draw(plane); @@ -408,7 +408,7 @@ void DistanceFieldVectorGLTest::render2D() { .setSubImage(0, {}, *image); #endif - DistanceFieldVector2D shader{data.flags}; + DistanceFieldVectorGL2D shader{data.flags}; shader /** @todo implement background color */ .setColor(data.color) @@ -474,7 +474,7 @@ void DistanceFieldVectorGLTest::render3D() { .setSubImage(0, {}, *image); #endif - DistanceFieldVector3D shader{data.flags}; + DistanceFieldVectorGL3D shader{data.flags}; shader /** @todo implement background color */ .setColor(data.color) diff --git a/src/Magnum/Shaders/Test/DistanceFieldVectorTest.cpp b/src/Magnum/Shaders/Test/DistanceFieldVectorGL_Test.cpp similarity index 51% rename from src/Magnum/Shaders/Test/DistanceFieldVectorTest.cpp rename to src/Magnum/Shaders/Test/DistanceFieldVectorGL_Test.cpp index 285f6dc63..b337b24c5 100644 --- a/src/Magnum/Shaders/Test/DistanceFieldVectorTest.cpp +++ b/src/Magnum/Shaders/Test/DistanceFieldVectorGL_Test.cpp @@ -27,12 +27,14 @@ #include #include -#include "Magnum/Shaders/DistanceFieldVector.h" +#include "Magnum/Shaders/DistanceFieldVectorGL.h" namespace Magnum { namespace Shaders { namespace Test { namespace { -struct DistanceFieldVectorTest: TestSuite::Tester { - explicit DistanceFieldVectorTest(); +/* There's an underscore between GL and Test to disambiguate from GLTest, which + is a common suffix used to mark tests that need a GL context. Ugly, I know. */ +struct DistanceFieldVectorGL_Test: TestSuite::Tester { + explicit DistanceFieldVectorGL_Test(); template void constructNoCreate(); template void constructCopy(); @@ -41,50 +43,50 @@ struct DistanceFieldVectorTest: TestSuite::Tester { void debugFlags(); }; -DistanceFieldVectorTest::DistanceFieldVectorTest() { - addTests({&DistanceFieldVectorTest::constructNoCreate<2>, - &DistanceFieldVectorTest::constructNoCreate<3>, +DistanceFieldVectorGL_Test::DistanceFieldVectorGL_Test() { + addTests({&DistanceFieldVectorGL_Test::constructNoCreate<2>, + &DistanceFieldVectorGL_Test::constructNoCreate<3>, - &DistanceFieldVectorTest::constructCopy<2>, - &DistanceFieldVectorTest::constructCopy<3>, + &DistanceFieldVectorGL_Test::constructCopy<2>, + &DistanceFieldVectorGL_Test::constructCopy<3>, - &DistanceFieldVectorTest::debugFlag, - &DistanceFieldVectorTest::debugFlags}); + &DistanceFieldVectorGL_Test::debugFlag, + &DistanceFieldVectorGL_Test::debugFlags}); } -template void DistanceFieldVectorTest::constructNoCreate() { +template void DistanceFieldVectorGL_Test::constructNoCreate() { setTestCaseTemplateName(std::to_string(dimensions)); { - DistanceFieldVector shader{NoCreate}; + DistanceFieldVectorGL shader{NoCreate}; CORRADE_COMPARE(shader.id(), 0); - CORRADE_COMPARE(shader.flags(), typename DistanceFieldVector::Flags{}); + CORRADE_COMPARE(shader.flags(), typename DistanceFieldVectorGL::Flags{}); } CORRADE_VERIFY(true); } -template void DistanceFieldVectorTest::constructCopy() { +template void DistanceFieldVectorGL_Test::constructCopy() { setTestCaseTemplateName(std::to_string(dimensions)); - CORRADE_VERIFY(!std::is_copy_constructible>{}); - CORRADE_VERIFY(!std::is_copy_assignable>{}); + CORRADE_VERIFY(!std::is_copy_constructible>{}); + CORRADE_VERIFY(!std::is_copy_assignable>{}); } -void DistanceFieldVectorTest::debugFlag() { +void DistanceFieldVectorGL_Test::debugFlag() { std::ostringstream out; - Debug{&out} << DistanceFieldVector2D::Flag::TextureTransformation << DistanceFieldVector2D::Flag(0xf0); - CORRADE_COMPARE(out.str(), "Shaders::DistanceFieldVector::Flag::TextureTransformation Shaders::DistanceFieldVector::Flag(0xf0)\n"); + Debug{&out} << DistanceFieldVectorGL2D::Flag::TextureTransformation << DistanceFieldVectorGL2D::Flag(0xf0); + CORRADE_COMPARE(out.str(), "Shaders::DistanceFieldVectorGL::Flag::TextureTransformation Shaders::DistanceFieldVectorGL::Flag(0xf0)\n"); } -void DistanceFieldVectorTest::debugFlags() { +void DistanceFieldVectorGL_Test::debugFlags() { std::ostringstream out; - Debug{&out} << DistanceFieldVector3D::Flags{DistanceFieldVector3D::Flag::TextureTransformation|DistanceFieldVector3D::Flag(0xf0)} << DistanceFieldVector3D::Flags{}; - CORRADE_COMPARE(out.str(), "Shaders::DistanceFieldVector::Flag::TextureTransformation|Shaders::DistanceFieldVector::Flag(0xf0) Shaders::DistanceFieldVector::Flags{}\n"); + Debug{&out} << DistanceFieldVectorGL3D::Flags{DistanceFieldVectorGL3D::Flag::TextureTransformation|DistanceFieldVectorGL3D::Flag(0xf0)} << DistanceFieldVectorGL3D::Flags{}; + CORRADE_COMPARE(out.str(), "Shaders::DistanceFieldVectorGL::Flag::TextureTransformation|Shaders::DistanceFieldVectorGL::Flag(0xf0) Shaders::DistanceFieldVectorGL::Flags{}\n"); } }}}} -CORRADE_TEST_MAIN(Magnum::Shaders::Test::DistanceFieldVectorTest) +CORRADE_TEST_MAIN(Magnum::Shaders::Test::DistanceFieldVectorGL_Test) diff --git a/src/Magnum/Shaders/Test/FlatGLTest.cpp b/src/Magnum/Shaders/Test/FlatGLTest.cpp index d70caf85b..34f2ff8f2 100644 --- a/src/Magnum/Shaders/Test/FlatGLTest.cpp +++ b/src/Magnum/Shaders/Test/FlatGLTest.cpp @@ -51,7 +51,7 @@ #include "Magnum/MeshTools/Compile.h" #include "Magnum/Primitives/Circle.h" #include "Magnum/Primitives/UVSphere.h" -#include "Magnum/Shaders/Flat.h" +#include "Magnum/Shaders/FlatGL.h" #include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/ImageData.h" #include "Magnum/Trade/MeshData.h" @@ -138,33 +138,33 @@ using namespace Math::Literals; constexpr struct { const char* name; - Flat2D::Flags flags; + FlatGL2D::Flags flags; } ConstructData[]{ {"", {}}, - {"textured", Flat2D::Flag::Textured}, - {"textured + texture transformation", Flat2D::Flag::Textured|Flat2D::Flag::TextureTransformation}, - {"alpha mask", Flat2D::Flag::AlphaMask}, - {"alpha mask + textured", Flat2D::Flag::AlphaMask|Flat2D::Flag::Textured}, - {"vertex colors", Flat2D::Flag::VertexColor}, - {"vertex colors + textured", Flat2D::Flag::VertexColor|Flat2D::Flag::Textured}, + {"textured", FlatGL2D::Flag::Textured}, + {"textured + texture transformation", FlatGL2D::Flag::Textured|FlatGL2D::Flag::TextureTransformation}, + {"alpha mask", FlatGL2D::Flag::AlphaMask}, + {"alpha mask + textured", FlatGL2D::Flag::AlphaMask|FlatGL2D::Flag::Textured}, + {"vertex colors", FlatGL2D::Flag::VertexColor}, + {"vertex colors + textured", FlatGL2D::Flag::VertexColor|FlatGL2D::Flag::Textured}, #ifndef MAGNUM_TARGET_GLES2 - {"object ID", Flat2D::Flag::ObjectId}, - {"instanced object ID", Flat2D::Flag::InstancedObjectId}, - {"object ID + alpha mask + textured", Flat2D::Flag::ObjectId|Flat2D::Flag::AlphaMask|Flat2D::Flag::Textured}, + {"object ID", FlatGL2D::Flag::ObjectId}, + {"instanced object ID", FlatGL2D::Flag::InstancedObjectId}, + {"object ID + alpha mask + textured", FlatGL2D::Flag::ObjectId|FlatGL2D::Flag::AlphaMask|FlatGL2D::Flag::Textured}, #endif - {"instanced transformation", Flat2D::Flag::InstancedTransformation}, - {"instanced texture offset", Flat2D::Flag::Textured|Flat2D::Flag::InstancedTextureOffset} + {"instanced transformation", FlatGL2D::Flag::InstancedTransformation}, + {"instanced texture offset", FlatGL2D::Flag::Textured|FlatGL2D::Flag::InstancedTextureOffset} }; const struct { const char* name; - Flat2D::Flags flags; + FlatGL2D::Flags flags; Matrix3 textureTransformation; bool flip; } RenderTexturedData[]{ - {"", Flat2D::Flag::Textured, {}, false}, + {"", FlatGL2D::Flag::Textured, {}, false}, {"texture transformation", - Flat2D::Flag::Textured|Flat2D::Flag::TextureTransformation, + FlatGL2D::Flag::Textured|FlatGL2D::Flag::TextureTransformation, Matrix3::translation(Vector2{1.0f})*Matrix3::scaling(Vector2{-1.0f}), true}, }; @@ -174,37 +174,37 @@ const struct { const char* expected2D; const char* expected3D; bool blending; - Flat2D::Flags flags; + FlatGL2D::Flags flags; Float threshold; } RenderAlphaData[] { /* All those deliberately have a non-white diffuse in order to match the expected data from textured() */ {"none", "FlatTestFiles/textured2D.tga", "FlatTestFiles/textured3D.tga", false, - Flat2D::Flag::Textured, 0.0f}, + FlatGL2D::Flag::Textured, 0.0f}, {"blending", "FlatTestFiles/textured2D-alpha.tga", "FlatTestFiles/textured3D-alpha.tga", true, - Flat2D::Flag::Textured, 0.0f}, + FlatGL2D::Flag::Textured, 0.0f}, {"masking 0.0", "FlatTestFiles/textured2D.tga", "FlatTestFiles/textured3D.tga", false, - Flat2D::Flag::Textured, 0.0f}, + FlatGL2D::Flag::Textured, 0.0f}, {"masking 0.5", "FlatTestFiles/textured2D-alpha-mask0.5.tga", "FlatTestFiles/textured3D-alpha-mask0.5.tga", false, - Flat2D::Flag::Textured|Flat2D::Flag::AlphaMask, 0.5f}, + FlatGL2D::Flag::Textured|FlatGL2D::Flag::AlphaMask, 0.5f}, {"masking 1.0", "TestFiles/alpha-mask1.0.tga", "TestFiles/alpha-mask1.0.tga", false, - Flat2D::Flag::Textured|Flat2D::Flag::AlphaMask, 1.0f} + FlatGL2D::Flag::Textured|FlatGL2D::Flag::AlphaMask, 1.0f} }; #ifndef MAGNUM_TARGET_GLES2 constexpr struct { const char* name; - Flat2D::Flags flags; + FlatGL2D::Flags flags; UnsignedInt uniformId; UnsignedInt instanceCount; UnsignedInt expected; } RenderObjectIdData[] { {"", /* Verify that it can hold 16 bits at least */ - Flat2D::Flag::ObjectId, 48526, 0, 48526}, + FlatGL2D::Flag::ObjectId, 48526, 0, 48526}, {"instanced, first instance", - Flat2D::Flag::InstancedObjectId, 13524, 1, 24526}, + FlatGL2D::Flag::InstancedObjectId, 13524, 1, 24526}, {"instanced, second instance", - Flat2D::Flag::InstancedObjectId, 13524, 2, 62347} + FlatGL2D::Flag::InstancedObjectId, 13524, 2, 62347} }; #endif @@ -305,11 +305,11 @@ template void FlatGLTest::construct() { setTestCaseDescription(data.name); #ifndef MAGNUM_TARGET_GLES - if((data.flags & Flat2D::Flag::ObjectId) && !GL::Context::current().isExtensionSupported()) + if((data.flags & FlatGL2D::Flag::ObjectId) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported."); #endif - Flat shader{data.flags}; + FlatGL shader{data.flags}; CORRADE_COMPARE(shader.flags(), data.flags); CORRADE_VERIFY(shader.id()); { @@ -325,21 +325,21 @@ template void FlatGLTest::construct() { template void FlatGLTest::constructMove() { setTestCaseTemplateName(std::to_string(dimensions)); - Flat a{Flat::Flag::Textured}; + FlatGL a{FlatGL::Flag::Textured}; const GLuint id = a.id(); CORRADE_VERIFY(id); MAGNUM_VERIFY_NO_GL_ERROR(); - Flat b{std::move(a)}; + FlatGL b{std::move(a)}; CORRADE_COMPARE(b.id(), id); - CORRADE_COMPARE(b.flags(), Flat::Flag::Textured); + CORRADE_COMPARE(b.flags(), FlatGL::Flag::Textured); CORRADE_VERIFY(!a.id()); - Flat c{NoCreate}; + FlatGL c{NoCreate}; c = std::move(b); CORRADE_COMPARE(c.id(), id); - CORRADE_COMPARE(c.flags(), Flat::Flag::Textured); + CORRADE_COMPARE(c.flags(), FlatGL::Flag::Textured); CORRADE_VERIFY(!b.id()); } @@ -352,9 +352,9 @@ template void FlatGLTest::constructTextureTransformation std::ostringstream out; Error redirectError{&out}; - Flat{Flat::Flag::TextureTransformation}; + FlatGL{FlatGL::Flag::TextureTransformation}; CORRADE_COMPARE(out.str(), - "Shaders::Flat: texture transformation enabled but the shader is not textured\n"); + "Shaders::FlatGL: texture transformation enabled but the shader is not textured\n"); } template void FlatGLTest::bindTextureNotEnabled() { @@ -368,10 +368,10 @@ template void FlatGLTest::bindTextureNotEnabled() { Error redirectError{&out}; GL::Texture2D texture; - Flat shader; + FlatGL shader; shader.bindTexture(texture); - CORRADE_COMPARE(out.str(), "Shaders::Flat::bindTexture(): the shader was not created with texturing enabled\n"); + CORRADE_COMPARE(out.str(), "Shaders::FlatGL::bindTexture(): the shader was not created with texturing enabled\n"); } template void FlatGLTest::setAlphaMaskNotEnabled() { @@ -384,11 +384,11 @@ template void FlatGLTest::setAlphaMaskNotEnabled() { std::ostringstream out; Error redirectError{&out}; - Flat shader; + FlatGL shader; shader.setAlphaMask(0.75f); CORRADE_COMPARE(out.str(), - "Shaders::Flat::setAlphaMask(): the shader was not created with alpha mask enabled\n"); + "Shaders::FlatGL::setAlphaMask(): the shader was not created with alpha mask enabled\n"); } template void FlatGLTest::setTextureMatrixNotEnabled() { @@ -401,11 +401,11 @@ template void FlatGLTest::setTextureMatrixNotEnabled() { std::ostringstream out; Error redirectError{&out}; - Flat shader; + FlatGL shader; shader.setTextureMatrix({}); CORRADE_COMPARE(out.str(), - "Shaders::Flat::setTextureMatrix(): the shader was not created with texture transformation enabled\n"); + "Shaders::FlatGL::setTextureMatrix(): the shader was not created with texture transformation enabled\n"); } #ifndef MAGNUM_TARGET_GLES2 @@ -419,11 +419,11 @@ template void FlatGLTest::setObjectIdNotEnabled() { std::ostringstream out; Error redirectError{&out}; - Flat shader; + FlatGL shader; shader.setObjectId(33376); CORRADE_COMPARE(out.str(), - "Shaders::Flat::setObjectId(): the shader was not created with object ID enabled\n"); + "Shaders::FlatGL::setObjectId(): the shader was not created with object ID enabled\n"); } #endif @@ -457,7 +457,7 @@ void FlatGLTest::renderTeardown() { void FlatGLTest::renderDefaults2D() { GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32)); - Flat2D{} + FlatGL2D{} .draw(circle); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -477,7 +477,7 @@ void FlatGLTest::renderDefaults2D() { void FlatGLTest::renderDefaults3D() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); - Flat3D{} + FlatGL3D{} .draw(sphere); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -497,7 +497,7 @@ void FlatGLTest::renderDefaults3D() { void FlatGLTest::renderColored2D() { GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32)); - Flat2D{} + FlatGL2D{} .setColor(0x9999ff_rgbf) .setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) .draw(circle); @@ -524,7 +524,7 @@ void FlatGLTest::renderColored2D() { void FlatGLTest::renderColored3D() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); - Flat3D{} + FlatGL3D{} .setColor(0x9999ff_rgbf) .setTransformationProjectionMatrix( Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* @@ -581,7 +581,7 @@ void FlatGLTest::renderSinglePixelTextured2D() { .setStorage(1, TextureFormatRGBA, Vector2i{1}) .setSubImage(0, {}, diffuseImage); - Flat2D{Flat3D::Flag::Textured} + FlatGL2D{FlatGL3D::Flag::Textured} .setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) .bindTexture(texture) .draw(circle); @@ -619,7 +619,7 @@ void FlatGLTest::renderSinglePixelTextured3D() { .setStorage(1, TextureFormatRGBA, Vector2i{1}) .setSubImage(0, {}, diffuseImage); - Flat3D{Flat3D::Flag::Textured} + FlatGL3D{FlatGL3D::Flag::Textured} .setTransformationProjectionMatrix( Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* Matrix4::translation(Vector3::zAxis(-2.15f))* @@ -671,7 +671,7 @@ void FlatGLTest::renderTextured2D() { .setStorage(1, TextureFormatRGB, image->size()) .setSubImage(0, {}, *image); - Flat2D shader{data.flags}; + FlatGL2D shader{data.flags}; shader .setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) /* Colorized. Case without a color (where it should be white) is tested @@ -727,7 +727,7 @@ void FlatGLTest::renderTextured3D() { .setStorage(1, TextureFormatRGB, image->size()) .setSubImage(0, {}, *image); - Flat3D shader{data.flags}; + FlatGL3D shader{data.flags}; shader .setTransformationProjectionMatrix( Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* @@ -782,7 +782,7 @@ template void FlatGLTest::renderVertexColor2D() { GL::Buffer colors; colors.setData(colorData); GL::Mesh circle = MeshTools::compile(circleData); - circle.addVertexBuffer(colors, 0, GL::Attribute{}); + circle.addVertexBuffer(colors, 0, GL::Attribute{}); Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); CORRADE_VERIFY(importer); @@ -796,7 +796,7 @@ template void FlatGLTest::renderVertexColor2D() { .setStorage(1, TextureFormatRGB, image->size()) .setSubImage(0, {}, *image); - Flat2D{Flat2D::Flag::Textured|Flat2D::Flag::VertexColor} + FlatGL2D{FlatGL2D::Flag::Textured|FlatGL2D::Flag::VertexColor} .setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) .setColor(0x9999ff_rgbf) .bindTexture(texture) @@ -836,7 +836,7 @@ template void FlatGLTest::renderVertexColor3D() { GL::Buffer colors; colors.setData(colorData); GL::Mesh sphere = MeshTools::compile(sphereData); - sphere.addVertexBuffer(colors, 0, GL::Attribute{}); + sphere.addVertexBuffer(colors, 0, GL::Attribute{}); Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); CORRADE_VERIFY(importer); @@ -850,7 +850,7 @@ template void FlatGLTest::renderVertexColor3D() { .setStorage(1, TextureFormatRGB, image->size()) .setSubImage(0, {}, *image); - Flat3D{Flat3D::Flag::Textured|Flat3D::Flag::VertexColor} + FlatGL3D{FlatGL3D::Flag::Textured|FlatGL3D::Flag::VertexColor} .setTransformationProjectionMatrix( Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* Matrix4::translation(Vector3::zAxis(-2.15f))* @@ -915,12 +915,12 @@ void FlatGLTest::renderAlpha2D() { GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32, Primitives::Circle2DFlag::TextureCoordinates)); - Flat2D shader{data.flags}; + FlatGL2D shader{data.flags}; shader.setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) .setColor(0x9999ff_rgbf) .bindTexture(texture); - if(data.flags & Flat3D::Flag::AlphaMask) + if(data.flags & FlatGL3D::Flag::AlphaMask) shader.setAlphaMask(data.threshold); shader.draw(circle); @@ -966,7 +966,7 @@ void FlatGLTest::renderAlpha3D() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32, Primitives::UVSphereFlag::TextureCoordinates)); - Flat3D shader{data.flags}; + FlatGL3D shader{data.flags}; shader.setTransformationProjectionMatrix( Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* Matrix4::translation(Vector3::zAxis(-2.15f))* @@ -975,7 +975,7 @@ void FlatGLTest::renderAlpha3D() { .setColor(0x9999ff_rgbf) .bindTexture(texture); - if(data.flags & Flat3D::Flag::AlphaMask) + if(data.flags & FlatGL3D::Flag::AlphaMask) shader.setAlphaMask(data.threshold); /* For proper Z order draw back faces first and then front faces */ @@ -1026,8 +1026,8 @@ void FlatGLTest::renderObjectIdSetup() { _objectId.setStorage(GL::RenderbufferFormat::R32UI, RenderSize); _framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{1}, _objectId) .mapForDraw({ - {Flat2D::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, - {Flat2D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}} + {FlatGL2D::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, + {FlatGL2D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}} }) .clearColor(1, Vector4ui{27}); } @@ -1056,9 +1056,9 @@ void FlatGLTest::renderObjectId2D() { .setInstanceCount(data.instanceCount) .addVertexBufferInstanced( GL::Buffer{Containers::arrayView({11002u, 48823u})}, - 1, 0, Flat2D::ObjectId{}); + 1, 0, FlatGL2D::ObjectId{}); - Flat2D{data.flags} + FlatGL2D{data.flags} .setColor(0x9999ff_rgbf) .setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) .setObjectId(data.uniformId) @@ -1114,9 +1114,9 @@ void FlatGLTest::renderObjectId3D() { .setInstanceCount(data.instanceCount) .addVertexBufferInstanced( GL::Buffer{Containers::arrayView({11002u, 48823u})}, - 1, 0, Flat2D::ObjectId{}); + 1, 0, FlatGL2D::ObjectId{}); - Flat3D{data.flags} + FlatGL3D{data.flags} .setColor(0x9999ff_rgbf) .setTransformationProjectionMatrix( Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* @@ -1202,9 +1202,9 @@ void FlatGLTest::renderInstanced2D() { circle .addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0, - Flat2D::TransformationMatrix{}, - Flat2D::Color3{}, - Flat2D::TextureOffset{}) + FlatGL2D::TransformationMatrix{}, + FlatGL2D::Color3{}, + FlatGL2D::TextureOffset{}) .setInstanceCount(3); Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); @@ -1219,10 +1219,10 @@ void FlatGLTest::renderInstanced2D() { .setStorage(1, TextureFormatRGB, image->size()) .setSubImage(0, {}, *image); - Flat2D{Flat2D::Flag::Textured| - Flat2D::Flag::VertexColor| - Flat2D::Flag::InstancedTransformation| - Flat2D::Flag::InstancedTextureOffset} + FlatGL2D{FlatGL2D::Flag::Textured| + FlatGL2D::Flag::VertexColor| + FlatGL2D::Flag::InstancedTransformation| + FlatGL2D::Flag::InstancedTextureOffset} .setColor(0xffff99_rgbf) .setTransformationProjectionMatrix( Matrix3::projection({2.1f, 2.1f})* @@ -1286,9 +1286,9 @@ void FlatGLTest::renderInstanced3D() { sphere .addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0, - Flat3D::TransformationMatrix{}, - Flat3D::Color3{}, - Flat3D::TextureOffset{}) + FlatGL3D::TransformationMatrix{}, + FlatGL3D::Color3{}, + FlatGL3D::TextureOffset{}) .setInstanceCount(3); Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); @@ -1303,10 +1303,10 @@ void FlatGLTest::renderInstanced3D() { .setStorage(1, TextureFormatRGB, image->size()) .setSubImage(0, {}, *image); - Flat3D{Flat3D::Flag::Textured| - Flat3D::Flag::VertexColor| - Flat3D::Flag::InstancedTransformation| - Flat3D::Flag::InstancedTextureOffset} + FlatGL3D{FlatGL3D::Flag::Textured| + FlatGL3D::Flag::VertexColor| + FlatGL3D::Flag::InstancedTransformation| + FlatGL3D::Flag::InstancedTextureOffset} .setColor(0xffff99_rgbf) .setTransformationProjectionMatrix( Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* diff --git a/src/Magnum/Shaders/Test/FlatTest.cpp b/src/Magnum/Shaders/Test/FlatGL_Test.cpp similarity index 53% rename from src/Magnum/Shaders/Test/FlatTest.cpp rename to src/Magnum/Shaders/Test/FlatGL_Test.cpp index 481076fe1..566ac3eb3 100644 --- a/src/Magnum/Shaders/Test/FlatTest.cpp +++ b/src/Magnum/Shaders/Test/FlatGL_Test.cpp @@ -27,12 +27,14 @@ #include #include -#include "Magnum/Shaders/Flat.h" +#include "Magnum/Shaders/FlatGL.h" namespace Magnum { namespace Shaders { namespace Test { namespace { -struct FlatTest: TestSuite::Tester { - explicit FlatTest(); +/* There's an underscore between GL and Test to disambiguate from GLTest, which + is a common suffix used to mark tests that need a GL context. Ugly, I know. */ +struct FlatGL_Test: TestSuite::Tester { + explicit FlatGL_Test(); template void constructNoCreate(); template void constructCopy(); @@ -42,69 +44,69 @@ struct FlatTest: TestSuite::Tester { void debugFlagsSupersets(); }; -FlatTest::FlatTest() { - addTests({&FlatTest::constructNoCreate<2>, - &FlatTest::constructNoCreate<3>, +FlatGL_Test::FlatGL_Test() { + addTests({&FlatGL_Test::constructNoCreate<2>, + &FlatGL_Test::constructNoCreate<3>, - &FlatTest::constructCopy<2>, - &FlatTest::constructCopy<3>, + &FlatGL_Test::constructCopy<2>, + &FlatGL_Test::constructCopy<3>, - &FlatTest::debugFlag, - &FlatTest::debugFlags, - &FlatTest::debugFlagsSupersets}); + &FlatGL_Test::debugFlag, + &FlatGL_Test::debugFlags, + &FlatGL_Test::debugFlagsSupersets}); } -template void FlatTest::constructNoCreate() { +template void FlatGL_Test::constructNoCreate() { setTestCaseTemplateName(std::to_string(dimensions)); { - Flat shader{NoCreate}; + FlatGL shader{NoCreate}; CORRADE_COMPARE(shader.id(), 0); - CORRADE_COMPARE(shader.flags(), typename Flat::Flags{}); + CORRADE_COMPARE(shader.flags(), typename FlatGL::Flags{}); } CORRADE_VERIFY(true); } -template void FlatTest::constructCopy() { +template void FlatGL_Test::constructCopy() { setTestCaseTemplateName(std::to_string(dimensions)); - CORRADE_VERIFY(!std::is_copy_constructible>{}); - CORRADE_VERIFY(!std::is_copy_assignable>{}); + CORRADE_VERIFY(!std::is_copy_constructible>{}); + CORRADE_VERIFY(!std::is_copy_assignable>{}); } -void FlatTest::debugFlag() { +void FlatGL_Test::debugFlag() { std::ostringstream out; - Debug{&out} << Flat3D::Flag::Textured << Flat3D::Flag(0xf0); - CORRADE_COMPARE(out.str(), "Shaders::Flat::Flag::Textured Shaders::Flat::Flag(0xf0)\n"); + Debug{&out} << FlatGL3D::Flag::Textured << FlatGL3D::Flag(0xf0); + CORRADE_COMPARE(out.str(), "Shaders::FlatGL::Flag::Textured Shaders::FlatGL::Flag(0xf0)\n"); } -void FlatTest::debugFlags() { +void FlatGL_Test::debugFlags() { std::ostringstream out; - Debug{&out} << (Flat3D::Flag::Textured|Flat3D::Flag::AlphaMask) << Flat3D::Flags{}; - CORRADE_COMPARE(out.str(), "Shaders::Flat::Flag::Textured|Shaders::Flat::Flag::AlphaMask Shaders::Flat::Flags{}\n"); + Debug{&out} << (FlatGL3D::Flag::Textured|FlatGL3D::Flag::AlphaMask) << FlatGL3D::Flags{}; + CORRADE_COMPARE(out.str(), "Shaders::FlatGL::Flag::Textured|Shaders::FlatGL::Flag::AlphaMask Shaders::FlatGL::Flags{}\n"); } -void FlatTest::debugFlagsSupersets() { +void FlatGL_Test::debugFlagsSupersets() { #ifndef MAGNUM_TARGET_GLES2 /* InstancedObjectId is a superset of ObjectId so only one should be printed */ { std::ostringstream out; - Debug{&out} << (Flat3D::Flag::ObjectId|Flat3D::Flag::InstancedObjectId); - CORRADE_COMPARE(out.str(), "Shaders::Flat::Flag::InstancedObjectId\n"); + Debug{&out} << (FlatGL3D::Flag::ObjectId|FlatGL3D::Flag::InstancedObjectId); + CORRADE_COMPARE(out.str(), "Shaders::FlatGL::Flag::InstancedObjectId\n"); } #endif /* InstancedTextureOffset is a superset of TextureTransformation so only one should be printed */ std::ostringstream out; - Debug{&out} << (Flat3D::Flag::InstancedTextureOffset|Flat3D::Flag::TextureTransformation); - CORRADE_COMPARE(out.str(), "Shaders::Flat::Flag::InstancedTextureOffset\n"); + Debug{&out} << (FlatGL3D::Flag::InstancedTextureOffset|FlatGL3D::Flag::TextureTransformation); + CORRADE_COMPARE(out.str(), "Shaders::FlatGL::Flag::InstancedTextureOffset\n"); } }}}} -CORRADE_TEST_MAIN(Magnum::Shaders::Test::FlatTest) +CORRADE_TEST_MAIN(Magnum::Shaders::Test::FlatGL_Test) diff --git a/src/Magnum/Shaders/Test/GenericGL_Test.cpp b/src/Magnum/Shaders/Test/GenericGL_Test.cpp new file mode 100644 index 000000000..991fae075 --- /dev/null +++ b/src/Magnum/Shaders/Test/GenericGL_Test.cpp @@ -0,0 +1,118 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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 + +#include "Magnum/Shaders/GenericGL.h" +/* Yes, really */ +#include "Magnum/Shaders/generic.glsl" + +namespace Magnum { namespace Shaders { namespace Test { namespace { + +/* There's an underscore between GL and Test to disambiguate from GLTest, which + is a common suffix used to mark tests that need a GL context. Ugly, I know. */ +struct GenericGL_Test: TestSuite::Tester { + explicit GenericGL_Test(); + + void glslMatch(); + void glslMatchOutput(); + + void tbnContiguous(); + void tbnBothNormalAndQuaternion(); + void textureTransformContiguous(); +}; + +GenericGL_Test::GenericGL_Test() { + addTests({&GenericGL_Test::glslMatch, + &GenericGL_Test::glslMatchOutput, + + &GenericGL_Test::tbnContiguous, + &GenericGL_Test::tbnBothNormalAndQuaternion, + &GenericGL_Test::textureTransformContiguous}); +} + +void GenericGL_Test::glslMatch() { + CORRADE_COMPARE(POSITION_ATTRIBUTE_LOCATION, GenericGL2D::Position::Location); + CORRADE_COMPARE(POSITION_ATTRIBUTE_LOCATION, GenericGL3D::Position::Location); + + CORRADE_COMPARE(TEXTURECOORDINATES_ATTRIBUTE_LOCATION, GenericGL2D::TextureCoordinates::Location); + CORRADE_COMPARE(TEXTURECOORDINATES_ATTRIBUTE_LOCATION, GenericGL3D::TextureCoordinates::Location); + + CORRADE_COMPARE(COLOR_ATTRIBUTE_LOCATION, GenericGL2D::Color3::Location); + CORRADE_COMPARE(COLOR_ATTRIBUTE_LOCATION, GenericGL3D::Color3::Location); + CORRADE_COMPARE(COLOR_ATTRIBUTE_LOCATION, GenericGL2D::Color4::Location); + CORRADE_COMPARE(COLOR_ATTRIBUTE_LOCATION, GenericGL3D::Color4::Location); + + #ifndef MAGNUM_TARGET_GLES2 + CORRADE_COMPARE(OBJECT_ID_ATTRIBUTE_LOCATION, GenericGL2D::ObjectId::Location); + CORRADE_COMPARE(OBJECT_ID_ATTRIBUTE_LOCATION, GenericGL3D::ObjectId::Location); + #endif + + CORRADE_COMPARE(TANGENT_ATTRIBUTE_LOCATION, GenericGL3D::Tangent::Location); + CORRADE_COMPARE(TANGENT_ATTRIBUTE_LOCATION, GenericGL3D::Tangent4::Location); + CORRADE_COMPARE(BITANGENT_ATTRIBUTE_LOCATION, GenericGL3D::Bitangent::Location); + CORRADE_COMPARE(NORMAL_ATTRIBUTE_LOCATION, GenericGL3D::Normal::Location); + + CORRADE_COMPARE(TRANSFORMATION_MATRIX_ATTRIBUTE_LOCATION, GenericGL2D::TransformationMatrix::Location); + CORRADE_COMPARE(TRANSFORMATION_MATRIX_ATTRIBUTE_LOCATION, GenericGL3D::TransformationMatrix::Location); + + CORRADE_COMPARE(NORMAL_MATRIX_ATTRIBUTE_LOCATION, GenericGL3D::NormalMatrix::Location); + + CORRADE_COMPARE(TEXTURE_OFFSET_ATTRIBUTE_LOCATION, GenericGL2D::TextureOffset::Location); + CORRADE_COMPARE(TEXTURE_OFFSET_ATTRIBUTE_LOCATION, GenericGL3D::TextureOffset::Location); +} + +void GenericGL_Test::glslMatchOutput() { + CORRADE_COMPARE(COLOR_OUTPUT_ATTRIBUTE_LOCATION, GenericGL2D::ColorOutput); + CORRADE_COMPARE(COLOR_OUTPUT_ATTRIBUTE_LOCATION, GenericGL3D::ColorOutput); + + #ifndef MAGNUM_TARGET_GLES2 + CORRADE_COMPARE(OBJECT_ID_OUTPUT_ATTRIBUTE_LOCATION, GenericGL2D::ObjectIdOutput); + CORRADE_COMPARE(OBJECT_ID_OUTPUT_ATTRIBUTE_LOCATION, GenericGL3D::ObjectIdOutput); + #endif +} + +void GenericGL_Test::tbnContiguous() { + CORRADE_COMPARE(GenericGL3D::Tangent::Location + 1, GenericGL3D::Bitangent::Location); + CORRADE_COMPARE(GenericGL3D::Bitangent::Location + 1, GenericGL3D::Normal::Location); +} + +void GenericGL_Test::tbnBothNormalAndQuaternion() { + CORRADE_SKIP("Quaternion TBN not implemented yet."); + + //CORRADE_VERIFY(GenericGL3D::TbnQuaternion::Location != GenericGL3D::Normal::Location); +} + +void GenericGL_Test::textureTransformContiguous() { + /* These depend on DualQuaternion-based (instanced) transformation */ + CORRADE_SKIP("TextureRotationScale and TextureMatrix attributes not implemented yet."); + + //CORRADE_COMPARE(GenericGL3D::TextureRotationScale::Location, GenericGL3D::TextureMatrix::Location); + //CORRADE_COMPARE(GenericGL3D::TextureOffset::Location, GenericGL3D::TextureMatrix::Location + 2); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Shaders::Test::GenericGL_Test) diff --git a/src/Magnum/Shaders/Test/GenericTest.cpp b/src/Magnum/Shaders/Test/GenericTest.cpp index 08e747193..e69de29bb 100644 --- a/src/Magnum/Shaders/Test/GenericTest.cpp +++ b/src/Magnum/Shaders/Test/GenericTest.cpp @@ -1,116 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, - 2020, 2021 Vladimír Vondruš - - 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 - -#include "Magnum/Shaders/Generic.h" -/* Yes, really */ -#include "Magnum/Shaders/generic.glsl" - -namespace Magnum { namespace Shaders { namespace Test { namespace { - -struct GenericTest: TestSuite::Tester { - explicit GenericTest(); - - void glslMatch(); - void glslMatchOutput(); - - void tbnContiguous(); - void tbnBothNormalAndQuaternion(); - void textureTransformContiguous(); -}; - -GenericTest::GenericTest() { - addTests({&GenericTest::glslMatch, - &GenericTest::glslMatchOutput, - - &GenericTest::tbnContiguous, - &GenericTest::tbnBothNormalAndQuaternion, - &GenericTest::textureTransformContiguous}); -} - -void GenericTest::glslMatch() { - CORRADE_COMPARE(POSITION_ATTRIBUTE_LOCATION, Generic2D::Position::Location); - CORRADE_COMPARE(POSITION_ATTRIBUTE_LOCATION, Generic3D::Position::Location); - - CORRADE_COMPARE(TEXTURECOORDINATES_ATTRIBUTE_LOCATION, Generic2D::TextureCoordinates::Location); - CORRADE_COMPARE(TEXTURECOORDINATES_ATTRIBUTE_LOCATION, Generic3D::TextureCoordinates::Location); - - CORRADE_COMPARE(COLOR_ATTRIBUTE_LOCATION, Generic2D::Color3::Location); - CORRADE_COMPARE(COLOR_ATTRIBUTE_LOCATION, Generic3D::Color3::Location); - CORRADE_COMPARE(COLOR_ATTRIBUTE_LOCATION, Generic2D::Color4::Location); - CORRADE_COMPARE(COLOR_ATTRIBUTE_LOCATION, Generic3D::Color4::Location); - - #ifndef MAGNUM_TARGET_GLES2 - CORRADE_COMPARE(OBJECT_ID_ATTRIBUTE_LOCATION, Generic2D::ObjectId::Location); - CORRADE_COMPARE(OBJECT_ID_ATTRIBUTE_LOCATION, Generic3D::ObjectId::Location); - #endif - - CORRADE_COMPARE(TANGENT_ATTRIBUTE_LOCATION, Generic3D::Tangent::Location); - CORRADE_COMPARE(TANGENT_ATTRIBUTE_LOCATION, Generic3D::Tangent4::Location); - CORRADE_COMPARE(BITANGENT_ATTRIBUTE_LOCATION, Generic3D::Bitangent::Location); - CORRADE_COMPARE(NORMAL_ATTRIBUTE_LOCATION, Generic3D::Normal::Location); - - CORRADE_COMPARE(TRANSFORMATION_MATRIX_ATTRIBUTE_LOCATION, Generic2D::TransformationMatrix::Location); - CORRADE_COMPARE(TRANSFORMATION_MATRIX_ATTRIBUTE_LOCATION, Generic3D::TransformationMatrix::Location); - - CORRADE_COMPARE(NORMAL_MATRIX_ATTRIBUTE_LOCATION, Generic3D::NormalMatrix::Location); - - CORRADE_COMPARE(TEXTURE_OFFSET_ATTRIBUTE_LOCATION, Generic2D::TextureOffset::Location); - CORRADE_COMPARE(TEXTURE_OFFSET_ATTRIBUTE_LOCATION, Generic3D::TextureOffset::Location); -} - -void GenericTest::glslMatchOutput() { - CORRADE_COMPARE(COLOR_OUTPUT_ATTRIBUTE_LOCATION, Generic2D::ColorOutput); - CORRADE_COMPARE(COLOR_OUTPUT_ATTRIBUTE_LOCATION, Generic3D::ColorOutput); - - #ifndef MAGNUM_TARGET_GLES2 - CORRADE_COMPARE(OBJECT_ID_OUTPUT_ATTRIBUTE_LOCATION, Generic2D::ObjectIdOutput); - CORRADE_COMPARE(OBJECT_ID_OUTPUT_ATTRIBUTE_LOCATION, Generic3D::ObjectIdOutput); - #endif -} - -void GenericTest::tbnContiguous() { - CORRADE_COMPARE(Generic3D::Tangent::Location + 1, Generic3D::Bitangent::Location); - CORRADE_COMPARE(Generic3D::Bitangent::Location + 1, Generic3D::Normal::Location); -} - -void GenericTest::tbnBothNormalAndQuaternion() { - CORRADE_SKIP("Quaternion TBN not implemented yet."); - - //CORRADE_VERIFY(Generic3D::TbnQuaternion::Location != Generic3D::Normal::Location); -} - -void GenericTest::textureTransformContiguous() { - /* These depend on DualQuaternion-based (instanced) transformation */ - CORRADE_SKIP("TextureRotationScale and TextureMatrix attributes not implemented yet."); - - //CORRADE_COMPARE(Generic3D::TextureRotationScale::Location, Generic3D::TextureMatrix::Location); - //CORRADE_COMPARE(Generic3D::TextureOffset::Location, Generic3D::TextureMatrix::Location + 2); -} - -}}}} - -CORRADE_TEST_MAIN(Magnum::Shaders::Test::GenericTest) diff --git a/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp b/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp index 6cab62742..183d504f4 100644 --- a/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp +++ b/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp @@ -57,7 +57,7 @@ #include "Magnum/Primitives/Icosphere.h" #include "Magnum/Primitives/Plane.h" #include "Magnum/Primitives/UVSphere.h" -#include "Magnum/Shaders/MeshVisualizer.h" +#include "Magnum/Shaders/MeshVisualizerGL.h" #include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/MeshData.h" @@ -153,60 +153,60 @@ using namespace Math::Literals; constexpr struct { const char* name; - MeshVisualizer2D::Flags flags; + MeshVisualizerGL2D::Flags flags; } ConstructData2D[] { - {"wireframe w/o GS", MeshVisualizer2D::Flag::Wireframe|MeshVisualizer2D::Flag::NoGeometryShader}, + {"wireframe w/o GS", MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader}, #ifndef MAGNUM_TARGET_GLES2 - {"object ID", MeshVisualizer2D::Flag::InstancedObjectId}, - {"vertex ID", MeshVisualizer2D::Flag::VertexId}, + {"object ID", MeshVisualizerGL2D::Flag::InstancedObjectId}, + {"vertex ID", MeshVisualizerGL2D::Flag::VertexId}, #ifndef MAGNUM_TARGET_WEBGL - {"primitive ID", MeshVisualizer2D::Flag::PrimitiveId}, + {"primitive ID", MeshVisualizerGL2D::Flag::PrimitiveId}, #endif - {"primitive ID from vertex ID", MeshVisualizer2D::Flag::PrimitiveIdFromVertexId} + {"primitive ID from vertex ID", MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId} #endif }; constexpr struct { const char* name; - MeshVisualizer3D::Flags flags; + MeshVisualizerGL3D::Flags flags; } ConstructData3D[] { - {"wireframe w/o GS", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::NoGeometryShader}, + {"wireframe w/o GS", MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader}, #ifndef MAGNUM_TARGET_GLES2 - {"object ID", MeshVisualizer3D::Flag::InstancedObjectId}, - {"vertex ID", MeshVisualizer3D::Flag::VertexId}, + {"object ID", MeshVisualizerGL3D::Flag::InstancedObjectId}, + {"vertex ID", MeshVisualizerGL3D::Flag::VertexId}, #ifndef MAGNUM_TARGET_WEBGL - {"primitive ID", MeshVisualizer3D::Flag::PrimitiveId}, + {"primitive ID", MeshVisualizerGL3D::Flag::PrimitiveId}, #endif - {"primitive ID from vertex ID", MeshVisualizer3D::Flag::PrimitiveIdFromVertexId} + {"primitive ID from vertex ID", MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId} #endif }; #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) constexpr struct { const char* name; - MeshVisualizer3D::Flags flags; + MeshVisualizerGL3D::Flags flags; } ConstructGeometryShaderData3D[] { - {"wireframe", MeshVisualizer3D::Flag::Wireframe}, - {"tangent direction", MeshVisualizer3D::Flag::TangentDirection}, - {"bitangent direction from tangent", MeshVisualizer3D::Flag::BitangentFromTangentDirection}, - {"bitangent direction", MeshVisualizer3D::Flag::BitangentDirection}, - {"normal direction", MeshVisualizer3D::Flag::NormalDirection}, - {"tbn direction", MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::BitangentDirection|MeshVisualizer3D::Flag::NormalDirection}, - {"tbn direction with bitangent from tangent", MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::BitangentFromTangentDirection|MeshVisualizer3D::Flag::NormalDirection}, - {"wireframe + vertex id", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::VertexId}, - {"wireframe + t/n direction", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::NormalDirection}, - {"wireframe + object id + t/n direction", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::InstancedObjectId|MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::NormalDirection}, - {"wireframe + vertex id + t/b direction", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::VertexId|MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::BitangentDirection} + {"wireframe", MeshVisualizerGL3D::Flag::Wireframe}, + {"tangent direction", MeshVisualizerGL3D::Flag::TangentDirection}, + {"bitangent direction from tangent", MeshVisualizerGL3D::Flag::BitangentFromTangentDirection}, + {"bitangent direction", MeshVisualizerGL3D::Flag::BitangentDirection}, + {"normal direction", MeshVisualizerGL3D::Flag::NormalDirection}, + {"tbn direction", MeshVisualizerGL3D::Flag::TangentDirection|MeshVisualizerGL3D::Flag::BitangentDirection|MeshVisualizerGL3D::Flag::NormalDirection}, + {"tbn direction with bitangent from tangent", MeshVisualizerGL3D::Flag::TangentDirection|MeshVisualizerGL3D::Flag::BitangentFromTangentDirection|MeshVisualizerGL3D::Flag::NormalDirection}, + {"wireframe + vertex id", MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::VertexId}, + {"wireframe + t/n direction", MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::TangentDirection|MeshVisualizerGL3D::Flag::NormalDirection}, + {"wireframe + object id + t/n direction", MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::InstancedObjectId|MeshVisualizerGL3D::Flag::TangentDirection|MeshVisualizerGL3D::Flag::NormalDirection}, + {"wireframe + vertex id + t/b direction", MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::VertexId|MeshVisualizerGL3D::Flag::TangentDirection|MeshVisualizerGL3D::Flag::BitangentDirection} }; #endif constexpr struct { const char* name; - MeshVisualizer2D::Flags flags; + MeshVisualizerGL2D::Flags flags; const char* message; } ConstructInvalidData2D[] { {"no feature enabled", - MeshVisualizer2D::Flag::NoGeometryShader, /* not a feature flag */ + MeshVisualizerGL2D::Flag::NoGeometryShader, /* not a feature flag */ #ifndef MAGNUM_TARGET_GLES2 "2D: at least one visualization feature has to be enabled" #else @@ -215,21 +215,21 @@ constexpr struct { }, #ifndef MAGNUM_TARGET_GLES2 {"both object and primitive id", - MeshVisualizer2D::Flag::InstancedObjectId|MeshVisualizer2D::Flag::PrimitiveIdFromVertexId, + MeshVisualizerGL2D::Flag::InstancedObjectId|MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId, ": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"}, {"both object and vertex id", - MeshVisualizer2D::Flag::InstancedObjectId|MeshVisualizer2D::Flag::VertexId, + MeshVisualizerGL2D::Flag::InstancedObjectId|MeshVisualizerGL2D::Flag::VertexId, ": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"} #endif }; constexpr struct { const char* name; - MeshVisualizer3D::Flags flags; + MeshVisualizerGL3D::Flags flags; const char* message; } ConstructInvalidData3D[] { {"no feature enabled", - MeshVisualizer3D::Flag::NoGeometryShader, /* not a feature flag */ + MeshVisualizerGL3D::Flag::NoGeometryShader, /* not a feature flag */ #ifndef MAGNUM_TARGET_GLES2 "3D: at least one visualization feature has to be enabled" #else @@ -238,10 +238,10 @@ constexpr struct { }, #ifndef MAGNUM_TARGET_GLES2 {"both object and primitive id", - MeshVisualizer3D::Flag::InstancedObjectId|MeshVisualizer3D::Flag::PrimitiveIdFromVertexId, + MeshVisualizerGL3D::Flag::InstancedObjectId|MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId, ": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"}, {"both vertex and primitive id", - MeshVisualizer3D::Flag::VertexId|MeshVisualizer3D::Flag::PrimitiveIdFromVertexId, + MeshVisualizerGL3D::Flag::VertexId|MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId, ": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"} #endif }; @@ -261,83 +261,83 @@ constexpr struct { constexpr struct { const char* name; - MeshVisualizer2D::Flags flags; + MeshVisualizerGL2D::Flags flags; Float width, smoothness; const char* file; const char* fileXfail; } WireframeData2D[] { #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - {"", MeshVisualizer2D::Flags{}, + {"", MeshVisualizerGL2D::Flags{}, 1.0f, 2.0f, "wireframe2D.tga", nullptr}, - {"wide/sharp", MeshVisualizer2D::Flags{}, + {"wide/sharp", MeshVisualizerGL2D::Flags{}, 3.0f, 1.0f, "wireframe-wide2D.tga", nullptr}, #endif - {"no geometry shader", MeshVisualizer2D::Flag::NoGeometryShader, + {"no geometry shader", MeshVisualizerGL2D::Flag::NoGeometryShader, 1.0f, 2.0f, "wireframe2D.tga", "wireframe-nogeo2D.tga"}, - {"no geometry shader, wide/sharp", MeshVisualizer2D::Flag::NoGeometryShader, + {"no geometry shader, wide/sharp", MeshVisualizerGL2D::Flag::NoGeometryShader, 3.0f, 1.0f, "wireframe-wide2D.tga", "wireframe-nogeo2D.tga"} }; constexpr struct { const char* name; - MeshVisualizer3D::Flags flags; + MeshVisualizerGL3D::Flags flags; Float width, smoothness; const char* file; const char* fileXfail; } WireframeData3D[] { #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - {"", MeshVisualizer3D::Flags{}, + {"", MeshVisualizerGL3D::Flags{}, 1.0f, 2.0f, "wireframe3D.tga", nullptr}, - {"wide/sharp", MeshVisualizer3D::Flags{}, + {"wide/sharp", MeshVisualizerGL3D::Flags{}, 3.0f, 1.0f, "wireframe-wide3D.tga", nullptr}, #endif {"no geometry shader", - MeshVisualizer3D::Flag::NoGeometryShader, + MeshVisualizerGL3D::Flag::NoGeometryShader, 1.0f, 2.0f, "wireframe3D.tga", "wireframe-nogeo3D.tga"}, {"no geometry shader, wide/sharp", - MeshVisualizer3D::Flag::NoGeometryShader, + MeshVisualizerGL3D::Flag::NoGeometryShader, 3.0f, 1.0f, "wireframe-wide3D.tga", "wireframe-nogeo3D.tga"} }; #ifndef MAGNUM_TARGET_GLES2 constexpr struct { const char* name; - MeshVisualizer2D::Flags flags2D; - MeshVisualizer3D::Flags flags3D; + MeshVisualizerGL2D::Flags flags2D; + MeshVisualizerGL3D::Flags flags3D; const char* file2D; const char* file3D; } ObjectVertexPrimitiveIdData[] { {"object ID", - MeshVisualizer2D::Flag::InstancedObjectId, - MeshVisualizer3D::Flag::InstancedObjectId, + MeshVisualizerGL2D::Flag::InstancedObjectId, + MeshVisualizerGL3D::Flag::InstancedObjectId, "objectid2D.tga", "objectid3D.tga"}, {"vertex ID", - MeshVisualizer2D::Flag::VertexId, - MeshVisualizer3D::Flag::VertexId, + MeshVisualizerGL2D::Flag::VertexId, + MeshVisualizerGL3D::Flag::VertexId, "vertexid2D.tga", "vertexid3D.tga"}, #ifndef MAGNUM_TARGET_WEBGL {"primitive ID", - MeshVisualizer2D::Flag::PrimitiveId, - MeshVisualizer3D::Flag::PrimitiveId, + MeshVisualizerGL2D::Flag::PrimitiveId, + MeshVisualizerGL3D::Flag::PrimitiveId, "primitiveid2D.tga", "primitiveid3D.tga"}, #endif {"primitive ID from vertex ID", - MeshVisualizer2D::Flag::PrimitiveIdFromVertexId, - MeshVisualizer3D::Flag::PrimitiveIdFromVertexId, + MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId, + MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId, "primitiveid2D.tga", "primitiveid3D.tga"}, {"wireframe + object ID", - MeshVisualizer2D::Flag::InstancedObjectId|MeshVisualizer2D::Flag::Wireframe, - MeshVisualizer3D::Flag::InstancedObjectId|MeshVisualizer3D::Flag::Wireframe, + MeshVisualizerGL2D::Flag::InstancedObjectId|MeshVisualizerGL2D::Flag::Wireframe, + MeshVisualizerGL3D::Flag::InstancedObjectId|MeshVisualizerGL3D::Flag::Wireframe, "wireframe-objectid2D.tga", "wireframe-objectid3D.tga"}, {"wireframe + object ID, no geometry shader", - MeshVisualizer2D::Flag::InstancedObjectId|MeshVisualizer2D::Flag::Wireframe| - MeshVisualizer2D::Flag::NoGeometryShader, - MeshVisualizer3D::Flag::InstancedObjectId|MeshVisualizer3D::Flag::Wireframe| - MeshVisualizer3D::Flag::NoGeometryShader, + MeshVisualizerGL2D::Flag::InstancedObjectId|MeshVisualizerGL2D::Flag::Wireframe| + MeshVisualizerGL2D::Flag::NoGeometryShader, + MeshVisualizerGL3D::Flag::InstancedObjectId|MeshVisualizerGL3D::Flag::Wireframe| + MeshVisualizerGL3D::Flag::NoGeometryShader, "wireframe-nogeo-objectid2D.tga", "wireframe-nogeo-objectid3D.tga"}, {"wireframe + vertex ID", - MeshVisualizer2D::Flag::VertexId|MeshVisualizer2D::Flag::Wireframe, - MeshVisualizer3D::Flag::VertexId|MeshVisualizer3D::Flag::Wireframe, + MeshVisualizerGL2D::Flag::VertexId|MeshVisualizerGL2D::Flag::Wireframe, + MeshVisualizerGL3D::Flag::VertexId|MeshVisualizerGL3D::Flag::Wireframe, "wireframe-vertexid2D.tga", "wireframe-vertexid3D.tga"} }; #endif @@ -345,8 +345,8 @@ constexpr struct { #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) constexpr struct { const char* name; - MeshVisualizer3D::Flags flags; - MeshVisualizer3D::Flags secondPassFlags; + MeshVisualizerGL3D::Flags flags; + MeshVisualizerGL3D::Flags secondPassFlags; bool skipBitagnentEvenIfEnabledInFlags; Float smoothness; Float lineWidth; @@ -355,50 +355,50 @@ constexpr struct { const char* file; } TangentBitangentNormalData[] { {"", - MeshVisualizer3D::Flag::TangentDirection| - MeshVisualizer3D::Flag::BitangentDirection| - MeshVisualizer3D::Flag::NormalDirection, {}, + MeshVisualizerGL3D::Flag::TangentDirection| + MeshVisualizerGL3D::Flag::BitangentDirection| + MeshVisualizerGL3D::Flag::NormalDirection, {}, false, 2.0f, 1.0f, 0.6f, 1.0f, "tbn.tga"}, {"bitangents from tangents", - MeshVisualizer3D::Flag::TangentDirection| - MeshVisualizer3D::Flag::BitangentFromTangentDirection| - MeshVisualizer3D::Flag::NormalDirection, {}, + MeshVisualizerGL3D::Flag::TangentDirection| + MeshVisualizerGL3D::Flag::BitangentFromTangentDirection| + MeshVisualizerGL3D::Flag::NormalDirection, {}, false, 2.0f, 1.0f, 0.6f, 1.0f, "tbn.tga"}, {"scaled data", - MeshVisualizer3D::Flag::TangentDirection| - MeshVisualizer3D::Flag::BitangentDirection| - MeshVisualizer3D::Flag::NormalDirection, {}, + MeshVisualizerGL3D::Flag::TangentDirection| + MeshVisualizerGL3D::Flag::BitangentDirection| + MeshVisualizerGL3D::Flag::NormalDirection, {}, false, 2.0f, 1.0f, 0.6f, 5.0f, "tbn.tga"}, {"wide blurry lines", - MeshVisualizer3D::Flag::TangentDirection| - MeshVisualizer3D::Flag::BitangentDirection| - MeshVisualizer3D::Flag::NormalDirection, {}, + MeshVisualizerGL3D::Flag::TangentDirection| + MeshVisualizerGL3D::Flag::BitangentDirection| + MeshVisualizerGL3D::Flag::NormalDirection, {}, false, 5.0f, 5.0f, 0.8f, 1.0f, "tbn-wide.tga"}, {"only bitangent from tangent", - MeshVisualizer3D::Flag::BitangentFromTangentDirection, {}, + MeshVisualizerGL3D::Flag::BitangentFromTangentDirection, {}, false, 2.0f, 1.0f, 0.6f, 1.0f, "bitangents-from-tangents.tga"}, {"wireframe + primitive ID + tangents + normals, single pass", - MeshVisualizer3D::Flag::Wireframe| - MeshVisualizer3D::Flag::PrimitiveId| - MeshVisualizer3D::Flag::TangentDirection| - MeshVisualizer3D::Flag::NormalDirection, {}, + MeshVisualizerGL3D::Flag::Wireframe| + MeshVisualizerGL3D::Flag::PrimitiveId| + MeshVisualizerGL3D::Flag::TangentDirection| + MeshVisualizerGL3D::Flag::NormalDirection, {}, false, 2.0f, 1.0f, 0.6f, 1.0f, "wireframe-primitiveid-tn.tga"}, {"wireframe + primitive ID, rendering all, but only tangents + normals present", - MeshVisualizer3D::Flag::Wireframe| - MeshVisualizer3D::Flag::PrimitiveId| - MeshVisualizer3D::Flag::TangentDirection| - MeshVisualizer3D::Flag::BitangentDirection| - MeshVisualizer3D::Flag::NormalDirection, {}, + MeshVisualizerGL3D::Flag::Wireframe| + MeshVisualizerGL3D::Flag::PrimitiveId| + MeshVisualizerGL3D::Flag::TangentDirection| + MeshVisualizerGL3D::Flag::BitangentDirection| + MeshVisualizerGL3D::Flag::NormalDirection, {}, true, 2.0f, 1.0f, 0.6f, 1.0f, "wireframe-primitiveid-tn.tga"}, {"wireframe + tangents + normals, two passes", - MeshVisualizer3D::Flag::TangentDirection| - MeshVisualizer3D::Flag::NormalDirection, - MeshVisualizer3D::Flag::Wireframe, + MeshVisualizerGL3D::Flag::TangentDirection| + MeshVisualizerGL3D::Flag::NormalDirection, + MeshVisualizerGL3D::Flag::Wireframe, false, 2.0f, 1.0f, 0.6f, 1.0f, "wireframe-tn-smooth.tga"}, {"primitive ID + tangents + normals", - MeshVisualizer3D::Flag::PrimitiveId| - MeshVisualizer3D::Flag::TangentDirection| - MeshVisualizer3D::Flag::NormalDirection, {}, + MeshVisualizerGL3D::Flag::PrimitiveId| + MeshVisualizerGL3D::Flag::TangentDirection| + MeshVisualizerGL3D::Flag::NormalDirection, {}, false, 2.0f, 1.0f, 0.6f, 1.0f, "primitiveid-tn.tga"} }; #endif @@ -543,12 +543,12 @@ void MeshVisualizerGLTest::construct2D() { setTestCaseDescription(data.name); #ifndef MAGNUM_TARGET_GLES - if((data.flags & MeshVisualizer2D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) + if((data.flags & MeshVisualizerGL2D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported."); #endif #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - if(data.flags >= MeshVisualizer2D::Flag::PrimitiveIdFromVertexId && + if(data.flags >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId && #ifndef MAGNUM_TARGET_GLES !GL::Context::current().isVersionSupported(GL::Version::GL300) #else @@ -558,7 +558,7 @@ void MeshVisualizerGLTest::construct2D() { #endif #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - if(data.flags & MeshVisualizer2D::Flag::PrimitiveId && !(data.flags >= MeshVisualizer2D::Flag::PrimitiveIdFromVertexId) && + if(data.flags & MeshVisualizerGL2D::Flag::PrimitiveId && !(data.flags >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId) && #ifndef MAGNUM_TARGET_GLES !GL::Context::current().isVersionSupported(GL::Version::GL320) #else @@ -567,7 +567,7 @@ void MeshVisualizerGLTest::construct2D() { ) CORRADE_SKIP("gl_PrimitiveID not supported."); #endif - MeshVisualizer2D shader{data.flags}; + MeshVisualizerGL2D shader{data.flags}; CORRADE_COMPARE(shader.flags(), data.flags); CORRADE_VERIFY(shader.id()); { @@ -585,12 +585,12 @@ void MeshVisualizerGLTest::construct3D() { setTestCaseDescription(data.name); #ifndef MAGNUM_TARGET_GLES - if((data.flags & MeshVisualizer3D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) + if((data.flags & MeshVisualizerGL3D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported."); #endif #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - if(data.flags >= MeshVisualizer3D::Flag::PrimitiveIdFromVertexId && + if(data.flags >= MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId && #ifndef MAGNUM_TARGET_GLES !GL::Context::current().isVersionSupported(GL::Version::GL300) #else @@ -600,7 +600,7 @@ void MeshVisualizerGLTest::construct3D() { #endif #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - if(data.flags & MeshVisualizer3D::Flag::PrimitiveId && !(data.flags >= MeshVisualizer3D::Flag::PrimitiveIdFromVertexId) && + if(data.flags & MeshVisualizerGL3D::Flag::PrimitiveId && !(data.flags >= MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId) && #ifndef MAGNUM_TARGET_GLES !GL::Context::current().isVersionSupported(GL::Version::GL320) #else @@ -609,7 +609,7 @@ void MeshVisualizerGLTest::construct3D() { ) CORRADE_SKIP("gl_PrimitiveID not supported."); #endif - MeshVisualizer3D shader{data.flags}; + MeshVisualizerGL3D shader{data.flags}; CORRADE_COMPARE(shader.flags(), data.flags); CORRADE_VERIFY(shader.id()); { @@ -637,8 +637,8 @@ void MeshVisualizerGLTest::constructWireframeGeometryShader2D() { Debug() << "Using" << GL::Extensions::NV::shader_noperspective_interpolation::string(); #endif - MeshVisualizer2D shader{MeshVisualizer2D::Flag::Wireframe}; - CORRADE_COMPARE(shader.flags(), MeshVisualizer2D::Flag::Wireframe); + MeshVisualizerGL2D shader{MeshVisualizerGL2D::Flag::Wireframe}; + CORRADE_COMPARE(shader.flags(), MeshVisualizerGL2D::Flag::Wireframe); { #ifdef CORRADE_TARGET_APPLE CORRADE_EXPECT_FAIL("macOS drivers need insane amount of state to validate properly."); @@ -665,7 +665,7 @@ void MeshVisualizerGLTest::constructGeometryShader3D() { Debug() << "Using" << GL::Extensions::NV::shader_noperspective_interpolation::string(); #endif - MeshVisualizer3D shader{data.flags}; + MeshVisualizerGL3D shader{data.flags}; CORRADE_COMPARE(shader.flags(), data.flags); { #ifdef CORRADE_TARGET_APPLE @@ -687,8 +687,8 @@ void MeshVisualizerGLTest::construct2DInvalid() { std::ostringstream out; Error redirectError{&out}; - MeshVisualizer2D{data.flags}; - CORRADE_COMPARE(out.str(), Utility::formatString("Shaders::MeshVisualizer{}\n", data.message)); + MeshVisualizerGL2D{data.flags}; + CORRADE_COMPARE(out.str(), Utility::formatString("Shaders::MeshVisualizerGL{}\n", data.message)); } void MeshVisualizerGLTest::construct3DInvalid() { @@ -701,8 +701,8 @@ void MeshVisualizerGLTest::construct3DInvalid() { std::ostringstream out; Error redirectError{&out}; - MeshVisualizer3D{data.flags}; - CORRADE_COMPARE(out.str(), Utility::formatString("Shaders::MeshVisualizer{}\n", data.message)); + MeshVisualizerGL3D{data.flags}; + CORRADE_COMPARE(out.str(), Utility::formatString("Shaders::MeshVisualizerGL{}\n", data.message)); } #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) @@ -721,9 +721,9 @@ void MeshVisualizerGLTest::construct3DGeometryShaderDisabledButNeeded() { std::ostringstream out; Error redirectError{&out}; - MeshVisualizer3D{MeshVisualizer3D::Flag::NoGeometryShader|MeshVisualizer3D::Flag::NormalDirection}; + MeshVisualizerGL3D{MeshVisualizerGL3D::Flag::NoGeometryShader|MeshVisualizerGL3D::Flag::NormalDirection}; CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer3D: geometry shader has to be enabled when rendering TBN direction\n"); + "Shaders::MeshVisualizerGL3D: geometry shader has to be enabled when rendering TBN direction\n"); } void MeshVisualizerGLTest::construct3DConflictingBitangentInput() { @@ -741,47 +741,47 @@ void MeshVisualizerGLTest::construct3DConflictingBitangentInput() { std::ostringstream out; Error redirectError{&out}; - MeshVisualizer3D{MeshVisualizer3D::Flag::BitangentFromTangentDirection|MeshVisualizer3D::Flag::BitangentDirection}; + MeshVisualizerGL3D{MeshVisualizerGL3D::Flag::BitangentFromTangentDirection|MeshVisualizerGL3D::Flag::BitangentDirection}; CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer3D: Flag::BitangentDirection and Flag::BitangentFromTangentDirection are mutually exclusive\n"); + "Shaders::MeshVisualizerGL3D: Flag::BitangentDirection and Flag::BitangentFromTangentDirection are mutually exclusive\n"); } #endif void MeshVisualizerGLTest::constructMove2D() { - MeshVisualizer2D a{MeshVisualizer2D::Flag::Wireframe|MeshVisualizer2D::Flag::NoGeometryShader}; + MeshVisualizerGL2D a{MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader}; const GLuint id = a.id(); CORRADE_VERIFY(id); MAGNUM_VERIFY_NO_GL_ERROR(); - MeshVisualizer2D b{std::move(a)}; + MeshVisualizerGL2D b{std::move(a)}; CORRADE_COMPARE(b.id(), id); - CORRADE_COMPARE(b.flags(), MeshVisualizer2D::Flag::Wireframe|MeshVisualizer2D::Flag::NoGeometryShader); + CORRADE_COMPARE(b.flags(), MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader); CORRADE_VERIFY(!a.id()); - MeshVisualizer2D c{NoCreate}; + MeshVisualizerGL2D c{NoCreate}; c = std::move(b); CORRADE_COMPARE(c.id(), id); - CORRADE_COMPARE(c.flags(), MeshVisualizer2D::Flag::Wireframe|MeshVisualizer2D::Flag::NoGeometryShader); + CORRADE_COMPARE(c.flags(), MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader); CORRADE_VERIFY(!b.id()); } void MeshVisualizerGLTest::constructMove3D() { - MeshVisualizer3D a{MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::NoGeometryShader}; + MeshVisualizerGL3D a{MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader}; const GLuint id = a.id(); CORRADE_VERIFY(id); MAGNUM_VERIFY_NO_GL_ERROR(); - MeshVisualizer3D b{std::move(a)}; + MeshVisualizerGL3D b{std::move(a)}; CORRADE_COMPARE(b.id(), id); - CORRADE_COMPARE(b.flags(), MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::NoGeometryShader); + CORRADE_COMPARE(b.flags(), MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader); CORRADE_VERIFY(!a.id()); - MeshVisualizer3D c{NoCreate}; + MeshVisualizerGL3D c{NoCreate}; c = std::move(b); CORRADE_COMPARE(c.id(), id); - CORRADE_COMPARE(c.flags(), MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::NoGeometryShader); + CORRADE_COMPARE(c.flags(), MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader); CORRADE_VERIFY(!b.id()); } @@ -795,16 +795,16 @@ void MeshVisualizerGLTest::setWireframeNotEnabled2D() { /* The constructor asserts for at least some feature being enabled (which is just wireframe in case of 2D), so fake it with a NoCreate */ - MeshVisualizer2D shader{NoCreate}; + MeshVisualizerGL2D shader{NoCreate}; shader .setColor({}); #ifndef MAGNUM_TARGET_GLES2 CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled\n"); + "Shaders::MeshVisualizerGL::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled\n"); #else CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe enabled\n"); + "Shaders::MeshVisualizerGL::setColor(): the shader was not created with wireframe enabled\n"); #endif out.str({}); @@ -814,9 +814,9 @@ void MeshVisualizerGLTest::setWireframeNotEnabled2D() { .setSmoothness({}); CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer::setWireframeColor(): the shader was not created with wireframe enabled\n" - "Shaders::MeshVisualizer::setWireframeWidth(): the shader was not created with wireframe enabled\n" - "Shaders::MeshVisualizer2D::setSmoothness(): the shader was not created with wireframe enabled\n"); + "Shaders::MeshVisualizerGL::setWireframeColor(): the shader was not created with wireframe enabled\n" + "Shaders::MeshVisualizerGL::setWireframeWidth(): the shader was not created with wireframe enabled\n" + "Shaders::MeshVisualizerGL2D::setSmoothness(): the shader was not created with wireframe enabled\n"); } void MeshVisualizerGLTest::setWireframeNotEnabled3D() { @@ -830,16 +830,16 @@ void MeshVisualizerGLTest::setWireframeNotEnabled3D() { /* The constructor asserts for at least some feature being enabled (which is just wireframe in case we're not on desktop or ES3.2), so fake it with a NoCreate */ - MeshVisualizer3D shader{NoCreate}; + MeshVisualizerGL3D shader{NoCreate}; shader .setColor({}); #ifndef MAGNUM_TARGET_GLES2 CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled\n"); + "Shaders::MeshVisualizerGL::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled\n"); #else CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe enabled\n"); + "Shaders::MeshVisualizerGL::setColor(): the shader was not created with wireframe enabled\n"); #endif out.str({}); @@ -849,9 +849,9 @@ void MeshVisualizerGLTest::setWireframeNotEnabled3D() { .setSmoothness({}); CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer::setWireframeColor(): the shader was not created with wireframe enabled\n" - "Shaders::MeshVisualizer::setWireframeWidth(): the shader was not created with wireframe enabled\n" - "Shaders::MeshVisualizer3D::setSmoothness(): the shader was not created with wireframe or TBN direction enabled\n"); + "Shaders::MeshVisualizerGL::setWireframeColor(): the shader was not created with wireframe enabled\n" + "Shaders::MeshVisualizerGL::setWireframeWidth(): the shader was not created with wireframe enabled\n" + "Shaders::MeshVisualizerGL3D::setSmoothness(): the shader was not created with wireframe or TBN direction enabled\n"); } #ifndef MAGNUM_TARGET_GLES2 @@ -864,13 +864,13 @@ void MeshVisualizerGLTest::setColorMapNotEnabled2D() { Error redirectError{&out}; GL::Texture2D texture; - MeshVisualizer2D shader{NoCreate}; + MeshVisualizerGL2D shader{NoCreate}; shader.setColorMapTransformation({}, {}) .bindColorMapTexture(texture); CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled\n" - "Shaders::MeshVisualizer::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled\n"); + "Shaders::MeshVisualizerGL::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled\n" + "Shaders::MeshVisualizerGL::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled\n"); } void MeshVisualizerGLTest::setColorMapNotEnabled3D() { @@ -882,13 +882,13 @@ void MeshVisualizerGLTest::setColorMapNotEnabled3D() { Error redirectError{&out}; GL::Texture2D texture; - MeshVisualizer3D shader{NoCreate}; + MeshVisualizerGL3D shader{NoCreate}; shader.setColorMapTransformation({}, {}) .bindColorMapTexture(texture); CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled\n" - "Shaders::MeshVisualizer::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled\n"); + "Shaders::MeshVisualizerGL::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled\n" + "Shaders::MeshVisualizerGL::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled\n"); } #endif @@ -909,15 +909,15 @@ void MeshVisualizerGLTest::setTangentBitangentNormalNotEnabled3D() { std::ostringstream out; Error redirectError{&out}; - MeshVisualizer3D shader{MeshVisualizer3D::Flag::Wireframe}; + MeshVisualizerGL3D shader{MeshVisualizerGL3D::Flag::Wireframe}; shader.setNormalMatrix({}) .setLineWidth({}) .setLineLength({}); CORRADE_COMPARE(out.str(), - "Shaders::MeshVisualizer3D::setNormalMatrix(): the shader was not created with TBN direction enabled\n" - "Shaders::MeshVisualizer3D::setLineWidth(): the shader was not created with TBN direction enabled\n" - "Shaders::MeshVisualizer3D::setLineLength(): the shader was not created with TBN direction enabled\n"); + "Shaders::MeshVisualizerGL3D::setNormalMatrix(): the shader was not created with TBN direction enabled\n" + "Shaders::MeshVisualizerGL3D::setLineWidth(): the shader was not created with TBN direction enabled\n" + "Shaders::MeshVisualizerGL3D::setLineLength(): the shader was not created with TBN direction enabled\n"); } #endif @@ -974,7 +974,7 @@ void MeshVisualizerGLTest::renderDefaultsWireframe2D() { GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(16)); - MeshVisualizer2D shader{MeshVisualizer2D::Flag::Wireframe}; + MeshVisualizerGL2D shader{MeshVisualizerGL2D::Flag::Wireframe}; shader.draw(circle); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -1023,7 +1023,7 @@ void MeshVisualizerGLTest::renderDefaultsWireframe3D() { GL::Mesh sphere = MeshTools::compile(Primitives::icosphereSolid(1)); - MeshVisualizer3D shader{MeshVisualizer3D::Flag::Wireframe}; + MeshVisualizerGL3D shader{MeshVisualizerGL3D::Flag::Wireframe}; shader.draw(sphere); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -1089,7 +1089,7 @@ void MeshVisualizerGLTest::renderDefaultsObjectId2D() { Containers::arrayView(ids)} })); - MeshVisualizer2D{MeshVisualizer2D::Flag::InstancedObjectId} + MeshVisualizerGL2D{MeshVisualizerGL2D::Flag::InstancedObjectId} .bindColorMapTexture(colorMapTexture) .draw(circle); @@ -1138,7 +1138,7 @@ void MeshVisualizerGLTest::renderDefaultsObjectId3D() { Containers::arrayView(ids)} })); - MeshVisualizer3D{MeshVisualizer3D::Flag::InstancedObjectId} + MeshVisualizerGL3D{MeshVisualizerGL3D::Flag::InstancedObjectId} .bindColorMapTexture(colorMapTexture) .draw(icosphere); @@ -1165,7 +1165,7 @@ void MeshVisualizerGLTest::renderDefaultsVertexId2D() { if(!GL::Context::current().isExtensionSupported()) CORRADE_SKIP("gl_VertexID not supported"); - MeshVisualizer2D{MeshVisualizer2D::Flag::VertexId} + MeshVisualizerGL2D{MeshVisualizerGL2D::Flag::VertexId} .bindColorMapTexture(_colorMapTexture) .draw(MeshTools::compile(Primitives::circle2DSolid(16))); @@ -1187,7 +1187,7 @@ void MeshVisualizerGLTest::renderDefaultsVertexId3D() { if(!GL::Context::current().isExtensionSupported()) CORRADE_SKIP("gl_VertexID not supported"); - MeshVisualizer2D{MeshVisualizer2D::Flag::VertexId} + MeshVisualizerGL2D{MeshVisualizerGL2D::Flag::VertexId} .bindColorMapTexture(_colorMapTexture) .draw(MeshTools::compile(Primitives::icosphereSolid(0))); @@ -1217,9 +1217,9 @@ void MeshVisualizerGLTest::renderDefaultsPrimitiveId2D() { ) CORRADE_SKIP("gl_VertexID not supported."); #endif - MeshVisualizer2D::Flags flags; + MeshVisualizerGL2D::Flags flags; #ifdef MAGNUM_TARGET_WEBGL - flags = MeshVisualizer2D::Flag::PrimitiveIdFromVertexId; + flags = MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId; #else #ifndef MAGNUM_TARGET_GLES if(!GL::Context::current().isVersionSupported(GL::Version::GL320)) @@ -1228,16 +1228,16 @@ void MeshVisualizerGLTest::renderDefaultsPrimitiveId2D() { #endif { Debug{} << "Using primitive ID from vertex ID"; - flags = MeshVisualizer2D::Flag::PrimitiveIdFromVertexId; + flags = MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId; } - else flags = MeshVisualizer2D::Flag::PrimitiveId; + else flags = MeshVisualizerGL2D::Flag::PrimitiveId; #endif Trade::MeshData circleData = Primitives::circle2DSolid(16); - if(flags >= MeshVisualizer2D::Flag::PrimitiveIdFromVertexId) + if(flags >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId) circleData = MeshTools::duplicate(MeshTools::generateIndices(circleData)); - MeshVisualizer2D{flags} + MeshVisualizerGL2D{flags} .bindColorMapTexture(_colorMapTexture) .draw(MeshTools::compile(circleData)); @@ -1269,9 +1269,9 @@ void MeshVisualizerGLTest::renderDefaultsPrimitiveId3D() { ) CORRADE_SKIP("gl_VertexID not supported."); #endif - MeshVisualizer2D::Flags flags; + MeshVisualizerGL2D::Flags flags; #ifdef MAGNUM_TARGET_WEBGL - flags = MeshVisualizer2D::Flag::PrimitiveIdFromVertexId; + flags = MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId; #else #ifndef MAGNUM_TARGET_GLES if(!GL::Context::current().isVersionSupported(GL::Version::GL320)) @@ -1280,16 +1280,16 @@ void MeshVisualizerGLTest::renderDefaultsPrimitiveId3D() { #endif { Debug{} << "Using primitive ID from vertex ID"; - flags = MeshVisualizer2D::Flag::PrimitiveIdFromVertexId; + flags = MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId; } - else flags = MeshVisualizer2D::Flag::PrimitiveId; + else flags = MeshVisualizerGL2D::Flag::PrimitiveId; #endif Trade::MeshData icosphereData = Primitives::icosphereSolid(0); - if(flags >= MeshVisualizer2D::Flag::PrimitiveIdFromVertexId) + if(flags >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId) icosphereData = MeshTools::duplicate(icosphereData); - MeshVisualizer2D{flags} + MeshVisualizerGL2D{flags} .bindColorMapTexture(_colorMapTexture) .draw(MeshTools::compile(icosphereData)); @@ -1317,9 +1317,9 @@ void MeshVisualizerGLTest::renderDefaultsTangentBitangentNormal() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(4, 8, Primitives::UVSphereFlag::Tangents)); - MeshVisualizer3D{MeshVisualizer3D::Flag::TangentDirection| - MeshVisualizer3D::Flag::BitangentFromTangentDirection| - MeshVisualizer3D::Flag::NormalDirection} + MeshVisualizerGL3D{MeshVisualizerGL3D::Flag::TangentDirection| + MeshVisualizerGL3D::Flag::BitangentFromTangentDirection| + MeshVisualizerGL3D::Flag::NormalDirection} .setViewportSize({80, 80}) /** @todo make this unnecessary */ .draw(sphere); @@ -1346,10 +1346,10 @@ void MeshVisualizerGLTest::renderWireframe2D() { #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #ifndef MAGNUM_TARGET_GLES - if(!(data.flags & MeshVisualizer2D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) + if(!(data.flags & MeshVisualizerGL2D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::ARB::geometry_shader4::string() << "is not supported."); #else - if(!(data.flags & MeshVisualizer2D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) + if(!(data.flags & MeshVisualizerGL2D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::geometry_shader::string() << "is not supported."); #endif @@ -1362,7 +1362,7 @@ void MeshVisualizerGLTest::renderWireframe2D() { const Trade::MeshData circleData = Primitives::circle2DSolid(16); GL::Mesh circle{NoCreate}; - if(data.flags & MeshVisualizer2D::Flag::NoGeometryShader) { + if(data.flags & MeshVisualizerGL2D::Flag::NoGeometryShader) { /* Duplicate the vertices. The circle primitive is */ const Trade::MeshData circleDataIndexed = MeshTools::generateIndices(circleData); @@ -1378,11 +1378,11 @@ void MeshVisualizerGLTest::renderWireframe2D() { GL::Buffer vertexId; vertexId.setData(vertexIndex); - circle.addVertexBuffer(std::move(vertexId), 0, MeshVisualizer2D::VertexIndex{}); + circle.addVertexBuffer(std::move(vertexId), 0, MeshVisualizerGL2D::VertexIndex{}); } } else circle = MeshTools::compile(circleData); - MeshVisualizer2D{data.flags|MeshVisualizer2D::Flag::Wireframe} + MeshVisualizerGL2D{data.flags|MeshVisualizerGL2D::Flag::Wireframe} .setColor(0xffff99_rgbf) .setWireframeColor(0x9999ff_rgbf) .setWireframeWidth(data.width) @@ -1398,7 +1398,7 @@ void MeshVisualizerGLTest::renderWireframe2D() { CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found."); { - CORRADE_EXPECT_FAIL_IF(data.flags & MeshVisualizer2D::Flag::NoGeometryShader, + CORRADE_EXPECT_FAIL_IF(data.flags & MeshVisualizerGL2D::Flag::NoGeometryShader, "Line width is currently not configurable w/o geometry shader."); #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) /* SwiftShader has differently rasterized edges on four pixels */ @@ -1415,7 +1415,7 @@ void MeshVisualizerGLTest::renderWireframe2D() { } /* Test it's not *too* off, at least */ - if(data.flags & MeshVisualizer2D::Flag::NoGeometryShader) { + if(data.flags & MeshVisualizerGL2D::Flag::NoGeometryShader) { #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) /* SwiftShader has differently rasterized edges on four pixels. Apple A8 on more. */ @@ -1438,10 +1438,10 @@ void MeshVisualizerGLTest::renderWireframe3D() { #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #ifndef MAGNUM_TARGET_GLES - if(!(data.flags & MeshVisualizer3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) + if(!(data.flags & MeshVisualizerGL3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::ARB::geometry_shader4::string() << "is not supported."); #else - if(!(data.flags & MeshVisualizer3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) + if(!(data.flags & MeshVisualizerGL3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::geometry_shader::string() << "is not supported."); #endif @@ -1454,7 +1454,7 @@ void MeshVisualizerGLTest::renderWireframe3D() { const Trade::MeshData sphereData = Primitives::icosphereSolid(1); GL::Mesh sphere{NoCreate}; - if(data.flags & MeshVisualizer3D::Flag::NoGeometryShader) { + if(data.flags & MeshVisualizerGL3D::Flag::NoGeometryShader) { /* Duplicate the vertices */ sphere = MeshTools::compile(MeshTools::duplicate(sphereData)); @@ -1468,11 +1468,11 @@ void MeshVisualizerGLTest::renderWireframe3D() { GL::Buffer vertexId; vertexId.setData(vertexIndex); - sphere.addVertexBuffer(std::move(vertexId), 0, MeshVisualizer3D::VertexIndex{}); + sphere.addVertexBuffer(std::move(vertexId), 0, MeshVisualizerGL3D::VertexIndex{}); } } else sphere = MeshTools::compile(sphereData); - MeshVisualizer3D{data.flags|MeshVisualizer3D::Flag::Wireframe} + MeshVisualizerGL3D{data.flags|MeshVisualizerGL3D::Flag::Wireframe} .setColor(0xffff99_rgbf) .setWireframeColor(0x9999ff_rgbf) .setWireframeWidth(data.width) @@ -1492,7 +1492,7 @@ void MeshVisualizerGLTest::renderWireframe3D() { CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found."); { - CORRADE_EXPECT_FAIL_IF(data.flags & MeshVisualizer3D::Flag::NoGeometryShader, + CORRADE_EXPECT_FAIL_IF(data.flags & MeshVisualizerGL3D::Flag::NoGeometryShader, "Line width is currently not configurable w/o geometry shader."); #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) /* SwiftShader has differently rasterized edges on four pixels. On a @@ -1500,7 +1500,7 @@ void MeshVisualizerGLTest::renderWireframe3D() { the artifacts are bigger. */ Float maxThreshold = 170.0f, meanThreshold = 0.327f; #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - if(!(data.flags & MeshVisualizer3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) + if(!(data.flags & MeshVisualizerGL3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) meanThreshold = 2.166f; #endif #else @@ -1515,7 +1515,7 @@ void MeshVisualizerGLTest::renderWireframe3D() { } /* Test it's not *too* off, at least */ - if(data.flags & MeshVisualizer3D::Flag::NoGeometryShader) { + if(data.flags & MeshVisualizerGL3D::Flag::NoGeometryShader) { #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) /* SwiftShader has differently rasterized edges on four pixels. Apple A8 on more. */ @@ -1538,17 +1538,17 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId2D() { setTestCaseDescription(data.name); #ifndef MAGNUM_TARGET_GLES - if((data.flags2D & MeshVisualizer2D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) + if((data.flags2D & MeshVisualizerGL2D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported."); #endif /* Interestingly for PrimitiveIdFromVertexId gl_VertexID in SwiftShader works -- maybe it works only for nonindexed triangle draws? */ - if(data.flags2D & MeshVisualizer2D::Flag::VertexId && !GL::Context::current().isExtensionSupported()) + if(data.flags2D & MeshVisualizerGL2D::Flag::VertexId && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP("gl_VertexID not supported"); #ifndef MAGNUM_TARGET_WEBGL - if(data.flags2D & MeshVisualizer2D::Flag::PrimitiveId && !(data.flags2D >= MeshVisualizer2D::Flag::PrimitiveIdFromVertexId) && + if(data.flags2D & MeshVisualizerGL2D::Flag::PrimitiveId && !(data.flags2D >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId) && #ifndef MAGNUM_TARGET_GLES !GL::Context::current().isVersionSupported(GL::Version::GL320) #else @@ -1557,17 +1557,17 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId2D() { ) CORRADE_SKIP("gl_PrimitiveID not supported."); #ifndef MAGNUM_TARGET_GLES - if(data.flags2D & MeshVisualizer2D::Flag::Wireframe && !(data.flags2D & MeshVisualizer2D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) + if(data.flags2D & MeshVisualizerGL2D::Flag::Wireframe && !(data.flags2D & MeshVisualizerGL2D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::ARB::geometry_shader4::string() << "is not supported."); #else - if(data.flags2D & MeshVisualizer2D::Flag::Wireframe && !(data.flags2D & MeshVisualizer2D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) + if(data.flags2D & MeshVisualizerGL2D::Flag::Wireframe && !(data.flags2D & MeshVisualizerGL2D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::geometry_shader::string() << "is not supported."); #endif #endif Trade::MeshData circleData = Primitives::circle2DSolid(16); - if(data.flags2D & MeshVisualizer2D::Flag::InstancedObjectId) { + if(data.flags2D & MeshVisualizerGL2D::Flag::InstancedObjectId) { Containers::Array ids{16}; /* Each two faces share the same ID */ for(std::size_t i = 0; i != ids.size(); ++i) ids[i] = i/2; @@ -1580,10 +1580,10 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId2D() { /* Duplicate the data if using primitive ID from vertex ID or if geometry shader is disabled */ - if(data.flags2D >= MeshVisualizer2D::Flag::PrimitiveIdFromVertexId) + if(data.flags2D >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId) circleData = MeshTools::generateIndices(circleData); - if(data.flags2D >= MeshVisualizer2D::Flag::PrimitiveIdFromVertexId || - data.flags2D & MeshVisualizer2D::Flag::NoGeometryShader) { + if(data.flags2D >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId || + data.flags2D & MeshVisualizerGL2D::Flag::NoGeometryShader) { if(circleData.primitive() != MeshPrimitive::Triangles) circleData = MeshTools::generateIndices(circleData); circleData = MeshTools::duplicate(circleData); @@ -1591,7 +1591,7 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId2D() { GL::Mesh circle = MeshTools::compile(circleData); - MeshVisualizer2D shader{data.flags2D}; + MeshVisualizerGL2D shader{data.flags2D}; shader /* Remove blue so it's clear the (wireframe) background and mapped ID colors got mixed */ @@ -1602,13 +1602,13 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId2D() { .bindColorMapTexture(_colorMapTexture); /* OTOH the wireframe color should stay at full channels, not mixed */ - if(data.flags3D & MeshVisualizer3D::Flag::Wireframe) + if(data.flags3D & MeshVisualizerGL3D::Flag::Wireframe) shader.setWireframeColor(0xffffff_rgbf); /* For vertex ID we don't want any repeat/wraparound as that causes disruptions in the gradient and test failures. There's 17 vertices also. */ - if(data.flags2D & MeshVisualizer2D::Flag::VertexId) + if(data.flags2D & MeshVisualizerGL2D::Flag::VertexId) shader.setColorMapTransformation(1.0f, -1.0f/17.0f); /* For object/primitive ID there's no gradient so a wraparound is okay. This should cover the first half of the colormap, in reverse order; for @@ -1638,17 +1638,17 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId3D() { setTestCaseDescription(data.name); #ifndef MAGNUM_TARGET_GLES - if((data.flags3D & MeshVisualizer3D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) + if((data.flags3D & MeshVisualizerGL3D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported."); #endif /* Interestingly for PrimitiveIdFromVertexId gl_VertexID in SwiftShader works -- maybe it works only for nonindexed triangle draws? */ - if(data.flags3D & MeshVisualizer3D::Flag::VertexId && !GL::Context::current().isExtensionSupported()) + if(data.flags3D & MeshVisualizerGL3D::Flag::VertexId && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP("gl_VertexID not supported"); #ifndef MAGNUM_TARGET_WEBGL - if(data.flags3D & MeshVisualizer3D::Flag::PrimitiveId && !(data.flags3D >= MeshVisualizer3D::Flag::PrimitiveIdFromVertexId) && + if(data.flags3D & MeshVisualizerGL3D::Flag::PrimitiveId && !(data.flags3D >= MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId) && #ifndef MAGNUM_TARGET_GLES !GL::Context::current().isVersionSupported(GL::Version::GL320) #else @@ -1657,17 +1657,17 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId3D() { ) CORRADE_SKIP("gl_PrimitiveID not supported."); #ifndef MAGNUM_TARGET_GLES - if(data.flags3D & MeshVisualizer3D::Flag::Wireframe && !(data.flags3D & MeshVisualizer3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) + if(data.flags3D & MeshVisualizerGL3D::Flag::Wireframe && !(data.flags3D & MeshVisualizerGL3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::ARB::geometry_shader4::string() << "is not supported."); #else - if(data.flags3D & MeshVisualizer3D::Flag::Wireframe && !(data.flags3D & MeshVisualizer3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) + if(data.flags3D & MeshVisualizerGL3D::Flag::Wireframe && !(data.flags3D & MeshVisualizerGL3D::Flag::NoGeometryShader) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::geometry_shader::string() << "is not supported."); #endif #endif Trade::MeshData icosphereData = Primitives::icosphereSolid(1); - if(data.flags3D & MeshVisualizer3D::Flag::InstancedObjectId) { + if(data.flags3D & MeshVisualizerGL3D::Flag::InstancedObjectId) { Containers::Array ids{80}; /* Each four faces share the same ID */ for(std::size_t i = 0; i != ids.size(); ++i) ids[i] = i/4; @@ -1680,13 +1680,13 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId3D() { /* Duplicate the data if using primitive ID from vertex ID or if geometry shader is disabled */ - if(data.flags3D >= MeshVisualizer3D::Flag::PrimitiveIdFromVertexId || - data.flags3D & MeshVisualizer3D::Flag::NoGeometryShader) + if(data.flags3D >= MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId || + data.flags3D & MeshVisualizerGL3D::Flag::NoGeometryShader) icosphereData = MeshTools::duplicate(icosphereData); GL::Mesh circle = MeshTools::compile(icosphereData); - MeshVisualizer3D shader{data.flags3D}; + MeshVisualizerGL3D shader{data.flags3D}; shader /* Remove blue so it's clear the wireframe background and mapped ID colors got mixed */ @@ -1701,12 +1701,12 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId3D() { .bindColorMapTexture(_colorMapTexture); /* OTOH the wireframe color should stay at full channels, not mixed */ - if(data.flags2D & MeshVisualizer2D::Flag::Wireframe) + if(data.flags2D & MeshVisualizerGL2D::Flag::Wireframe) shader.setWireframeColor(0xffffff_rgbf); /* For vertex ID we don't want any repeat/wraparound as that causes disruptions in the gradient and test failures. There's 42 vertices also. */ - if(data.flags2D & MeshVisualizer2D::Flag::VertexId) + if(data.flags2D & MeshVisualizerGL2D::Flag::VertexId) shader.setColorMapTransformation(1.0f, -1.0f/42.0f); /* For object/primitive ID there's no gradient so a wraparound is okay. This should cover the first half of the colormap, in reverse order; for @@ -1728,7 +1728,7 @@ void MeshVisualizerGLTest::renderObjectVertexPrimitiveId3D() { supported, the artifacts are bigger when wireframe is enabled. */ Float maxThreshold = 138.4f, meanThreshold = 0.279f; #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL) - if(data.flags3D & MeshVisualizer3D::Flag::Wireframe && !GL::Context::current().isExtensionSupported()) { + if(data.flags3D & MeshVisualizerGL3D::Flag::Wireframe && !GL::Context::current().isExtensionSupported()) { /* SwiftShader has a bit more rounding errors */ maxThreshold = 238.0f; meanThreshold = 1.957f; @@ -1754,7 +1754,7 @@ void MeshVisualizerGLTest::renderWireframe3DPerspective() { GL::Mesh plane = MeshTools::compile(Primitives::planeSolid()); - MeshVisualizer3D{MeshVisualizer3D::Flag::Wireframe} + MeshVisualizerGL3D{MeshVisualizerGL3D::Flag::Wireframe} .setWireframeWidth(8.0f) .setWireframeColor(0xff0000_rgbf) .setViewportSize({80, 80}) @@ -1848,26 +1848,26 @@ void MeshVisualizerGLTest::renderTangentBitangentNormal() { GL::Mesh mesh{MeshPrimitive::TriangleStrip}; mesh.setCount(4) .addVertexBuffer(vertices, 0, - Shaders::MeshVisualizer3D::Position{}, + Shaders::MeshVisualizerGL3D::Position{}, sizeof(Vector4), /* conditionally added below */ sizeof(Vector3), /* conditionally added below */ - Shaders::MeshVisualizer3D::Normal{}); - if(data.flags & MeshVisualizer3D::Flag::BitangentFromTangentDirection && !data.skipBitagnentEvenIfEnabledInFlags) + Shaders::MeshVisualizerGL3D::Normal{}); + if(data.flags & MeshVisualizerGL3D::Flag::BitangentFromTangentDirection && !data.skipBitagnentEvenIfEnabledInFlags) mesh.addVertexBuffer(vertices, 0, sizeof(Vector3), - Shaders::MeshVisualizer3D::Tangent4{}, + Shaders::MeshVisualizerGL3D::Tangent4{}, sizeof(Vector3), sizeof(Vector3)); - else if(data.flags & MeshVisualizer3D::Flag::TangentDirection) + else if(data.flags & MeshVisualizerGL3D::Flag::TangentDirection) mesh.addVertexBuffer(vertices, 0, sizeof(Vector3), - Shaders::MeshVisualizer3D::Tangent{}, sizeof(Float), sizeof(Vector3), + Shaders::MeshVisualizerGL3D::Tangent{}, sizeof(Float), sizeof(Vector3), sizeof(Vector3)); - if(data.flags & MeshVisualizer3D::Flag::BitangentDirection && !data.skipBitagnentEvenIfEnabledInFlags) + if(data.flags & MeshVisualizerGL3D::Flag::BitangentDirection && !data.skipBitagnentEvenIfEnabledInFlags) mesh.addVertexBuffer(vertices, 0, sizeof(Vector3), sizeof(Vector4), - Shaders::MeshVisualizer3D::Bitangent{}, + Shaders::MeshVisualizerGL3D::Bitangent{}, sizeof(Vector3)); Matrix4 transformation = Matrix4::translation({0.0f, 0.5f, -3.5f})* @@ -1875,7 +1875,7 @@ void MeshVisualizerGLTest::renderTangentBitangentNormal() { Matrix4::scaling(Vector3::yScale(1.5f)); if(data.secondPassFlags) { - MeshVisualizer3D{data.secondPassFlags} + MeshVisualizerGL3D{data.secondPassFlags} /** @todo make this unnecessary */ .setViewportSize({80, 80}) .setTransformationMatrix(transformation) @@ -1885,7 +1885,7 @@ void MeshVisualizerGLTest::renderTangentBitangentNormal() { .draw(mesh); } - MeshVisualizer3D shader{data.flags}; + MeshVisualizerGL3D shader{data.flags}; shader /** @todo make this unnecessary */ .setViewportSize({80, 80}) @@ -1896,10 +1896,10 @@ void MeshVisualizerGLTest::renderTangentBitangentNormal() { .setLineLength(data.lineLength) .setLineWidth(data.lineWidth); - if(data.flags & MeshVisualizer3D::Flag::Wireframe) shader + if(data.flags & MeshVisualizerGL3D::Flag::Wireframe) shader .setColor(0xffff99_rgbf) .setWireframeColor(0x9999ff_rgbf); - if(data.flags & MeshVisualizer3D::Flag::PrimitiveId) shader + if(data.flags & MeshVisualizerGL3D::Flag::PrimitiveId) shader .bindColorMapTexture(_colorMapTexture) .setColorMapTransformation(1.0f/512.0f, 0.5f); diff --git a/src/Magnum/Shaders/Test/MeshVisualizerGL_Test.cpp b/src/Magnum/Shaders/Test/MeshVisualizerGL_Test.cpp new file mode 100644 index 000000000..acee35225 --- /dev/null +++ b/src/Magnum/Shaders/Test/MeshVisualizerGL_Test.cpp @@ -0,0 +1,145 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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 +#include +#include + +#include "Magnum/Shaders/MeshVisualizerGL.h" + +namespace Magnum { namespace Shaders { namespace Test { namespace { + +/* There's an underscore between GL and Test to disambiguate from GLTest, which + is a common suffix used to mark tests that need a GL context. Ugly, I know. */ +struct MeshVisualizerGL_Test: TestSuite::Tester { + explicit MeshVisualizerGL_Test(); + + void constructNoCreate2D(); + void constructNoCreate3D(); + + void constructCopy2D(); + void constructCopy3D(); + + void vertexIndexSameAsObjectId(); + + void debugFlag2D(); + void debugFlag3D(); + void debugFlags2D(); + void debugFlags3D(); +}; + +MeshVisualizerGL_Test::MeshVisualizerGL_Test() { + addTests({&MeshVisualizerGL_Test::constructNoCreate2D, + &MeshVisualizerGL_Test::constructNoCreate3D, + + &MeshVisualizerGL_Test::constructCopy2D, + &MeshVisualizerGL_Test::constructCopy3D, + + &MeshVisualizerGL_Test::vertexIndexSameAsObjectId, + + &MeshVisualizerGL_Test::debugFlag2D, + &MeshVisualizerGL_Test::debugFlag3D, + &MeshVisualizerGL_Test::debugFlags2D, + &MeshVisualizerGL_Test::debugFlags3D}); +} + +void MeshVisualizerGL_Test::constructNoCreate2D() { + { + MeshVisualizerGL2D shader{NoCreate}; + CORRADE_COMPARE(shader.id(), 0); + CORRADE_COMPARE(shader.flags(), MeshVisualizerGL2D::Flags{}); + } + + CORRADE_VERIFY(true); +} + +void MeshVisualizerGL_Test::constructNoCreate3D() { + { + MeshVisualizerGL3D shader{NoCreate}; + CORRADE_COMPARE(shader.id(), 0); + CORRADE_COMPARE(shader.flags(), MeshVisualizerGL3D::Flags{}); + } + + CORRADE_VERIFY(true); +} + +void MeshVisualizerGL_Test::constructCopy2D() { + CORRADE_VERIFY(!std::is_copy_constructible{}); + CORRADE_VERIFY(!std::is_copy_assignable{}); +} + +void MeshVisualizerGL_Test::constructCopy3D() { + CORRADE_VERIFY(!std::is_copy_constructible{}); + CORRADE_VERIFY(!std::is_copy_assignable{}); +} + +void MeshVisualizerGL_Test::vertexIndexSameAsObjectId() { + #ifdef MAGNUM_TARGET_GLES2 + CORRADE_SKIP("Object ID is not available on ES2."); + #else + CORRADE_COMPARE(MeshVisualizerGL2D::VertexIndex::Location, GenericGL2D::ObjectId::Location); + CORRADE_COMPARE(MeshVisualizerGL3D::VertexIndex::Location, GenericGL3D::ObjectId::Location); + #endif +} + +void MeshVisualizerGL_Test::debugFlag2D() { + std::ostringstream out; + + Debug{&out} << MeshVisualizerGL2D::Flag::Wireframe << MeshVisualizerGL2D::Flag(0xf0); + CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL2D::Flag::Wireframe Shaders::MeshVisualizerGL2D::Flag(0xf0)\n"); +} + +void MeshVisualizerGL_Test::debugFlag3D() { + std::ostringstream out; + + Debug{&out} << MeshVisualizerGL3D::Flag::Wireframe << MeshVisualizerGL3D::Flag(0xf0); + CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL3D::Flag::Wireframe Shaders::MeshVisualizerGL3D::Flag(0xf0)\n"); +} + +void MeshVisualizerGL_Test::debugFlags2D() { + std::ostringstream out; + + Debug{&out} << (MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader) << MeshVisualizerGL2D::Flags{}; + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL2D::Flag::Wireframe|Shaders::MeshVisualizerGL2D::Flag::NoGeometryShader Shaders::MeshVisualizerGL2D::Flags{}\n"); + #else + CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL2D::Flag::Wireframe Shaders::MeshVisualizerGL2D::Flags{}\n"); + #endif +} + +void MeshVisualizerGL_Test::debugFlags3D() { + std::ostringstream out; + + Debug{&out} << (MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader) << MeshVisualizerGL3D::Flags{}; + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL3D::Flag::Wireframe|Shaders::MeshVisualizerGL3D::Flag::NoGeometryShader Shaders::MeshVisualizerGL3D::Flags{}\n"); + #else + CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL3D::Flag::Wireframe Shaders::MeshVisualizerGL3D::Flags{}\n"); + #endif +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Shaders::Test::MeshVisualizerGL_Test) diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTest.cpp b/src/Magnum/Shaders/Test/MeshVisualizerTest.cpp deleted file mode 100644 index 7b9ebde52..000000000 --- a/src/Magnum/Shaders/Test/MeshVisualizerTest.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, - 2020, 2021 Vladimír Vondruš - - 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 -#include -#include - -#include "Magnum/Shaders/MeshVisualizer.h" - -namespace Magnum { namespace Shaders { namespace Test { namespace { - -struct MeshVisualizerTest: TestSuite::Tester { - explicit MeshVisualizerTest(); - - void constructNoCreate2D(); - void constructNoCreate3D(); - - void constructCopy2D(); - void constructCopy3D(); - - void vertexIndexSameAsObjectId(); - - void debugFlag2D(); - void debugFlag3D(); - void debugFlags2D(); - void debugFlags3D(); -}; - -MeshVisualizerTest::MeshVisualizerTest() { - addTests({&MeshVisualizerTest::constructNoCreate2D, - &MeshVisualizerTest::constructNoCreate3D, - - &MeshVisualizerTest::constructCopy2D, - &MeshVisualizerTest::constructCopy3D, - - &MeshVisualizerTest::vertexIndexSameAsObjectId, - - &MeshVisualizerTest::debugFlag2D, - &MeshVisualizerTest::debugFlag3D, - &MeshVisualizerTest::debugFlags2D, - &MeshVisualizerTest::debugFlags3D}); -} - -void MeshVisualizerTest::constructNoCreate2D() { - { - MeshVisualizer2D shader{NoCreate}; - CORRADE_COMPARE(shader.id(), 0); - CORRADE_COMPARE(shader.flags(), MeshVisualizer2D::Flags{}); - } - - CORRADE_VERIFY(true); -} - -void MeshVisualizerTest::constructNoCreate3D() { - { - MeshVisualizer3D shader{NoCreate}; - CORRADE_COMPARE(shader.id(), 0); - CORRADE_COMPARE(shader.flags(), MeshVisualizer3D::Flags{}); - } - - CORRADE_VERIFY(true); -} - -void MeshVisualizerTest::constructCopy2D() { - CORRADE_VERIFY(!std::is_copy_constructible{}); - CORRADE_VERIFY(!std::is_copy_assignable{}); -} - -void MeshVisualizerTest::constructCopy3D() { - CORRADE_VERIFY(!std::is_copy_constructible{}); - CORRADE_VERIFY(!std::is_copy_assignable{}); -} - -void MeshVisualizerTest::vertexIndexSameAsObjectId() { - #ifdef MAGNUM_TARGET_GLES2 - CORRADE_SKIP("Object ID is not available on ES2."); - #else - CORRADE_COMPARE(MeshVisualizer2D::VertexIndex::Location, Generic2D::ObjectId::Location); - CORRADE_COMPARE(MeshVisualizer3D::VertexIndex::Location, Generic3D::ObjectId::Location); - #endif -} - -void MeshVisualizerTest::debugFlag2D() { - std::ostringstream out; - - Debug{&out} << MeshVisualizer2D::Flag::Wireframe << MeshVisualizer2D::Flag(0xf0); - CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizer2D::Flag::Wireframe Shaders::MeshVisualizer2D::Flag(0xf0)\n"); -} - -void MeshVisualizerTest::debugFlag3D() { - std::ostringstream out; - - Debug{&out} << MeshVisualizer3D::Flag::Wireframe << MeshVisualizer3D::Flag(0xf0); - CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizer3D::Flag::Wireframe Shaders::MeshVisualizer3D::Flag(0xf0)\n"); -} - -void MeshVisualizerTest::debugFlags2D() { - std::ostringstream out; - - Debug{&out} << (MeshVisualizer2D::Flag::Wireframe|MeshVisualizer2D::Flag::NoGeometryShader) << MeshVisualizer2D::Flags{}; - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizer2D::Flag::Wireframe|Shaders::MeshVisualizer2D::Flag::NoGeometryShader Shaders::MeshVisualizer2D::Flags{}\n"); - #else - CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizer2D::Flag::Wireframe Shaders::MeshVisualizer2D::Flags{}\n"); - #endif -} - -void MeshVisualizerTest::debugFlags3D() { - std::ostringstream out; - - Debug{&out} << (MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::NoGeometryShader) << MeshVisualizer3D::Flags{}; - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizer3D::Flag::Wireframe|Shaders::MeshVisualizer3D::Flag::NoGeometryShader Shaders::MeshVisualizer3D::Flags{}\n"); - #else - CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizer3D::Flag::Wireframe Shaders::MeshVisualizer3D::Flags{}\n"); - #endif -} - -}}}} - -CORRADE_TEST_MAIN(Magnum::Shaders::Test::MeshVisualizerTest) diff --git a/src/Magnum/Shaders/Test/PhongGLTest.cpp b/src/Magnum/Shaders/Test/PhongGLTest.cpp index 8a811c711..1d0d031cb 100644 --- a/src/Magnum/Shaders/Test/PhongGLTest.cpp +++ b/src/Magnum/Shaders/Test/PhongGLTest.cpp @@ -52,7 +52,7 @@ #include "Magnum/MeshTools/Transform.h" #include "Magnum/Primitives/Plane.h" #include "Magnum/Primitives/UVSphere.h" -#include "Magnum/Shaders/Phong.h" +#include "Magnum/Shaders/PhongGL.h" #include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/ImageData.h" #include "Magnum/Trade/MeshData.h" @@ -140,36 +140,36 @@ struct PhongGLTest: GL::OpenGLTester { constexpr struct { const char* name; - Phong::Flags flags; + PhongGL::Flags flags; UnsignedInt lightCount; } ConstructData[]{ {"", {}, 1}, - {"ambient texture", Phong::Flag::AmbientTexture, 1}, - {"diffuse texture", Phong::Flag::DiffuseTexture, 1}, - {"diffuse texture + texture transform", Phong::Flag::DiffuseTexture|Phong::Flag::TextureTransformation, 1}, - {"specular texture", Phong::Flag::SpecularTexture, 1}, - {"normal texture", Phong::Flag::NormalTexture, 1}, - {"normal texture + separate bitangents", Phong::Flag::NormalTexture|Phong::Flag::Bitangent, 1}, - {"separate bitangents alone", Phong::Flag::Bitangent, 1}, - {"ambient + diffuse texture", Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture, 1}, - {"ambient + specular texture", Phong::Flag::AmbientTexture|Phong::Flag::SpecularTexture, 1}, - {"diffuse + specular texture", Phong::Flag::DiffuseTexture|Phong::Flag::SpecularTexture, 1}, - {"ambient + diffuse + specular texture", Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::SpecularTexture, 1}, - {"ambient + diffuse + specular + normal texture", Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::SpecularTexture|Phong::Flag::NormalTexture, 1}, - {"alpha mask", Phong::Flag::AlphaMask, 1}, - {"alpha mask + diffuse texture", Phong::Flag::AlphaMask|Phong::Flag::DiffuseTexture, 1}, - {"vertex colors", Phong::Flag::VertexColor, 1}, - {"vertex colors + diffuse texture", Phong::Flag::VertexColor|Phong::Flag::DiffuseTexture, 1}, + {"ambient texture", PhongGL::Flag::AmbientTexture, 1}, + {"diffuse texture", PhongGL::Flag::DiffuseTexture, 1}, + {"diffuse texture + texture transform", PhongGL::Flag::DiffuseTexture|PhongGL::Flag::TextureTransformation, 1}, + {"specular texture", PhongGL::Flag::SpecularTexture, 1}, + {"normal texture", PhongGL::Flag::NormalTexture, 1}, + {"normal texture + separate bitangents", PhongGL::Flag::NormalTexture|PhongGL::Flag::Bitangent, 1}, + {"separate bitangents alone", PhongGL::Flag::Bitangent, 1}, + {"ambient + diffuse texture", PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture, 1}, + {"ambient + specular texture", PhongGL::Flag::AmbientTexture|PhongGL::Flag::SpecularTexture, 1}, + {"diffuse + specular texture", PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture, 1}, + {"ambient + diffuse + specular texture", PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture, 1}, + {"ambient + diffuse + specular + normal texture", PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture|PhongGL::Flag::NormalTexture, 1}, + {"alpha mask", PhongGL::Flag::AlphaMask, 1}, + {"alpha mask + diffuse texture", PhongGL::Flag::AlphaMask|PhongGL::Flag::DiffuseTexture, 1}, + {"vertex colors", PhongGL::Flag::VertexColor, 1}, + {"vertex colors + diffuse texture", PhongGL::Flag::VertexColor|PhongGL::Flag::DiffuseTexture, 1}, #ifndef MAGNUM_TARGET_GLES2 - {"object ID", Phong::Flag::ObjectId, 1}, - {"instanced object ID", Phong::Flag::InstancedObjectId, 1}, - {"object ID + alpha mask + specular texture", Phong::Flag::ObjectId|Phong::Flag::AlphaMask|Phong::Flag::SpecularTexture, 1}, + {"object ID", PhongGL::Flag::ObjectId, 1}, + {"instanced object ID", PhongGL::Flag::InstancedObjectId, 1}, + {"object ID + alpha mask + specular texture", PhongGL::Flag::ObjectId|PhongGL::Flag::AlphaMask|PhongGL::Flag::SpecularTexture, 1}, #endif {"five lights", {}, 5}, {"zero lights", {}, 0}, - {"instanced transformation", Phong::Flag::InstancedTransformation, 3}, - {"instanced specular texture offset", Phong::Flag::SpecularTexture|Phong::Flag::InstancedTextureOffset, 3}, - {"instanced normal texture offset", Phong::Flag::NormalTexture|Phong::Flag::InstancedTextureOffset, 3} + {"instanced transformation", PhongGL::Flag::InstancedTransformation, 3}, + {"instanced specular texture offset", PhongGL::Flag::SpecularTexture|PhongGL::Flag::InstancedTextureOffset, 3}, + {"instanced normal texture offset", PhongGL::Flag::NormalTexture|PhongGL::Flag::InstancedTextureOffset, 3} }; using namespace Math::Literals; @@ -196,17 +196,17 @@ constexpr struct { const struct { const char* name; const char* expected; - Phong::Flags flags; + PhongGL::Flags flags; Matrix3 textureTransformation; } RenderTexturedData[]{ - {"all", "textured.tga", Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::SpecularTexture, {}}, - {"ambient", "textured-ambient.tga", Phong::Flag::AmbientTexture, {}}, - {"diffuse", "textured-diffuse.tga", Phong::Flag::DiffuseTexture, {}}, + {"all", "textured.tga", PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture, {}}, + {"ambient", "textured-ambient.tga", PhongGL::Flag::AmbientTexture, {}}, + {"diffuse", "textured-diffuse.tga", PhongGL::Flag::DiffuseTexture, {}}, {"diffuse transformed", "textured-diffuse-transformed.tga", - Phong::Flag::DiffuseTexture|Phong::Flag::TextureTransformation, + PhongGL::Flag::DiffuseTexture|PhongGL::Flag::TextureTransformation, Matrix3::translation(Vector2{1.0f})*Matrix3::scaling(Vector2{-1.0f}) }, - {"specular", "textured-specular.tga", Phong::Flag::SpecularTexture, {}} + {"specular", "textured-specular.tga", PhongGL::Flag::SpecularTexture, {}} }; /* MSVC 2015 doesn't like constexpr here due to the angles */ @@ -218,50 +218,50 @@ const struct { Float scale; Vector4 tangent; Vector3 bitangent; - Shaders::Phong::Tangent4::Components tangentComponents; + PhongGL::Tangent4::Components tangentComponents; bool flipNormalY; - Shaders::Phong::Flags flags; + PhongGL::Flags flags; } RenderTexturedNormalData[]{ {"", "textured-normal.tga", false, {}, 1.0f, {1.0f, 0.0f, 0.0f, 1.0f}, {}, - Shaders::Phong::Tangent4::Components::Four, false, {}}, + PhongGL::Tangent4::Components::Four, false, {}}, {"multi bind", "textured-normal.tga", true, {}, 1.0f, {1.0f, 0.0f, 0.0f, 1.0f}, {}, - Shaders::Phong::Tangent4::Components::Four, false, {}}, + PhongGL::Tangent4::Components::Four, false, {}}, {"rotated 90°", "textured-normal.tga", false, 90.0_degf, 1.0f, {1.0f, 0.0f, 0.0f, 1.0f}, {}, - Shaders::Phong::Tangent4::Components::Four, false, {}}, + PhongGL::Tangent4::Components::Four, false, {}}, {"rotated -90°", "textured-normal.tga", false, -90.0_degf, 1.0f, {1.0f, 0.0f, 0.0f, 1.0f}, {}, - Shaders::Phong::Tangent4::Components::Four, false, {}}, + PhongGL::Tangent4::Components::Four, false, {}}, {"0.5 scale", "textured-normal0.5.tga", false, {}, 0.5f, {1.0f, 0.0f, 0.0f, 1.0f}, {}, - Shaders::Phong::Tangent4::Components::Four, false, {}}, + PhongGL::Tangent4::Components::Four, false, {}}, {"0.0 scale", "textured-normal0.0.tga", false, {}, 0.0f, {1.0f, 0.0f, 0.0f, 1.0f}, {}, - Shaders::Phong::Tangent4::Components::Four, false, {}}, + PhongGL::Tangent4::Components::Four, false, {}}, /* The fourth component, if missing, gets automatically filled up to 1, so this should work */ {"implicit bitangent direction", "textured-normal.tga", false, {}, 1.0f, {1.0f, 0.0f, 0.0f, 0.0f}, {}, - Shaders::Phong::Tangent4::Components::Three, false, {}}, + PhongGL::Tangent4::Components::Three, false, {}}, {"separate bitangents", "textured-normal.tga", false, {}, 1.0f, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f}, - Shaders::Phong::Tangent4::Components::Three, false, - Shaders::Phong::Flag::Bitangent}, + PhongGL::Tangent4::Components::Three, false, + PhongGL::Flag::Bitangent}, {"right-handed, flipped Y", "textured-normal-left.tga", false, {}, 1.0f, {1.0f, 0.0f, 0.0f, 1.0f}, {}, - Shaders::Phong::Tangent4::Components::Four, true, {}}, + PhongGL::Tangent4::Components::Four, true, {}}, {"left-handed", "textured-normal-left.tga", false, {}, 1.0f, {1.0f, 0.0f, 0.0f, -1.0f}, {}, - Shaders::Phong::Tangent4::Components::Four, false, {}}, + PhongGL::Tangent4::Components::Four, false, {}}, {"left-handed, separate bitangents", "textured-normal-left.tga", false, {}, 1.0f, {1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, - Shaders::Phong::Tangent4::Components::Three, false, - Shaders::Phong::Flag::Bitangent}, + PhongGL::Tangent4::Components::Three, false, + PhongGL::Flag::Bitangent}, {"left-handed, flipped Y", "textured-normal.tga", false, {}, 1.0f, {1.0f, 0.0f, 0.0f, -1.0f}, {}, - Shaders::Phong::Tangent4::Components::Four, true, {}} + PhongGL::Tangent4::Components::Four, true, {}} }; const struct { @@ -281,7 +281,7 @@ const struct { const char* name; const char* expected; bool blending; - Phong::Flags flags; + PhongGL::Flags flags; Float threshold; const char* ambientTexture; const char* diffuseTexture; @@ -291,35 +291,35 @@ const struct { /* All those deliberately have a non-white diffuse in order to match the expected data from textured() */ {"none, separate", "PhongTestFiles/textured-diffuse.tga", false, - Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture, 0.0f, + PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture, 0.0f, "alpha-texture.tga", "diffuse-texture.tga", 0xffffffff_rgbaf, 0x9999ff00_rgbaf}, {"none, combined", "PhongTestFiles/textured-diffuse.tga", false, - Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture, 0.0f, + PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture, 0.0f, "diffuse-alpha-texture.tga", "diffuse-alpha-texture.tga", 0x000000ff_rgbaf, 0x9999ff00_rgbaf}, {"blending, separate", "PhongTestFiles/textured-diffuse-alpha.tga", true, - Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture, 0.0f, + PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture, 0.0f, "alpha-texture.tga", "diffuse-texture.tga", 0xffffffff_rgbaf, 0x9999ff00_rgbaf}, {"blending, combined", "PhongTestFiles/textured-diffuse-alpha.tga", true, - Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture, 0.0f, + PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture, 0.0f, "diffuse-alpha-texture.tga", "diffuse-alpha-texture.tga", 0x000000ff_rgbaf, 0x9999ff00_rgbaf}, {"masking 0.0, separate", "PhongTestFiles/textured-diffuse.tga", false, - Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::AlphaMask, 0.0f, + PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::AlphaMask, 0.0f, "alpha-texture.tga", "diffuse-texture.tga", 0xffffffff_rgbaf, 0x9999ff00_rgbaf}, {"masking 0.5, separate", "PhongTestFiles/textured-diffuse-alpha-mask0.5.tga", false, - Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::AlphaMask, 0.5f, + PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::AlphaMask, 0.5f, "alpha-texture.tga", "diffuse-texture.tga", 0xffffffff_rgbaf, 0x9999ff00_rgbaf}, {"masking 0.5, combined", "PhongTestFiles/textured-diffuse-alpha-mask0.5.tga", false, - Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::AlphaMask, 0.5f, + PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::AlphaMask, 0.5f, "diffuse-alpha-texture.tga", "diffuse-alpha-texture.tga", 0x000000ff_rgbaf, 0x9999ff00_rgbaf}, {"masking 1.0, separate", "TestFiles/alpha-mask1.0.tga", false, - Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::AlphaMask, 1.0f, + PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::AlphaMask, 1.0f, "alpha-texture.tga", "diffuse-texture.tga", 0xffffffff_rgbaf, 0x9999ff00_rgbaf} }; @@ -327,17 +327,17 @@ const struct { #ifndef MAGNUM_TARGET_GLES2 constexpr struct { const char* name; - Phong::Flags flags; + PhongGL::Flags flags; UnsignedInt uniformId; UnsignedInt instanceCount; UnsignedInt expected; } RenderObjectIdData[] { {"", /* Verify that it can hold 16 bits at least */ - Phong::Flag::ObjectId, 48526, 0, 48526}, + PhongGL::Flag::ObjectId, 48526, 0, 48526}, {"instanced, first instance", - Phong::Flag::InstancedObjectId, 13524, 1, 24526}, + PhongGL::Flag::InstancedObjectId, 13524, 1, 24526}, {"instanced, second instance", - Phong::Flag::InstancedObjectId, 13524, 2, 62347} + PhongGL::Flag::InstancedObjectId, 13524, 2, 62347} }; #endif @@ -460,7 +460,7 @@ const struct { constexpr struct { const char* name; const char* file; - Phong::Flags flags; + PhongGL::Flags flags; Float maxThreshold, meanThreshold; } RenderInstancedData[] { {"diffuse", "instanced.tga", {}, @@ -472,7 +472,7 @@ constexpr struct { 96.34f, 0.113f, #endif }, - {"diffuse + normal", "instanced-normal.tga", Phong::Flag::NormalTexture, + {"diffuse + normal", "instanced-normal.tga", PhongGL::Flag::NormalTexture, #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) /* AMD has one off pixel, llvmpipe more */ 96.0f, 0.333f, @@ -599,11 +599,11 @@ void PhongGLTest::construct() { setTestCaseDescription(data.name); #ifndef MAGNUM_TARGET_GLES - if((data.flags & Phong::Flag::ObjectId) && !GL::Context::current().isExtensionSupported()) + if((data.flags & PhongGL::Flag::ObjectId) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported."); #endif - Phong shader{data.flags, data.lightCount}; + PhongGL shader{data.flags, data.lightCount}; CORRADE_COMPARE(shader.flags(), data.flags); CORRADE_COMPARE(shader.lightCount(), data.lightCount); CORRADE_VERIFY(shader.id()); @@ -618,22 +618,22 @@ void PhongGLTest::construct() { } void PhongGLTest::constructMove() { - Phong a{Phong::Flag::AlphaMask, 3}; + PhongGL a{PhongGL::Flag::AlphaMask, 3}; const GLuint id = a.id(); CORRADE_VERIFY(id); MAGNUM_VERIFY_NO_GL_ERROR(); - Phong b{std::move(a)}; + PhongGL b{std::move(a)}; CORRADE_COMPARE(b.id(), id); - CORRADE_COMPARE(b.flags(), Phong::Flag::AlphaMask); + CORRADE_COMPARE(b.flags(), PhongGL::Flag::AlphaMask); CORRADE_COMPARE(b.lightCount(), 3); CORRADE_VERIFY(!a.id()); - Phong c{NoCreate}; + PhongGL c{NoCreate}; c = std::move(b); CORRADE_COMPARE(c.id(), id); - CORRADE_COMPARE(c.flags(), Phong::Flag::AlphaMask); + CORRADE_COMPARE(c.flags(), PhongGL::Flag::AlphaMask); CORRADE_COMPARE(c.lightCount(), 3); CORRADE_VERIFY(!b.id()); } @@ -645,9 +645,9 @@ void PhongGLTest::constructTextureTransformationNotTextured() { std::ostringstream out; Error redirectError{&out}; - Phong{Phong::Flag::TextureTransformation}; + PhongGL{PhongGL::Flag::TextureTransformation}; CORRADE_COMPARE(out.str(), - "Shaders::Phong: texture transformation enabled but the shader is not textured\n"); + "Shaders::PhongGL: texture transformation enabled but the shader is not textured\n"); } void PhongGLTest::bindTexturesNotEnabled() { @@ -659,7 +659,7 @@ void PhongGLTest::bindTexturesNotEnabled() { Error redirectError{&out}; GL::Texture2D texture; - Phong shader; + PhongGL shader; shader.bindAmbientTexture(texture) .bindDiffuseTexture(texture) .bindSpecularTexture(texture) @@ -668,12 +668,12 @@ void PhongGLTest::bindTexturesNotEnabled() { .bindTextures(&texture, &texture, &texture, &texture); CORRADE_COMPARE(out.str(), - "Shaders::Phong::bindAmbientTexture(): the shader was not created with ambient texture enabled\n" - "Shaders::Phong::bindDiffuseTexture(): the shader was not created with diffuse texture enabled\n" - "Shaders::Phong::bindSpecularTexture(): the shader was not created with specular texture enabled\n" - "Shaders::Phong::bindNormalTexture(): the shader was not created with normal texture enabled\n" - "Shaders::Phong::setNormalTextureScale(): the shader was not created with normal texture enabled\n" - "Shaders::Phong::bindTextures(): the shader was not created with any textures enabled\n"); + "Shaders::PhongGL::bindAmbientTexture(): the shader was not created with ambient texture enabled\n" + "Shaders::PhongGL::bindDiffuseTexture(): the shader was not created with diffuse texture enabled\n" + "Shaders::PhongGL::bindSpecularTexture(): the shader was not created with specular texture enabled\n" + "Shaders::PhongGL::bindNormalTexture(): the shader was not created with normal texture enabled\n" + "Shaders::PhongGL::setNormalTextureScale(): the shader was not created with normal texture enabled\n" + "Shaders::PhongGL::bindTextures(): the shader was not created with any textures enabled\n"); } void PhongGLTest::setAlphaMaskNotEnabled() { @@ -684,11 +684,11 @@ void PhongGLTest::setAlphaMaskNotEnabled() { std::ostringstream out; Error redirectError{&out}; - Phong shader; + PhongGL shader; shader.setAlphaMask(0.75f); CORRADE_COMPARE(out.str(), - "Shaders::Phong::setAlphaMask(): the shader was not created with alpha mask enabled\n"); + "Shaders::PhongGL::setAlphaMask(): the shader was not created with alpha mask enabled\n"); } void PhongGLTest::setTextureMatrixNotEnabled() { @@ -699,11 +699,11 @@ void PhongGLTest::setTextureMatrixNotEnabled() { std::ostringstream out; Error redirectError{&out}; - Phong shader; + PhongGL shader; shader.setTextureMatrix({}); CORRADE_COMPARE(out.str(), - "Shaders::Phong::setTextureMatrix(): the shader was not created with texture transformation enabled\n"); + "Shaders::PhongGL::setTextureMatrix(): the shader was not created with texture transformation enabled\n"); } #ifndef MAGNUM_TARGET_GLES2 @@ -715,11 +715,11 @@ void PhongGLTest::setObjectIdNotEnabled() { std::ostringstream out; Error redirectError{&out}; - Phong shader; + PhongGL shader; shader.setObjectId(33376); CORRADE_COMPARE(out.str(), - "Shaders::Phong::setObjectId(): the shader was not created with object ID enabled\n"); + "Shaders::PhongGL::setObjectId(): the shader was not created with object ID enabled\n"); } #endif @@ -730,14 +730,14 @@ void PhongGLTest::setWrongLightCount() { std::ostringstream out; Error redirectError{&out}; - Phong{{}, 5} + PhongGL{{}, 5} .setLightColors({Color3{}}) .setLightPositions({Vector4{}}) .setLightRanges({0.0f}); CORRADE_COMPARE(out.str(), - "Shaders::Phong::setLightColors(): expected 5 items but got 1\n" - "Shaders::Phong::setLightPositions(): expected 5 items but got 1\n" - "Shaders::Phong::setLightRanges(): expected 5 items but got 1\n"); + "Shaders::PhongGL::setLightColors(): expected 5 items but got 1\n" + "Shaders::PhongGL::setLightPositions(): expected 5 items but got 1\n" + "Shaders::PhongGL::setLightRanges(): expected 5 items but got 1\n"); } void PhongGLTest::setWrongLightId() { @@ -747,14 +747,14 @@ void PhongGLTest::setWrongLightId() { std::ostringstream out; Error redirectError{&out}; - Phong{{}, 3} + PhongGL{{}, 3} .setLightColor(3, Color3{}) .setLightPosition(3, Vector4{}) .setLightRange(3, 0.0f); CORRADE_COMPARE(out.str(), - "Shaders::Phong::setLightColor(): light ID 3 is out of bounds for 3 lights\n" - "Shaders::Phong::setLightPosition(): light ID 3 is out of bounds for 3 lights\n" - "Shaders::Phong::setLightRange(): light ID 3 is out of bounds for 3 lights\n"); + "Shaders::PhongGL::setLightColor(): light ID 3 is out of bounds for 3 lights\n" + "Shaders::PhongGL::setLightPosition(): light ID 3 is out of bounds for 3 lights\n" + "Shaders::PhongGL::setLightRange(): light ID 3 is out of bounds for 3 lights\n"); } constexpr Vector2i RenderSize{80, 80}; @@ -788,7 +788,7 @@ void PhongGLTest::renderTeardown() { void PhongGLTest::renderDefaults() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); - Phong{} + PhongGL{} .draw(sphere); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -818,7 +818,7 @@ void PhongGLTest::renderColored() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); - Phong{{}, 2} + PhongGL{{}, 2} .setLightColors({data.lightColor1, data.lightColor2}) .setLightPositions({{data.lightPosition1, -3.0f, 2.0f, 0.0f}, {data.lightPosition2, -3.0f, 2.0f, 0.0f}}) @@ -901,7 +901,7 @@ void PhongGLTest::renderSinglePixelTextured() { .setStorage(1, TextureFormatRGBA, Vector2i{1}) .setSubImage(0, {}, specularImage); - Phong shader{Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::SpecularTexture, 2}; + PhongGL shader{PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture, 2}; shader.setLightColors({0x993366_rgbf, 0x669933_rgbf}) .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, { 3.0f, -3.0f, 2.0f, 0.0f}}) @@ -949,7 +949,7 @@ void PhongGLTest::renderTextured() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32, Primitives::UVSphereFlag::TextureCoordinates)); - Phong shader{data.flags, 2}; + PhongGL shader{data.flags, 2}; if(data.textureTransformation != Matrix3{}) shader.setTextureMatrix(data.textureTransformation); @@ -958,7 +958,7 @@ void PhongGLTest::renderTextured() { CORRADE_VERIFY(importer); GL::Texture2D ambient; - if(data.flags & Phong::Flag::AmbientTexture) { + if(data.flags & PhongGL::Flag::AmbientTexture) { Containers::Optional image; CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "TestFiles/ambient-texture.tga")) && (image = importer->image2D(0))); ambient.setMinificationFilter(GL::SamplerFilter::Linear) @@ -976,7 +976,7 @@ void PhongGLTest::renderTextured() { /* If no diffuse texture is present, dial down the default diffuse color so ambient/specular is visible */ GL::Texture2D diffuse; - if(data.flags & Phong::Flag::DiffuseTexture) { + if(data.flags & PhongGL::Flag::DiffuseTexture) { Containers::Optional image; CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "TestFiles/diffuse-texture.tga")) && (image = importer->image2D(0))); diffuse.setMinificationFilter(GL::SamplerFilter::Linear) @@ -992,7 +992,7 @@ void PhongGLTest::renderTextured() { } else shader.setDiffuseColor(0x333333_rgbf); GL::Texture2D specular; - if(data.flags & Phong::Flag::SpecularTexture) { + if(data.flags & PhongGL::Flag::SpecularTexture) { Containers::Optional image; CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "TestFiles/specular-texture.tga")) && (image = importer->image2D(0))); specular.setMinificationFilter(GL::SamplerFilter::Linear) @@ -1073,15 +1073,15 @@ void PhongGLTest::renderTexturedNormal() { GL::Buffer tangents; tangents.setData(Containers::Array{DirectInit, 4, tangentBitangent}); plane.addVertexBuffer(tangents, 0, sizeof(TangentBitangent), - GL::DynamicAttribute{Shaders::Phong::Tangent4{data.tangentComponents}}); + GL::DynamicAttribute{Shaders::PhongGL::Tangent4{data.tangentComponents}}); plane.addVertexBuffer(std::move(tangents), sizeof(Vector4), sizeof(TangentBitangent), - GL::DynamicAttribute{Shaders::Phong::Bitangent{}}); + GL::DynamicAttribute{Shaders::PhongGL::Bitangent{}}); /* Rotating the view a few times (together with light positions). If the tangent transformation in the shader is correct, it should result in exactly the same images. */ - Phong shader{Phong::Flag::NormalTexture|data.flags, 2}; + PhongGL shader{PhongGL::Flag::NormalTexture|data.flags, 2}; shader.setLightPositions({ Matrix4::rotationZ(data.rotation)*Vector4{-3.0f, -3.0f, 2.0f, 0.0f}, Matrix4::rotationZ(data.rotation)*Vector4{ 3.0f, -3.0f, 2.0f, 0.0f}}) @@ -1157,7 +1157,7 @@ template void PhongGLTest::renderVertexColor() { GL::Buffer colors; colors.setData(colorData); GL::Mesh sphere = MeshTools::compile(sphereData); - sphere.addVertexBuffer(colors, 0, GL::Attribute{}); + sphere.addVertexBuffer(colors, 0, GL::Attribute{}); Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); CORRADE_VERIFY(importer); @@ -1171,7 +1171,7 @@ template void PhongGLTest::renderVertexColor() { .setStorage(1, TextureFormatRGB, image->size()) .setSubImage(0, {}, *image); - Phong{Phong::Flag::DiffuseTexture|Phong::Flag::VertexColor, 2} + PhongGL{PhongGL::Flag::DiffuseTexture|PhongGL::Flag::VertexColor, 2} .setLightPositions({{-3.0f, -3.0f, 0.0f, 0.0f}, { 3.0f, -3.0f, 0.0f, 0.0f}}) .setTransformationMatrix( @@ -1209,7 +1209,7 @@ void PhongGLTest::renderShininess() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); - Phong{} + PhongGL{} .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}}) .setDiffuseColor(0xff3333_rgbf) .setSpecularColor(data.specular) @@ -1343,7 +1343,7 @@ void PhongGLTest::renderAlpha() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32, Primitives::UVSphereFlag::TextureCoordinates)); - Phong shader{data.flags, 2}; + PhongGL shader{data.flags, 2}; shader.setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, { 3.0f, -3.0f, 2.0f, 0.0f}}) .setTransformationMatrix( @@ -1360,7 +1360,7 @@ void PhongGLTest::renderAlpha() { /* Test that the default is correct by not setting the threshold if it's equal to the default */ - if(data.flags & Phong::Flag::AlphaMask && data.threshold != 0.5f) + if(data.flags & PhongGL::Flag::AlphaMask && data.threshold != 0.5f) shader.setAlphaMask(data.threshold); /* For proper Z order draw back faces first and then front faces */ @@ -1413,8 +1413,8 @@ void PhongGLTest::renderObjectIdSetup() { _objectId.setStorage(GL::RenderbufferFormat::R32UI, RenderSize); _framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{1}, _objectId) .mapForDraw({ - {Phong::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, - {Phong::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}} + {PhongGL::ColorOutput, GL::Framebuffer::ColorAttachment{0}}, + {PhongGL::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}} }) .clearColor(1, Vector4ui{27}); } @@ -1443,9 +1443,9 @@ void PhongGLTest::renderObjectId() { .setInstanceCount(data.instanceCount) .addVertexBufferInstanced( GL::Buffer{Containers::arrayView({11002u, 48823u})}, - 1, 0, Phong::ObjectId{}); + 1, 0, PhongGL::ObjectId{}); - Phong{data.flags, 2} + PhongGL{data.flags, 2} .setLightColors({0x993366_rgbf, 0x669933_rgbf}) .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, { 3.0f, -3.0f, 2.0f, 0.0f}}) @@ -1502,7 +1502,7 @@ void PhongGLTest::renderLights() { Matrix4 transformation = Matrix4::translation({0.0f, 0.0f, -1.5f}); - Phong{{}, 1} + PhongGL{{}, 1} /* Set non-black ambient to catch accidental NaNs -- the render should never be fully black */ .setAmbientColor(0x222222_rgbf) @@ -1553,7 +1553,7 @@ void PhongGLTest::renderLightsSetOneByOne() { Matrix4 transformation = Matrix4::translation({0.0f, 0.0f, -1.5f}); - Phong{{}, 2} + PhongGL{{}, 2} /* Set non-black ambient to catch accidental NaNs -- the render should never be fully black */ .setAmbientColor(0x222222_rgbf) @@ -1608,7 +1608,7 @@ void PhongGLTest::renderLowLightAngle() { in the vertex shader, where the incorrect normalization caused the fragment-interpolated light direction being incorrect, most visible with long polygons and low light angles. */ - Phong{{}, 1} + PhongGL{{}, 1} .setLightPositions({{0.0f, 0.1f, 0.0f, 1.0f}}) .setShininess(200) .setTransformationMatrix(transformation) @@ -1646,16 +1646,16 @@ void PhongGLTest::renderZeroLights() { Primitives::UVSphereFlag::TextureCoordinates)); /* Enable also Object ID, if supported */ - Phong::Flags flags = Phong::Flag::AmbientTexture|Phong::Flag::NormalTexture|Phong::Flag::AlphaMask; + PhongGL::Flags flags = PhongGL::Flag::AmbientTexture|PhongGL::Flag::NormalTexture|PhongGL::Flag::AlphaMask; #ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES if(GL::Context::current().isExtensionSupported()) #endif { - flags |= Phong::Flag::ObjectId; + flags |= PhongGL::Flag::ObjectId; } #endif - Phong shader{flags, 0}; + PhongGL shader{flags, 0}; Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); CORRADE_VERIFY(importer); @@ -1796,10 +1796,10 @@ void PhongGLTest::renderInstanced() { sphere .addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0, - Phong::TransformationMatrix{}, - Phong::NormalMatrix{}, - Phong::Color3{}, - Phong::TextureOffset{}) + PhongGL::TransformationMatrix{}, + PhongGL::NormalMatrix{}, + PhongGL::Color3{}, + PhongGL::TextureOffset{}) .setInstanceCount(3); Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); @@ -1822,10 +1822,10 @@ void PhongGLTest::renderInstanced() { .setStorage(1, TextureFormatRGB, image->size()) .setSubImage(0, {}, *image); - Phong shader{Phong::Flag::DiffuseTexture| - Phong::Flag::VertexColor| - Phong::Flag::InstancedTransformation| - Phong::Flag::InstancedTextureOffset|data.flags, 2}; + PhongGL shader{PhongGL::Flag::DiffuseTexture| + PhongGL::Flag::VertexColor| + PhongGL::Flag::InstancedTransformation| + PhongGL::Flag::InstancedTextureOffset|data.flags, 2}; shader .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, { 3.0f, -3.0f, 2.0f, 0.0f}}) @@ -1842,7 +1842,7 @@ void PhongGLTest::renderInstanced() { .bindDiffuseTexture(diffuse) .setDiffuseColor(0xffff99_rgbf); - if(data.flags & Phong::Flag::NormalTexture) + if(data.flags & PhongGL::Flag::NormalTexture) shader.bindNormalTexture(normal); shader.draw(sphere); diff --git a/src/Magnum/Shaders/Test/PhongTest.cpp b/src/Magnum/Shaders/Test/PhongGL_Test.cpp similarity index 54% rename from src/Magnum/Shaders/Test/PhongTest.cpp rename to src/Magnum/Shaders/Test/PhongGL_Test.cpp index 6fbf55df1..b76638f6c 100644 --- a/src/Magnum/Shaders/Test/PhongTest.cpp +++ b/src/Magnum/Shaders/Test/PhongGL_Test.cpp @@ -27,12 +27,14 @@ #include #include -#include "Magnum/Shaders/Phong.h" +#include "Magnum/Shaders/PhongGL.h" namespace Magnum { namespace Shaders { namespace Test { namespace { -struct PhongTest: TestSuite::Tester { - explicit PhongTest(); +/* There's an underscore between GL and Test to disambiguate from GLTest, which + is a common suffix used to mark tests that need a GL context. Ugly, I know. */ +struct PhongGL_Test: TestSuite::Tester { + explicit PhongGL_Test(); void constructNoCreate(); void constructCopy(); @@ -42,63 +44,63 @@ struct PhongTest: TestSuite::Tester { void debugFlagsSupersets(); }; -PhongTest::PhongTest() { - addTests({&PhongTest::constructNoCreate, - &PhongTest::constructCopy, +PhongGL_Test::PhongGL_Test() { + addTests({&PhongGL_Test::constructNoCreate, + &PhongGL_Test::constructCopy, - &PhongTest::debugFlag, - &PhongTest::debugFlags, - &PhongTest::debugFlagsSupersets}); + &PhongGL_Test::debugFlag, + &PhongGL_Test::debugFlags, + &PhongGL_Test::debugFlagsSupersets}); } -void PhongTest::constructNoCreate() { +void PhongGL_Test::constructNoCreate() { { - Phong shader{NoCreate}; + PhongGL shader{NoCreate}; CORRADE_COMPARE(shader.id(), 0); - CORRADE_COMPARE(shader.flags(), Phong::Flags{}); + CORRADE_COMPARE(shader.flags(), PhongGL::Flags{}); CORRADE_COMPARE(shader.lightCount(), 0); } CORRADE_VERIFY(true); } -void PhongTest::constructCopy() { - CORRADE_VERIFY(!std::is_copy_constructible{}); - CORRADE_VERIFY(!std::is_copy_assignable{}); +void PhongGL_Test::constructCopy() { + CORRADE_VERIFY(!std::is_copy_constructible{}); + CORRADE_VERIFY(!std::is_copy_assignable{}); } -void PhongTest::debugFlag() { +void PhongGL_Test::debugFlag() { std::ostringstream out; - Debug{&out} << Phong::Flag::AmbientTexture << Phong::Flag(0xf0); - CORRADE_COMPARE(out.str(), "Shaders::Phong::Flag::AmbientTexture Shaders::Phong::Flag(0xf0)\n"); + Debug{&out} << PhongGL::Flag::AmbientTexture << PhongGL::Flag(0xf0); + CORRADE_COMPARE(out.str(), "Shaders::PhongGL::Flag::AmbientTexture Shaders::PhongGL::Flag(0xf0)\n"); } -void PhongTest::debugFlags() { +void PhongGL_Test::debugFlags() { std::ostringstream out; - Debug{&out} << (Phong::Flag::DiffuseTexture|Phong::Flag::SpecularTexture) << Phong::Flags{}; - CORRADE_COMPARE(out.str(), "Shaders::Phong::Flag::DiffuseTexture|Shaders::Phong::Flag::SpecularTexture Shaders::Phong::Flags{}\n"); + Debug{&out} << (PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture) << PhongGL::Flags{}; + CORRADE_COMPARE(out.str(), "Shaders::PhongGL::Flag::DiffuseTexture|Shaders::PhongGL::Flag::SpecularTexture Shaders::PhongGL::Flags{}\n"); } -void PhongTest::debugFlagsSupersets() { +void PhongGL_Test::debugFlagsSupersets() { #ifndef MAGNUM_TARGET_GLES2 /* InstancedObjectId is a superset of ObjectId so only one should be printed */ { std::ostringstream out; - Debug{&out} << (Phong::Flag::ObjectId|Phong::Flag::InstancedObjectId); - CORRADE_COMPARE(out.str(), "Shaders::Phong::Flag::InstancedObjectId\n"); + Debug{&out} << (PhongGL::Flag::ObjectId|PhongGL::Flag::InstancedObjectId); + CORRADE_COMPARE(out.str(), "Shaders::PhongGL::Flag::InstancedObjectId\n"); } #endif /* InstancedTextureOffset is a superset of TextureTransformation so only one should be printed */ std::ostringstream out; - Debug{&out} << (Phong::Flag::InstancedTextureOffset|Phong::Flag::TextureTransformation); - CORRADE_COMPARE(out.str(), "Shaders::Phong::Flag::InstancedTextureOffset\n"); + Debug{&out} << (PhongGL::Flag::InstancedTextureOffset|PhongGL::Flag::TextureTransformation); + CORRADE_COMPARE(out.str(), "Shaders::PhongGL::Flag::InstancedTextureOffset\n"); } }}}} -CORRADE_TEST_MAIN(Magnum::Shaders::Test::PhongTest) +CORRADE_TEST_MAIN(Magnum::Shaders::Test::PhongGL_Test) diff --git a/src/Magnum/Shaders/Test/VectorGLTest.cpp b/src/Magnum/Shaders/Test/VectorGLTest.cpp index 83d20eb0a..581281b6c 100644 --- a/src/Magnum/Shaders/Test/VectorGLTest.cpp +++ b/src/Magnum/Shaders/Test/VectorGLTest.cpp @@ -47,7 +47,7 @@ #include "Magnum/MeshTools/Compile.h" #include "Magnum/Primitives/Plane.h" #include "Magnum/Primitives/Square.h" -#include "Magnum/Shaders/Vector.h" +#include "Magnum/Shaders/VectorGL.h" #include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/ImageData.h" #include "Magnum/Trade/MeshData.h" @@ -99,22 +99,22 @@ using namespace Math::Literals; constexpr struct { const char* name; - Vector2D::Flags flags; + VectorGL2D::Flags flags; } ConstructData[]{ {"", {}}, - {"texture transformation", Vector2D::Flag::TextureTransformation} + {"texture transformation", VectorGL2D::Flag::TextureTransformation} }; const struct { const char* name; - Vector2D::Flags flags; + VectorGL2D::Flags flags; Matrix3 textureTransformation; Color4 backgroundColor, color; const char* file2D; const char* file3D; bool flip; } RenderData[] { - {"texture transformation", Vector2D::Flag::TextureTransformation, + {"texture transformation", VectorGL2D::Flag::TextureTransformation, Matrix3::translation(Vector2{1.0f})*Matrix3::scaling(Vector2{-1.0f}), 0x00000000_rgbaf, 0xffffff_rgbf, "defaults.tga", "defaults.tga", true}, @@ -176,7 +176,7 @@ template void VectorGLTest::construct() { auto&& data = ConstructData[testCaseInstanceId()]; setTestCaseDescription(data.name); - Vector shader{data.flags}; + VectorGL shader{data.flags}; CORRADE_COMPARE(shader.flags(), data.flags); CORRADE_VERIFY(shader.id()); { @@ -192,21 +192,21 @@ template void VectorGLTest::construct() { template void VectorGLTest::constructMove() { setTestCaseTemplateName(std::to_string(dimensions)); - Vector a{Vector::Flag::TextureTransformation}; + VectorGL a{VectorGL::Flag::TextureTransformation}; const GLuint id = a.id(); CORRADE_VERIFY(id); MAGNUM_VERIFY_NO_GL_ERROR(); - Vector b{std::move(a)}; + VectorGL b{std::move(a)}; CORRADE_COMPARE(b.id(), id); - CORRADE_COMPARE(b.flags(), Vector::Flag::TextureTransformation); + CORRADE_COMPARE(b.flags(), VectorGL::Flag::TextureTransformation); CORRADE_VERIFY(!a.id()); - Vector c{NoCreate}; + VectorGL c{NoCreate}; c = std::move(b); CORRADE_COMPARE(c.id(), id); - CORRADE_COMPARE(c.flags(), Vector::Flag::TextureTransformation); + CORRADE_COMPARE(c.flags(), VectorGL::Flag::TextureTransformation); CORRADE_VERIFY(!b.id()); } @@ -220,11 +220,11 @@ template void VectorGLTest::setTextureMatrixNotEnabled() std::ostringstream out; Error redirectError{&out}; - Vector shader; + VectorGL shader; shader.setTextureMatrix({}); CORRADE_COMPARE(out.str(), - "Shaders::Vector::setTextureMatrix(): the shader was not created with texture transformation enabled\n"); + "Shaders::VectorGL::setTextureMatrix(): the shader was not created with texture transformation enabled\n"); } constexpr Vector2i RenderSize{80, 80}; @@ -288,7 +288,7 @@ void VectorGLTest::renderDefaults2D() { .setSubImage(0, {}, *image); #endif - Vector2D{} + VectorGL2D{} .bindVectorTexture(texture) .draw(square); @@ -335,7 +335,7 @@ void VectorGLTest::renderDefaults3D() { .setSubImage(0, {}, *image); #endif - Vector3D{} + VectorGL3D{} .bindVectorTexture(texture) .draw(plane); @@ -385,7 +385,7 @@ void VectorGLTest::render2D() { .setSubImage(0, {}, *image); #endif - Vector2D shader{data.flags}; + VectorGL2D shader{data.flags}; shader.setBackgroundColor(data.backgroundColor) .setColor(data.color) .bindVectorTexture(texture); @@ -447,7 +447,7 @@ void VectorGLTest::render3D() { .setSubImage(0, {}, *image); #endif - Vector3D shader{data.flags}; + VectorGL3D shader{data.flags}; shader.setBackgroundColor(data.backgroundColor) .setColor(data.color) .bindVectorTexture(texture); diff --git a/src/Magnum/Shaders/Test/VectorTest.cpp b/src/Magnum/Shaders/Test/VectorGL_Test.cpp similarity index 54% rename from src/Magnum/Shaders/Test/VectorTest.cpp rename to src/Magnum/Shaders/Test/VectorGL_Test.cpp index e6374d79f..ff8e7f2e6 100644 --- a/src/Magnum/Shaders/Test/VectorTest.cpp +++ b/src/Magnum/Shaders/Test/VectorGL_Test.cpp @@ -27,12 +27,14 @@ #include #include -#include "Magnum/Shaders/Vector.h" +#include "Magnum/Shaders/VectorGL.h" namespace Magnum { namespace Shaders { namespace Test { namespace { -struct VectorTest: TestSuite::Tester { - explicit VectorTest(); +/* There's an underscore between GL and Test to disambiguate from GLTest, which + is a common suffix used to mark tests that need a GL context. Ugly, I know. */ +struct VectorGL_Test: TestSuite::Tester { + explicit VectorGL_Test(); template void constructNoCreate(); template void constructCopy(); @@ -41,50 +43,50 @@ struct VectorTest: TestSuite::Tester { void debugFlags(); }; -VectorTest::VectorTest() { - addTests({&VectorTest::constructNoCreate<2>, - &VectorTest::constructNoCreate<3>, +VectorGL_Test::VectorGL_Test() { + addTests({&VectorGL_Test::constructNoCreate<2>, + &VectorGL_Test::constructNoCreate<3>, - &VectorTest::constructCopy<2>, - &VectorTest::constructCopy<3>, + &VectorGL_Test::constructCopy<2>, + &VectorGL_Test::constructCopy<3>, - &VectorTest::debugFlag, - &VectorTest::debugFlags}); + &VectorGL_Test::debugFlag, + &VectorGL_Test::debugFlags}); } -template void VectorTest::constructNoCreate() { +template void VectorGL_Test::constructNoCreate() { setTestCaseTemplateName(std::to_string(dimensions)); { - Vector shader{NoCreate}; + VectorGL shader{NoCreate}; CORRADE_COMPARE(shader.id(), 0); - CORRADE_COMPARE(shader.flags(), typename Vector::Flags{}); + CORRADE_COMPARE(shader.flags(), typename VectorGL::Flags{}); } CORRADE_VERIFY(true); } -template void VectorTest::constructCopy() { +template void VectorGL_Test::constructCopy() { setTestCaseTemplateName(std::to_string(dimensions)); - CORRADE_VERIFY(!std::is_copy_constructible>{}); - CORRADE_VERIFY(!std::is_copy_assignable>{}); + CORRADE_VERIFY(!std::is_copy_constructible>{}); + CORRADE_VERIFY(!std::is_copy_assignable>{}); } -void VectorTest::debugFlag() { +void VectorGL_Test::debugFlag() { std::ostringstream out; - Debug{&out} << Vector2D::Flag::TextureTransformation << Vector2D::Flag(0xf0); - CORRADE_COMPARE(out.str(), "Shaders::Vector::Flag::TextureTransformation Shaders::Vector::Flag(0xf0)\n"); + Debug{&out} << VectorGL2D::Flag::TextureTransformation << VectorGL2D::Flag(0xf0); + CORRADE_COMPARE(out.str(), "Shaders::VectorGL::Flag::TextureTransformation Shaders::VectorGL::Flag(0xf0)\n"); } -void VectorTest::debugFlags() { +void VectorGL_Test::debugFlags() { std::ostringstream out; - Debug{&out} << Vector3D::Flags{Vector3D::Flag::TextureTransformation|Vector3D::Flag(0xf0)} << Vector3D::Flags{}; - CORRADE_COMPARE(out.str(), "Shaders::Vector::Flag::TextureTransformation|Shaders::Vector::Flag(0xf0) Shaders::Vector::Flags{}\n"); + Debug{&out} << VectorGL3D::Flags{VectorGL3D::Flag::TextureTransformation|VectorGL3D::Flag(0xf0)} << VectorGL3D::Flags{}; + CORRADE_COMPARE(out.str(), "Shaders::VectorGL::Flag::TextureTransformation|Shaders::VectorGL::Flag(0xf0) Shaders::VectorGL::Flags{}\n"); } }}}} -CORRADE_TEST_MAIN(Magnum::Shaders::Test::VectorTest) +CORRADE_TEST_MAIN(Magnum::Shaders::Test::VectorGL_Test) diff --git a/src/Magnum/Shaders/Test/VertexColorGLTest.cpp b/src/Magnum/Shaders/Test/VertexColorGLTest.cpp index 8740beb6f..d0e73cbd6 100644 --- a/src/Magnum/Shaders/Test/VertexColorGLTest.cpp +++ b/src/Magnum/Shaders/Test/VertexColorGLTest.cpp @@ -42,7 +42,7 @@ #include "Magnum/MeshTools/Compile.h" #include "Magnum/Primitives/Circle.h" #include "Magnum/Primitives/UVSphere.h" -#include "Magnum/Shaders/VertexColor.h" +#include "Magnum/Shaders/VertexColorGL.h" #include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/MeshData.h" @@ -135,7 +135,7 @@ VertexColorGLTest::VertexColorGLTest() { template void VertexColorGLTest::construct() { setTestCaseTemplateName(std::to_string(dimensions)); - VertexColor shader; + VertexColorGL shader; CORRADE_VERIFY(shader.id()); { #ifdef CORRADE_TARGET_APPLE @@ -150,17 +150,17 @@ template void VertexColorGLTest::construct() { template void VertexColorGLTest::constructMove() { setTestCaseTemplateName(std::to_string(dimensions)); - VertexColor a; + VertexColorGL a; const GLuint id = a.id(); CORRADE_VERIFY(id); MAGNUM_VERIFY_NO_GL_ERROR(); - VertexColor b{std::move(a)}; + VertexColorGL b{std::move(a)}; CORRADE_COMPARE(b.id(), id); CORRADE_VERIFY(!a.id()); - VertexColor c{NoCreate}; + VertexColorGL c{NoCreate}; c = std::move(b); CORRADE_COMPARE(c.id(), id); CORRADE_VERIFY(!b.id()); @@ -205,9 +205,9 @@ template void VertexColorGLTest::renderDefaults2D() { GL::Buffer colors; colors.setData(colorData); GL::Mesh circle = MeshTools::compile(circleData); - circle.addVertexBuffer(colors, 0, GL::Attribute{}); + circle.addVertexBuffer(colors, 0, GL::Attribute{}); - VertexColor2D{} + VertexColorGL2D{} .draw(circle); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -246,9 +246,9 @@ template void VertexColorGLTest::renderDefaults3D() { GL::Buffer colors; colors.setData(colorData); GL::Mesh sphere = MeshTools::compile(sphereData); - sphere.addVertexBuffer(colors, 0, GL::Attribute{}); + sphere.addVertexBuffer(colors, 0, GL::Attribute{}); - VertexColor3D{} + VertexColorGL3D{} .draw(sphere); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -281,9 +281,9 @@ template void VertexColorGLTest::render2D() { GL::Buffer colors; colors.setData(colorData); GL::Mesh circle = MeshTools::compile(circleData); - circle.addVertexBuffer(colors, 0, GL::Attribute{}); + circle.addVertexBuffer(colors, 0, GL::Attribute{}); - VertexColor2D{} + VertexColorGL2D{} .setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) .draw(circle); @@ -326,9 +326,9 @@ template void VertexColorGLTest::render3D() { GL::Buffer colors; colors.setData(colorData); GL::Mesh sphere = MeshTools::compile(sphereData); - sphere.addVertexBuffer(colors, 0, GL::Attribute{}); + sphere.addVertexBuffer(colors, 0, GL::Attribute{}); - VertexColor3D{} + VertexColorGL3D{} .setTransformationProjectionMatrix( Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* Matrix4::translation(Vector3::zAxis(-2.15f))* diff --git a/src/Magnum/Shaders/Test/VertexColorTest.cpp b/src/Magnum/Shaders/Test/VertexColorGL_Test.cpp similarity index 63% rename from src/Magnum/Shaders/Test/VertexColorTest.cpp rename to src/Magnum/Shaders/Test/VertexColorGL_Test.cpp index 630dd37d4..34a8b27d9 100644 --- a/src/Magnum/Shaders/Test/VertexColorTest.cpp +++ b/src/Magnum/Shaders/Test/VertexColorGL_Test.cpp @@ -25,44 +25,46 @@ #include -#include "Magnum/Shaders/VertexColor.h" +#include "Magnum/Shaders/VertexColorGL.h" namespace Magnum { namespace Shaders { namespace Test { namespace { -struct VertexColorTest: TestSuite::Tester { - explicit VertexColorTest(); +/* There's an underscore between GL and Test to disambiguate from GLTest, which + is a common suffix used to mark tests that need a GL context. Ugly, I know. */ +struct VertexColorGL_Test: TestSuite::Tester { + explicit VertexColorGL_Test(); template void constructNoCreate(); template void constructCopy(); }; -VertexColorTest::VertexColorTest() { - addTests({ - &VertexColorTest::constructNoCreate<2>, - &VertexColorTest::constructNoCreate<3>, +VertexColorGL_Test::VertexColorGL_Test() { + addTests({ + &VertexColorGL_Test::constructNoCreate<2>, + &VertexColorGL_Test::constructNoCreate<3>, - &VertexColorTest::constructCopy<2>, - &VertexColorTest::constructCopy<3>}); + &VertexColorGL_Test::constructCopy<2>, + &VertexColorGL_Test::constructCopy<3>}); } -template void VertexColorTest::constructNoCreate() { +template void VertexColorGL_Test::constructNoCreate() { setTestCaseTemplateName(std::to_string(dimensions)); { - VertexColor shader{NoCreate}; + VertexColorGL shader{NoCreate}; CORRADE_COMPARE(shader.id(), 0); } CORRADE_VERIFY(true); } -template void VertexColorTest::constructCopy() { +template void VertexColorGL_Test::constructCopy() { setTestCaseTemplateName(std::to_string(dimensions)); - CORRADE_VERIFY(!std::is_copy_constructible>{}); - CORRADE_VERIFY(!std::is_copy_assignable>{}); + CORRADE_VERIFY(!std::is_copy_constructible>{}); + CORRADE_VERIFY(!std::is_copy_assignable>{}); } }}}} -CORRADE_TEST_MAIN(Magnum::Shaders::Test::VertexColorTest) +CORRADE_TEST_MAIN(Magnum::Shaders::Test::VertexColorGL_Test) diff --git a/src/Magnum/Shaders/Vector.h b/src/Magnum/Shaders/Vector.h index e29d93c2a..e73d13435 100644 --- a/src/Magnum/Shaders/Vector.h +++ b/src/Magnum/Shaders/Vector.h @@ -25,210 +25,46 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef MAGNUM_BUILD_DEPRECATED /** @file - * @brief Class @ref Magnum::Shaders::Vector, typedef @ref Magnum::Shaders::Vector2D, @ref Magnum::Shaders::Vector3D + * @brief Typedef @ref Magnum::Shaders::Vector, alias @ref Magnum::Shaders::Vector2D, @ref Magnum::Shaders::Vector3D + * @m_deprecated_since_latest Use @ref Magnum/Shaders/VectorGL.h, the + * @ref Magnum::Shaders::VectorGL "VectorGL" class and + * related typedefs instead. */ +#endif -#include "Magnum/DimensionTraits.h" -#include "Magnum/Shaders/AbstractVector.h" -#include "Magnum/Shaders/visibility.h" - -namespace Magnum { namespace Shaders { - -namespace Implementation { - enum class VectorFlag: UnsignedByte { - TextureTransformation = 1 << 0 - }; - typedef Containers::EnumSet VectorFlags; -} - -/** -@brief Vector shader - -Renders vector art in plain grayscale form. See also @ref DistanceFieldVector -for more advanced effects. For rendering an unchanged texture you can use the -@ref Flat shader. You need to provide the @ref Position and -@ref TextureCoordinates attributes in your triangle mesh and call at least -@ref bindVectorTexture(). By default, the shader renders the texture with a -white color in an identity transformation. Use -@ref setTransformationProjectionMatrix(), @ref setColor() and others to -configure the shader. - -@image html shaders-vector.png width=256px - -Alpha / transparency is supported by the shader implicitly, but to have it -working on the framebuffer, you need to enable -@ref GL::Renderer::Feature::Blending and set up the blending function. See -@ref GL::Renderer::setBlendFunction() for details. - -@section Shaders-Vector-usage Example usage - -Common mesh setup: - -@snippet MagnumShaders.cpp Vector-usage1 - -Common rendering setup: - -@snippet MagnumShaders.cpp Vector-usage2 - -@see @ref shaders, @ref Vector2D, @ref Vector3D -*/ -template class MAGNUM_SHADERS_EXPORT Vector: public AbstractVector { - public: - #ifdef DOXYGEN_GENERATING_OUTPUT - /** - * @brief Flag - * @m_since{2020,06} - * - * @see @ref Flags, @ref flags() - */ - enum class Flag: UnsignedByte { - /** - * Enable texture coordinate transformation. - * @see @ref setTextureMatrix() - * @m_since{2020,06} - */ - TextureTransformation = 1 << 0 - }; - - /** - * @brief Flags - * @m_since{2020,06} - * - * @see @ref flags() - */ - typedef Containers::EnumSet Flags; - #else - /* Done this way to be prepared for possible future diversion of 2D - and 3D flags (e.g. introducing 3D-specific features) */ - typedef Implementation::VectorFlag Flag; - typedef Implementation::VectorFlags Flags; - #endif - - /** - * @brief Constructor - * @param flags Flags - */ - explicit Vector(Flags flags = {}); - - /** - * @brief Construct without creating the underlying OpenGL object - * - * The constructed instance is equivalent to a moved-from state. Useful - * in cases where you will overwrite the instance later anyway. Move - * another object over it to make it useful. - * - * This function can be safely used for constructing (and later - * destructing) objects even without any OpenGL context being active. - * However note that this is a low-level and a potentially dangerous - * API, see the documentation of @ref NoCreate for alternatives. - */ - explicit Vector(NoCreateT) noexcept - /** @todoc remove workaround when doxygen is sane */ - #ifndef DOXYGEN_GENERATING_OUTPUT - : AbstractVector{NoCreate} - #endif - {} - - /** @brief Copying is not allowed */ - Vector(const Vector&) = delete; - - /** @brief Move constructor */ - Vector(Vector&&) noexcept = default; - - /** @brief Copying is not allowed */ - Vector& operator=(const Vector&) = delete; - - /** @brief Move assignment */ - Vector& operator=(Vector&&) noexcept = default; - - /** - * @brief Flags - * @m_since{2020,06} - */ - Flags flags() const { return _flags; } - - /** - * @brief Set transformation and projection matrix - * @return Reference to self (for method chaining) - * - * Default is an identity matrix. - */ - Vector& setTransformationProjectionMatrix(const MatrixTypeFor& matrix); - - /** - * @brief Set texture coordinate transformation matrix - * @return Reference to self (for method chaining) - * @m_since{2020,06} - * - * Expects that the shader was created with - * @ref Flag::TextureTransformation enabled. Initial value is an - * identity matrix. - */ - Vector& setTextureMatrix(const Matrix3& matrix); - - /** - * @brief Set background color - * @return Reference to self (for method chaining) - * - * Default is @cpp 0x00000000_rgbaf @ce. - * @see @ref setColor() - */ - Vector& setBackgroundColor(const Color4& color); +#include "Magnum/configure.h" - /** - * @brief Set fill color - * @return Reference to self (for method chaining) - * - * Default is @cpp 0xffffffff_rgbaf @ce. - * @see @ref setBackgroundColor() - */ - Vector& setColor(const Color4& color); +#ifdef MAGNUM_BUILD_DEPRECATED +#include - #ifndef DOXYGEN_GENERATING_OUTPUT - /* Overloads to remove WTF-factor from method chaining order */ - Vector& bindVectorTexture(GL::Texture2D& texture) { - AbstractVector::bindVectorTexture(texture); - return *this; - } - #endif +#include "Magnum/Shaders/VectorGL.h" - private: - /* Prevent accidentally calling irrelevant functions */ - #ifndef MAGNUM_TARGET_GLES - using GL::AbstractShaderProgram::drawTransformFeedback; - #endif - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - using GL::AbstractShaderProgram::dispatchCompute; - #endif +CORRADE_DEPRECATED_FILE("use Magnum/Shaders/VectorGL.h, the VectorGL class and related typedefs instead") - Flags _flags; - Int _transformationProjectionMatrixUniform{0}, - _textureMatrixUniform{1}, - _backgroundColorUniform{2}, - _colorUniform{3}; -}; +namespace Magnum { namespace Shaders { -/** @brief Two-dimensional vector shader */ -typedef Vector<2> Vector2D; +/** @brief @copybrief Shaders::VectorGL + * @m_deprecated_since_latest Use @ref Shaders::VectorGL "VectorGL" instead. + */ +#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Multiple definitions still broken */ +template using Vector CORRADE_DEPRECATED_ALIAS("use VectorGL instead") = VectorGL; +#endif -/** @brief Three-dimensional vector shader */ -typedef Vector<3> Vector3D; +/** @brief @copybrief VectorGL2D + * @m_deprecated_since_latest Use @ref VectorGL2D instead. + */ +typedef CORRADE_DEPRECATED("use VectorGL2D instead") VectorGL2D Vector2D; -#ifdef DOXYGEN_GENERATING_OUTPUT -/** @debugoperatorclassenum{Vector,Vector::Flag} */ -template Debug& operator<<(Debug& debug, Vector::Flag value); +/** @brief @copybrief VectorGL3D + * @m_deprecated_since_latest Use @ref VectorGL3D instead. + */ +typedef CORRADE_DEPRECATED("use VectorGL3D instead") VectorGL3D Vector3D; -/** @debugoperatorclassenum{Vector,Vector::Flags} */ -template Debug& operator<<(Debug& debug, Vector::Flags value); +}} #else -namespace Implementation { - MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, VectorFlag value); - MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, VectorFlags value); - CORRADE_ENUMSET_OPERATORS(VectorFlags) -} +#error use Magnum/Shaders/VectorGL.h, the VectorGL class and related typedefs instead #endif -}} - #endif diff --git a/src/Magnum/Shaders/Vector.cpp b/src/Magnum/Shaders/VectorGL.cpp similarity index 78% rename from src/Magnum/Shaders/Vector.cpp rename to src/Magnum/Shaders/VectorGL.cpp index c61655d69..6e3a3fb68 100644 --- a/src/Magnum/Shaders/Vector.cpp +++ b/src/Magnum/Shaders/VectorGL.cpp @@ -23,7 +23,7 @@ DEALINGS IN THE SOFTWARE. */ -#include "Vector.h" +#include "VectorGL.h" #include #include @@ -40,13 +40,13 @@ namespace Magnum { namespace Shaders { -template Vector::Vector(const Flags flags): _flags{flags} { +template VectorGL::VectorGL(const Flags flags): _flags{flags} { #ifdef MAGNUM_BUILD_STATIC /* Import resources on static build, if not already */ - if(!Utility::Resource::hasGroup("MagnumShaders")) + if(!Utility::Resource::hasGroup("MagnumShadersGL")) importShaderResources(); #endif - Utility::Resource rs("MagnumShaders"); + Utility::Resource rs("MagnumShadersGL"); #ifndef MAGNUM_TARGET_GLES const GL::Version version = GL::Context::current().supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); @@ -74,8 +74,8 @@ template Vector::Vector(const Flags flags): if(!GL::Context::current().isExtensionSupported(version)) #endif { - GL::AbstractShaderProgram::bindAttributeLocation(AbstractVector::Position::Location, "position"); - GL::AbstractShaderProgram::bindAttributeLocation(AbstractVector::TextureCoordinates::Location, "textureCoordinates"); + GL::AbstractShaderProgram::bindAttributeLocation(AbstractVectorGL::Position::Location, "position"); + GL::AbstractShaderProgram::bindAttributeLocation(AbstractVectorGL::TextureCoordinates::Location, "textureCoordinates"); } #endif @@ -96,7 +96,7 @@ template Vector::Vector(const Flags flags): if(!GL::Context::current().isExtensionSupported(version)) #endif { - GL::AbstractShaderProgram::setUniform(GL::AbstractShaderProgram::uniformLocation("vectorTexture"), AbstractVector::VectorTextureUnit); + GL::AbstractShaderProgram::setUniform(GL::AbstractShaderProgram::uniformLocation("vectorTexture"), AbstractVectorGL::VectorTextureUnit); } /* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */ @@ -108,39 +108,39 @@ template Vector::Vector(const Flags flags): #endif } -template Vector& Vector::setTransformationProjectionMatrix(const MatrixTypeFor& matrix) { +template VectorGL& VectorGL::setTransformationProjectionMatrix(const MatrixTypeFor& matrix) { GL::AbstractShaderProgram::setUniform(_transformationProjectionMatrixUniform, matrix); return *this; } -template Vector& Vector::setTextureMatrix(const Matrix3& matrix) { +template VectorGL& VectorGL::setTextureMatrix(const Matrix3& matrix) { CORRADE_ASSERT(_flags & Flag::TextureTransformation, - "Shaders::Vector::setTextureMatrix(): the shader was not created with texture transformation enabled", *this); + "Shaders::VectorGL::setTextureMatrix(): the shader was not created with texture transformation enabled", *this); GL::AbstractShaderProgram::setUniform(_textureMatrixUniform, matrix); return *this; } -template Vector& Vector::setBackgroundColor(const Color4& color) { +template VectorGL& VectorGL::setBackgroundColor(const Color4& color) { GL::AbstractShaderProgram::setUniform(_backgroundColorUniform, color); return *this; } -template Vector& Vector::setColor(const Color4& color) { +template VectorGL& VectorGL::setColor(const Color4& color) { GL::AbstractShaderProgram::setUniform(_colorUniform, color); return *this; } -template class Vector<2>; -template class Vector<3>; +template class VectorGL<2>; +template class VectorGL<3>; namespace Implementation { -Debug& operator<<(Debug& debug, const VectorFlag value) { - debug << "Shaders::Vector::Flag" << Debug::nospace; +Debug& operator<<(Debug& debug, const VectorGLFlag value) { + debug << "Shaders::VectorGL::Flag" << Debug::nospace; switch(value) { /* LCOV_EXCL_START */ - #define _c(v) case VectorFlag::v: return debug << "::" #v; + #define _c(v) case VectorGLFlag::v: return debug << "::" #v; _c(TextureTransformation) #undef _c /* LCOV_EXCL_STOP */ @@ -149,9 +149,9 @@ Debug& operator<<(Debug& debug, const VectorFlag value) { return debug << "(" << Debug::nospace << reinterpret_cast(UnsignedByte(value)) << Debug::nospace << ")"; } -Debug& operator<<(Debug& debug, const VectorFlags value) { - return Containers::enumSetDebugOutput(debug, value, "Shaders::Vector::Flags{}", { - VectorFlag::TextureTransformation +Debug& operator<<(Debug& debug, const VectorGLFlags value) { + return Containers::enumSetDebugOutput(debug, value, "Shaders::VectorGL::Flags{}", { + VectorGLFlag::TextureTransformation }); } diff --git a/src/Magnum/Shaders/VectorGL.h b/src/Magnum/Shaders/VectorGL.h new file mode 100644 index 000000000..8cca43e87 --- /dev/null +++ b/src/Magnum/Shaders/VectorGL.h @@ -0,0 +1,242 @@ +#ifndef Magnum_Shaders_VectorGL_h +#define Magnum_Shaders_VectorGL_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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::VectorGL, typedef @ref Magnum::Shaders::VectorGL2D, @ref Magnum::Shaders::VectorGL3D + * @m_since_latest + */ + +#include "Magnum/DimensionTraits.h" +#include "Magnum/Shaders/AbstractVectorGL.h" +#include "Magnum/Shaders/visibility.h" + +namespace Magnum { namespace Shaders { + +namespace Implementation { + enum class VectorGLFlag: UnsignedByte { + TextureTransformation = 1 << 0 + }; + typedef Containers::EnumSet VectorGLFlags; +} + +/** +@brief Vector OpenGL shader +@m_since_latest + +Renders vector art in plain grayscale form. See also @ref DistanceFieldVectorGL +for more advanced effects. For rendering an unchanged texture you can use the +@ref FlatGL shader. You need to provide the @ref Position and +@ref TextureCoordinates attributes in your triangle mesh and call at least +@ref bindVectorTexture(). By default, the shader renders the texture with a +white color in an identity transformation. Use +@ref setTransformationProjectionMatrix(), @ref setColor() and others to +configure the shader. + +@image html shaders-vector.png width=256px + +Alpha / transparency is supported by the shader implicitly, but to have it +working on the framebuffer, you need to enable +@ref GL::Renderer::Feature::Blending and set up the blending function. See +@ref GL::Renderer::setBlendFunction() for details. + +@section Shaders-VectorGL-usage Example usage + +Common mesh setup: + +@snippet MagnumShaders-gl.cpp VectorGL-usage1 + +Common rendering setup: + +@snippet MagnumShaders-gl.cpp VectorGL-usage2 + +@see @ref shaders, @ref VectorGL2D, @ref VectorGL3D +*/ +template class MAGNUM_SHADERS_EXPORT VectorGL: public AbstractVectorGL { + public: + #ifdef DOXYGEN_GENERATING_OUTPUT + /** + * @brief Flag + * @m_since{2020,06} + * + * @see @ref Flags, @ref flags() + */ + enum class Flag: UnsignedByte { + /** + * Enable texture coordinate transformation. + * @see @ref setTextureMatrix() + * @m_since{2020,06} + */ + TextureTransformation = 1 << 0 + }; + + /** + * @brief Flags + * @m_since{2020,06} + * + * @see @ref flags() + */ + typedef Containers::EnumSet Flags; + #else + /* Done this way to be prepared for possible future diversion of 2D + and 3D flags (e.g. introducing 3D-specific features) */ + typedef Implementation::VectorGLFlag Flag; + typedef Implementation::VectorGLFlags Flags; + #endif + + /** + * @brief Constructor + * @param flags Flags + */ + explicit VectorGL(Flags flags = {}); + + /** + * @brief Construct without creating the underlying OpenGL object + * + * The constructed instance is equivalent to a moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + * + * This function can be safely used for constructing (and later + * destructing) objects even without any OpenGL context being active. + * However note that this is a low-level and a potentially dangerous + * API, see the documentation of @ref NoCreate for alternatives. + */ + explicit VectorGL(NoCreateT) noexcept + /** @todoc remove workaround when doxygen is sane */ + #ifndef DOXYGEN_GENERATING_OUTPUT + : AbstractVectorGL{NoCreate} + #endif + {} + + /** @brief Copying is not allowed */ + VectorGL(const VectorGL&) = delete; + + /** @brief Move constructor */ + VectorGL(VectorGL&&) noexcept = default; + + /** @brief Copying is not allowed */ + VectorGL& operator=(const VectorGL&) = delete; + + /** @brief Move assignment */ + VectorGL& operator=(VectorGL&&) noexcept = default; + + /** + * @brief Flags + * @m_since{2020,06} + */ + Flags flags() const { return _flags; } + + /** + * @brief Set transformation and projection matrix + * @return Reference to self (for method chaining) + * + * Default is an identity matrix. + */ + VectorGL& setTransformationProjectionMatrix(const MatrixTypeFor& matrix); + + /** + * @brief Set texture coordinate transformation matrix + * @return Reference to self (for method chaining) + * @m_since{2020,06} + * + * Expects that the shader was created with + * @ref Flag::TextureTransformation enabled. Initial value is an + * identity matrix. + */ + VectorGL& setTextureMatrix(const Matrix3& matrix); + + /** + * @brief Set background color + * @return Reference to self (for method chaining) + * + * Default is @cpp 0x00000000_rgbaf @ce. + * @see @ref setColor() + */ + VectorGL& setBackgroundColor(const Color4& color); + + /** + * @brief Set fill color + * @return Reference to self (for method chaining) + * + * Default is @cpp 0xffffffff_rgbaf @ce. + * @see @ref setBackgroundColor() + */ + VectorGL& setColor(const Color4& color); + + #ifndef DOXYGEN_GENERATING_OUTPUT + /* Overloads to remove WTF-factor from method chaining order */ + VectorGL& bindVectorTexture(GL::Texture2D& texture) { + AbstractVectorGL::bindVectorTexture(texture); + return *this; + } + #endif + + private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + + Flags _flags; + Int _transformationProjectionMatrixUniform{0}, + _textureMatrixUniform{1}, + _backgroundColorUniform{2}, + _colorUniform{3}; +}; + +/** +@brief Two-dimensional vector OpenGL shader +@m_since_latest +*/ +typedef VectorGL<2> VectorGL2D; + +/** +@brief Three-dimensional vector OpenGL shader +@m_since_latest +*/ +typedef VectorGL<3> VectorGL3D; + +#ifdef DOXYGEN_GENERATING_OUTPUT +/** @debugoperatorclassenum{VectorGL,VectorGL::Flag} */ +template Debug& operator<<(Debug& debug, VectorGL::Flag value); + +/** @debugoperatorclassenum{VectorGL,VectorGL::Flags} */ +template Debug& operator<<(Debug& debug, VectorGL::Flags value); +#else +namespace Implementation { + MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, VectorGLFlag value); + MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, VectorGLFlags value); + CORRADE_ENUMSET_OPERATORS(VectorGLFlags) +} +#endif + +}} + +#endif diff --git a/src/Magnum/Shaders/VertexColor.h b/src/Magnum/Shaders/VertexColor.h index ccf70e07a..dc8992428 100644 --- a/src/Magnum/Shaders/VertexColor.h +++ b/src/Magnum/Shaders/VertexColor.h @@ -25,140 +25,46 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef MAGNUM_BUILD_DEPRECATED /** @file - * @brief Class @ref Magnum::Shaders::VertexColor + * @brief Typedef @ref Magnum::Shaders::VertexColor, alias @ref Magnum::Shaders::VertexColor2D, @ref Magnum::Shaders::VertexColor3D + * @m_deprecated_since_latest Use @ref Magnum/Shaders/VertexColorGL.h, the + * @ref Magnum::Shaders::VertexColorGL "VertexColorGL" class and + * related typedefs instead. */ +#endif -#include "Magnum/DimensionTraits.h" -#include "Magnum/GL/AbstractShaderProgram.h" -#include "Magnum/Shaders/Generic.h" -#include "Magnum/Shaders/visibility.h" - -namespace Magnum { namespace Shaders { - -/** -@brief Vertex color shader - -Draws a vertex-colored mesh. You need to provide @ref Position and @ref Color3 -/ @ref Color4 attributes in your triangle mesh. By default, the shader renders -the mesh in an identity transformation. Use -@ref setTransformationProjectionMatrix() to configure the shader. - -@image html shaders-vertexcolor.png width=256px - -This shader is equivalent to @ref Flat with @ref Flat::Flag::VertexColor -enabled; the 3D version of this shader is equivalent to @ref Phong with -@ref Phong::Flag::VertexColor enabled. In both cases this implementation is -much simpler and thus likely also faster. - -Alpha / transparency is supported by the shader implicitly, but to have it -working on the framebuffer, you need to enable -@ref GL::Renderer::Feature::Blending and set up the blending function. See -@ref GL::Renderer::setBlendFunction() for details. - -@section Shaders-VertexColor-example Example usage - -Common mesh setup. The shader accepts either three- or four-component color -attribute, use either @ref Color3 or @ref Color4 to specify which one you use. - -@snippet MagnumShaders.cpp VertexColor-usage1 - -Common rendering setup: - -@snippet MagnumShaders.cpp VertexColor-usage2 - -@see @ref shaders, @ref VertexColor2D, @ref VertexColor3D -*/ -template class MAGNUM_SHADERS_EXPORT VertexColor: 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 Generic::Position Position; - - /** - * @brief Three-component vertex color - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Color3. Use - * either this or the @ref Color4 attribute. - */ - typedef typename Generic::Color3 Color3; - - /** - * @brief Four-component vertex color - * - * @ref shaders-generic "Generic attribute", @ref Magnum::Color4. Use - * either this or the @ref Color3 attribute. - */ - typedef typename Generic::Color4 Color4; - - enum: UnsignedInt { - /** - * Color shader output. @ref shaders-generic "Generic output", - * present always. Expects three- or four-component floating-point - * or normalized buffer attachment. - */ - ColorOutput = Generic::ColorOutput - }; - - explicit VertexColor(); - - /** - * @brief Construct without creating the underlying OpenGL object - * - * The constructed instance is equivalent to a moved-from state. Useful - * in cases where you will overwrite the instance later anyway. Move - * another object over it to make it useful. - * - * This function can be safely used for constructing (and later - * destructing) objects even without any OpenGL context being active. - * However note that this is a low-level and a potentially dangerous - * API, see the documentation of @ref NoCreate for alternatives. - */ - explicit VertexColor(NoCreateT) noexcept: AbstractShaderProgram{NoCreate} {} - - /** @brief Copying is not allowed */ - VertexColor(const VertexColor&) = delete; - - /** @brief Move constructor */ - VertexColor(VertexColor&&) noexcept = default; +#include "Magnum/configure.h" - /** @brief Copying is not allowed */ - VertexColor& operator=(const VertexColor&) = delete; +#ifdef MAGNUM_BUILD_DEPRECATED +#include - /** @brief Move assignment */ - VertexColor& operator=(VertexColor&&) noexcept = default; +#include "Magnum/Shaders/VertexColorGL.h" - /** - * @brief Set transformation and projection matrix - * @return Reference to self (for method chaining) - * - * Default is an identity matrix. - */ - VertexColor& setTransformationProjectionMatrix(const MatrixTypeFor& matrix); +CORRADE_DEPRECATED_FILE("use Magnum/Shaders/VertexColorGL.h, the VertexColorGL class and related typedefs instead") - private: - /* Prevent accidentally calling irrelevant functions */ - #ifndef MAGNUM_TARGET_GLES - using GL::AbstractShaderProgram::drawTransformFeedback; - #endif - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - using GL::AbstractShaderProgram::dispatchCompute; - #endif +namespace Magnum { namespace Shaders { - Int _transformationProjectionMatrixUniform{0}; -}; +/** @brief @copybrief VertexColorGL + * @m_deprecated_since_latest Use @ref VertexColorGL instead. + */ +#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Multiple definitions still broken */ +template using VertexColor CORRADE_DEPRECATED_ALIAS("use VertexColorGL instead") = VertexColorGL; +#endif -/** @brief 2D vertex color shader */ -typedef VertexColor<2> VertexColor2D; +/** @brief @copybrief VertexColorGL2D + * @m_deprecated_since_latest Use @ref VertexColorGL2D instead. + */ +typedef CORRADE_DEPRECATED("use VertexColorGL2D instead") VertexColorGL2D VertexColor2D; -/** @brief 3D vertex color shader */ -typedef VertexColor<3> VertexColor3D; +/** @brief @copybrief VertexColorGL3D + * @m_deprecated_since_latest Use @ref VertexColorGL3D instead. + */ +typedef CORRADE_DEPRECATED("use VertexColorGL3D instead") VertexColorGL3D VertexColor3D; }} +#else +#error use Magnum/Shaders/VertexColorGL.h, the VertexColorGL class and related typedefs instead +#endif #endif diff --git a/src/Magnum/Shaders/VertexColor.cpp b/src/Magnum/Shaders/VertexColorGL.cpp similarity index 89% rename from src/Magnum/Shaders/VertexColor.cpp rename to src/Magnum/Shaders/VertexColorGL.cpp index 36510ff50..a767d74b4 100644 --- a/src/Magnum/Shaders/VertexColor.cpp +++ b/src/Magnum/Shaders/VertexColorGL.cpp @@ -23,7 +23,7 @@ DEALINGS IN THE SOFTWARE. */ -#include "VertexColor.h" +#include "VertexColorGL.h" #include #include @@ -39,13 +39,13 @@ namespace Magnum { namespace Shaders { -template VertexColor::VertexColor() { +template VertexColorGL::VertexColorGL() { #ifdef MAGNUM_BUILD_STATIC /* Import resources on static build, if not already */ - if(!Utility::Resource::hasGroup("MagnumShaders")) + if(!Utility::Resource::hasGroup("MagnumShadersGL")) importShaderResources(); #endif - Utility::Resource rs("MagnumShaders"); + Utility::Resource rs("MagnumShadersGL"); #ifndef MAGNUM_TARGET_GLES const GL::Version version = GL::Context::current().supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); @@ -92,12 +92,12 @@ template VertexColor::VertexColor() { #endif } -template VertexColor& VertexColor::setTransformationProjectionMatrix(const MatrixTypeFor& matrix) { +template VertexColorGL& VertexColorGL::setTransformationProjectionMatrix(const MatrixTypeFor& matrix) { setUniform(_transformationProjectionMatrixUniform, matrix); return *this; } -template class VertexColor<2>; -template class VertexColor<3>; +template class VertexColorGL<2>; +template class VertexColorGL<3>; }} diff --git a/src/Magnum/Shaders/VertexColorGL.h b/src/Magnum/Shaders/VertexColorGL.h new file mode 100644 index 000000000..5bbd17fdc --- /dev/null +++ b/src/Magnum/Shaders/VertexColorGL.h @@ -0,0 +1,172 @@ +#ifndef Magnum_Shaders_VertexColorGL_h +#define Magnum_Shaders_VertexColorGL_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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::VertexColorGL + * @m_since_latest + */ + +#include "Magnum/DimensionTraits.h" +#include "Magnum/GL/AbstractShaderProgram.h" +#include "Magnum/Shaders/GenericGL.h" +#include "Magnum/Shaders/visibility.h" + +namespace Magnum { namespace Shaders { + +/** +@brief Vertex color OpenGL shader +@m_since_latest + +Draws a vertex-colored mesh. You need to provide @ref Position and @ref Color3 +/ @ref Color4 attributes in your triangle mesh. By default, the shader renders +the mesh in an identity transformation. Use +@ref setTransformationProjectionMatrix() to configure the shader. + +@image html shaders-vertexcolor.png width=256px + +This shader is equivalent to @ref FlatGL with @ref FlatGL::Flag::VertexColor +enabled; the 3D version of this shader is equivalent to @ref PhongGL with +@ref PhongGL::Flag::VertexColor enabled. In both cases this implementation is +much simpler and thus likely also faster. + +Alpha / transparency is supported by the shader implicitly, but to have it +working on the framebuffer, you need to enable +@ref GL::Renderer::Feature::Blending and set up the blending function. See +@ref GL::Renderer::setBlendFunction() for details. + +@section Shaders-VertexColorGL-example Example usage + +Common mesh setup. The shader accepts either three- or four-component color +attribute, use either @ref Color3 or @ref Color4 to specify which one you use. + +@snippet MagnumShaders-gl.cpp VertexColorGL-usage1 + +Common rendering setup: + +@snippet MagnumShaders-gl.cpp VertexColorGL-usage2 + +@see @ref shaders, @ref VertexColorGL2D, @ref VertexColorGL3D +*/ +template class MAGNUM_SHADERS_EXPORT VertexColorGL: 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::Position Position; + + /** + * @brief Three-component vertex color + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Color3. Use + * either this or the @ref Color4 attribute. + */ + typedef typename GenericGL::Color3 Color3; + + /** + * @brief Four-component vertex color + * + * @ref shaders-generic "Generic attribute", @ref Magnum::Color4. Use + * either this or the @ref Color3 attribute. + */ + typedef typename GenericGL::Color4 Color4; + + 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::ColorOutput + }; + + explicit VertexColorGL(); + + /** + * @brief Construct without creating the underlying OpenGL object + * + * The constructed instance is equivalent to a moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + * + * This function can be safely used for constructing (and later + * destructing) objects even without any OpenGL context being active. + * However note that this is a low-level and a potentially dangerous + * API, see the documentation of @ref NoCreate for alternatives. + */ + explicit VertexColorGL(NoCreateT) noexcept: AbstractShaderProgram{NoCreate} {} + + /** @brief Copying is not allowed */ + VertexColorGL(const VertexColorGL&) = delete; + + /** @brief Move constructor */ + VertexColorGL(VertexColorGL&&) noexcept = default; + + /** @brief Copying is not allowed */ + VertexColorGL& operator=(const VertexColorGL&) = delete; + + /** @brief Move assignment */ + VertexColorGL& operator=(VertexColorGL&&) noexcept = default; + + /** + * @brief Set transformation and projection matrix + * @return Reference to self (for method chaining) + * + * Default is an identity matrix. + */ + VertexColorGL& setTransformationProjectionMatrix(const MatrixTypeFor& matrix); + + private: + /* Prevent accidentally calling irrelevant functions */ + #ifndef MAGNUM_TARGET_GLES + using GL::AbstractShaderProgram::drawTransformFeedback; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + using GL::AbstractShaderProgram::dispatchCompute; + #endif + + Int _transformationProjectionMatrixUniform{0}; +}; + +/** +@brief 2D vertex color OpenGL shader +@m_since_latest +*/ +typedef VertexColorGL<2> VertexColorGL2D; + +/** +@brief 3D vertex color OpenGL shader +@m_since_latest +*/ +typedef VertexColorGL<3> VertexColorGL3D; + +}} + +#endif diff --git a/src/Magnum/Shaders/resources.conf b/src/Magnum/Shaders/resources-gl.conf similarity index 95% rename from src/Magnum/Shaders/resources.conf rename to src/Magnum/Shaders/resources-gl.conf index 59924c314..f545425c9 100644 --- a/src/Magnum/Shaders/resources.conf +++ b/src/Magnum/Shaders/resources-gl.conf @@ -1,4 +1,4 @@ -group=MagnumShaders +group=MagnumShadersGL [file] filename=AbstractVector.vert diff --git a/src/Magnum/Text/Renderer.cpp b/src/Magnum/Text/Renderer.cpp index a3a5071b3..088561041 100644 --- a/src/Magnum/Text/Renderer.cpp +++ b/src/Magnum/Text/Renderer.cpp @@ -33,7 +33,7 @@ #include "Magnum/GL/Extensions.h" #include "Magnum/GL/Mesh.h" #include "Magnum/Math/Functions.h" -#include "Magnum/Shaders/AbstractVector.h" +#include "Magnum/Shaders/AbstractVectorGL.h" #include "Magnum/Text/AbstractFont.h" #include "Magnum/Text/GlyphCache.h" @@ -255,9 +255,9 @@ template std::tuple Renderer(r); mesh.addVertexBuffer(vertexBuffer, 0, - typename Shaders::AbstractVector::Position( - Shaders::AbstractVector::Position::Components::Two), - typename Shaders::AbstractVector::TextureCoordinates()); + typename Shaders::AbstractVectorGL::Position( + Shaders::AbstractVectorGL::Position::Components::Two), + typename Shaders::AbstractVectorGL::TextureCoordinates()); return r; } @@ -320,8 +320,8 @@ AbstractRenderer::~AbstractRenderer() = default; template Renderer::Renderer(AbstractFont& font, const GlyphCache& cache, const Float size, const Alignment alignment): AbstractRenderer(font, cache, size, alignment) { /* Finalize mesh configuration */ _mesh.addVertexBuffer(_vertexBuffer, 0, - typename Shaders::AbstractVector::Position(Shaders::AbstractVector::Position::Components::Two), - typename Shaders::AbstractVector::TextureCoordinates()); + typename Shaders::AbstractVectorGL::Position(Shaders::AbstractVectorGL::Position::Components::Two), + typename Shaders::AbstractVectorGL::TextureCoordinates()); } void AbstractRenderer::reserve(const uint32_t glyphCount, const GL::BufferUsage vertexBufferUsage, const GL::BufferUsage indexBufferUsage) { diff --git a/src/Magnum/Text/Renderer.h b/src/Magnum/Text/Renderer.h index 5acc03b01..eb9edfdf9 100644 --- a/src/Magnum/Text/Renderer.h +++ b/src/Magnum/Text/Renderer.h @@ -202,7 +202,7 @@ asynchronous buffer updates. There is no similar extension in WebGL, thus plain (and slow) buffer updates are used there. @see @ref Renderer2D, @ref Renderer3D, @ref AbstractFont, - @ref Shaders::AbstractVector + @ref Shaders::AbstractVectorGL */ template class MAGNUM_TEXT_EXPORT Renderer: public AbstractRenderer { public: @@ -217,7 +217,7 @@ template class MAGNUM_TEXT_EXPORT Renderer: public Abstr * @param usage Usage of vertex and index buffer * @param alignment Text alignment * - * Returns mesh prepared for use with @ref Shaders::AbstractVector + * Returns mesh prepared for use with @ref Shaders::AbstractVectorGL * subclasses and rectangle spanning the rendered text. */ static std::tuple render(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, GL::Buffer& vertexBuffer, GL::Buffer& indexBuffer, GL::BufferUsage usage, Alignment alignment = Alignment::LineLeft); diff --git a/src/Magnum/TextureTools/DistanceField.h b/src/Magnum/TextureTools/DistanceField.h index 9195d5209..8d560dffe 100644 --- a/src/Magnum/TextureTools/DistanceField.h +++ b/src/Magnum/TextureTools/DistanceField.h @@ -72,7 +72,7 @@ The resulting texture can be used with bilinear filtering. It can be converted back to binary form in shader using e.g. GLSL @glsl smoothstep() @ce function with step around 0.5 to create antialiased edges. Or you can exploit the distance field features to create many other effects. See also -@ref Shaders::DistanceFieldVector. +@ref Shaders::DistanceFieldVectorGL. Based on: *Chris Green - Improved Alpha-Tested Magnification for Vector Textures and Special Effects, SIGGRAPH 2007, diff --git a/src/Magnum/TextureTools/distancefieldconverter.cpp b/src/Magnum/TextureTools/distancefieldconverter.cpp index aa230cc30..cc072cf57 100644 --- a/src/Magnum/TextureTools/distancefieldconverter.cpp +++ b/src/Magnum/TextureTools/distancefieldconverter.cpp @@ -113,7 +113,7 @@ Arguments: Images with @ref PixelFormat::R8Unorm, @ref PixelFormat::RGB8Unorm or @ref PixelFormat::RGBA8Unorm are accepted on input. -The resulting image can be then used with @ref Shaders::DistanceFieldVector +The resulting image can be then used with @ref Shaders::DistanceFieldVectorGL shader. See also @ref TextureTools::DistanceField for more information about the algorithm and parameters. diff --git a/src/Magnum/Trade/MeshData.h b/src/Magnum/Trade/MeshData.h index 613ae00e7..a83083fb9 100644 --- a/src/Magnum/Trade/MeshData.h +++ b/src/Magnum/Trade/MeshData.h @@ -66,7 +66,7 @@ enum class MeshAttribute: UnsignedShort { * @ref VertexFormat::Vector3b, @ref VertexFormat::Vector3bNormalized, * @ref VertexFormat::Vector3us, @ref VertexFormat::Vector3usNormalized, * @ref VertexFormat::Vector3s or @ref VertexFormat::Vector3sNormalized. - * Corresponds to @ref Shaders::Generic::Position. + * Corresponds to @ref Shaders::GenericGL::Position. * @see @ref MeshData::positions2DAsArray(), * @ref MeshData::positions3DAsArray() */ @@ -86,8 +86,8 @@ enum class MeshAttribute: UnsignedShort { * * @snippet MagnumTrade.cpp MeshAttribute-bitangent-from-tangent * - * Corresponds to @ref Shaders::Generic::Tangent or - * @ref Shaders::Generic::Tangent4. + * Corresponds to @ref Shaders::GenericGL::Tangent or + * @ref Shaders::GenericGL::Tangent4. * @see @ref MeshData::tangentsAsArray(), * @ref MeshData::bitangentSignsAsArray() */ @@ -99,7 +99,7 @@ enum class MeshAttribute: UnsignedShort { * @ref VertexFormat::Vector3sNormalized. For better storage efficiency, * the bitangent can be also reconstructed from the normal and tangent, see * @ref MeshAttribute::Tangent for more information. Corresponds to - * @ref Shaders::Generic::Bitangent. + * @ref Shaders::GenericGL::Bitangent. * @see @ref MeshData::bitangentsAsArray() */ Bitangent, @@ -108,7 +108,7 @@ enum class MeshAttribute: UnsignedShort { * Normal. Type is usually @ref VertexFormat::Vector3, but can be also * @ref VertexFormat::Vector3h. @ref VertexFormat::Vector3bNormalized or * @ref VertexFormat::Vector3sNormalized. Corresponds to - * @ref Shaders::Generic::Normal. + * @ref Shaders::GenericGL::Normal. * @see @ref MeshData::normalsAsArray() */ Normal, @@ -120,7 +120,7 @@ enum class MeshAttribute: UnsignedShort { * @ref VertexFormat::Vector2b, @ref VertexFormat::Vector2bNormalized, * @ref VertexFormat::Vector2us, @ref VertexFormat::Vector2usNormalized, * @ref VertexFormat::Vector2s or @ref VertexFormat::Vector2sNormalized. - * Corresponds to @ref Shaders::Generic::TextureCoordinates. + * Corresponds to @ref Shaders::GenericGL::TextureCoordinates. * @see @ref MeshData::textureCoordinates2DAsArray() */ TextureCoordinates, @@ -133,7 +133,7 @@ enum class MeshAttribute: UnsignedShort { * @ref VertexFormat::Vector3usNormalized, * @ref VertexFormat::Vector4ubNormalized or * @ref VertexFormat::Vector4usNormalized. Corresponds to - * @ref Shaders::Generic::Color3 or @ref Shaders::Generic::Color4. + * @ref Shaders::GenericGL::Color3 or @ref Shaders::GenericGL::Color4. * @see @ref MeshData::colorsAsArray() */ Color, @@ -142,7 +142,7 @@ enum class MeshAttribute: UnsignedShort { * (Instanced) object ID for editor selection or scene annotation. Type is * usually @ref VertexFormat::UnsignedInt, but can be also * @ref VertexFormat::UnsignedShort or @ref VertexFormat::UnsignedByte. - * Corresponds to @ref Shaders::Generic::ObjectId. + * Corresponds to @ref Shaders::GenericGL::ObjectId. * @see @ref MeshData::objectIdsAsArray() */ ObjectId,