Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/Magnum/DebugTools/ShapeRenderer.h
	src/Magnum/Math/Angle.h
	src/Magnum/Platform/ScreenedApplication.h
	src/Magnum/Primitives/Capsule.cpp
	src/Magnum/Primitives/Circle.cpp
	src/Magnum/Primitives/Crosshair.cpp
	src/Magnum/Primitives/Cube.cpp
	src/Magnum/Primitives/Cylinder.cpp
	src/Magnum/Primitives/Implementation/WireframeSpheroid.cpp
	src/Magnum/Primitives/Line.cpp
	src/Magnum/Primitives/Plane.cpp
	src/Magnum/Primitives/Square.cpp
	src/Magnum/Primitives/UVSphere.cpp
	src/Magnum/ResourceManager.h
	src/Magnum/Text/GlyphCache.cpp
	src/Magnum/Trade/TextureData.h
Vladimír Vondruš 12 years ago
parent
commit
5bc519717f
  1. 12
      CMakeLists.txt
  2. 2311
      Doxyfile
  3. 3
      doc/building.dox
  4. 1
      doc/cmake.dox
  5. 49
      doc/coding-style.dox
  6. 5
      doc/opengl-mapping.dox
  7. 6
      doc/opengl-support.dox
  8. 16
      modules/FindMagnum.cmake
  9. 56
      package/archlinux/PKGBUILD-gcc49
  10. 14
      package/archlinux/PKGBUILD-mingw-w64
  11. 2
      src/Magnum/AbstractFramebuffer.cpp
  12. 17
      src/Magnum/AbstractImage.h
  13. 2
      src/Magnum/AbstractResourceLoader.h
  14. 50
      src/Magnum/AbstractShaderProgram.cpp
  15. 99
      src/Magnum/AbstractShaderProgram.h
  16. 10
      src/Magnum/AbstractTexture.cpp
  17. 1
      src/Magnum/AbstractTexture.h
  18. 10
      src/Magnum/Array.h
  19. 43
      src/Magnum/Audio/AbstractImporter.h
  20. 2
      src/Magnum/Audio/Audio.h
  21. 4
      src/Magnum/Audio/Buffer.h
  22. 8
      src/Magnum/Audio/Context.h
  23. 8
      src/Magnum/Audio/Renderer.h
  24. 8
      src/Magnum/Audio/Source.h
  25. 1
      src/Magnum/Buffer.cpp
  26. 20
      src/Magnum/Buffer.h
  27. 4
      src/Magnum/Color.h
  28. 16
      src/Magnum/ColorFormat.h
  29. 27
      src/Magnum/Context.cpp
  30. 78
      src/Magnum/Context.h
  31. 6
      src/Magnum/CubeMapTexture.h
  32. 6
      src/Magnum/CubeMapTextureArray.h
  33. 6
      src/Magnum/DebugMessage.h
  34. 2
      src/Magnum/DebugTools/DebugTools.h
  35. 5
      src/Magnum/DebugTools/ForceRenderer.h
  36. 5
      src/Magnum/DebugTools/ObjectRenderer.h
  37. 24
      src/Magnum/DebugTools/Profiler.h
  38. 2
      src/Magnum/DebugTools/ResourceManager.h
  39. 10
      src/Magnum/DebugTools/ShapeRenderer.h
  40. 8
      src/Magnum/DefaultFramebuffer.h
  41. 9
      src/Magnum/DimensionTraits.h
  42. 22
      src/Magnum/Extensions.h
  43. 1
      src/Magnum/Framebuffer.cpp
  44. 10
      src/Magnum/Framebuffer.h
  45. 6
      src/Magnum/Implementation/BufferState.cpp
  46. 2
      src/Magnum/Implementation/BufferState.h
  47. 7
      src/Magnum/Implementation/FramebufferState.cpp
  48. 2
      src/Magnum/Implementation/FramebufferState.h
  49. 16
      src/Magnum/Implementation/MeshState.cpp
  50. 6
      src/Magnum/Implementation/MeshState.h
  51. 6
      src/Magnum/Implementation/ShaderProgramState.cpp
  52. 2
      src/Magnum/Implementation/ShaderProgramState.h
  53. 3
      src/Magnum/Implementation/State.h
  54. 6
      src/Magnum/Implementation/TextureState.cpp
  55. 2
      src/Magnum/Implementation/TextureState.h
  56. 1
      src/Magnum/Implementation/setupDriverWorkarounds.cpp
  57. 2
      src/Magnum/Magnum.h
  58. 9
      src/Magnum/Math/Algorithms/GaussJordan.h
  59. 10
      src/Magnum/Math/Algorithms/GramSchmidt.h
  60. 2
      src/Magnum/Math/Algorithms/Svd.h
  61. 20
      src/Magnum/Math/Angle.h
  62. 14
      src/Magnum/Math/BoolVector.h
  63. 64
      src/Magnum/Math/Complex.h
  64. 6
      src/Magnum/Math/Constants.h
  65. 8
      src/Magnum/Math/Dual.h
  66. 49
      src/Magnum/Math/DualComplex.h
  67. 83
      src/Magnum/Math/DualQuaternion.h
  68. 14
      src/Magnum/Math/Functions.h
  69. 53
      src/Magnum/Math/Geometry/Distance.h
  70. 6
      src/Magnum/Math/Geometry/Intersection.h
  71. 2
      src/Magnum/Math/Math.h
  72. 26
      src/Magnum/Math/Matrix.h
  73. 97
      src/Magnum/Math/Matrix3.h
  74. 133
      src/Magnum/Math/Matrix4.h
  75. 101
      src/Magnum/Math/Quaternion.h
  76. 6
      src/Magnum/Math/Range.h
  77. 66
      src/Magnum/Math/RectangularMatrix.h
  78. 2
      src/Magnum/Math/Swizzle.h
  79. 8
      src/Magnum/Math/Test/FunctionsTest.cpp
  80. 8
      src/Magnum/Math/Test/SwizzleTest.cpp
  81. 6
      src/Magnum/Math/TypeTraits.h
  82. 4
      src/Magnum/Math/Unit.h
  83. 135
      src/Magnum/Math/Vector.h
  84. 28
      src/Magnum/Math/Vector2.h
  85. 9
      src/Magnum/Math/Vector3.h
  86. 3
      src/Magnum/Math/Vector4.h
  87. 1
      src/Magnum/Mesh.cpp
  88. 23
      src/Magnum/Mesh.h
  89. 4
      src/Magnum/MeshTools/CombineIndexedArrays.h
  90. 7
      src/Magnum/MeshTools/CompressIndices.h
  91. 15
      src/Magnum/MeshTools/FlipNormals.h
  92. 10
      src/Magnum/MeshTools/GenerateFlatNormals.h
  93. 16
      src/Magnum/MeshTools/Interleave.h
  94. 2
      src/Magnum/MeshTools/Subdivide.h
  95. 2
      src/Magnum/MeshTools/Test/GenerateFlatNormalsTest.cpp
  96. 2
      src/Magnum/MeshTools/Tipsify.h
  97. 20
      src/Magnum/MeshTools/Transform.h
  98. 119
      src/Magnum/MeshView.cpp
  99. 37
      src/Magnum/MeshView.h
  100. 2
      src/Magnum/MultisampleTexture.h
  101. Some files were not shown because too many files have changed in this diff Show More

12
CMakeLists.txt

@ -63,6 +63,10 @@ elseif(CORRADE_TARGET_UNIX AND NOT APPLE)
option(WITH_GLXAPPLICATION "Build GlxApplication library" OFF)
cmake_dependent_option(WITH_WINDOWLESSGLXAPPLICATION "Build WindowlessGlxApplication library" OFF "NOT WITH_MAGNUMINFO;NOT WITH_FONTCONVERTER;NOT WITH_DISTANCEFIELDCONVERTER" ON)
cmake_dependent_option(WITH_XEGLAPPLICATION "Build XEglApplication library" OFF "TARGET_GLES" OFF)
# Windows-specific application libraries
elseif(CORRADE_TARGET_WINDOWS)
cmake_dependent_option(WITH_WINDOWLESSWGLAPPLICATION "Build WindowlessWglApplication library" OFF "NOT WITH_MAGNUMINFO;NOT WITH_FONTCONVERTER;NOT WITH_DISTANCEFIELDCONVERTER" ON)
endif()
# Platform-independent (almost) application libraries
@ -71,13 +75,13 @@ if(NOT CORRADE_TARGET_NACL AND NOT CORRADE_TARGET_ANDROID)
option(WITH_SDL2APPLICATION "Build Sdl2Application library" OFF)
endif()
# Magnum Info (currently only using GLX or NaCl)
if((CORRADE_TARGET_UNIX AND NOT APPLE) OR CORRADE_TARGET_NACL)
# Magnum Info (currently only using GLX or WGL or on NaCl)
if((CORRADE_TARGET_UNIX AND NOT APPLE) OR CORRADE_TARGET_NACL OR CORRADE_TARGET_WINDOWS)
option(WITH_MAGNUMINFO "Build magnum-info utility" OFF)
endif()
# Utilities (currently depending on WindowlessGlxApplication)
if(CORRADE_TARGET_UNIX AND NOT APPLE)
# Utilities (currently only using GLX or WGL)
if((CORRADE_TARGET_UNIX AND NOT APPLE) OR CORRADE_TARGET_WINDOWS)
cmake_dependent_option(WITH_FONTCONVERTER "Build magnum-fontconverter utility" OFF "NOT TARGET_GLES" OFF)
cmake_dependent_option(WITH_DISTANCEFIELDCONVERTER "Build magnum-distancefieldconverter utility" OFF "NOT TARGET_GLES" OFF)
endif()

2311
Doxyfile

File diff suppressed because it is too large Load Diff

3
doc/building.dox

@ -201,9 +201,10 @@ platform best:
- `WITH_XEGLAPPLICATION` - @ref Platform::XEglApplication "XEglApplication"
- `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `WITH_WINDOWLESSNACLAPPLICATION` - @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication"
- `WITH_WINDOWLESSWGLAPPLICATION` - @ref Platform::WindowlessWglApplication "WindowlessWglApplication"
There are also a few command-line utilities. They are currently available only
on Linux and are disabled by default:
on Linux and Windows, also disabled by default:
- `WITH_MAGNUMINFO` - `magnum-info` executable, provides information about
the engine and OpenGL capabilities.

1
doc/cmake.dox

@ -90,6 +90,7 @@ Platform namespace is split into more components:
- `%XEglApplication` -- @ref Platform::XEglApplication "XEglApplication"
- `%WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `%WindowlessNaClApplication` -- @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication"
- `%WindowlessWglApplication` -- @ref Platform::WindowlessWglApplication "WindowlessWglApplication"
The library also contains a set of plugins for importing essential file
formats. Additional plugins are provided in separate plugin repository, see

49
doc/coding-style.dox

@ -39,9 +39,9 @@ needed. You are encouraged to read it first:
- @ref corrade-coding-style
@section cpp C++ code
@section coding-style-cpp C++ code
@subsection cpp-headers Headers
@subsection coding-style-cpp-headers Headers
Headers shouldn't have `using` declarations inside them (unless there is good
excuse, see Magnum.h).
@ -50,9 +50,9 @@ Headers have `*.h` extension, @ref compilation-speedup-hpp "template implementat
have `*.hpp` extension (hinting that they are something between `*.h` and
`*.cpp` files).
@subsection cpp-format Code format
@subsection coding-style-cpp-format Code format
@subsubsection cpp-types Builtin types
@subsubsection coding-style-cpp-types Builtin types
Use %Magnum's own type aliases for public API (e.g. @ref UnsignedInt, see
@ref types for more information), but use specific types when interacting with
@ -61,13 +61,13 @@ conversions when converting between them. This helps avoiding sign, truncation
and other issues, e.g. `%Math::%Vector2<GLsizei>` will implicitly convert to
@ref Vector2i if and only if @ref Int is the same type as `GLsizei`.
@subsubsection cpp-naming Naming
@subsubsection coding-style-cpp-naming Naming
When writing wrappers for OpenGL functions and defines, try to match the
original name as closely as possible, although expanding abbrevations (and
removing redundant prefixes) is encouraged.
@subsubsection cpp-forward-declarations Forward declarations and forward declaration headers
@subsubsection coding-style-cpp-forward-declarations Forward declarations and forward declaration headers
When a namespace has classes which are commonly forward-declared, consider
making a forward declaration header - it should have the same name as the
@ -75,14 +75,14 @@ namespace itself and contain foward declarations for all classes, enums and
copies of all meaningful typedefs. See @ref compilation-forward-declarations
for more information.
@section compatibility Compatibility with various OpenGL editions
@section coding-style-compatibility Compatibility with various OpenGL editions
If any class, function or part of code depends on particular OpenGL edition
(e.g. only for desktop), use conditional compilation to avoid erors on other
platforms (see @ref portability-target for more information). Put related
documentation also into the conditional compilation block and don't forget to
appropriately mark the class/function (@ref documentation-commands-requires "see below").
Example:
appropriately mark the class/function
(@ref coding-style-documentation-commands-requires "see below"). Example:
@code
#ifndef MAGNUM_TARGET_GLES
//
@ -94,14 +94,15 @@ void setPolygonMode(PolygonMode mode);
#endif
@endcode
@section documentation Doxygen documentation
@section coding-style-documentation Doxygen documentation
@subsection documentation-commands Special documentation commands
@subsection coding-style-documentation-commands Special documentation commands
Additionally to @c \@todoc, @c \@debugoperator @c \@configurationvalue and
@c \@configurationvalueref (same as in Corrade), these are defined:
Additionally to @c \@todoc, @c \@debugoperator, @c \@debugoperatorenum,
@c \@debugoperatorclassenum, @c \@configurationvalue and
@c \@configurationvalueref (same as in %Corrade), these are defined:
@subsubsection documentation-commands-collisionoperator Shape collision operators
@subsubsection coding-style-documentation-commands-collisionoperator Shape collision operators
Out-of-class operators for collision and collision occurence in Shapes
namespace should be marked with @c \@collisionoperator and @c \@collisionoccurenceoperator,
@ -118,7 +119,7 @@ the operator is implemented (not of class in which the operator is
implemented), thus efficiently connecting the two classes together in the
documentation.
@subsubsection documentation-commands-extension Links to OpenGL extensions
@subsubsection coding-style-documentation-commands-extension Links to OpenGL extensions
If an OpenGL extension is referenced in the documentation, it should be done
with @c \@extension command:
@ -137,7 +138,7 @@ specify extension filename, if the previous command gives 404 error. For example
produces this link:
> @es_extension2{NV,read_buffer_front,GL_NV_read_buffer}
@subsubsection documentation-commands-ref_gl Links to related OpenGL functions and definitions
@subsubsection coding-style-documentation-commands-ref_gl Links to related OpenGL functions and definitions
If an function touches OpenGL, related OpenGL functions should be documented
in @c \@see block with @c \@fn_gl command. If only specific definition is used
@ -161,7 +162,7 @@ are the same as in @c \@extension command. It produced link to extension
specification, with function name as link text:
> @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access}.
@subsubsection documentation-commands-requires Classes and functions requiring specific OpenGL version or extensions
@subsubsection coding-style-documentation-commands-requires Classes and functions requiring specific OpenGL version or extensions
If any class or function requires specific OpenGL version above 2.1, it should
be marked with appropriate command @c \@requires_glXX, where `XX` is version
@ -190,7 +191,19 @@ requirements.
All classes and functions using those commands are cross-referenced in page
@ref opengl-required-extensions.
@section unit-tests Unit tests
@subsection coding-style-documentation-ordering Section ordering
In detailed documentation the text should be always first, the blocks are then
ordered by their importance. Various @c \@note, @c \@attention and @c \@warning
blocks to highlight some information are always first, then @c \@see block with
links to related stuff, where related %Magnum functions are first and links to
related GL API last, then various support information such as
@c \@requires_glXX, @c \@requires_es_extension etc. (first desktop GL, then ES,
then WebGL), after that @c \@deprecated_gl and @c \@deprecated information and
@c \@todo, @c \@todoc and @c \@bug always last, as they are the least important
and in most cases only for internal use.
@section coding-style-unit-tests Unit tests
All unit tests use Corrade's @ref Corrade::TestSuite "TestSuite".

5
doc/opengl-mapping.dox

@ -196,8 +196,7 @@ OpenGL function | Matching API
@fn_gl_extension{MapBufferSubData,CHROMIUM,map_sub}, @fn_gl_extension{UnmapBufferSubData,CHROMIUM,map_sub} | @ref Buffer::mapSub(), @ref Buffer::unmapSub()
@fn_gl{MemoryBarrier} | |
@fn_gl{MinSampleShading} | |
@fn_gl{MultiDrawArrays}, \n @fn_gl{MultiDrawElements} | |
@fn_gl{MultiDrawElementsBaseVertex} | |
@fn_gl{MultiDrawArrays}, \n @fn_gl{MultiDrawElements}, \n @fn_gl{MultiDrawElementsBaseVertex} | @ref MeshView::draw(AbstractShaderProgram&, std::initializer_list<std::reference_wrapper<MeshView>>)
@fn_gl{ObjectLabel}, \n @fn_gl{ObjectPtrLabel}, \n @fn_gl_extension2{LabelObject,EXT,debug_label} | @ref AbstractShaderProgram::setLabel(), \n @ref AbstractQuery::setLabel(), \n @ref AbstractTexture::setLabel(), \n @ref Buffer::setLabel(), \n @ref Framebuffer::setLabel(), \n @ref Mesh::setLabel(), \n @ref Renderbuffer::setLabel(), \n @ref Shader::setLabel()
@fn_gl{PatchParameter} | |
@fn_gl{PauseTransformFeedback}, @fn_gl{ResumeTransformFeedback} | |
@ -232,7 +231,7 @@ OpenGL function | Matching API
@fn_gl{TexBuffer}, \n @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, \n @fn_gl{TexBufferRange}, \n @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} | @ref BufferTexture::setBuffer()
@fn_gl{TexImage1D}, \n @fn_gl_extension{TextureImage1D,EXT,direct_state_access} \n @fn_gl{TexImage2D}, \n @fn_gl_extension{TextureImage2D,EXT,direct_state_access}, \n @fn_gl{TexImage3D}, \n @fn_gl_extension{TextureImage3D,EXT,direct_state_access} | @ref Texture::setImage(), \n @ref TextureArray::setImage(), \n @ref CubeMapTexture::setImage(), \n @ref CubeMapTextureArray::setImage(), \n @ref RectangleTexture::setImage()
@fn_gl{TexImage2DMultisample}, \n @fn_gl{TexImage3DMultisample} | @ref MultisampleTexture::setStorage()
@fn_gl{TexParameter}, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref Texture::setBaseLevel() "*Texture::setBaseLevel()", \n @ref Texture::setMaxLevel() "*Texture::setMaxLevel()", \n @ref Texture::setMinificationFilter() "*Texture::setMinificationFilter()", \n @ref Texture::setMagnificationFilter() "*Texture::setMagnificationFilter()", \n @ref Texture::setMinLod() "*Texture::setMinLod()", \n @ref Texture::setMaxLod() "*Texture::setMaxLod()", \n @ref Texture::setLodBias() "*Texture::setLodBias()", \n @ref Texture::setWrapping() "*Texture::setWrapping()", \n @ref Texture::setBorderColor() "*Texture::setBorderColor()", \n @ref Texture::setMaxAnisotropy() "*Texture::setMaxAnisotropy()", \n @ref Texture::setSwizzle() "*Texture::setSwizzle()", \n @ref Texture::setCompareMode() "*Texture::setCompareMode()", \n @ref Texture::setCompareFunction() "*Texture::setCompareFunction()", \n @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()"
@fn_gl{TexParameter}, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref Texture::setBaseLevel() "*Texture::setBaseLevel()", \n @ref Texture::setMaxLevel() "*Texture::setMaxLevel()", \n @ref Texture::setMinificationFilter() "*Texture::setMinificationFilter()", \n @ref Texture::setMagnificationFilter() "*Texture::setMagnificationFilter()", \n @ref Texture::setMinLod() "*Texture::setMinLod()", \n @ref Texture::setMaxLod() "*Texture::setMaxLod()", \n @ref Texture::setLodBias() "*Texture::setLodBias()", \n @ref Texture::setWrapping() "*Texture::setWrapping()", \n @ref Texture::setBorderColor() "*Texture::setBorderColor()", \n @ref Texture::setMaxAnisotropy() "*Texture::setMaxAnisotropy()", \n @ref Texture::setSRGBDecode() "*Texture::setSRGBDecode()", \n @ref Texture::setSwizzle() "*Texture::setSwizzle()", \n @ref Texture::setCompareMode() "*Texture::setCompareMode()", \n @ref Texture::setCompareFunction() "*Texture::setCompareFunction()", \n @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()"
@fn_gl{TexStorage1D}, \n @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}, \n @fn_gl{TexStorage2D}, \n @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}, \n @fn_gl{TexStorage3D}, \n @fn_gl_extension{TextureStorage3D,EXT,direct_state_access} | @ref Texture::setStorage(), \n @ref TextureArray::setStorage(), \n @ref CubeMapTexture::setStorage(), \n @ref CubeMapTextureArray::setStorage(), \n @ref RectangleTexture::setStorage()
@fn_gl{TexStorage2DMultisample}, \n @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access}, \n @fn_gl{TexStorage3DMultisample}, \n @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access} | @ref MultisampleTexture::setStorage()
@fn_gl{TexSubImage1D}, \n @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{TexSubImage2D}, \n @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{TexSubImage3D}, \n @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} | @ref Texture::setSubImage(), \n @ref TextureArray::setSubImage(), \n @ref CubeMapTexture::setSubImage(), \n @ref CubeMapTextureArray::setSubImage(), \n @ref RectangleTexture::setSubImage()

6
doc/opengl-support.dox

@ -95,7 +95,7 @@ following:
-------------------------------------------- | ------
@extension{ARB,geometry_shader4} | missing layered attachments
@extension{ARB,depth_clamp} | done
@extension{ARB,draw_elements_base_vertex} | missing `Multi*` command
@extension{ARB,draw_elements_base_vertex} | done
@extension{ARB,fragment_coord_conventions} | done (shading language only)
@extension{ARB,provoking_vertex} | done
@extension{ARB,seamless_cube_map} | done
@ -205,7 +205,7 @@ following:
@extension{ARB,query_buffer_object} | |
@extension{ARB,texture_mirror_clamp_to_edge} | done
@extension{ARB,texture_stencil8} | done
@extension{ARB,vertex_type_10f_11f_11f_rev} | |
@extension{ARB,vertex_type_10f_11f_11f_rev} | done
@subsection opengl-support-extensions OpenGL extensions
@ -222,6 +222,7 @@ following:
@extension{EXT,texture_filter_anisotropic} (also in ES) | done
@extension{EXT,texture_mirror_clamp} | only GL 4.4 subset
@extension{EXT,direct_state_access} | done for implemented functionality
@extension{EXT,texture_sRGB_decode} (also in ES) | done
@extension{EXT,shader_integer_mix} (also in ES) | done (shading language only)
@extension2{EXT,debug_label} (also in ES) | missing pipeline, transform feedback and sampler label
@extension2{EXT,debug_marker} (also in ES) | missing marker groups
@ -298,6 +299,7 @@ Only extensions not already listed in above tables are included here.
@es_extension{CHROMIUM,map_sub} | only buffer mapping
@es_extension{EXT,texture_format_BGRA8888} | done
@es_extension{EXT,read_format_bgra} | done
@es_extension2{EXT,multi_draw_arrays,multi_draw_arrays} | done
@es_extension{EXT,disjoint_timer_query} | only time elapsed query
@es_extension{EXT,separate_shader_objects} | only direct uniform binding
@es_extension{EXT,sRGB} | done

16
modules/FindMagnum.cmake

@ -49,6 +49,7 @@
# XEglApplication - X/EGL application
# WindowlessGlxApplication - Windowless GLX application
# WindowlessNaClApplication - Windowless NaCl application
# WindowlessWglApplication - Windowless WGL application
# Example usage with specifying additional components is:
# find_package(Magnum [REQUIRED|COMPONENTS]
# MeshTools Primitives GlutApplication)
@ -329,7 +330,7 @@ foreach(component ${Magnum_FIND_COMPONENTS})
if(${component} STREQUAL AndroidApplication)
find_package(EGL)
if(EGL_FOUND)
set(_MAGNUM_${_COMPONENT}_LIBRARIES android ${EGL_LIBRARY} ${_WINDOWCONTEXT_MAGNUM_LIBRARIES_DEPENDENCY})
set(_MAGNUM_${_COMPONENT}_LIBRARIES android ${EGL_LIBRARY})
set(_MAGNUM_${_COMPONENT}_INCLUDE_DIRS ${ANDROID_NATIVE_APP_GLUE_INCLUDE_DIR})
else()
unset(MAGNUM_${_COMPONENT}_LIBRARY)
@ -340,7 +341,7 @@ foreach(component ${Magnum_FIND_COMPONENTS})
if(${component} STREQUAL GlutApplication)
find_package(GLUT)
if(GLUT_FOUND)
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${GLUT_glut_LIBRARY} ${_WINDOWCONTEXT_MAGNUM_LIBRARIES_DEPENDENCY})
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${GLUT_glut_LIBRARY})
else()
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
@ -350,7 +351,7 @@ foreach(component ${Magnum_FIND_COMPONENTS})
if(${component} STREQUAL Sdl2Application)
find_package(SDL2)
if(SDL2_FOUND)
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${SDL2_LIBRARY} ${_WINDOWCONTEXT_MAGNUM_LIBRARIES_DEPENDENCY})
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${SDL2_LIBRARY})
set(_MAGNUM_${_COMPONENT}_INCLUDE_DIRS ${SDL2_INCLUDE_DIR})
else()
unset(MAGNUM_${_COMPONENT}_LIBRARY)
@ -359,14 +360,14 @@ foreach(component ${Magnum_FIND_COMPONENTS})
# (Windowless) NaCl application dependencies
if(${component} STREQUAL NaClApplication OR ${component} STREQUAL WindowlessNaClApplication)
set(_MAGNUM_${_COMPONENT}_LIBRARIES ppapi_cpp ppapi ${_WINDOWCONTEXT_MAGNUM_LIBRARIES_DEPENDENCY})
set(_MAGNUM_${_COMPONENT}_LIBRARIES ppapi_cpp ppapi)
endif()
# GLX application dependencies
if(${component} STREQUAL GlxApplication OR ${component} STREQUAL WindowlessGlxApplication)
find_package(X11)
if(X11_FOUND)
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${X11_LIBRARIES} ${_WINDOWCONTEXT_MAGNUM_LIBRARIES_DEPENDENCY})
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${X11_LIBRARIES})
else()
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
@ -377,12 +378,15 @@ foreach(component ${Magnum_FIND_COMPONENTS})
find_package(EGL)
find_package(X11)
if(EGL_FOUND AND X11_FOUND)
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${EGL_LIBRARY} ${X11_LIBRARIES} ${_WINDOWCONTEXT_MAGNUM_LIBRARIES_DEPENDENCY})
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${EGL_LIBRARY} ${X11_LIBRARIES})
else()
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
endif()
# Common application dependencies
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${_MAGNUM_${_COMPONENT}_LIBRARIES} ${_WINDOWCONTEXT_MAGNUM_LIBRARIES_DEPENDENCY})
# Audio library
elseif(${component} STREQUAL Audio)
find_package(OpenAL)

56
package/archlinux/PKGBUILD-gcc49

@ -1,56 +0,0 @@
# Author: mosra <mosra@centrum.cz>
pkgname=magnum
pkgver=dev.gcc49
pkgrel=1
pkgdesc="C++11 and OpenGL 2D/3D graphics engine (built with GCC 4.9)"
arch=('i686' 'x86_64')
url="http://mosra.cz/blog/magnum.php"
license=('MIT')
depends=('corrade' 'openal' 'freeglut' 'sdl2')
makedepends=('cmake' 'ninja' 'gcc-git')
options=('!strip' 'staticlibs')
provides=('magnum-git')
build() {
if [ ! -d "$startdir/build-gcc49" ] ; then
mkdir "$startdir/build-gcc49"
cd "$startdir/build-gcc49"
cmake .. \
-DCMAKE_CXX_COMPILER=g++-4.9 \
-G Ninja
fi
cd "$startdir/build-gcc49"
cmake .. \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_INSTALL_PREFIX=/usr \
-DWITH_AUDIO=ON \
-DWITH_GLUTAPPLICATION=ON \
-DWITH_GLXAPPLICATION=ON \
-DWITH_SDL2APPLICATION=ON \
-DWITH_WINDOWLESSGLXAPPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_OBJIMPORTER=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-DWITH_DISTANCEFIELDCONVERTER=ON \
-DWITH_FONTCONVERTER=ON \
-DWITH_MAGNUMINFO=ON \
-DBUILD_TESTS=ON \
-DBUILD_GL_TESTS=ON
ninja
}
check() {
cd "$startdir/build-gcc49"
ctest --output-on-failure -j5
}
package() {
cd "$startdir/build-gcc49"
DESTDIR="$pkgdir/" ninja install
}

14
package/archlinux/PKGBUILD-mingw-w64

@ -20,13 +20,18 @@ build() {
-DCMAKE_INSTALL_PREFIX=/usr/i686-w64-mingw32 \
-DWITH_AUDIO=ON \
-DWITH_GLUTAPPLICATION=ON \
-DWITH_SDL2APPLICATION=ON \
-DWITH_WINDOWLESSWGLAPPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_OBJIMPORTER=ON \
-DWITH_SDL2APPLICATION=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-DWITH_DISTANCEFIELDCONVERTER=ON \
-DWITH_FONTCONVERTER=ON \
-DWITH_MAGNUMINFO=ON \
-DBUILD_TESTS=ON \
-G Ninja
ninja
@ -39,13 +44,18 @@ build() {
-DCMAKE_INSTALL_PREFIX=/usr/x86_64-w64-mingw32 \
-DWITH_AUDIO=ON \
-DWITH_GLUTAPPLICATION=ON \
-DWITH_SDL2APPLICATION=ON \
-DWITH_WINDOWLESSWGLAPPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_OBJIMPORTER=ON \
-DWITH_SDL2APPLICATION=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-DWITH_DISTANCEFIELDCONVERTER=ON \
-DWITH_FONTCONVERTER=ON \
-DWITH_MAGNUMINFO=ON \
-DBUILD_TESTS=ON \
-G Ninja
ninja
}

2
src/Magnum/AbstractFramebuffer.cpp

@ -158,6 +158,8 @@ AbstractFramebuffer& AbstractFramebuffer::setViewport(const Range2Di& rectangle)
void AbstractFramebuffer::setViewportInternal() {
Implementation::FramebufferState* state = Context::current()->state().framebuffer;
/* We are using empty viewport to indicate disengaged state */
CORRADE_INTERNAL_ASSERT(_viewport != Range2Di{});
CORRADE_INTERNAL_ASSERT(state->drawBinding == _id);
/* Already up-to-date, nothing to do */

17
src/Magnum/AbstractImage.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::AbstractImage
* @brief Class @ref Magnum::AbstractImage
*/
#include <cstddef>
@ -43,12 +43,12 @@ namespace Magnum {
/**
@brief Non-templated base for one-, two- or three-dimensional images
See Image, ImageReference, BufferImage, Trade::ImageData documentation for
more information.
See @ref Image, @ref ImageReference, @ref BufferImage, @ref Trade::ImageData
documentation for more information.
@todo Where to put glClampColor() and glPixelStore() encapsulation? It is
needed in AbstractFramebuffer::read(), Texture::setImage() etc (i.e. all
functions operating with images). It also possibly needs to be "stackable" to
easily revert the state back.
needed in AbstractFramebuffer::read(), Texture::setImage() etc (i.e. all
functions operating with images). It also possibly needs to be "stackable"
to easily revert the state back.
*/
class MAGNUM_EXPORT AbstractImage {
public:
@ -57,7 +57,7 @@ class MAGNUM_EXPORT AbstractImage {
* @param format Format of the pixel
* @param type Data type of the pixel
*
* @see pixelSize() const
* @see @ref pixelSize()
*/
static std::size_t pixelSize(ColorFormat format, ColorType type);
@ -70,7 +70,8 @@ class MAGNUM_EXPORT AbstractImage {
/**
* @brief Pixel size (in bytes)
*
* Convenience member alternative for pixelSize(Format, Type).
* Convenience member alternative for
* @ref pixelSize(ColorFormat, ColorType).
*/
std::size_t pixelSize() const { return pixelSize(_format, _type); }

2
src/Magnum/AbstractResourceLoader.h

@ -60,7 +60,7 @@ In your @ref doLoad() implementation, after your resources are loaded, call
@ref set() to pass them to @ref ResourceManager or call @ref setNotFound() to
indicate that the resource was not found.
You can also implement @ref name() to provide meaningful names for resource
You can also implement @ref doName() to provide meaningful names for resource
keys.
Example implementation for synchronous mesh loader:

50
src/Magnum/AbstractShaderProgram.cpp

@ -198,7 +198,9 @@ Int AbstractShaderProgram::maxTexelOffset() {
}
#endif
AbstractShaderProgram::AbstractShaderProgram(): _id(glCreateProgram()) {}
AbstractShaderProgram::AbstractShaderProgram(): _id(glCreateProgram()) {
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
AbstractShaderProgram::AbstractShaderProgram(AbstractShaderProgram&& other) noexcept: _id(other._id) {
other._id = 0;
@ -1229,6 +1231,31 @@ UnsignedInt DoubleAttribute::size(GLint components, DataType dataType) {
}
#endif
UnsignedInt Attribute<Math::Vector<3, Float>>::size(GLint components, DataType dataType) {
switch(dataType) {
case DataType::UnsignedByte:
case DataType::Byte:
return components;
case DataType::UnsignedShort:
case DataType::Short:
case DataType::HalfFloat:
return 2*components;
case DataType::UnsignedInt:
case DataType::Int:
case DataType::Float:
return 4*components;
#ifndef MAGNUM_TARGET_GLES
case DataType::Double:
return 8*components;
case DataType::UnsignedInt10f11f11fRev:
CORRADE_INTERNAL_ASSERT(components == 3);
return 4;
#endif
}
CORRADE_ASSERT_UNREACHABLE();
}
UnsignedInt Attribute<Math::Vector<4, Float>>::size(GLint components, DataType dataType) {
#ifndef MAGNUM_TARGET_GLES
if(components == GL_BGRA) components = 4;
@ -1405,6 +1432,27 @@ Debug operator<<(Debug debug, DoubleAttribute::DataType value) {
}
#endif
Debug operator<<(Debug debug, Attribute<Math::Vector<3, Float>>::DataType value) {
switch(value) {
#define _c(value) case Attribute<Math::Vector<3, Float>>::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value;
_c(UnsignedByte)
_c(Byte)
_c(UnsignedShort)
_c(Short)
_c(UnsignedInt)
_c(Int)
_c(HalfFloat)
_c(Float)
#ifndef MAGNUM_TARGET_GLES
_c(Double)
_c(UnsignedInt10f11f11fRev)
#endif
#undef _c
}
return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)";
}
Debug operator<<(Debug debug, Attribute<Math::Vector<4, Float>>::DataType value) {
switch(value) {
#define _c(value) case Attribute<Math::Vector<4, Float>>::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value;

99
src/Magnum/AbstractShaderProgram.h

@ -350,8 +350,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_atomic_counters} is
* not available, returns `0`.
* @requires_gl Atomic counters are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_ATOMIC_COUNTER_BUFFER_SIZE}
* @requires_gl Atomic counters are not available in OpenGL ES.
*/
static Int maxAtomicCounterBufferSize();
@ -361,8 +361,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,compute_shader} is not
* available, returns `0`.
* @requires_gl Compute shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_COMPUTE_SHARED_MEMORY_SIZE}
* @requires_gl Compute shaders are not available in OpenGL ES.
*/
static Int maxComputeSharedMemorySize();
@ -372,8 +372,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,compute_shader} is not
* available, returns `0`.
* @requires_gl Compute shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_COMPUTE_WORK_GROUP_INVOCATIONS}
* @requires_gl Compute shaders are not available in OpenGL ES.
*/
static Int maxComputeWorkGroupInvocations();
@ -385,8 +385,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_image_load_store}
* is not available, returns `0`.
* @requires_gl Image load/store is not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_IMAGE_UNITS}
* @requires_gl %Image load/store is not available in OpenGL ES.
*/
static Int maxImageUnits();
@ -396,8 +396,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_image_load_store}
* is not available, returns `0`.
* @requires_gl Image load/store is not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_IMAGE_SAMPLES}
* @requires_gl %Image load/store is not available in OpenGL ES.
*/
static Int maxImageSamples();
@ -408,8 +408,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* OpenGL calls. If neither @extension{ARB,shader_image_load_store}
* nor @extension{ARB,shader_storage_buffer_object} extension is
* available, returns `0`.
* @requires_gl Image load/store is not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_COMBINED_SHADER_OUTPUT_RESOURCES}
* @requires_gl %Image load/store is not available in OpenGL ES.
*/
static Int maxCombinedShaderOutputResources();
@ -419,8 +419,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_storage_buffer_object}
* is not available, returns `0`.
* @requires_gl Shader storage is not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_SHADER_STORAGE_BLOCK_SIZE}
* @requires_gl %Shader storage is not available in OpenGL ES.
*/
static Long maxShaderStorageBlockSize();
#endif
@ -432,8 +432,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,uniform_buffer_object}
* is not available, returns `0`.
* @requires_gles30 Uniform blocks are not available in OpenGL ES 2.0.
* @see @fn_gl{Get} with @def_gl{MAX_UNIFORM_BLOCK_SIZE}
* @requires_gles30 Uniform blocks are not available in OpenGL ES 2.0.
*/
static Int maxUniformBlockSize();
#endif
@ -445,8 +445,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,explicit_uniform_location}
* is not available, returns `0`.
* @requires_gl Explicit uniform location is not supported in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_UNIFORM_LOCATIONS}
* @requires_gl Explicit uniform location is not supported in OpenGL ES.
*/
static Int maxUniformLocations();
#endif
@ -458,9 +458,9 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{EXT,gpu_shader4} is not
* available, returns `0`.
* @requires_gles30 Texture lookup with offset is not available in
* OpenGL ES 2.0.
* @see @fn_gl{Get} with @def_gl{MIN_PROGRAM_TEXEL_OFFSET}
* @requires_gles30 %Texture lookup with offset is not available in
* OpenGL ES 2.0.
*/
static Int minTexelOffset();
@ -470,9 +470,9 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{EXT,gpu_shader4} is not
* available, returns `0`.
* @requires_gles30 Texture lookup with offset is not available in
* OpenGL ES 2.0.
* @see @fn_gl{Get} with @def_gl{MAX_PROGRAM_TEXEL_OFFSET}
* @requires_gles30 %Texture lookup with offset is not available in
* OpenGL ES 2.0.
*/
static Int maxTexelOffset();
#endif
@ -609,15 +609,15 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
/**
* @brief Bind attribute to given location
* @param location Location
* @param name Attribute name
* @param name %Attribute name
*
* Binds attribute to location which is used later for binding vertex
* buffers.
* @see @fn_gl{BindAttribLocation}
* @deprecated_gl Preferred usage is to specify attribute location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgram-attribute-location "class documentation"
* for more information.
* @see @fn_gl{BindAttribLocation}
*/
void bindAttributeLocation(UnsignedInt location, const std::string& name);
@ -631,11 +631,11 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* Binds fragment data to location which is used later for framebuffer
* operations. See also @ref Renderer::BlendFunction for more
* information about using color input index.
* @see @fn_gl{BindFragDataLocationIndexed}
* @deprecated_gl Preferred usage is to specify attribute location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgram-attribute-location "class documentation"
* for more information.
* @see @fn_gl{BindFragDataLocationIndexed}
* @requires_gl33 %Extension @extension{ARB,blend_func_extended}
* @requires_gl Multiple blend function inputs are not available in
* OpenGL ES.
@ -675,11 +675,11 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* @brief Get uniform location
* @param name Uniform name
*
* @see @fn_gl{GetUniformLocation}
* @deprecated_gl Preferred usage is to specify uniform location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgram-uniform-location "class documentation"
* for more information.
* @see @fn_gl{GetUniformLocation}
*/
Int uniformLocation(const std::string& name);
@ -1066,6 +1066,15 @@ template<UnsignedInt location, class T> class AbstractShaderProgram::Attribute {
* @requires_gl Only floats are available in OpenGL ES.
*/
Double = GL_DOUBLE,
/**
* Unsigned 10.11.11 packed float. Only for three-component float
* vector attribute type.
* @requires_gl44 %Extension @extension{ARB,vertex_type_10f_11f_11f_rev}
* @requires_gl Packed float attributes are not available in OpenGL
* ES.
*/
UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV,
#endif
/* GL_FIXED not supported */
@ -1166,10 +1175,10 @@ template<UnsignedInt location, class T> class AbstractShaderProgram::Attribute {
};
#ifdef DOXYGEN_GENERATING_OUTPUT
/** @debugoperator{Magnum::AbstractShaderProgram::Attribute} */
/** @debugoperatorclassenum{Magnum::AbstractShaderProgram::Attribute,Magnum::AbstractShaderProgram::Attribute::Components} */
template<class T> Debug operator<<(Debug debug, AbstractShaderProgram::Attribute<T>::Components);
/** @debugoperator{Magnum::AbstractShaderProgram::Attribute} */
/** @debugoperatorclassenum{Magnum::AbstractShaderProgram::Attribute,Magnum::AbstractShaderProgram::Attribute::DataType} */
template<class T> Debug operator<<(Debug debug, AbstractShaderProgram::Attribute<T>::DataType);
#endif
@ -1338,6 +1347,8 @@ struct IntAttribute {
static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType);
};
CORRADE_ENUMSET_OPERATORS(IntAttribute::DataOptions)
Debug MAGNUM_EXPORT operator<<(Debug debug, IntAttribute::DataType value);
/* Base for unsigned int attributes */
@ -1353,7 +1364,7 @@ struct UnsignedIntAttribute {
DataType DefaultDataType = DataType::UnsignedInt;
typedef IntAttribute::DataOption DataOption;
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
typedef IntAttribute::DataOptions DataOptions;
static UnsignedInt size(GLint components, DataType dataType) {
return IntAttribute::size(components, dataType);
@ -1376,8 +1387,8 @@ struct DoubleAttribute {
#endif
DataType DefaultDataType = DataType::Double;
enum class DataOption: UnsignedByte {};
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
typedef IntAttribute::DataOption DataOption;
typedef IntAttribute::DataOptions DataOptions;
static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType);
};
@ -1385,6 +1396,41 @@ struct DoubleAttribute {
Debug MAGNUM_EXPORT operator<<(Debug debug, DoubleAttribute::DataType value);
#endif
/* Floating-point three-component vector has additional data type compared to
classic floats */
template<> struct Attribute<Math::Vector<3, Float>>: SizedAttribute<1, 3> {
typedef Float ScalarType;
enum class DataType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE,
Byte = GL_BYTE,
UnsignedShort = GL_UNSIGNED_SHORT,
Short = GL_SHORT,
UnsignedInt = GL_UNSIGNED_INT,
Int = GL_INT,
#ifndef MAGNUM_TARGET_GLES2
HalfFloat = GL_HALF_FLOAT,
#else
HalfFloat = GL_HALF_FLOAT_OES,
#endif
Float = GL_FLOAT
#ifndef MAGNUM_TARGET_GLES
,
Double = GL_DOUBLE,
UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV
#endif
};
constexpr static DataType DefaultDataType = DataType::Float;
typedef FloatAttribute::DataOption DataOption;
typedef FloatAttribute::DataOptions DataOptions;
static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType);
};
Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute<Math::Vector<3, Float>>::DataType value);
/* Floating-point four-component vector is absolutely special case */
template<> struct Attribute<Math::Vector<4, Float>> {
typedef Float ScalarType;
@ -1436,19 +1482,14 @@ template<> struct Attribute<Math::Vector<4, Float>> {
#endif
DataType DefaultDataType = DataType::Float;
enum class DataOption: UnsignedByte {
Normalized = 1 << 0
};
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
typedef FloatAttribute::DataOption DataOption;
typedef FloatAttribute::DataOptions DataOptions;
enum: UnsignedInt { VectorCount = 1 };
static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType);
};
typedef Math::Vector<4, Float> _Vector4;
CORRADE_ENUMSET_OPERATORS(Attribute<_Vector4>::DataOptions)
Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute<Math::Vector<4, Float>>::Components value);
Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute<Math::Vector<4, Float>>::DataType value);

10
src/Magnum/AbstractTexture.cpp

@ -171,6 +171,7 @@ void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, std:
AbstractTexture::AbstractTexture(GLenum target): _target(target) {
glGenTextures(1, &_id);
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
AbstractTexture::~AbstractTexture() {
@ -287,6 +288,11 @@ void AbstractTexture::setMaxAnisotropy(const Float anisotropy) {
(this->*Context::current()->state().texture->setMaxAnisotropyImplementation)(anisotropy);
}
void AbstractTexture::setSRGBDecode(bool decode) {
(this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_SRGB_DECODE_EXT,
decode ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT);
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::setSwizzleInternal(const GLint r, const GLint g, const GLint b, const GLint a) {
#ifndef MAGNUM_TARGET_GLES
@ -386,7 +392,7 @@ ColorFormat AbstractTexture::imageFormatForInternalFormat(const TextureFormat in
#endif
#ifndef MAGNUM_TARGET_GLES
case TextureFormat::CompressedRed:
case TextureFormat::CompressedRedRtgc1:
case TextureFormat::CompressedRedRgtc1:
case TextureFormat::CompressedSignedRedRgtc1:
#endif
return ColorFormat::Red;
@ -589,7 +595,7 @@ ColorType AbstractTexture::imageTypeForInternalFormat(const TextureFormat intern
case TextureFormat::CompressedRG:
case TextureFormat::CompressedRGB:
case TextureFormat::CompressedRGBA:
case TextureFormat::CompressedRedRtgc1:
case TextureFormat::CompressedRedRgtc1:
case TextureFormat::CompressedRGRgtc2:
case TextureFormat::CompressedRGBABptcUnorm:
case TextureFormat::CompressedSRGBAlphaBptcUnorm:

1
src/Magnum/AbstractTexture.h

@ -315,6 +315,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void setBorderColor(const Vector4ui& color);
#endif
void setMaxAnisotropy(Float anisotropy);
void setSRGBDecode(bool decode);
#ifndef MAGNUM_TARGET_GLES2
template<char r, char g, char b, char a> void setSwizzle() {

10
src/Magnum/Array.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Array, Magnum::Array1D, Magnum::Array2D, Magnum::Array3D
* @brief Class @ref Magnum::Array, @ref Magnum::Array1D, @ref Magnum::Array2D, @ref Magnum::Array3D
*/
#include <type_traits>
@ -45,10 +45,10 @@ namespace Magnum {
@tparam dimensions Dimension count
@tparam T Data type
Similar to Math::Vector, but more suitable for storing enum values which don't
need any math operations and fuzzy comparison (e.g. enum values). Unlike
Math::Vector this class has non-explicit constructor from one value.
@see Array1D, Array2D, Array3D
Similar to @ref Math::Vector, but more suitable for storing enum values which
don't need any math operations and fuzzy comparison (e.g. enum values). Unlike
@ref Math::Vector this class has implicit constructor from one value.
@see @ref Array1D, @ref Array2D, @ref Array3D
*/
template<UnsignedInt dimensions, class T> class Array {
public:

43
src/Magnum/Audio/AbstractImporter.h

@ -25,8 +25,8 @@
DEALINGS IN THE SOFTWARE.
*/
/** @file Audio/AbstractImporter.h
* @brief Class Magnum::Audio::AbstractImporter
/** @file
* @brief Class @ref Magnum::Audio::AbstractImporter
*/
#include <Corrade/PluginManager/AbstractPlugin.h>
@ -45,16 +45,17 @@ importer plugins.
@section Audio-AbstractImporter-subclassing Subclassing
Plugin implements function doFeatures(), doIsOpened(), one of or both
doOpenData() and doOpenFile() functions, function doClose() and data access
functions doFormat(), doFrequency() and doData().
Plugin implements function @ref doFeatures(), @ref doIsOpened(), one of or both
@ref doOpenData() and @ref doOpenFile() functions, function @ref doClose() and
data access functions @ref doFormat(), @ref doFrequency() and @ref doData().
You don't need to do most of the redundant sanity checks, these things are
checked by the implementation:
- Functions doOpenData() and doOpenFile() are called after the previous file
was closed, function doClose() is called only if there is any file opened.
- Function doOpenData() is called only if @ref Feature::OpenData is
- Functions @ref doOpenData() and @ref doOpenFile() are called after the
previous file was closed, function @ref doClose() is called only if there
is any file opened.
- Function @ref doOpenData() is called only if @ref Feature::OpenData is
supported.
- All `do*()` implementations working on opened file are called only if
there is any file opened.
@ -66,17 +67,17 @@ class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin
/**
* @brief Features supported by this importer
*
* @see Features, features()
* @see @ref Features, @ref features()
*/
enum class Feature: UnsignedByte {
/** Opening files from raw data using openData() */
/** Opening files from raw data using @ref openData() */
OpenData = 1 << 0
};
/**
* @brief Features supported by this importer
*
* @see features()
* @see @ref features()
*/
typedef Containers::EnumSet<Feature, UnsignedByte> Features;
@ -98,7 +99,7 @@ class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin
* Closes previous file, if it was opened, and tries to open given
* file. Available only if @ref Feature::OpenData is supported. Returns
* `true` on success, `false` otherwise.
* @see features(), openFile()
* @see @ref features(), @ref openFile()
*/
bool openData(Containers::ArrayReference<const unsigned char> data);
@ -107,7 +108,7 @@ class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin
*
* Closes previous file, if it was opened, and tries to open given
* file. Returns `true` on success, `false` otherwise.
* @see features(), openData()
* @see @ref features(), @ref openData()
*/
bool openFile(const std::string& filename);
@ -132,33 +133,33 @@ class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin
#else
protected:
#endif
/** @brief Implementation for features() */
/** @brief Implementation for @ref features() */
virtual Features doFeatures() const = 0;
/** @brief Implementation for isOpened() */
/** @brief Implementation for @ref isOpened() */
virtual bool doIsOpened() const = 0;
/** @brief Implementation for openData() */
/** @brief Implementation for @ref openData() */
virtual void doOpenData(Containers::ArrayReference<const unsigned char> data);
/**
* @brief Implementation for openFile()
* @brief Implementation for @ref openFile()
*
* If @ref Feature::OpenData is supported, default implementation opens
* the file and calls @ref doOpenData() with its contents.
*/
virtual void doOpenFile(const std::string& filename);
/** @brief Implementation for close() */
/** @brief Implementation for @ref close() */
virtual void doClose() = 0;
/** @brief Implementation for format() */
/** @brief Implementation for @ref format() */
virtual Buffer::Format doFormat() const = 0;
/** @brief Implementation for frequency() */
/** @brief Implementation for @ref frequency() */
virtual UnsignedInt doFrequency() const = 0;
/** @brief Implementation for data() */
/** @brief Implementation for @ref data() */
virtual Containers::Array<unsigned char> doData() = 0;
};

2
src/Magnum/Audio/Audio.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Forward declarations for Magnum::Audio namespace
* @brief Forward declarations for @ref Magnum::Audio namespace
*/
namespace Magnum { namespace Audio {

4
src/Magnum/Audio/Buffer.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Audio::Buffer
* @brief Class @ref Magnum::Audio::Buffer
*/
#include <utility>
@ -104,7 +104,7 @@ class Buffer {
ALuint _id;
};
/** @debugoperator{Magnum::Audio::Buffer} */
/** @debugoperatorclassenum{Magnum::Audio::Buffer,Magnum::Audio::Buffer::Format} */
Debug MAGNUM_AUDIO_EXPORT operator<<(Debug debug, Buffer::Format value);
inline Buffer::Buffer(Buffer&& other): _id(other._id) {

8
src/Magnum/Audio/Context.h

@ -25,8 +25,8 @@
DEALINGS IN THE SOFTWARE.
*/
/** @file Audio/Context.h
* @brief Class Magnum::Audio::Context
/** @file
* @brief Class @ref Magnum::Audio::Context
*/
#include <string>
@ -66,14 +66,14 @@ class MAGNUM_AUDIO_EXPORT Context {
/**
* @brief Vendor string
*
* @see rendererString(), @fn_al{GetString} with @def_al{VENDOR}
* @see @ref rendererString(), @fn_al{GetString} with @def_al{VENDOR}
*/
std::string vendorString() const { return alGetString(AL_VENDOR); }
/**
* @brief %Renderer string
*
* @see vendorString(), @fn_al{GetString} with @def_al{RENDERER}
* @see @ref vendorString(), @fn_al{GetString} with @def_al{RENDERER}
*/
std::string rendererString() const { return alGetString(AL_RENDERER); }

8
src/Magnum/Audio/Renderer.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Audio::Renderer
* @brief Class @ref Magnum::Audio::Renderer
*/
#include <al.h>
@ -45,7 +45,7 @@ class Renderer {
/**
* @brief Error status
*
* @see error()
* @see @ref error()
*/
enum class Error: ALenum {
NoError = AL_NO_ERROR, /**< No error occured */
@ -116,7 +116,7 @@ class Renderer {
/**
* @brief Distance model
*
* @see setDistanceModel()
* @see @ref setDistanceModel()
*/
enum class DistanceModel: ALenum {
/** No distance attenuation calculation */
@ -185,7 +185,7 @@ class Renderer {
/*@}*/
};
/** @debugoperator{Magnum::Audio::Renderer} */
/** @debugoperatorclassenum{Magnum::Audio::Renderer,Magnum::Audio::Renderer::Error} */
Debug MAGNUM_AUDIO_EXPORT operator<<(Debug debug, Renderer::Error value);
inline void Renderer::setListenerOrientation(const Vector3& forward, const Vector3& up) {

8
src/Magnum/Audio/Source.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Audio::Source
* @brief Class @ref Magnum::Audio::Source
*/
#include <functional>
@ -338,7 +338,7 @@ class MAGNUM_AUDIO_EXPORT Source {
};
/**
* @brief Source type
* @brief %Source type
*
* @see @ref setBuffer(), @fn_al{GetSourcei} with @def_al{SOURCE_TYPE}
*/
@ -346,7 +346,7 @@ class MAGNUM_AUDIO_EXPORT Source {
/**
* @brief Attach buffer
* @param buffer Buffer to attach or `nullptr`
* @param buffer %Buffer to attach or `nullptr`
* @return Reference to self (for method chaining)
*
* If an buffer is attached, changes source type to @ref Type::Static,
@ -586,7 +586,7 @@ class MAGNUM_AUDIO_EXPORT Source {
ALuint _id;
};
/** @debugoperator{Magnum::Audio::Source} */
/** @debugoperatorclassenum{Magnum::Audio::Source,Magnum::Audio::Source::State} */
Debug MAGNUM_AUDIO_EXPORT operator<<(Debug debug, Source::State value);
inline Source::Source(Source&& other): _id(other._id) {

1
src/Magnum/Buffer.cpp

@ -114,6 +114,7 @@ Buffer::Buffer(Buffer::Target targetHint): _targetHint(targetHint)
#endif
{
glGenBuffers(1, &_id);
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
Buffer::~Buffer() {

20
src/Magnum/Buffer.h

@ -291,7 +291,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
ShaderStorage = GL_SHADER_STORAGE_BUFFER,
/**
* Source for texel fetches. See BufferTexture.
* Source for texel fetches. See @ref BufferTexture.
* @requires_gl31 %Extension @extension{ARB,texture_buffer_object}
* @requires_gl Texture buffers are not available in OpenGL ES.
*/
@ -328,11 +328,11 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
/**
* @brief Memory mapping access
*
* @deprecated_gl Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features.
* @see @ref map(MapAccess), @ref mapSub()
* @requires_es_extension %Extension @es_extension{OES,mapbuffer} or
* @es_extension{CHROMIUM,map_sub}
* @deprecated_gl Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features.
*/
enum class MapAccess: GLenum {
#ifndef MAGNUM_TARGET_GLES
@ -610,11 +610,11 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* @brief Bind buffer
* @param target %Target
*
* @see @fn_gl{BindBuffer}
* @todo Allow binding to Target::ElementArray only if VAO is bound
* to avoid potential issues?
* @bug Binding to ElementArray if any VAO is active will corrupt the mesh
* @todo Don't allow user to bind buffers?
* @see @fn_gl{BindBuffer}
* @bug Binding to ElementArray if any VAO is active will corrupt the mesh
*/
void bind(Target target) { bind(target, _id); }
@ -746,14 +746,14 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* If @extension{EXT,direct_state_access} is not available and the
* buffer is not already bound somewhere, it is bound to hinted target
* before the operation.
* @deprecated_gl Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features.
* @see @ref minMapAlignment(), @ref unmap(), @ref setTargetHint(),
* @fn_gl{BindBuffer} and @fn_gl{MapBuffer} or
* @fn_gl_extension{MapNamedBuffer,EXT,direct_state_access}
* @requires_es_extension %Extension @es_extension{OES,mapbuffer} in
* OpenGL ES 2.0, use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* in OpenGL ES 3.0 instead.
* @deprecated_gl Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features.
*/
void* map(MapAccess access);
@ -767,14 +767,14 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
*
* If the buffer is not already bound somewhere, it is bound to hinted
* target before the operation.
* @deprecated_gl Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features.
* @see @ref unmapSub(), @ref setTargetHint(),
* @fn_gl_extension{MapBufferSubData,CHROMIUM,map_sub}
* @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use
* @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead.
* @requires_es_extension %Extension @es_extension{CHROMIUM,map_sub}
* @deprecated_gl Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features.
*/
void* mapSub(GLintptr offset, GLsizeiptr length, MapAccess access);
#endif
@ -926,7 +926,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
CORRADE_ENUMSET_OPERATORS(Buffer::MapFlags)
/** @debugoperator{Magnum::Buffer} */
/** @debugoperatorclassenum{Magnum::Buffer,Magnum::Buffer::Target} */
Debug MAGNUM_EXPORT operator<<(Debug debug, Buffer::Target value);
inline Buffer::Buffer(Buffer&& other) noexcept: _id(other._id), _targetHint(other._targetHint) {

4
src/Magnum/Color.h

@ -357,7 +357,9 @@ typedef BasicColor3<Float> Color3;
/** @brief Three-component (RGB) unsigned byte color */
typedef BasicColor3<UnsignedByte> Color3ub;
#ifndef DOXYGEN_GENERATING_OUTPUT
MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(3, BasicColor3)
#endif
/**
@brief Four-component (RGBA) color
@ -581,7 +583,9 @@ typedef BasicColor4<Float> Color4;
/** @brief Four-component (RGBA) unsigned byte color */
typedef BasicColor4<UnsignedByte> Color4ub;
#ifndef DOXYGEN_GENERATING_OUTPUT
MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(4, BasicColor4)
#endif
/** @debugoperator{Magnum::BasicColor3} */
template<class T> inline Debug operator<<(Debug debug, const BasicColor3<T>& value) {

16
src/Magnum/ColorFormat.h

@ -85,10 +85,10 @@ enum class ColorFormat: GLenum {
/**
* Floating-point luminance channel. The value is used for all RGB
* channels.
* @deprecated_gl Included for compatibility reasons only, use
* @ref Magnum::ColorFormat::Red "ColorFormat::Red" instead.
* @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use
* @ref Magnum::ColorFormat::Red "ColorFormat::Red" instead.
* @deprecated_gl Included for compatibility reasons only, use
* @ref Magnum::ColorFormat::Red "ColorFormat::Red" instead.
*/
Luminance = GL_LUMINANCE,
#endif
@ -110,10 +110,10 @@ enum class ColorFormat: GLenum {
/**
* Floating-point luminance and alpha channel. First value is used for all
* RGB channels, second value is used for alpha channel.
* @deprecated_gl Included for compatibility reasons only, use
* @ref Magnum::ColorFormat::RG "ColorFormat::RG" instead.
* @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use
* @ref Magnum::ColorFormat::RG "ColorFormat::RG" instead.
* @deprecated_gl Included for compatibility reasons only, use
* @ref Magnum::ColorFormat::RG "ColorFormat::RG" instead.
*/
LuminanceAlpha = GL_LUMINANCE_ALPHA,
#endif
@ -372,8 +372,8 @@ enum class ColorType: GLenum {
#ifndef MAGNUM_TARGET_GLES
/**
* BGR, unsigned short, red and blue 5bit, green 6bit.
* @requires_gl Only @ref Magnum::ColorType::RGB565 "ColorType::RGB565" is
* available in OpenGL ES.
* @requires_gl Only @ref Magnum::ColorType::UnsignedShort565 "ColorType::UnsignedShort565"
* is available in OpenGL ES.
*/
UnsignedShort565Rev = GL_UNSIGNED_SHORT_5_6_5_REV,
#endif
@ -491,10 +491,10 @@ enum class ColorType: GLenum {
#endif
};
/** @debugoperator{ColorFormat} */
/** @debugoperatorenum{Magnum::ColorFormat} */
Debug MAGNUM_EXPORT operator<<(Debug debug, ColorFormat value);
/** @debugoperator{ColorFormat} */
/** @debugoperatorenum{Magnum::ColorType} */
Debug MAGNUM_EXPORT operator<<(Debug debug, ColorType value);
}

27
src/Magnum/Context.cpp

@ -45,6 +45,11 @@
#include "Magnum/Renderer.h"
#include "Implementation/State.h"
#include "Implementation/BufferState.h"
#include "Implementation/FramebufferState.h"
#include "Implementation/MeshState.h"
#include "Implementation/ShaderProgramState.h"
#include "Implementation/TextureState.h"
namespace Magnum {
@ -61,6 +66,7 @@ const std::vector<Extension>& Extension::extensions(Version version) {
_extension(GL,EXT,texture_filter_anisotropic),
_extension(GL,EXT,texture_mirror_clamp),
_extension(GL,EXT,direct_state_access),
_extension(GL,EXT,texture_sRGB_decode),
_extension(GL,EXT,shader_integer_mix),
_extension(GL,EXT,debug_label),
_extension(GL,EXT,debug_marker),
@ -191,9 +197,11 @@ const std::vector<Extension>& Extension::extensions(Version version) {
_extension(GL,EXT,texture_filter_anisotropic),
_extension(GL,EXT,texture_format_BGRA8888),
_extension(GL,EXT,read_format_bgra),
_extension(GL,EXT,multi_draw_arrays),
_extension(GL,EXT,debug_label),
_extension(GL,EXT,debug_marker),
_extension(GL,EXT,disjoint_timer_query),
_extension(GL,EXT,texture_sRGB_decode),
_extension(GL,EXT,separate_shader_objects),
_extension(GL,EXT,sRGB),
_extension(GL,EXT,multisampled_render_to_texture),
@ -529,6 +537,25 @@ Version Context::supportedVersion(std::initializer_list<Version> versions) const
#endif
}
void Context::resetState(const States states) {
if(states & State::Buffers)
_state->buffer->reset();
if(states & State::Framebuffers)
_state->framebuffer->reset();
if(states & State::Meshes)
_state->mesh->reset();
/* Nothing to reset for renderer yet */
if(states & State::Shaders) {
/* Nothing to reset for shaders */
_state->shaderProgram->reset();
}
if(states & State::Textures)
_state->texture->reset();
}
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug operator<<(Debug debug, const Context::Flag value) {
switch(value) {

78
src/Magnum/Context.h

@ -45,8 +45,6 @@
namespace Magnum {
/** @todoc Resolve conflict with Audio/Context.h (Doxygen doesn't list this file) */
namespace Implementation {
struct State;
}
@ -89,7 +87,7 @@ class MAGNUM_EXPORT Extension {
};
/**
@brief Magnum context
@brief %Magnum context
Provides access to version and extension information. Instance available
through @ref Context::current() is automatically created during construction of
@ -98,14 +96,9 @@ instance is available during whole lifetime of *Application object. See
@ref platform documentation for more information about engine setup.
*/
class MAGNUM_EXPORT Context {
Context(const Context&) = delete;
Context(Context&&) = delete;
Context& operator=(const Context&) = delete;
Context& operator=(Context&&) = delete;
public:
/**
* @brief Context flag
* @brief %Context flag
*
* @see @ref Flags, @ref flags(), @ref Platform::Sdl2Application::Configuration::setFlags() "Platform::*Application::Configuration::setFlags()"
*/
@ -142,7 +135,39 @@ class MAGNUM_EXPORT Context {
};
/**
* @brief Context flags
* @brief State to reset
*
* @see @ref States, @ref resetState()
*/
enum class State: UnsignedInt {
/** Reset tracked buffer-related bindings and state */
Buffers = 1 << 0,
/** Reset tracked framebuffer-related bindings and state */
Framebuffers = 1 << 1,
/** Reset tracked mesh-related bindings */
Meshes = 1 << 2,
/** Reset tracked renderer-related state */
Renderer = 1 << 3,
/** Reset tracked shader-related bindings */
Shaders = 1 << 4,
/** Reset tracked texture-related bindings and state */
Textures = 1 << 5
};
/**
* @brief States to reset
*
* @see @ref resetState()
*/
typedef Containers::EnumSet<State, UnsignedInt> States;
/**
* @brief %Context flags
*
* @see @ref flags()
*/
@ -159,8 +184,20 @@ class MAGNUM_EXPORT Context {
*/
explicit Context();
/** @brief Copying is not allowed */
Context(const Context&) = delete;
/** @brief Moving is not allowed */
Context(Context&&) = delete;
~Context();
/** @brief Copying is not allowed */
Context& operator=(const Context&) = delete;
/** @brief Moving is not allowed */
Context& operator=(Context&&) = delete;
/** @brief Current context */
static Context* current() { return _current; }
@ -246,7 +283,7 @@ class MAGNUM_EXPORT Context {
std::vector<std::string> shadingLanguageVersionStrings() const;
/**
* @brief Extension strings
* @brief %Extension strings
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls. Note that this function returns list of all extensions
@ -258,7 +295,7 @@ class MAGNUM_EXPORT Context {
*/
std::vector<std::string> extensionStrings() const;
/** @brief Context flags */
/** @brief %Context flags */
Flags flags() const { return _flags; }
/**
@ -295,7 +332,7 @@ class MAGNUM_EXPORT Context {
* OpenGL version (@ref Version::GL210 for desktop OpenGL,
* @ref Version::GLES200 for OpenGL ES).
* @see isExtensionSupported(Version) const
* @todoc Explicit reference when Doxygen is sane
* @todoc Explicit reference when Doxygen can handle const
*/
Version supportedVersion(std::initializer_list<Version> versions) const;
@ -315,7 +352,7 @@ class MAGNUM_EXPORT Context {
* @see isExtensionSupported(const Extension&) const,
* @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED(),
* @ref isExtensionDisabled()
* @todoc Explicit reference when Doxygen is sane
* @todoc Explicit reference when Doxygen can handle const
*/
template<class T> bool isExtensionSupported() const {
return isExtensionSupported<T>(version());
@ -386,6 +423,17 @@ class MAGNUM_EXPORT Context {
return isVersionSupported(extension._requiredVersion) && extensionStatus[extension._index] && !isVersionSupported(_extensionRequiredVersion[extension._index]);
}
/**
* @brief Reset internal state tracker
* @param states Tracked states to reset. Default is all state.
*
* The engine internally tracks object bindings and other state to
* avoid redundant OpenGL calls. In some cases (e.g. when non-Magnum
* code makes GL calls) the internal tracker no longer reflects actual
* state and needs to be reset to avoid strange issues.
*/
void resetState(States states = ~States{});
#ifndef DOXYGEN_GENERATING_OUTPUT
Implementation::State& state() { return *_state; }
#endif
@ -407,7 +455,7 @@ class MAGNUM_EXPORT Context {
Implementation::State* _state;
};
/** @debugoperator{Magnum::Context} */
/** @debugoperatorclassenum{Magnum::Context,Magnum::Context::Flag} */
MAGNUM_EXPORT Debug operator<<(Debug debug, Context::Flag value);
/** @hideinitializer

6
src/Magnum/CubeMapTexture.h

@ -198,6 +198,12 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
return *this;
}
/** @copydoc Texture::setSRGBDecode() */
CubeMapTexture& setSRGBDecode(bool decode) {
AbstractTexture::setSRGBDecode(decode);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setSwizzle() */
template<char r, char g, char b, char a> CubeMapTexture& setSwizzle() {

6
src/Magnum/CubeMapTextureArray.h

@ -228,6 +228,12 @@ class CubeMapTextureArray: public AbstractTexture {
return *this;
}
/** @copydoc RectangleTexture::setSRGBDecode() */
CubeMapTextureArray& setSRGBDecode(bool decode) {
AbstractTexture::setSRGBDecode(decode);
return *this;
}
/**
* @copybrief Texture::setSwizzle()
* @return Reference to self (for method chaining)

6
src/Magnum/DebugMessage.h

@ -317,13 +317,13 @@ class MAGNUM_EXPORT DebugMessage {
static MAGNUM_LOCAL void callbackImplementationKhr(Callback callback, const void* userParam);
};
/** @debugoperator{Magnum::DebugMessage} */
/** @debugoperatorclassenum{Magnum::DebugMessage,Magnum::DebugMessage::Source} */
Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Source value);
/** @debugoperator{Magnum::DebugMessage} */
/** @debugoperatorclassenum{Magnum::DebugMessage,Magnum::DebugMessage::Type} */
Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Type value);
/** @debugoperator{Magnum::DebugMessage} */
/** @debugoperatorclassenum{Magnum::DebugMessage,Magnum::DebugMessage::Severity} */
Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Severity value);
}

2
src/Magnum/DebugTools/DebugTools.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Forward declarations for Magnum::DebugTools namespace
* @brief Forward declarations for @ref Magnum::DebugTools namespace
*/
#include "Magnum/Types.h"

5
src/Magnum/DebugTools/ForceRenderer.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::DebugTools::ForceRenderer, Magnum::DebugTools::ForceRendererOptions, typedef Magnum::DebugTools::ForceRenderer2D, Magnum::DebugTools::ForceRenderer3D
* @brief Class @ref Magnum::DebugTools::ForceRenderer, @ref Magnum::DebugTools::ForceRendererOptions, typedef @ref Magnum::DebugTools::ForceRenderer2D, @ref Magnum::DebugTools::ForceRenderer3D
*/
#include "Magnum/Color.h"
@ -122,10 +122,9 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ForceRenderer: p
/** @overload */
ForceRenderer(SceneGraph::AbstractObject<dimensions, Float>&, const typename DimensionTraits<dimensions, Float>::VectorType&, typename DimensionTraits<dimensions, Float>::VectorType&&, ResourceKey = ResourceKey(), SceneGraph::DrawableGroup<dimensions, Float>* = nullptr) = delete;
protected:
private:
void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>& camera) override;
private:
const typename DimensionTraits<dimensions, Float>::VectorType forcePosition;
const typename DimensionTraits<dimensions, Float>::VectorType& force;

5
src/Magnum/DebugTools/ObjectRenderer.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::DebugTools::ObjectRenderer, Magnum::DebugTools::ObjectRendererOptions, typedef Magnum::DebugTools::ObjectRenderer2D, Magnum::DebugTools::ObjectRenderer3D
* @brief Class @ref Magnum::DebugTools::ObjectRenderer, @ref Magnum::DebugTools::ObjectRendererOptions, typedef @ref Magnum::DebugTools::ObjectRenderer2D, @ref Magnum::DebugTools::ObjectRenderer3D
*/
#include "Magnum/Resource.h"
@ -97,10 +97,9 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ObjectRenderer:
*/
explicit ObjectRenderer(SceneGraph::AbstractObject<dimensions, Float>& object, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup<dimensions, Float>* drawables = nullptr);
protected:
private:
void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>& camera) override;
private:
Resource<ObjectRendererOptions> options;
Resource<AbstractShaderProgram, Shaders::VertexColor<dimensions>> shader;
Resource<Mesh> mesh;

24
src/Magnum/DebugTools/Profiler.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::DebugTools::Profiler
* @brief Class @ref Magnum::DebugTools::Profiler
*/
#include <chrono>
@ -44,7 +44,7 @@ namespace Magnum { namespace DebugTools {
@brief %Profiler
Measures time passed during specified sections of each frame. It's meant to be
used in rendering and event loops (e.g. Platform::Sdl2Application::drawEvent()),
used in rendering and event loops (e.g. @ref Platform::Sdl2Application::drawEvent()),
but it's possible to use it standalone elsewhere. Example usage:
@code
DebugTools::Profiler p;
@ -95,7 +95,7 @@ p.printStatistics();
@endcode
It's possible to start profiler only for certain parts of the code and then
stop it again using stop(), if you are not interested in profiling the rest.
stop it again using @ref stop(), if you are not interested in profiling the rest.
@todo Some unit testing
@todo More time intervals
@ -105,14 +105,14 @@ class MAGNUM_DEBUGTOOLS_EXPORT Profiler {
/**
* @brief Section ID
*
* @see otherSection, addSection(), start(Section)
* @see @ref otherSection, @ref addSection(), @ref start(Section)
*/
typedef UnsignedInt Section;
/**
* @brief Default section
*
* @see start()
* @see @ref start()
*/
static const Section otherSection = 0;
@ -137,15 +137,15 @@ class MAGNUM_DEBUGTOOLS_EXPORT Profiler {
* @brief Add named section
*
* @attention This function cannot be called if profiling is enabled.
* @see otherSection, start(Section), stop()
* @see @ref otherSection, @ref start(Section), @ref stop()
*/
Section addSection(const std::string& name);
/**
* @brief Whether profiling is enabled
*
* If the profiling is not enabled, calls to start() and stop() have
* no effect.
* If the profiling is not enabled, calls to @ref start() and
* @ref stop() have no effect.
*/
bool isEnabled() { return enabled; }
@ -153,14 +153,14 @@ class MAGNUM_DEBUGTOOLS_EXPORT Profiler {
* @brief Enable profiling
*
* Clears already mesaured data.
* @see disable(), isEnabled()
* @see @ref disable(), @ref isEnabled()
*/
void enable();
/**
* @brief Disable profiling
*
* @see enable(), isEnabled()
* @see @ref enable(), @ref isEnabled()
*/
void disable();
@ -169,14 +169,14 @@ class MAGNUM_DEBUGTOOLS_EXPORT Profiler {
*
* If profiling is already running, current time is saved for previous
* section.
* @see @ref otherSection, start(Section)
* @see @ref otherSection, @ref start(Section)
*/
void start(Section section);
/**
* @brief Start profiling of "other" section
*
* Same as calling `start(Profiler::otherSection)`.
* Same as calling `start(DebugTools::Profiler::otherSection)`.
* @note Does nothing if profiling is disabled.
*/
void start() { start(otherSection); }

2
src/Magnum/DebugTools/ResourceManager.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::DebugTools::ResourceManager
* @brief Class @ref Magnum::DebugTools::ResourceManager
*/
#ifndef MAGNUM_RESOURCEMANAGER_DEFINE_INTERNALINSTANCE

10
src/Magnum/DebugTools/ShapeRenderer.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::DebugTools::ShapeRenderer, Magnum::DebugTools::ShapeRendererOptions, typedef Magnum::DebugTools::ShapeRenderer2D, Magnum::DebugTools::ShapeRenderer3D
* @brief Class @ref Magnum::DebugTools::ShapeRenderer, @ref Magnum::DebugTools::ShapeRendererOptions, typedef @ref Magnum::DebugTools::ShapeRenderer2D, @ref Magnum::DebugTools::ShapeRenderer3D
*/
#include "Magnum/Color.h"
@ -56,7 +56,7 @@ class ShapeRendererOptions {
/**
* @brief Shape rendering mode
*
* @see setRenderMode()
* @see @ref setRenderMode()
*/
enum class RenderMode: UnsignedByte {
Wireframe, /**< Wireframe rendering */
@ -138,12 +138,14 @@ new DebugTools::ShapeRenderer2D(shape, "red", debugDrawables);
@todo Different drawing style for inverted shapes? (marking the "inside" somehow)
*/
template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ShapeRenderer: public SceneGraph::Drawable<dimensions, Float> {
#ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC can't cope with <> here */
#ifndef CORRADE_MSVC2013_COMPATIBILITY
friend void Implementation::createDebugMesh<>(ShapeRenderer<dimensions>&, const Shapes::Implementation::AbstractShape<dimensions>&);
#else
template<UnsignedInt dimensions_> friend void Implementation::createDebugMesh(ShapeRenderer<dimensions_>&, const Shapes::Implementation::AbstractShape<dimensions_>&);
#endif
#endif
public:
/**
@ -162,11 +164,9 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ShapeRenderer: p
~ShapeRenderer();
protected:
/** @todoc Remove Float when Doxygen properly treats this as override */
private:
void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>& camera) override;
private:
Resource<ShapeRendererOptions> options;
std::vector<Implementation::AbstractShapeRenderer<dimensions>*> renderers;
};

8
src/Magnum/DefaultFramebuffer.h

@ -145,7 +145,8 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/**
* Write output to back buffer.
*
* On desktop OpenGL, this is equal to @ref DrawAttachment::BackLeft.
* On desktop OpenGL, this is equal to
* @ref DrawAttachment::BackLeft.
*/
#ifdef MAGNUM_TARGET_GLES
Back = GL_BACK,
@ -156,7 +157,8 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/**
* Write output to front buffer.
*
* On desktop OpenGL, this is equal to @ref DrawAttachment::FrontLeft.
* On desktop OpenGL, this is equal to
* @ref DrawAttachment::FrontLeft.
*/
#ifdef MAGNUM_TARGET_GLES
Front = GL_FRONT
@ -433,7 +435,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/** @brief Default framebuffer instance */
extern DefaultFramebuffer MAGNUM_EXPORT defaultFramebuffer;
/** @debugoperator{DefaultFramebuffer} */
/** @debugoperatorclassenum{Magnum::DefaultFramebuffer,Magnum::DefaultFramebuffer::Status} */
Debug MAGNUM_EXPORT operator<<(Debug debug, DefaultFramebuffer::Status value);
}

9
src/Magnum/DimensionTraits.h

@ -29,7 +29,7 @@
#include "Magnum/Types.h"
/** @file
* @brief Class Magnum::DimensionTraits
* @brief Class @ref Magnum::DimensionTraits
*/
namespace Magnum {
@ -42,15 +42,16 @@ template<UnsignedInt dimensions, class T> struct DimensionTraits {
/**
* @brief Vector type
*
* Math::Vector, Math::Vector2 or Math::Vector3 based on dimension count.
* @ref Math::Vector, @ref Math::Vector2 or @ref Math::Vector3 based on
* dimension count.
*/
typedef U VectorType;
/**
* @brief Matrix type
*
* Floating-point Math::Matrix3 or Math::Matrix4 for 2D or 3D. No matrix
* type defined for one dimension and integral types.
* Floating-point @ref Math::Matrix3 or @ref Math::Matrix4 for 2D or 3D. No
* matrix type defined for one dimension and integral types.
*/
typedef U MatrixType;
#endif

22
src/Magnum/Extensions.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Namespace Magnum::Extensions
* @brief Namespace @ref Magnum::Extensions
*/
#include "Magnum/Version.h"
@ -37,16 +37,21 @@ namespace Magnum {
@brief Compile-time information about OpenGL extensions
Each extension is `struct` named hierarchically by prefix, vendor and
extension name, for example `GL::APPLE::vertex_array_object`. Each struct has
the same public methods as Extension class (requiredVersion(), coreVersion()
and string(), but these structs are better suited for compile-time decisions
rather than %Extension instances. See Context::isExtensionSupported() for
example usage.
extension name taken from list at @ref opengl-support, for example
`GL::ARB::texture_storage`. Note that desktop extensions are available only on
desktop build, OpenGL ES 2.0 extensions which are part of ES 3.0 are available
only on @ref MAGNUM_TARGET_GLES2 "OpenGL ES 2.0 build" and vendor OpenGL ES
extensions are available only on @ref MAGNUM_TARGET_GLES "OpenGL ES builds".
Each struct has the same public methods as Extension class (requiredVersion(),
coreVersion() and string(), but these structs are better suited for
compile-time decisions rather than %Extension instances. See
@ref Context::isExtensionSupported() for example usage.
This namespace is built by default. To use it, you need to add `${MAGNUM_INCLUDE_DIRS}`
to include path and link to `${MAGNUM_LIBRARIES}`. See @ref building and
@ref cmake for more information.
@see MAGNUM_ASSERT_EXTENSION_SUPPORTED()
@see @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED()
@todo Manual indices for extensions, this has gaps
*/
namespace Extensions {
@ -182,6 +187,7 @@ namespace GL {
_extension(GL,EXT,transform_feedback, GL210, GL300) // #352
_extension(GL,EXT,direct_state_access, GL210, None) // #353
_extension(GL,EXT,texture_snorm, GL300, GL310) // #365
_extension(GL,EXT,texture_sRGB_decode, GL210, None) // #402
_extension(GL,EXT,shader_integer_mix, GL300, None) // #437
_extension(GL,EXT,debug_label, GL210, None) // #439
_extension(GL,EXT,debug_marker, GL210, None) // #440
@ -233,6 +239,7 @@ namespace GL {
_extension(GL,EXT,blend_minmax, GLES200, GLES300) // #65
#endif
_extension(GL,EXT,read_format_bgra, GLES200, None) // #66
_extension(GL,EXT,multi_draw_arrays, GLES200, None) // #67
#ifdef MAGNUM_TARGET_GLES2
_extension(GL,EXT,shader_texture_lod, GLES200, GLES300) // #77
#endif
@ -254,6 +261,7 @@ namespace GL {
_extension(GL,EXT,map_buffer_range, GLES200, GLES300) // #121
#endif
_extension(GL,EXT,disjoint_timer_query, GLES200, None) // #150
_extension(GL,EXT,texture_sRGB_decode, GLES200, None) // #152
#ifdef MAGNUM_TARGET_GLES2
_extension(GL,EXT,instanced_arrays, GLES200, GLES300) // #156
_extension(GL,EXT,draw_instanced, GLES200, GLES300) // #157

1
src/Magnum/Framebuffer.cpp

@ -82,6 +82,7 @@ Framebuffer::Framebuffer(const Range2Di& viewport) {
_viewport = viewport;
glGenFramebuffers(1, &_id);
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
Framebuffer::~Framebuffer() {

10
src/Magnum/Framebuffer.h

@ -496,7 +496,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
/**
* @brief Attach texture to given buffer
* @param attachment %Buffer attachment
* @param texture Texture
* @param texture %Texture
* @param level Mip level
* @return Reference to self (for method chaining)
*
@ -514,7 +514,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
/**
* @brief Attach texture to given buffer
* @param attachment %Buffer attachment
* @param texture Texture
* @param texture %Texture
* @param level Mip level
* @return Reference to self (for method chaining)
*
@ -544,7 +544,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
/**
* @brief Attach cube map texture to given buffer
* @param attachment %Buffer attachment
* @param texture Cube map texture
* @param texture %Texture
* @param coordinate Cube map coordinate
* @param level Mip level
* @return Reference to self (for method chaining)
@ -561,7 +561,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
/**
* @brief Attach texture layer to given buffer
* @param attachment %Buffer attachment
* @param texture Texture
* @param texture %Texture
* @param level Mip level
* @param layer Layer
* @return Reference to self (for method chaining)
@ -663,7 +663,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
#endif
};
/** @debugoperator{DefaultFramebuffer} */
/** @debugoperatorclassenum{Magnum::Framebuffer,Magnum::Framebuffer::Status} */
Debug MAGNUM_EXPORT operator<<(Debug debug, Framebuffer::Status value);
inline Framebuffer::Framebuffer(Framebuffer&& other) noexcept {

6
src/Magnum/Implementation/BufferState.cpp

@ -30,6 +30,8 @@
#include "Magnum/Context.h"
#include "Magnum/Extensions.h"
#include "State.h"
namespace Magnum { namespace Implementation {
const Buffer::Target BufferState::targetForIndex[] = {
@ -136,4 +138,8 @@ BufferState::BufferState(Context& context, std::vector<std::string>& extensions)
#endif
}
void BufferState::reset() {
std::fill_n(bindings, TargetCount, State::DisengagedBinding);
}
}}

2
src/Magnum/Implementation/BufferState.h

@ -46,6 +46,8 @@ struct BufferState {
explicit BufferState(Context& context, std::vector<std::string>& extensions);
void reset();
#ifndef MAGNUM_TARGET_GLES2
void(*copyImplementation)(Buffer&, Buffer&, GLintptr, GLintptr, GLsizeiptr);
#endif

7
src/Magnum/Implementation/FramebufferState.cpp

@ -29,6 +29,8 @@
#include "Magnum/Extensions.h"
#include "Magnum/Renderbuffer.h"
#include "State.h"
namespace Magnum { namespace Implementation {
FramebufferState::FramebufferState(Context& context, std::vector<std::string>& extensions): readBinding(0), drawBinding(0), renderbufferBinding(0), maxDrawBuffers(0), maxColorAttachments(0), maxRenderbufferSize(0), maxSamples(0)
@ -138,4 +140,9 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
}
}
void FramebufferState::reset() {
readBinding = drawBinding = renderbufferBinding = State::DisengagedBinding;
viewport = {};
}
}}

2
src/Magnum/Implementation/FramebufferState.h

@ -45,6 +45,8 @@ namespace Magnum { namespace Implementation {
struct FramebufferState {
explicit FramebufferState(Context& context, std::vector<std::string>& extensions);
void reset();
GLenum(AbstractFramebuffer::*checkStatusImplementation)(FramebufferTarget);
void(AbstractFramebuffer::*drawBuffersImplementation)(GLsizei, const GLenum*);
void(AbstractFramebuffer::*drawBufferImplementation)(GLenum);

16
src/Magnum/Implementation/MeshState.cpp

@ -27,6 +27,9 @@
#include "Magnum/Context.h"
#include "Magnum/Extensions.h"
#include "Magnum/MeshView.h"
#include "State.h"
namespace Magnum { namespace Implementation {
@ -93,6 +96,15 @@ MeshState::MeshState(Context& context, std::vector<std::string>& extensions): cu
}
#endif
#ifdef MAGNUM_TARGET_GLES
/* Multi draw implementation on ES */
if(context.isExtensionSupported<Extensions::GL::EXT::multi_draw_arrays>()) {
extensions.push_back(Extensions::GL::EXT::multi_draw_arrays::string());
multiDrawImplementation = &MeshView::multiDrawImplementationDefault;
} else multiDrawImplementation = &MeshView::multiDrawImplementationFallback;
#endif
#ifdef MAGNUM_TARGET_GLES2
/* Instanced draw ímplementation on ES2 */
if(context.isExtensionSupported<Extensions::GL::ANGLE::instanced_arrays>()) {
@ -138,4 +150,8 @@ MeshState::MeshState(Context& context, std::vector<std::string>& extensions): cu
#endif
}
void MeshState::reset() {
currentVAO = State::DisengagedBinding;
}
}}

6
src/Magnum/Implementation/MeshState.h

@ -35,6 +35,8 @@ namespace Magnum { namespace Implementation {
struct MeshState {
explicit MeshState(Context& context, std::vector<std::string>& extensions);
void reset();
void(Mesh::*createImplementation)();
void(Mesh::*destroyImplementation)();
void(Mesh::*attributePointerImplementation)(const Mesh::Attribute&);
@ -56,6 +58,10 @@ struct MeshState {
void(Mesh::*drawElementsInstancedImplementation)(GLsizei, GLintptr, GLsizei);
#endif
#ifdef MAGNUM_TARGET_GLES
void(*multiDrawImplementation)(std::initializer_list<std::reference_wrapper<MeshView>>);
#endif
GLuint currentVAO;
#ifndef MAGNUM_TARGET_GLES2
GLint maxElementsIndices, maxElementsVertices;

6
src/Magnum/Implementation/ShaderProgramState.cpp

@ -29,6 +29,8 @@
#include "Magnum/Context.h"
#include "Magnum/Extensions.h"
#include "State.h"
namespace Magnum { namespace Implementation {
ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string>& extensions): current(0), maxVertexAttributes(0)
@ -185,4 +187,8 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string
}
}
void ShaderProgramState::reset() {
current = State::DisengagedBinding;
}
}}

2
src/Magnum/Implementation/ShaderProgramState.h

@ -42,6 +42,8 @@ namespace Magnum { namespace Implementation {
struct ShaderProgramState {
explicit ShaderProgramState(Context& context, std::vector<std::string>& extensions);
void reset();
void(AbstractShaderProgram::*uniform1fvImplementation)(GLint, GLsizei, const GLfloat*);
void(AbstractShaderProgram::*uniform2fvImplementation)(GLint, GLsizei, const Math::Vector<2, GLfloat>*);
void(AbstractShaderProgram::*uniform3fvImplementation)(GLint, GLsizei, const Math::Vector<3, GLfloat>*);

3
src/Magnum/Implementation/State.h

@ -26,6 +26,7 @@
*/
#include "Magnum/Magnum.h"
#include "Magnum/OpenGL.h"
namespace Magnum { namespace Implementation {
@ -44,6 +45,8 @@ struct State {
~State();
enum: GLuint { DisengagedBinding = ~0u };
BufferState* buffer;
DebugState* debug;
FramebufferState* framebuffer;

6
src/Magnum/Implementation/TextureState.cpp

@ -34,6 +34,8 @@
#include "Magnum/Context.h"
#include "Magnum/Extensions.h"
#include "State.h"
namespace Magnum { namespace Implementation {
TextureState::TextureState(Context& context, std::vector<std::string>& extensions): maxSize{}, max3DSize{}, maxCubeMapSize{},
@ -228,4 +230,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
TextureState::~TextureState() = default;
void TextureState::reset() {
std::fill_n(bindings.begin(), bindings.size(), std::pair<GLenum, GLuint>{{}, State::DisengagedBinding});
}
}}

2
src/Magnum/Implementation/TextureState.h

@ -55,6 +55,8 @@ struct TextureState {
explicit TextureState(Context& context, std::vector<std::string>& extensions);
~TextureState();
void reset();
void(*unbindImplementation)(GLint);
void(*bindMultiImplementation)(GLint, std::initializer_list<AbstractTexture*>);
void(AbstractTexture::*bindImplementation)(GLint);

1
src/Magnum/Implementation/setupDriverWorkarounds.cpp

@ -56,6 +56,7 @@ void Context::setupDriverWorkarounds() {
#ifndef CORRADE_TARGET_NACL
_setRequiredVersion(GL::CHROMIUM::map_sub, None);
#endif
_setRequiredVersion(GL::EXT::multi_draw_arrays, None);
_setRequiredVersion(GL::EXT::debug_label, None);
_setRequiredVersion(GL::EXT::debug_marker, None);
_setRequiredVersion(GL::EXT::disjoint_timer_query, None);

2
src/Magnum/Magnum.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Forward declarations for Magnum namespace
* @brief Forward declarations for @ref Magnum namespace
*/
#include <Corrade/Utility/Utility.h>

9
src/Magnum/Math/Algorithms/GaussJordan.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function Magnum::Math::Algorithms::gaussJordanInPlaceTransposed(), Magnum::Math::Algorithms::gaussJordanInPlace()
* @brief Function @ref Magnum::Math::Algorithms::gaussJordanInPlaceTransposed(), @ref Magnum::Math::Algorithms::gaussJordanInPlace()
*/
#include "Magnum/Math/RectangularMatrix.h"
@ -42,7 +42,8 @@ namespace Magnum { namespace Math { namespace Algorithms {
As Gauss-Jordan elimination works on rows and matrices in OpenGL are
column-major, it is more efficient to operate on transposed matrices and treat
columns as rows. See also gaussJordanInPlace() which works with non-transposed matrices.
columns as rows. See also @ref gaussJordanInPlace() which works with
non-transposed matrices.
The function eliminates matrix @p a and solves @p t in place. For efficiency
reasons, only pure Gaussian elimination is done on @p a and the final
@ -94,8 +95,8 @@ template<std::size_t size, std::size_t rows, class T> bool gaussJordanInPlaceTra
/**
@brief In-place Gauss-Jordan elimination
Transposes the matrices, calls gaussJordanInPlaceTransposed() on them and then
transposes them back.
Transposes the matrices, calls @ref gaussJordanInPlaceTransposed() on them and
then transposes them back.
*/
template<std::size_t size, std::size_t cols, class T> bool gaussJordanInPlace(RectangularMatrix<size, size, T>& a, RectangularMatrix<cols, size, T>& t) {
a = a.transposed();

10
src/Magnum/Math/Algorithms/GramSchmidt.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function Magnum::Math::Algorithms::gramSchmidtOrthogonalizeInPlace(), Magnum::Math::Algorithms::gramSchmidtOrthogonalize(), Magnum::Math::Algorithms::gramSchmidtOrthonormalizeInPlace(), Magnum::Math::Algorithms::gramSchmidtOrthonormalize()
* @brief Function @ref Magnum::Math::Algorithms::gramSchmidtOrthogonalizeInPlace(), @ref Magnum::Math::Algorithms::gramSchmidtOrthogonalize(), @ref Magnum::Math::Algorithms::gramSchmidtOrthonormalizeInPlace(), @ref Magnum::Math::Algorithms::gramSchmidtOrthonormalize()
*/
#include "Magnum/Math/RectangularMatrix.h"
@ -48,8 +48,8 @@ template<std::size_t cols, std::size_t rows, class T> void gramSchmidtOrthogonal
/**
@brief Gram-Schmidt matrix orthogonalization
Unlike gramSchmidtOrthogonalizeInPlace() returns the modified matrix instead
of performing the orthogonalization in-place.
Unlike @ref gramSchmidtOrthogonalizeInPlace() returns the modified matrix
instead of performing the orthogonalization in-place.
*/
template<std::size_t cols, std::size_t rows, class T> RectangularMatrix<cols, rows, T> gramSchmidtOrthogonalize(RectangularMatrix<cols, rows, T> matrix) {
gramSchmidtOrthogonalizeInPlace(matrix);
@ -72,8 +72,8 @@ template<std::size_t cols, std::size_t rows, class T> void gramSchmidtOrthonorma
/**
@brief Gram-Schmidt matrix orthonormalization
Unlike gramSchmidtOrthonormalizeInPlace() returns the modified matrix instead
of performing the orthonormalization in-place.
Unlike @ref gramSchmidtOrthonormalizeInPlace() returns the modified matrix
instead of performing the orthonormalization in-place.
*/
template<std::size_t cols, std::size_t rows, class T> RectangularMatrix<cols, rows, T> gramSchmidtOrthonormalize(RectangularMatrix<cols, rows, T> matrix) {
gramSchmidtOrthonormalizeInPlace(matrix);

2
src/Magnum/Math/Algorithms/Svd.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function Magnum::Math::Algorithms::svd()
* @brief Function @ref Magnum::Math::Algorithms::svd()
*/
#include <tuple>

20
src/Magnum/Math/Angle.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Deg, Magnum::Math::Rad and related operators.
* @brief Class @ref Magnum::Math::Deg, @ref Magnum::Math::Rad and related operators.
*/
#include <Corrade/configure.h>
@ -119,7 +119,7 @@ std::sin(Float(Rad<Float>(b)); // required explicit conversion hints to user
// (i.e., conversion to radians)
@endcode
@see Magnum::Deg, Magnum::Degd
@see @ref Magnum::Deg, @ref Magnum::Degd
*/
template<class T> class Deg: public Unit<Deg, T> {
public:
@ -157,8 +157,9 @@ Double cosine = Math::cos(60.0_deg); // cosine = 0.5
Double cosine = Math::cos(1.047_rad); // cosine = 0.5
@endcode
@see Magnum::operator""_deg(), operator""_degf(), operator""_rad()
@note Not available on GCC < 4.7 and MSVC 2013. Use Deg::Deg(T) instead.
@note Not available on GCC < 4.7 and MSVC 2013. Use @ref Deg::Deg(T) instead.
@requires_gl Only single-precision types are available in OpenGL ES.
@todoc Make references explicit when Doxygen can link to operator""
*/
constexpr Deg<Double> operator "" _deg(long double value) { return Deg<Double>(value); }
#endif
@ -172,8 +173,9 @@ Float tangent = Math::tan(60.0_degf); // tangent = 1.732f
Float tangent = Math::tan(1.047_radf); // tangent = 1.732f
@endcode
@see Magnum::operator""_degf(), operator""_deg(), operator""_radf()
@note Not available on GCC < 4.7 and MSVC 2013. Use Deg::Deg(T) instead.
@note Not available on GCC < 4.7 and MSVC 2013. Use @ref Deg::Deg(T) instead.
@requires_gl Only single-precision types are available in OpenGL ES.
@todoc Make references explicit when Doxygen can link to operator""
*/
constexpr Deg<Float> operator "" _degf(long double value) { return Deg<Float>(value); }
#endif
@ -181,8 +183,8 @@ constexpr Deg<Float> operator "" _degf(long double value) { return Deg<Float>(va
/**
@brief Angle in radians
See Deg for more information.
@see Magnum::Rad, Magnum::Radd
See @ref Deg for more information.
@see @ref Magnum::Rad, @ref Magnum::Radd
*/
template<class T> class Rad: public Unit<Rad, T> {
public:
@ -216,7 +218,8 @@ template<class T> class Rad: public Unit<Rad, T> {
See operator""_rad() for more information.
@see Magnum::operator""_rad(), operator""_radf(), operator""_deg()
@note Not available on GCC < 4.7 and MSVC 2013. Use Rad::Rad(T) instead.
@note Not available on GCC < 4.7 and MSVC 2013. Use @ref Rad::Rad(T) instead.
@todoc Make references explicit when Doxygen can link to operator""
*/
constexpr Rad<Double> operator "" _rad(long double value) { return Rad<Double>(value); }
#endif
@ -226,7 +229,8 @@ constexpr Rad<Double> operator "" _rad(long double value) { return Rad<Double>(v
See operator""_degf() for more information.
@see Magnum::operator""_radf(), operator""_rad(), operator""_degf()
@note Not available on GCC < 4.7 and MSVC 2013. Use Rad::Rad(T) instead.
@note Not available on GCC < 4.7 and MSVC 2013. Use @ref Rad::Rad(T) instead.
@todoc Make references explicit when Doxygen can link to operator""
*/
constexpr Rad<Float> operator "" _radf(long double value) { return Rad<Float>(value); }
#endif

14
src/Magnum/Math/BoolVector.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::BoolVector
* @brief Class @ref Magnum::Math::BoolVector
*/
#include <Corrade/configure.h>
@ -63,8 +63,8 @@ namespace Implementation {
Result of component-wise comparison from Vector. The boolean values are stored
as bits in array of unsigned bytes, unused bits have undefined value which
doesn't affect comparison or all() / none() / any() functions. See also
@ref matrix-vector for brief introduction.
doesn't affect comparison or @ref all() / @ref none() / @ref any() functions.
See also @ref matrix-vector for brief introduction.
*/
template<std::size_t size> class BoolVector {
static_assert(size != 0, "BoolVector cannot have zero elements");
@ -115,7 +115,7 @@ template<std::size_t size> class BoolVector {
* @brief Raw data
* @return %Array of DataSize length
*
* @see operator[](), set()
* @see @ref operator[](), @ref set()
*/
UnsignedByte* data() {
#ifndef CORRADE_MSVC2013_COMPATIBILITY
@ -180,7 +180,7 @@ template<std::size_t size> class BoolVector {
/**
* @brief Bitwise AND
*
* @see operator&=()
* @see @ref operator&=()
*/
BoolVector<size> operator&(const BoolVector<size>& other) const {
return BoolVector<size>(*this) &= other;
@ -201,7 +201,7 @@ template<std::size_t size> class BoolVector {
/**
* @brief Bitwise OR
*
* @see operator|=()
* @see @ref operator|=()
*/
BoolVector<size> operator|(const BoolVector<size>& other) const {
return BoolVector<size>(*this) |= other;
@ -222,7 +222,7 @@ template<std::size_t size> class BoolVector {
/**
* @brief Bitwise XOR
*
* @see operator^=()
* @see @ref operator^=()
*/
BoolVector<size> operator^(const BoolVector<size>& other) const {
return BoolVector<size>(*this) ^= other;

64
src/Magnum/Math/Complex.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Complex
* @brief Class @ref Magnum::Math::Complex
*/
#include <limits>
@ -51,11 +51,11 @@ namespace Implementation {
@tparam T Data type
Represents 2D rotation. See @ref transformations for brief introduction.
@see Magnum::Complex, Magnum::Complexd, Matrix3
@see @ref Magnum::Complex, @ref Magnum::Complexd, @ref Matrix3
*/
template<class T> class Complex {
public:
typedef T Type; /**< @brief Underlying data type */
typedef T Type; /**< @brief Underlying data type */
/**
* @brief Dot product
@ -64,6 +64,7 @@ template<class T> class Complex {
* c_0 \cdot c_1 = a_0 a_1 + b_0 b_1
* @f]
* @see dot() const
* @todoc Explicit reference when Doxygen can handle const
*/
static T dot(const Complex<T>& a, const Complex<T>& b) {
return a._real*b._real + a._imaginary*b._imaginary;
@ -75,7 +76,8 @@ template<class T> class Complex {
* Expects that both complex numbers are normalized. @f[
* \theta = acos \left( \frac{Re(c_0 \cdot c_1))}{|c_0| |c_1|} \right) = acos (a_0 a_1 + b_0 b_1)
* @f]
* @see isNormalized(), Quaternion::angle(), Vector::angle()
* @see @ref isNormalized(), @ref Quaternion::angle(),
* @ref Vector::angle()
*/
static Rad<T> angle(const Complex<T>& normalizedA, const Complex<T>& normalizedB) {
CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(),
@ -90,7 +92,8 @@ template<class T> class Complex {
* @f[
* c = cos \theta + i sin \theta
* @f]
* @see angle(), Matrix3::rotation(), Quaternion::rotation()
* @see @ref angle(), @ref Matrix3::rotation(),
* @ref Quaternion::rotation()
*/
static Complex<T> rotation(Rad<T> angle) {
return {std::cos(angle.toUnderlyingType()), std::sin(angle.toUnderlyingType())};
@ -100,7 +103,8 @@ template<class T> class Complex {
* @brief Create complex number from rotation matrix
*
* Expects that the matrix is orthogonal (i.e. pure rotation).
* @see toMatrix(), DualComplex::fromMatrix(), Matrix::isOrthogonal()
* @see @ref toMatrix(), @ref DualComplex::fromMatrix(),
* @ref Matrix::isOrthogonal()
*/
static Complex<T> fromMatrix(const Matrix<2, T>& matrix) {
CORRADE_ASSERT(matrix.isOrthogonal(),
@ -132,7 +136,8 @@ template<class T> class Complex {
* To be used in transformations later. @f[
* c = v_x + iv_y
* @f]
* @see operator Vector2(), transformVector()
* @see operator Vector2(), @ref transformVector()
* @todoc Explicit reference when Doxygen can handle conversion operators
*/
constexpr explicit Complex(const Vector2<T>& vector): _real(vector.x()), _imaginary(vector.y()) {}
@ -153,7 +158,7 @@ template<class T> class Complex {
* Complex number is normalized if it has unit length: @f[
* |c \cdot c - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon
* @f]
* @see dot(), normalized()
* @see @ref dot(), @ref normalized()
*/
bool isNormalized() const {
return Implementation::isNormalizedSquared(dot());
@ -186,7 +191,7 @@ template<class T> class Complex {
* @f[
* \theta = atan2(b, a)
* @f]
* @see rotation()
* @see @ref rotation()
*/
Rad<T> angle() const {
return Rad<T>(std::atan2(_imaginary, _real));
@ -201,8 +206,8 @@ template<class T> class Complex {
* b & a
* \end{pmatrix}
* @f]
* @see fromMatrix(), DualComplex::toMatrix(),
* Matrix3::from(const Matrix<2, T>&, const Vector2<T>&)
* @see @ref fromMatrix(), @ref DualComplex::toMatrix(),
* @ref Matrix3::from(const Matrix<2, T>&, const Vector2<T>&)
*/
Matrix<2, T> toMatrix() const {
return {Vector<2, T>(_real, _imaginary),
@ -225,7 +230,7 @@ template<class T> class Complex {
/**
* @brief Add complex number
*
* @see operator+=()
* @see @ref operator+=(const Complex<T>&)
*/
Complex<T> operator+(const Complex<T>& other) const {
return Complex<T>(*this) += other;
@ -258,7 +263,7 @@ template<class T> class Complex {
/**
* @brief Subtract complex number
*
* @see operator-=()
* @see @ref operator-=(const Complex<T>&)
*/
Complex<T> operator-(const Complex<T>& other) const {
return Complex<T>(*this) -= other;
@ -280,7 +285,7 @@ template<class T> class Complex {
/**
* @brief Multiply with scalar
*
* @see operator*=(T)
* @see @ref operator*=(T)
*/
Complex<T> operator*(T scalar) const {
return Complex<T>(*this) *= scalar;
@ -302,7 +307,7 @@ template<class T> class Complex {
/**
* @brief Divide with scalar
*
* @see operator/=(T)
* @see @ref operator/=(T)
*/
Complex<T> operator/(T scalar) const {
return Complex<T>(*this) /= scalar;
@ -323,11 +328,12 @@ template<class T> class Complex {
/**
* @brief Dot product of the complex number
*
* Should be used instead of length() for comparing complex number length
* with other values, because it doesn't compute the square root. @f[
* Should be used instead of @ref length() for comparing complex number
* length with other values, because it doesn't compute the square
* root. @f[
* c \cdot c = a^2 + b^2
* @f]
* @see dot(const Complex&, const Complex&), isNormalized()
* @see @ref dot(const Complex&, const Complex&), @ref isNormalized()
*/
T dot() const {
return dot(*this, *this);
@ -336,11 +342,11 @@ template<class T> class Complex {
/**
* @brief %Complex number length
*
* See also dot() const which is faster for comparing length with other
* values. @f[
* See also @ref dot() const which is faster for comparing length with
* other values. @f[
* |c| = \sqrt{c \cdot c}
* @f]
* @see isNormalized()
* @see @ref isNormalized()
*/
T length() const {
/** @todo Remove when newlib has this fixed */
@ -354,7 +360,7 @@ template<class T> class Complex {
/**
* @brief Normalized complex number (of unit length)
*
* @see isNormalized()
* @see @ref isNormalized()
*/
Complex<T> normalized() const {
return (*this)/length();
@ -374,7 +380,7 @@ template<class T> class Complex {
/**
* @brief Inverted complex number
*
* See invertedNormalized() which is faster for normalized
* See @ref invertedNormalized() which is faster for normalized
* complex numbers. @f[
* c^{-1} = \frac{c^*}{|c|^2} = \frac{c^*}{c \cdot c}
* @f]
@ -386,11 +392,11 @@ template<class T> class Complex {
/**
* @brief Inverted normalized complex number
*
* Equivalent to conjugated(). Expects that the complex number is
* Equivalent to @ref conjugated(). Expects that the complex number is
* normalized. @f[
* c^{-1} = \frac{c^*}{c \cdot c} = c^*
* @f]
* @see isNormalized(), inverted()
* @see @ref isNormalized(), @ref inverted()
*/
Complex<T> invertedNormalized() const {
CORRADE_ASSERT(isNormalized(),
@ -405,7 +411,9 @@ template<class T> class Complex {
* @f[
* v' = c v = c (v_x + iv_y)
* @f]
* @see Complex(const Vector2&), operator Vector2(), Matrix3::transformVector()
* @see @ref Complex(const Vector2<T>&), operator Vector2(),
* @ref Matrix3::transformVector()
* @todoc Explicit reference when Doxygen can handle conversion operators
*/
Vector2<T> transformVector(const Vector2<T>& vector) const {
return Vector2<T>((*this)*Complex<T>(vector));
@ -418,7 +426,7 @@ template<class T> class Complex {
/** @relates Complex
@brief Multiply scalar with complex
Same as Complex::operator*(T) const.
Same as @ref Complex::operator*(T) const.
*/
template<class T> inline Complex<T> operator*(T scalar, const Complex<T>& complex) {
return complex*scalar;
@ -430,7 +438,7 @@ template<class T> inline Complex<T> operator*(T scalar, const Complex<T>& comple
@f[
\frac t c = \frac t a + i \frac t b
@f]
@see Complex::operator/()
@see @ref Complex::operator/()
*/
template<class T> inline Complex<T> operator/(T scalar, const Complex<T>& complex) {
return {scalar/complex.real(), scalar/complex.imaginary()};

6
src/Magnum/Math/Constants.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Constants
* @brief Class @ref Magnum::Math::Constants
*/
#include "Magnum/Types.h"
@ -36,7 +36,7 @@ namespace Magnum { namespace Math {
/**
@brief Numeric constants
@see Magnum::Constants, Magnum::Constantsd
@see @ref Magnum::Constants, @ref Magnum::Constantsd
*/
template<class T> struct Constants {
Constants() = delete;
@ -46,7 +46,7 @@ template<class T> struct Constants {
/**
* @brief Pi
*
* @see Deg, Rad
* @see @ref Deg, @ref Rad
*/
static constexpr T pi();

8
src/Magnum/Math/Dual.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Dual
* @brief Class @ref Magnum::Math::Dual
*/
#include <cmath>
@ -95,7 +95,7 @@ template<class T> class Dual {
/**
* @brief Add dual number
*
* @see operator+=()
* @see @ref operator+=()
*/
Dual<T> operator+(const Dual<T>& other) const {
return Dual<T>(*this)+=other;
@ -128,7 +128,7 @@ template<class T> class Dual {
/**
* @brief Subtract dual number
*
* @see operator-=()
* @see @ref operator-=()
*/
Dual<T> operator-(const Dual<T>& other) const {
return Dual<T>(*this)-=other;
@ -213,7 +213,7 @@ template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug deb
@f[
\sqrt{\hat a} = \sqrt{a_0} + \epsilon \frac{a_\epsilon}{2 \sqrt{a_0}}
@f]
@see Math::sqrt(const T&)
@see @ref Math::sqrt(const T&)
*/
template<class T> Dual<T> sqrt(const Dual<T>& dual) {
T sqrt0 = std::sqrt(dual.real());

49
src/Magnum/Math/DualComplex.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::DualComplex
* @brief Class @ref Magnum::Math::DualComplex
*/
#include "Magnum/Math/Complex.h"
@ -41,7 +41,8 @@ namespace Magnum { namespace Math {
Represents 2D rotation and translation. See @ref transformations for brief
introduction.
@see Magnum::DualComplex, Magnum::DualComplexd, Dual, Complex, Matrix3
@see @ref Magnum::DualComplex, @ref Magnum::DualComplexd, @ref Dual,
@ref Complex, @ref Matrix3
@todo Can this be done similarly as in dual quaternions? It sort of works, but
the math beneath is weird.
*/
@ -56,8 +57,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[
* \hat c = (cos \theta + i sin \theta) + \epsilon (0 + i0)
* @f]
* @see angle(), Complex::rotation(), Matrix3::rotation(),
* DualQuaternion::rotation()
* @see @ref Complex::rotation(), @ref Matrix3::rotation(),
* @ref DualQuaternion::rotation()
*/
static DualComplex<T> rotation(Rad<T> angle) {
return {Complex<T>::rotation(angle), {{}, {}}};
@ -70,8 +71,11 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[
* \hat c = (0 + i1) + \epsilon (v_x + iv_y)
* @f]
* @see translation() const, Matrix3::translation(const Vector2&),
* DualQuaternion::translation(), Vector2::xAxis(), Vector2::yAxis()
* @see translation() const,
* @ref Matrix3::translation(const Vector2<T>&),
* @ref DualQuaternion::translation(), @ref Vector2::xAxis(),
* @ref Vector2::yAxis()
* @todoc Explicit reference when Doxygen can handle const
*/
static DualComplex<T> translation(const Vector2<T>& vector) {
return {{}, {vector.x(), vector.y()}};
@ -81,8 +85,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @brief Create dual complex number from rotation matrix
*
* Expects that the matrix represents rigid transformation.
* @see toMatrix(), Complex::fromMatrix(),
* Matrix3::isRigidTransformation()
* @see @ref toMatrix(), @ref Complex::fromMatrix(),
* @ref Matrix3::isRigidTransformation()
*/
static DualComplex<T> fromMatrix(const Matrix3<T>& matrix) {
CORRADE_ASSERT(matrix.isRigidTransformation(),
@ -96,7 +100,6 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* Creates unit dual complex number. @f[
* \hat c = (0 + i1) + \epsilon (0 + i0)
* @f]
* @todoc Remove workaround when Doxygen is predictable
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
constexpr /*implicit*/ DualComplex();
@ -119,7 +122,6 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* To be used in transformations later. @f[
* \hat c = (0 + i1) + \epsilon(v_x + iv_y)
* @f]
* @todoc Remove workaround when Doxygen is predictable
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
constexpr explicit DualComplex(const Vector2<T>& vector);
@ -136,7 +138,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* Dual complex number is normalized if its real part has unit length: @f[
* |c_0|^2 = |c_0| = 1
* @f]
* @see Complex::dot(), normalized()
* @see @ref Complex::dot(), @ref normalized()
* @todoc Improve the equation as in Complex::isNormalized()
*/
bool isNormalized() const {
@ -146,7 +148,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
/**
* @brief Rotation part of dual complex number
*
* @see Complex::angle()
* @see @ref Complex::angle()
*/
constexpr Complex<T> rotation() const {
return Dual<Complex<T>>::real();
@ -158,7 +160,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[
* \boldsymbol a = (c_\epsilon c_0^*)
* @f]
* @see translation(const Vector2&)
* @see @ref translation(const Vector2<T>&)
*/
Vector2<T> translation() const {
return Vector2<T>(Dual<Complex<T>>::dual());
@ -167,7 +169,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
/**
* @brief Convert dual complex number to transformation matrix
*
* @see fromMatrix(), Complex::toMatrix()
* @see @ref fromMatrix(), @ref Complex::toMatrix()
*/
Matrix3<T> toMatrix() const {
return Matrix3<T>::from(Dual<Complex<T>>::real().toMatrix(), translation());
@ -191,7 +193,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[
* \hat c^* = c^*_0 + c^*_\epsilon
* @f]
* @see dualConjugated(), conjugated(), Complex::conjugated()
* @see @ref dualConjugated(), @ref conjugated(),
* @ref Complex::conjugated()
*/
DualComplex<T> complexConjugated() const {
return {Dual<Complex<T>>::real().conjugated(), Dual<Complex<T>>::dual().conjugated()};
@ -203,7 +206,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[
* \overline{\hat c} = c_0 - \epsilon c_\epsilon
* @f]
* @see complexConjugated(), conjugated(), Dual::conjugated()
* @see @ref complexConjugated(), @ref conjugated(),
* @ref Dual::conjugated()
*/
DualComplex<T> dualConjugated() const {
return Dual<Complex<T>>::conjugated();
@ -215,8 +219,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* Both complex and dual conjugation. @f[
* \overline{\hat c^*} = c^*_0 - \epsilon c^*_\epsilon = c^*_0 + \epsilon(-a_\epsilon + ib_\epsilon)
* @f]
* @see complexConjugated(), dualConjugated(), Complex::conjugated(),
* Dual::conjugated()
* @see @ref complexConjugated(), @ref dualConjugated(),
* @ref Complex::conjugated(), @ref Dual::conjugated()
*/
DualComplex<T> conjugated() const {
return {Dual<Complex<T>>::real().conjugated(), {-Dual<Complex<T>>::dual().real(), Dual<Complex<T>>::dual().imaginary()}};
@ -254,7 +258,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[
* c' = \frac{c_0}{|c_0|}
* @f]
* @see isNormalized()
* @see @ref isNormalized()
* @todo can this be done similarly to dual quaternions?
*/
DualComplex<T> normalized() const {
@ -280,7 +284,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* Expects that the complex number is normalized. @f[
* \hat c^{-1} = c_0^{-1} - \epsilon c_\epsilon = c_0^* - \epsilon c_\epsilon
* @f]
* @see isNormalized(), inverted()
* @see @ref isNormalized(), @ref inverted()
* @todo can this be done similarly to dual quaternions?
*/
DualComplex<T> invertedNormalized() const {
@ -294,8 +298,9 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* complex number. @f[
* v' = \hat c v = \hat c ((0 + i) + \epsilon(v_x + iv_y))
* @f]
* @see DualComplex(const Vector2&), dual(), Matrix3::transformPoint(),
* Complex::transformVector(), DualQuaternion::transformPoint()
* @see @ref DualComplex(const Vector2<T>&), @ref dual(),
* @ref Matrix3::transformPoint(), @ref Complex::transformVector(),
* @ref DualQuaternion::transformPoint()
*/
Vector2<T> transformPoint(const Vector2<T>& vector) const {
return Vector2<T>(((*this)*DualComplex<T>(vector)).dual());

83
src/Magnum/Math/DualQuaternion.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::DualQuaternion
* @brief Class @ref Magnum::Math::DualQuaternion
*/
#include "Magnum/Math/Dual.h"
@ -41,7 +41,8 @@ namespace Magnum { namespace Math {
Represents 3D rotation and translation. See @ref transformations for brief
introduction.
@see Magnum::DualQuaternion, Magnum::DualQuaterniond, Dual, Quaternion, Matrix4
@see @ref Magnum::DualQuaternion, @ref Magnum::DualQuaterniond, @ref Dual,
@ref Quaternion, @ref Matrix4
*/
template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
public:
@ -55,9 +56,11 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* Expects that the rotation axis is normalized. @f[
* \hat q = [\boldsymbol a \cdot sin \frac \theta 2, cos \frac \theta 2] + \epsilon [\boldsymbol 0, 0]
* @f]
* @see rotation() const, Quaternion::rotation(), Matrix4::rotation(),
* DualComplex::rotation(), Vector3::xAxis(), Vector3::yAxis(),
* Vector3::zAxis(), Vector::isNormalized()
* @see rotation() const, @ref Quaternion::rotation(),
* @ref Matrix4::rotation(), @ref DualComplex::rotation(),
* @ref Vector3::xAxis(), @ref Vector3::yAxis(),
* @ref Vector3::zAxis(), @ref Vector::isNormalized()
* @todoc Explicit reference when Doxygen can handle const
*/
static DualQuaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) {
return {Quaternion<T>::rotation(angle, normalizedAxis), {{}, T(0)}};
@ -72,9 +75,11 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f[
* \hat q = [\boldsymbol 0, 1] + \epsilon [\frac{\boldsymbol v}{2}, 0]
* @f]
* @see translation() const, Matrix4::translation(const Vector3&),
* DualComplex::translation(), Vector3::xAxis(), Vector3::yAxis(),
* Vector3::zAxis()
* @see translation() const,
* @ref Matrix4::translation(const Vector3<T>&),
* @ref DualComplex::translation(), @ref Vector3::xAxis(),
* @ref Vector3::yAxis(), @ref Vector3::zAxis()
* @todoc Explicit reference when Doxygen can handle const
*/
static DualQuaternion<T> translation(const Vector3<T>& vector) {
return {{}, {vector/T(2), T(0)}};
@ -84,8 +89,8 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @brief Create dual quaternion from transformation matrix
*
* Expects that the matrix represents rigid transformation.
* @see toMatrix(), Quaternion::fromMatrix(),
* Matrix4::isRigidTransformation()
* @see @ref toMatrix(), @ref Quaternion::fromMatrix(),
* @ref Matrix4::isRigidTransformation()
*/
static DualQuaternion<T> fromMatrix(const Matrix4<T>& matrix) {
CORRADE_ASSERT(matrix.isRigidTransformation(),
@ -101,7 +106,6 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* Creates unit dual quaternion. @f[
* \hat q = [\boldsymbol 0, 1] + \epsilon [\boldsymbol 0, 0]
* @f]
* @todoc Remove workaround when Doxygen is predictable
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
constexpr /*implicit*/ DualQuaternion();
@ -124,8 +128,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* To be used in transformations later. @f[
* \hat q = [\boldsymbol 0, 1] + \epsilon [\boldsymbol v, 0]
* @f]
* @see transformPointNormalized()
* @todoc Remove workaround when Doxygen is predictable
* @see @ref transformPointNormalized()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
constexpr explicit DualQuaternion(const Vector3<T>& vector);
@ -142,7 +145,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* Dual quaternion is normalized if it has unit length: @f[
* |\hat q|^2 = |\hat q| = 1 + \epsilon 0
* @f]
* @see lengthSquared(), normalized()
* @see @ref lengthSquared(), @ref normalized()
* @todoc Improve the equation as in Quaternion::isNormalized()
*/
bool isNormalized() const {
@ -156,7 +159,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/**
* @brief Rotation part of unit dual quaternion
*
* @see Quaternion::angle(), Quaternion::axis()
* @see @ref Quaternion::angle(), @ref Quaternion::axis()
*/
constexpr Quaternion<T> rotation() const {
return Dual<Quaternion<T>>::real();
@ -168,7 +171,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f[
* \boldsymbol a = 2 (q_\epsilon q_0^*)_V
* @f]
* @see translation(const Vector3&)
* @see @ref translation(const Vector3<T>&)
*/
Vector3<T> translation() const {
return (Dual<Quaternion<T>>::dual()*Dual<Quaternion<T>>::real().conjugated()).vector()*T(2);
@ -177,7 +180,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/**
* @brief Convert dual quaternion to transformation matrix
*
* @see fromMatrix(), Quaternion::toMatrix()
* @see @ref fromMatrix(), @ref Quaternion::toMatrix()
*/
Matrix4<T> toMatrix() const {
return Matrix4<T>::from(Dual<Quaternion<T>>::real().toMatrix(), translation());
@ -189,7 +192,8 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f[
* \hat q^* = q_0^* + q_\epsilon^*
* @f]
* @see dualConjugated(), conjugated(), Quaternion::conjugated()
* @see @ref dualConjugated(), @ref conjugated(),
* @ref Quaternion::conjugated()
*/
DualQuaternion<T> quaternionConjugated() const {
return {Dual<Quaternion<T>>::real().conjugated(), Dual<Quaternion<T>>::dual().conjugated()};
@ -201,7 +205,8 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f[
* \overline{\hat q} = q_0 - \epsilon q_\epsilon
* @f]
* @see quaternionConjugated(), conjugated(), Dual::conjugated()
* @see @ref quaternionConjugated(), @ref conjugated(),
* @ref Dual::conjugated()
*/
DualQuaternion<T> dualConjugated() const {
return Dual<Quaternion<T>>::conjugated();
@ -213,8 +218,8 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* Both quaternion and dual conjugation. @f[
* \overline{\hat q^*} = q_0^* - \epsilon q_\epsilon^* = q_0^* + \epsilon [\boldsymbol q_{V \epsilon}, -q_{S \epsilon}]
* @f]
* @see quaternionConjugated(), dualConjugated(), Quaternion::conjugated(),
* Dual::conjugated()
* @see @ref quaternionConjugated(), @ref dualConjugated(),
* @ref Quaternion::conjugated(), @ref Dual::conjugated()
*/
DualQuaternion<T> conjugated() const {
return {Dual<Quaternion<T>>::real().conjugated(), {Dual<Quaternion<T>>::dual().vector(), -Dual<Quaternion<T>>::dual().scalar()}};
@ -223,8 +228,9 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/**
* @brief %Dual quaternion length squared
*
* Should be used instead of length() for comparing dual quaternion
* length with other values, because it doesn't compute the square root. @f[
* Should be used instead of @ref length() for comparing dual
* quaternion length with other values, because it doesn't compute the
* square root. @f[
* |\hat q|^2 = \sqrt{\hat q^* \hat q}^2 = q_0 \cdot q_0 + \epsilon 2 (q_0 \cdot q_\epsilon)
* @f]
*/
@ -235,7 +241,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/**
* @brief %Dual quaternion length
*
* See lengthSquared() which is faster for comparing length with other
* See @ref lengthSquared() which is faster for comparing length with other
* values. @f[
* |\hat q| = \sqrt{\hat q^* \hat q} = |q_0| + \epsilon \frac{q_0 \cdot q_\epsilon}{|q_0|}
* @f]
@ -247,7 +253,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/**
* @brief Normalized dual quaternion (of unit length)
*
* @see isNormalized()
* @see @ref isNormalized()
*/
DualQuaternion<T> normalized() const {
return (*this)/length();
@ -256,7 +262,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/**
* @brief Inverted dual quaternion
*
* See invertedNormalized() which is faster for normalized dual
* See @ref invertedNormalized() which is faster for normalized dual
* quaternions. @f[
* \hat q^{-1} = \frac{\hat q^*}{|\hat q|^2}
* @f]
@ -268,11 +274,11 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/**
* @brief Inverted normalized dual quaternion
*
* Equivalent to quaternionConjugated(). Expects that the quaternion is
* normalized. @f[
* Equivalent to @ref quaternionConjugated(). Expects that the
* quaternion is normalized. @f[
* \hat q^{-1} = \frac{\hat q^*}{|\hat q|^2} = \hat q^*
* @f]
* @see isNormalized(), inverted()
* @see @ref isNormalized(), @ref inverted()
*/
DualQuaternion<T> invertedNormalized() const {
CORRADE_ASSERT(isNormalized(),
@ -283,12 +289,14 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/**
* @brief Rotate and translate point with dual quaternion
*
* See transformPointNormalized(), which is faster for normalized dual
* quaternions. @f[
* See @ref transformPointNormalized(), which is faster for normalized
* dual quaternions. @f[
* v' = \hat q v \overline{\hat q^{-1}} = \hat q ([\boldsymbol 0, 1] + \epsilon [\boldsymbol v, 0]) \overline{\hat q^{-1}}
* @f]
* @see DualQuaternion(const Vector3&), dual(), Matrix4::transformPoint(),
* Quaternion::transformVector(), DualComplex::transformPoint()
* @see @ref DualQuaternion(const Vector3<T>&), @ref dual(),
* @ref Matrix4::transformPoint(),
* @ref Quaternion::transformVector(),
* @ref DualComplex::transformPoint()
*/
Vector3<T> transformPoint(const Vector3<T>& vector) const {
return ((*this)*DualQuaternion<T>(vector)*inverted().dualConjugated()).dual().vector();
@ -297,13 +305,14 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/**
* @brief Rotate and translate point with normalized dual quaternion
*
* Faster alternative to transformPoint(), expects that the dual
* Faster alternative to @ref transformPoint(), expects that the dual
* quaternion is normalized. @f[
* v' = \hat q v \overline{\hat q^{-1}} = \hat q v \overline{\hat q^*} = \hat q ([\boldsymbol 0, 1] + \epsilon [\boldsymbol v, 0]) \overline{\hat q^*}
* @f]
* @see isNormalized(), DualQuaternion(const Vector3&), dual(),
* Matrix4::transformPoint(), Quaternion::transformVectorNormalized(),
* DualComplex::transformPointNormalized()
* @see @ref isNormalized(), @ref DualQuaternion(const Vector3<T>&),
* @ref dual(), @ref Matrix4::transformPoint(),
* @ref Quaternion::transformVectorNormalized(),
* @ref DualComplex::transformPoint()
*/
Vector3<T> transformPointNormalized(const Vector3<T>& vector) const {
CORRADE_ASSERT(isNormalized(),

14
src/Magnum/Math/Functions.h

@ -68,7 +68,7 @@ template<UnsignedInt exponent, class T> constexpr T pow(T base) {
* @brief Base-2 integral logarithm
*
* Returns integral logarithm of given number with base `2`.
* @see log()
* @see @ref log()
*/
UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number);
@ -76,7 +76,7 @@ UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number);
* @brief Integral logarithm
*
* Returns integral logarithm of given number with given base.
* @see log2()
* @see @ref log2()
*/
UnsignedInt MAGNUM_EXPORT log(UnsignedInt base, UnsignedInt number);
@ -290,7 +290,7 @@ template<std::size_t size, class T> Vector<size, T> ceil(const Vector<size, T>&
/**
@brief Square root
@see sqrtInverted(), Vector::length()
@see @ref sqrtInverted(), @ref Vector::length()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T sqrt(const T& a);
@ -309,7 +309,7 @@ template<std::size_t size, class T> Vector<size, T> sqrt(const Vector<size, T>&
/**
@brief Inverse square root
@see sqrt(), Vector::lengthInverted()
@see @ref sqrt(), @ref Vector::lengthInverted()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T sqrtInverted(const T& a);
@ -327,7 +327,7 @@ template<std::size_t size, class T> Vector<size, T> sqrtInverted(const Vector<si
Values smaller than @p min are set to @p min, values larger than @p max are
set to @p max.
@see min(), max()
@see @ref min(), @ref max()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T, class U> inline T clamp(const T& value, U min, U max);
@ -352,7 +352,7 @@ template<std::size_t size, class T> Vector<size, T> clamp(const Vector<size, T>&
The interpolation for vectors is done as in following, similarly for scalars: @f[
\boldsymbol v_{LERP} = (1 - t) \boldsymbol v_A + t \boldsymbol v_B
@f]
@see lerpInverted(), Quaternion::lerp()
@see @ref lerpInverted(), @ref Quaternion::lerp()
@todo http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
(when SIMD is in place)
*/
@ -376,7 +376,7 @@ template<std::size_t size, class T, class U> inline Vector<size, T> lerp(const V
Returns interpolation phase *t*: @f[
t = \frac{\boldsymbol v_{LERP} - \boldsymbol v_A}{\boldsymbol v_B - \boldsymbol v_A}
@f]
@see lerp()
@see @ref lerp()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T lerpInverted(const T& a, const T& b, const T& lerp);

53
src/Magnum/Math/Geometry/Distance.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Geometry::Distance
* @brief Class @ref Magnum::Math::Geometry::Distance
*/
#include "Magnum/Math/Functions.h"
@ -50,7 +50,7 @@ class Distance {
* d = \frac{|(\boldsymbol b - \boldsymbol a)_\bot \cdot (\boldsymbol a - \boldsymbol p)|} {|\boldsymbol b - \boldsymbol a|}
* @f]
* Source: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
* @see linePointSquared(const Vector2&, const Vector2&, const Vector2&)
* @see @ref linePointSquared(const Vector2<T>&, const Vector2<T>&, const Vector2<T>&)
*/
template<class T> static T linePoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
const Vector2<T> bMinusA = b - a;
@ -63,7 +63,8 @@ class Distance {
* @param b Second point of the line
* @param point Point
*
* More efficient than linePoint(const Vector2&, const Vector2&, const Vector2&)
* More efficient than
* @ref linePoint(const Vector2<T>&, const Vector2<T>&, const Vector2<T>&)
* for comparing distance with other values, because it doesn't
* compute the square root.
*/
@ -84,7 +85,7 @@ class Distance {
* {|\boldsymbol b - \boldsymbol a|}
* @f]
* Source: http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
* @see linePointSquared(const Vector3&, const Vector3&, const Vector3&)
* @see @ref linePointSquared(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&)
*/
template<class T> static T linePoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
return std::sqrt(linePointSquared(a, b, point));
@ -93,7 +94,7 @@ class Distance {
/**
* @brief %Distance of line and point in 3D, squared
*
* More efficient than linePoint(const Vector3&, const Vector3&, const Vector3&)
* More efficient than @ref linePoint(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&)
* for comparing distance with other values, because it doesn't
* compute the square root.
*/
@ -121,19 +122,19 @@ class Distance {
* @f]
* The last alternative is when the following equation applies. The
* point then lies between **a** and **b** and the distance is
* computed the same way as in linePoint(). @f[
* computed the same way as in @ref linePoint(). @f[
* |\boldsymbol b - \boldsymbol a|^2 > |\boldsymbol p - \boldsymbol a|^2 + |\boldsymbol p - \boldsymbol b|^2
* @f]
*
* @see lineSegmentPointSquared()
* @see @ref lineSegmentPointSquared()
*/
template<class T> static T lineSegmentPoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point);
/**
* @brief %Distance of point from line segment in 2D, squared
*
* More efficient than lineSegmentPoint() for comparing distance with
* other values, because it doesn't compute the square root.
* More efficient than @ref lineSegmentPoint() for comparing distance
* with other values, because it doesn't compute the square root.
*/
template<class T> static T lineSegmentPointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point);
@ -144,9 +145,9 @@ class Distance {
* @param point Point
*
* Similar to 2D implementation
* lineSegmentPoint(const Vector2&, const Vector2&, const Vector2&).
* @ref lineSegmentPoint(const Vector2<T>&, const Vector2<T>&, const Vector2<T>&).
*
* @see lineSegmentPointSquared(const Vector3&, const Vector3&, const Vector3&)
* @see @ref lineSegmentPointSquared(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&)
*/
template<class T> static T lineSegmentPoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
return std::sqrt(lineSegmentPointSquared(a, b, point));
@ -155,19 +156,15 @@ class Distance {
/**
* @brief %Distance of point from line segment in 3D, squared
*
* More efficient than lineSegmentPoint(const Vector3&, const Vector3&, const Vector3&) for comparing distance with
* other values, because it doesn't compute the square root.
* More efficient than
* @ref lineSegmentPoint(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&)
* for comparing distance with other values, because it doesn't compute
* the square root.
*/
template<class T> static T lineSegmentPointSquared(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point);
};
/** @todoc Remove workaround when Doxygen is sane */
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> static
#else
template<class T>
#endif
T Distance::lineSegmentPoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
template<class T> T Distance::lineSegmentPoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
const Vector2<T> pointMinusA = point - a;
const Vector2<T> pointMinusB = point - b;
const Vector2<T> bMinusA = b - a;
@ -187,13 +184,7 @@ T Distance::lineSegmentPoint(const Vector2<T>& a, const Vector2<T>& b, const Vec
return std::abs(Vector2<T>::cross(bMinusA, -pointMinusA))/std::sqrt(bDistanceA);
}
/** @todoc Remove workaround when Doxygen is sane */
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> static
#else
template<class T>
#endif
T Distance::lineSegmentPointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
template<class T> T Distance::lineSegmentPointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
const Vector2<T> pointMinusA = point - a;
const Vector2<T> pointMinusB = point - b;
const Vector2<T> bMinusA = b - a;
@ -213,13 +204,7 @@ T Distance::lineSegmentPointSquared(const Vector2<T>& a, const Vector2<T>& b, co
return Math::pow<2>(Vector2<T>::cross(bMinusA, -pointMinusA))/bDistanceA;
}
/** @todoc Remove workaround when Doxygen is sane */
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> static
#else
template<class T>
#endif
T Distance::lineSegmentPointSquared(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
template<class T> T Distance::lineSegmentPointSquared(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
const Vector3<T> pointMinusA = point - a;
const Vector3<T> pointMinusB = point - b;
const T pointDistanceA = pointMinusA.dot();

6
src/Magnum/Math/Geometry/Intersection.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Geometry::Intersection
* @brief Class @ref Magnum::Math::Geometry::Intersection
*/
#include "Magnum/Math/Vector3.h"
@ -66,7 +66,7 @@ class Intersection {
* \end{array}
* @f]
*
* See also lineSegmentLine() which computes only **t**, which is
* See also @ref lineSegmentLine() which computes only **t**, which is
* useful if you don't need to test that the intersection lies inside
* line segment defined by `q` and `q + s`.
*/
@ -89,7 +89,7 @@ class Intersection {
* value is in range @f$ [ 0 ; 1 ] @f$, the intersection is inside
* the line segment defined by `p` and `p + r`.
*
* Unlike lineSegmentLineSegment() computes only **t**.
* Unlike @ref lineSegmentLineSegment() computes only **t**.
*/
template<class T> static T lineSegmentLine(const Vector2<T>& p, const Vector2<T>& r, const Vector2<T>& q, const Vector2<T>& s) {
return Vector2<T>::cross(q - p, s)/Vector2<T>::cross(r, s);

2
src/Magnum/Math/Math.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Forward declarations for Magnum::Math namespace
* @brief Forward declarations for @ref Magnum::Math namespace
*/
#include <cstddef>

26
src/Magnum/Math/Matrix.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Matrix
* @brief Class @ref Magnum::Math::Matrix, typedef @ref Magnum::Math::Matrix2x2, @ref Magnum::Math::Matrix3x3, @ref Magnum::Math::Matrix4x4
*/
#include "Magnum/Math/RectangularMatrix.h"
@ -57,7 +57,7 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
/**
* @brief Zero-filled matrix constructor
*
* Use this constructor by calling `Matrix m(Matrix::Zero);`.
* Use this constructor by calling `%Matrix m(Matrix::Zero);`.
*/
constexpr explicit Matrix(ZeroType) {}
@ -68,7 +68,7 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* @brief Default constructor
*
* You can also explicitly call this constructor with
* `Matrix m(Matrix::Identity);`. Optional parameter @p value allows
* `%Matrix m(Matrix::Identity);`. Optional parameter @p value allows
* you to specify value on diagonal.
*/
constexpr /*implicit*/ Matrix(IdentityType = Identity, T value = T(1)): RectangularMatrix<size, size, T>(typename Implementation::GenerateSequence<size>::Type(),
@ -117,8 +117,9 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* The matrix is orthogonal if its transpose is equal to its inverse: @f[
* Q^T = Q^{-1}
* @f]
* @see transposed(), inverted(), Matrix3::isRigidTransformation(),
* Matrix4::isRigidTransformation()
* @see @ref transposed(), @ref inverted(),
* @ref Matrix3::isRigidTransformation(),
* @ref Matrix4::isRigidTransformation()
*/
bool isOrthogonal() const;
@ -140,7 +141,7 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* Computed recursively using Laplace's formula: @f[
* \det(A) = \sum_{j=1}^n (-1)^{i+j} a_{i,j} \det(A^{i,j})
* @f] @f$ A^{i, j} @f$ is matrix without i-th row and j-th column, see
* ij(). The formula is expanded down to 2x2 matrix, where the
* @ref ij(). The formula is expanded down to 2x2 matrix, where the
* determinant is computed directly: @f[
* \det(A) = a_{0, 0} a_{1, 1} - a_{1, 0} a_{0, 1}
* @f]
@ -153,19 +154,22 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* Computed using Cramer's rule: @f[
* A^{-1} = \frac{1}{\det(A)} Adj(A)
* @f]
* See invertedOrthogonal(), Matrix3::invertedRigid() and Matrix4::invertedRigid()
* which are faster alternatives for particular matrix types.
* See @ref invertedOrthogonal(), @ref Matrix3::invertedRigid() and
* @ref Matrix4::invertedRigid() which are faster alternatives for
* particular matrix types.
*/
Matrix<size, T> inverted() const;
/**
* @brief Inverted orthogonal matrix
*
* Equivalent to transposed(), expects that the matrix is orthogonal. @f[
* Equivalent to @ref transposed(), expects that the matrix is
* orthogonal. @f[
* A^{-1} = A^T
* @f]
* @see inverted(), isOrthogonal(), Matrix3::invertedRigid(),
* Matrix4::invertedRigid()
* @see @ref inverted(), @ref isOrthogonal(),
* @ref Matrix3::invertedRigid(),
* @ref Matrix4::invertedRigid()
*/
Matrix<size, T> invertedOrthogonal() const {
CORRADE_ASSERT(isOrthogonal(),

97
src/Magnum/Math/Matrix3.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Matrix3
* @brief Class @ref Magnum::Math::Matrix3
*/
#include "Magnum/Math/Matrix.h"
@ -35,13 +35,12 @@
namespace Magnum { namespace Math {
/**
@brief 3x3 matrix
@brief 2D transformation matrix
@tparam T Underlying data type
Represents 2D transformation. See @ref matrix-vector and @ref transformations
for brief introduction.
@see Magnum::Matrix3, Magnum::Matrix3d, DualComplex,
SceneGraph::MatrixTransformation2D
See @ref matrix-vector and @ref transformations for brief introduction.
@see @ref Magnum::Matrix3, @ref Magnum::Matrix3d, @ref Matrix3x3,
@ref DualComplex, @ref SceneGraph::MatrixTransformation2D
@configurationvalueref{Magnum::Math::Matrix3}
*/
template<class T> class Matrix3: public Matrix<3, T> {
@ -50,9 +49,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D translation matrix
* @param vector Translation vector
*
* @see translation(), DualComplex::translation(),
* Matrix4::translation(const Vector3&), Vector2::xAxis(),
* Vector2::yAxis()
* @see translation() const, @ref DualComplex::translation(),
* @ref Matrix4::translation(const Vector3<T>&),
* @ref Vector2::xAxis(), @ref Vector2::yAxis()
* @todoc Explicit reference when Doxygen can handle const
*/
constexpr static Matrix3<T> translation(const Vector2<T>& vector) {
return {{ T(1), T(0), T(0)},
@ -64,8 +64,9 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D scaling matrix
* @param vector Scaling vector
*
* @see rotationScaling() const, Matrix4::scaling(const Vector3&),
* Vector2::xScale(), Vector2::yScale()
* @see @ref rotationScaling(),
* @ref Matrix4::scaling(const Vector3<T>&),
* @ref Vector2::xScale(), @ref Vector2::yScale()
*/
constexpr static Matrix3<T> scaling(const Vector2<T>& vector) {
return {{vector.x(), T(0), T(0)},
@ -77,8 +78,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D rotation matrix
* @param angle Rotation angle (counterclockwise)
*
* @see rotation() const, Complex::rotation(), DualComplex::rotation(),
* Matrix4::rotation(Rad, const Vector3&)
* @see rotation() const, @ref Complex::rotation(),
* @ref DualComplex::rotation(),
* @ref Matrix4::rotation(Rad, const Vector3<T>&)
* @todoc Explicit reference when Doxygen can handle const
*/
static Matrix3<T> rotation(Rad<T> angle);
@ -87,7 +90,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @param normal Normal of the line through which to reflect
*
* Expects that the normal is normalized.
* @see Matrix4::reflection(), Vector::isNormalized()
* @see @ref Matrix4::reflection(), @ref Vector::isNormalized()
*/
static Matrix3<T> reflection(const Vector2<T>& normal) {
CORRADE_ASSERT(normal.isNormalized(),
@ -99,7 +102,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D projection matrix
* @param size Size of the view
*
* @see Matrix4::orthographicProjection(), Matrix4::perspectiveProjection()
* @see @ref Matrix4::orthographicProjection(),
* @ref Matrix4::perspectiveProjection()
*/
static Matrix3<T> projection(const Vector2<T>& size) {
return scaling(2.0f/size);
@ -112,7 +116,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @param translation Translation part (first two elements of
* third column)
*
* @see rotationScaling() const, translation() const
* @see @ref rotationScaling(), translation() const
* @todoc Explicit reference when Doxygen can handle const
*/
constexpr static Matrix3<T> from(const Matrix<2, T>& rotationScaling, const Vector2<T>& translation) {
return {{rotationScaling[0], T(0)},
@ -127,8 +132,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief Default constructor
*
* Creates identity matrix. You can also explicitly call this
* constructor with `Matrix3 m(Matrix3::Identity);`. Optional parameter
* @p value allows you to specify value on diagonal.
* constructor with `%Matrix3 m(Matrix3::Identity);`. Optional
* parameter @p value allows you to specify value on diagonal.
*/
constexpr /*implicit*/ Matrix3(typename Matrix<3, T>::IdentityType = (Matrix<3, T>::Identity), T value = T(1)): Matrix<3, T>(Matrix<3, T>::Identity, value) {}
@ -153,7 +158,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
*
* Rigid transformation consists only of rotation and translation (i.e.
* no scaling or projection).
* @see isOrthogonal()
* @see @ref isOrthogonal()
*/
bool isRigidTransformation() const {
return rotationScaling().isOrthogonal() && row(2) == Vector3<T>(T(0), T(0), T(1));
@ -163,9 +168,11 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D rotation and scaling part of the matrix
*
* Upper-left 2x2 part of the matrix.
* @see from(const Matrix<2, T>&, const Vector2&), rotation() const
* rotationNormalized(), @ref uniformScaling(), rotation(T),
* Matrix4::rotationScaling() const
* @see @ref from(const Matrix<2, T>&, const Vector2<T>&),
* rotation() const, @ref rotationNormalized(),
* @ref uniformScaling(), @ref rotation(Rad<T>),
* @ref Matrix4::rotationScaling()
* @todoc Explicit reference when Doxygen can handle const
*/
constexpr Matrix<2, T> rotationScaling() const {
return {(*this)[0].xy(),
@ -180,6 +187,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @see rotation() const, @ref uniformScaling(),
* @ref Matrix4::rotationNormalized()
* @todo assert also orthogonality or this is good enough?
* @todoc Explicit reference when Doxygen can handle const
*/
Matrix<2, T> rotationNormalized() const {
CORRADE_ASSERT((*this)[0].xy().isNormalized() && (*this)[1].xy().isNormalized(),
@ -193,8 +201,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
*
* Normalized upper-left 2x2 part of the matrix. Expects uniform
* scaling.
* @see rotationNormalized(), rotationScaling(), @ref uniformScaling(),
* rotation(T), Matrix4::rotation() const
* @see @ref rotationNormalized(), @ref rotationScaling(),
* @ref uniformScaling(), @ref rotation(Rad<T>),
* Matrix4::rotation() const
* @todoc Explicit reference when Doxygen can handle const
*/
Matrix<2, T> rotation() const {
CORRADE_ASSERT(TypeTraits<T>::equals((*this)[0].xy().dot(), (*this)[1].xy().dot()),
@ -210,9 +220,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* Expects that the scaling is the same in all axes. Faster alternative
* to @ref uniformScaling(), because it doesn't compute the square
* root.
* @see @ref rotationScaling(), @ref rotation(),
* @see @ref rotationScaling(), rotation() const,
* @ref rotationNormalized(), @ref scaling(const Vector2<T>&),
* @ref Matrix4::uniformScaling()
* @todoc Explicit reference when Doxygen can handle const
*/
T uniformScalingSquared() const {
const T scalingSquared = (*this)[0].xy().dot();
@ -227,9 +238,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* Length of vectors in upper-left 2x2 part of the matrix. Expects that
* the scaling is the same in all axes. Use faster alternative
* @ref uniformScalingSquared() where possible.
* @see @ref rotationScaling(), @ref rotation(),
* @see @ref rotationScaling(), rotation() const,
* @ref rotationNormalized(), @ref scaling(const Vector2<T>&),
* @ref Matrix4::uniformScaling()
* @todoc Explicit reference when Doxygen can handle const
*/
T uniformScaling() const { return std::sqrt(uniformScalingSquared()); }
@ -237,7 +249,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief Right-pointing 2D vector
*
* First two elements of first column.
* @see up(), Vector2::xAxis(), Matrix4::right()
* @see @ref up(), @ref Vector2::xAxis(), @ref Matrix4::right()
*/
Vector2<T>& right() { return (*this)[0].xy(); }
constexpr Vector2<T> right() const { return (*this)[0].xy(); } /**< @overload */
@ -246,7 +258,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief Up-pointing 2D vector
*
* First two elements of second column.
* @see right(), Vector2::yAxis(), Matrix4::up()
* @see @ref right(), @ref Vector2::yAxis(), @ref Matrix4::up()
*/
Vector2<T>& up() { return (*this)[1].xy(); }
constexpr Vector2<T> up() const { return (*this)[1].xy(); } /**< @overload */
@ -255,8 +267,9 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D translation part of the matrix
*
* First two elements of third column.
* @see from(const Matrix<2, T>&, const Vector2&),
* translation(const Vector2&), Matrix4::translation()
* @see @ref from(const Matrix<2, T>&, const Vector2<T>&),
* @ref translation(const Vector2<T>&),
* @ref Matrix4::translation()
*/
Vector2<T>& translation() { return (*this)[2].xy(); }
constexpr Vector2<T> translation() const { return (*this)[2].xy(); } /**< @overload */
@ -265,20 +278,27 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief Inverted rigid transformation matrix
*
* Expects that the matrix represents rigid transformation.
* Significantly faster than the general algorithm in inverted().
* @see isRigidTransformation(), invertedOrthogonal(),
* rotationScaling() const, translation() const
* Significantly faster than the general algorithm in @ref inverted(). @f[
* A^{-1} = \begin{pmatrix} (A^{2,2})^T & (A^{2,2})^T \begin{pmatrix} a_{2,0} \\ a_{2,1} \end{pmatrix} \\ \begin{array}{cc} 0 & 0 \end{array} & 1 \end{pmatrix}
* @f]
* @f$ A^{i, j} @f$ is matrix without i-th row and j-th column, see
* @ref ij()
* @see @ref isRigidTransformation(), @ref invertedOrthogonal(),
* @ref rotationScaling(), translation() const,
* @ref Matrix4::invertedRigid()
* @todoc Explicit reference when Doxygen can handle const
*/
Matrix3<T> invertedRigid() const;
/**
* @brief Transform 2D vector with the matrix
*
* Unlike in transformPoint(), translation is not involved in the
* Unlike in @ref transformPoint(), translation is not involved in the
* transformation. @f[
* \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ 0 \end{pmatrix}
* @f]
* @see Complex::transformVector(), Matrix4::transformVector()
* @see @ref Complex::transformVector(),
* @ref Matrix4::transformVector()
* @todo extract 2x2 matrix and multiply directly? (benchmark that)
*/
Vector2<T> transformVector(const Vector2<T>& vector) const {
@ -294,11 +314,12 @@ template<class T> class Matrix3: public Matrix<3, T> {
/**
* @brief Transform 2D point with the matrix
*
* Unlike in transformVector(), translation is also involved in the
* transformation. @f[
* Unlike in @ref transformVector(), translation is also involved in
* the transformation. @f[
* \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ 1 \end{pmatrix}
* @f]
* @see DualComplex::transformPoint(), Matrix4::transformPoint()
* @see @ref DualComplex::transformPoint(),
* @ref Matrix4::transformPoint()
*/
Vector2<T> transformPoint(const Vector2<T>& vector) const {
/* Workaround for GCC 4.4 strict-aliasing fascism */

133
src/Magnum/Math/Matrix4.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Matrix4
* @brief Class @ref Magnum::Math::Matrix4
*/
#include "Magnum/Math/Matrix.h"
@ -40,13 +40,12 @@
namespace Magnum { namespace Math {
/**
@brief 4x4 matrix
@brief 3D transformation matrix
@tparam T Underlying data type
Represents 3D transformation. See @ref matrix-vector and @ref transformations
for brief introduction.
@see Magnum::Matrix4, Magnum::Matrix4d, DualQuaternion,
SceneGraph::MatrixTransformation3D
See @ref matrix-vector and @ref transformations for brief introduction.
@see @ref Magnum::Matrix4, @ref Magnum::Matrix4d, @ref Matrix4x4,
@ref DualQuaternion, @ref SceneGraph::MatrixTransformation3D
@configurationvalueref{Magnum::Math::Matrix4}
*/
template<class T> class Matrix4: public Matrix<4, T> {
@ -55,9 +54,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D translation
* @param vector Translation vector
*
* @see translation(), DualQuaternion::translation(),
* Matrix3::translation(const Vector2&), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis()
* @see @ref translation(), @ref DualQuaternion::translation(),
* @ref Matrix3::translation(const Vector2<T>&),
* @ref Vector3::xAxis(), @ref Vector3::yAxis(),
* @ref Vector3::zAxis()
*/
constexpr static Matrix4<T> translation(const Vector3<T>& vector) {
return {{ T(1), T(0), T(0), T(0)},
@ -70,8 +70,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D scaling
* @param vector Scaling vector
*
* @see rotationScaling() const, Matrix3::scaling(const Vector2&),
* Vector3::xScale(), Vector3::yScale(), Vector3::zScale()
* @see @ref rotationScaling(),
* @ref Matrix3::scaling(const Vector2<T>&),
* @ref Vector3::xScale(), @ref Vector3::yScale(),
* @ref Vector3::zScale()
*/
constexpr static Matrix4<T> scaling(const Vector3<T>& vector) {
return {{vector.x(), T(0), T(0), T(0)},
@ -86,10 +88,13 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param normalizedAxis Normalized rotation axis
*
* Expects that the rotation axis is normalized. If possible, use
* faster alternatives like rotationX(), rotationY() and rotationZ().
* @see rotation() const, Quaternion::rotation(), DualQuaternion::rotation(),
* Matrix3::rotation(Rad), Vector3::xAxis(), Vector3::yAxis(),
* Vector3::zAxis(), Vector::isNormalized()
* faster alternatives like @ref rotationX(), @ref rotationY() and
* @ref rotationZ().
* @see rotation() const, @ref Quaternion::rotation(),
* @ref DualQuaternion::rotation(), @ref Matrix3::rotation(Rad),
* @ref Vector3::xAxis(), @ref Vector3::yAxis(),
* @ref Vector3::zAxis(), @ref Vector::isNormalized()
* @todoc Explicit reference when Doxygen can handle const
*/
static Matrix4<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis);
@ -97,9 +102,11 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D rotation around X axis
* @param angle Rotation angle (counterclockwise)
*
* Faster than calling `Matrix4::rotation(angle, Vector3::xAxis())`.
* @see rotation(Rad, const Vector3&), rotationY(), rotationZ(),
* rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad)
* Faster than calling `%Matrix4::rotation(angle, %Vector3::xAxis())`.
* @see @ref rotation(Rad, const Vector3<T>&), @ref rotationY(),
* @ref rotationZ(), rotation() const,
* @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad)
* @todoc Explicit reference when Doxygen can handle const
*/
static Matrix4<T> rotationX(Rad<T> angle);
@ -107,9 +114,11 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D rotation around Y axis
* @param angle Rotation angle (counterclockwise)
*
* Faster than calling `Matrix4::rotation(angle, Vector3::yAxis())`.
* @see rotation(Rad, const Vector3&), rotationX(), rotationZ(),
* rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad)
* Faster than calling `%Matrix4::rotation(angle, %Vector3::yAxis())`.
* @see @ref rotation(Rad, const Vector3<T>&), @ref rotationX(),
* @ref rotationZ(), rotation() const,
* @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad)
* @todoc Explicit reference when Doxygen can handle const
*/
static Matrix4<T> rotationY(Rad<T> angle);
@ -117,9 +126,11 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D rotation matrix around Z axis
* @param angle Rotation angle (counterclockwise)
*
* Faster than calling `Matrix4::rotation(angle, Vector3::zAxis())`.
* @see rotation(Rad, const Vector3&), rotationX(), rotationY(),
* rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad)
* Faster than calling `%Matrix4::rotation(angle, %Vector3::zAxis())`.
* @see @ref rotation(Rad, const Vector3<T>&), @ref rotationX(),
* @ref rotationY(), rotation() const,
* @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad)
* @todoc Explicit reference when Doxygen can handle const
*/
static Matrix4<T> rotationZ(Rad<T> angle);
@ -128,7 +139,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param normal Normal of the plane through which to reflect
*
* Expects that the normal is normalized.
* @see Matrix3::reflection(), Vector::isNormalized()
* @see @ref Matrix3::reflection(), @ref Vector::isNormalized()
*/
static Matrix4<T> reflection(const Vector3<T>& normal);
@ -138,7 +149,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param near Near clipping plane
* @param far Far clipping plane
*
* @see perspectiveProjection(), Matrix3::projection()
* @see @ref perspectiveProjection(), @ref Matrix3::projection()
*/
static Matrix4<T> orthographicProjection(const Vector2<T>& size, T near, T far);
@ -148,7 +159,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param near Near clipping plane
* @param far Far clipping plane
*
* @see orthographicProjection(), Matrix3::projection()
* @see @ref orthographicProjection(), @ref Matrix3::projection()
*/
static Matrix4<T> perspectiveProjection(const Vector2<T>& size, T near, T far);
@ -159,7 +170,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param near Near clipping plane
* @param far Far clipping plane
*
* @see orthographicProjection(), Matrix3::projection()
* @see @ref orthographicProjection(), @ref Matrix3::projection()
*/
static Matrix4<T> perspectiveProjection(Rad<T> fov, T aspectRatio, T near, T far) {
const T xyScale = 2*std::tan(fov.toUnderlyingType()/2)*near;
@ -173,7 +184,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param translation Translation part (first three elements of
* fourth column)
*
* @see rotationScaling() const, translation() const
* @see @ref rotationScaling(), translation() const
* @todoc Explicit reference when Doxygen can handle const
*/
constexpr static Matrix4<T> from(const Matrix<3, T>& rotationScaling, const Vector3<T>& translation) {
return {{rotationScaling[0], T(0)},
@ -189,8 +201,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Default constructor
*
* Creates identity matrix. You can also explicitly call this
* constructor with `Matrix4 m(Matrix4::Identity);`. Optional parameter
* @p value allows you to specify value on diagonal.
* constructor with `%Matrix4 m(Matrix4::Identity);`. Optional
* parameter @p value allows you to specify value on diagonal.
*/
constexpr /*implicit*/ Matrix4(typename Matrix<4, T>::IdentityType = (Matrix<4, T>::Identity), T value = T(1)): Matrix<4, T>(Matrix<4, T>::Identity, value) {}
@ -215,7 +227,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
*
* Rigid transformation consists only of rotation and translation (i.e.
* no scaling or projection).
* @see isOrthogonal()
* @see @ref isOrthogonal()
*/
bool isRigidTransformation() const {
return rotationScaling().isOrthogonal() && row(3) == Vector4<T>(T(0), T(0), T(0), T(1));
@ -225,9 +237,11 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D rotation and scaling part of the matrix
*
* Upper-left 3x3 part of the matrix.
* @see from(const Matrix<3, T>&, const Vector3&), rotation() const,
* rotationNormalized(), @ref uniformScaling(),
* rotation(T, const Vector3&), Matrix3::rotationScaling() const
* @see @ref from(const Matrix<3, T>&, const Vector3<T>&),
* rotation() const, @ref rotationNormalized(),
* @ref uniformScaling(), @ref rotation(Rad, const Vector3<T>&),
* Matrix3::rotationScaling() const
* @todoc Explicit reference when Doxygen can handle const
*/
/* Not Matrix3, because it is for affine 2D transformations */
constexpr Matrix<3, T> rotationScaling() const {
@ -244,6 +258,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @see rotation() const, @ref uniformScaling(),
* @ref Matrix3::rotationNormalized()
* @todo assert also orthogonality or this is good enough?
* @todoc Explicit reference when Doxygen can handle const
*/
/* Not Matrix3, because it is for affine 2D transformations */
Matrix<3, T> rotationNormalized() const {
@ -259,9 +274,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
*
* Normalized upper-left 3x3 part of the matrix. Expects uniform
* scaling.
* @see rotationNormalized(), rotationScaling() const,
* @ref uniformScaling(), rotation(T, const Vector3&),
* @see @ref rotationNormalized(), @ref rotationScaling(),
* @ref uniformScaling(), @ref rotation(Rad, const Vector3<T>&),
* Matrix3::rotation() const
* @todoc Explicit reference when Doxygen can handle const
*/
/* Not Matrix3, because it is for affine 2D transformations */
Matrix<3, T> rotation() const;
@ -273,9 +289,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* Expects that the scaling is the same in all axes. Faster alternative
* to @ref uniformScaling(), because it doesn't compute the square
* root.
* @see @ref rotationScaling(), @ref rotation(),
* @see @ref rotationScaling(), rotation() const,
* @ref rotationNormalized(), @ref scaling(const Vector3<T>&),
* @ref Matrix3::uniformScaling()
* @todoc Explicit reference when Doxygen can handle const
*/
T uniformScalingSquared() const;
@ -285,9 +302,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* Length of vectors in upper-left 3x3 part of the matrix. Expects that
* the scaling is the same in all axes. Use faster alternative
* @ref uniformScalingSquared() where possible.
* @see @ref rotationScaling(), @ref rotation(),
* @see @ref rotationScaling(), rotation() const,
* @ref rotationNormalized(), @ref scaling(const Vector3<T>&),
* @ref Matrix3::uniformScaling()
* @todoc Explicit reference when Doxygen can handle const
*/
T uniformScaling() const { return std::sqrt(uniformScalingSquared()); }
@ -295,7 +313,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Right-pointing 3D vector
*
* First three elements of first column.
* @see up(), backward(), Vector3::xAxis(), Matrix3::right()
* @see @ref up(), @ref backward(), @ref Vector3::xAxis(),
* @ref Matrix3::right()
*/
Vector3<T>& right() { return (*this)[0].xyz(); }
constexpr Vector3<T> right() const { return (*this)[0].xyz(); } /**< @overload */
@ -304,7 +323,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Up-pointing 3D vector
*
* First three elements of second column.
* @see right(), backward(), Vector3::yAxis(), Matrix3::up()
* @see @ref right(), @ref backward(), @ref Vector3::yAxis(),
* @ref Matrix3::up()
*/
Vector3<T>& up() { return (*this)[1].xyz(); }
constexpr Vector3<T> up() const { return (*this)[1].xyz(); } /**< @overload */
@ -313,7 +333,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Backward-pointing 3D vector
*
* First three elements of third column.
* @see right(), up(), Vector3::yAxis()
* @see @ref right(), @ref up(), @ref Vector3::yAxis()
*/
Vector3<T>& backward() { return (*this)[2].xyz(); }
constexpr Vector3<T> backward() const { return (*this)[2].xyz(); } /**< @overload */
@ -322,8 +342,9 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D translation part of the matrix
*
* First three elements of fourth column.
* @see from(const Matrix<3, T>&, const Vector3&),
* translation(const Vector3&), Matrix3::translation()
* @see @ref from(const Matrix<3, T>&, const Vector3<T>&),
* @ref translation(const Vector3<T>&),
* @ref Matrix3::translation()
*/
Vector3<T>& translation() { return (*this)[3].xyz(); }
constexpr Vector3<T> translation() const { return (*this)[3].xyz(); } /**< @overload */
@ -332,20 +353,27 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Inverted rigid transformation matrix
*
* Expects that the matrix represents rigid transformation.
* Significantly faster than the general algorithm in inverted().
* @see isRigidTransformation(), invertedOrthogonal(),
* rotationScaling() const, translation() const
* Significantly faster than the general algorithm in @ref inverted(). @f[
* A^{-1} = \begin{pmatrix} (A^{3,3})^T & (A^{3,3})^T \begin{pmatrix} a_{3,0} \\ a_{3,1} \\ a_{3,2} \\ \end{pmatrix} \\ \begin{array}{ccc} 0 & 0 & 0 \end{array} & 1 \end{pmatrix}
* @f]
* @f$ A^{i, j} @f$ is matrix without i-th row and j-th column, see
* @ref ij()
* @see @ref isRigidTransformation(), @ref invertedOrthogonal(),
* @ref rotationScaling(), translation() const,
* @ref Matrix3::invertedRigid()
* @todoc Explicit reference when Doxygen can handle const
*/
Matrix4<T> invertedRigid() const;
/**
* @brief Transform 3D vector with the matrix
*
* Unlike in transformVector(), translation is not involved in the
* Unlike in @ref transformVector(), translation is not involved in the
* transformation. @f[
* \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ v_z \\ 0 \end{pmatrix}
* @f]
* @see Quaternion::transformVector(), Matrix3::transformVector()
* @see @ref Quaternion::transformVector(),
* @ref Matrix3::transformVector()
* @todo extract 3x3 matrix and multiply directly? (benchmark that)
*/
Vector3<T> transformVector(const Vector3<T>& vector) const {
@ -361,11 +389,12 @@ template<class T> class Matrix4: public Matrix<4, T> {
/**
* @brief Transform 3D point with the matrix
*
* Unlike in transformVector(), translation is also involved in the
* transformation. @f[
* Unlike in @ref transformVector(), translation is also involved in
* the transformation. @f[
* \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ v_z \\ 1 \end{pmatrix}
* @f]
* @see DualQuaternion::transformPoint(), Matrix3::transformPoint()
* @see @ref DualQuaternion::transformPoint(),
* @ref Matrix3::transformPoint()
*/
Vector3<T> transformPoint(const Vector3<T>& vector) const {
/* Workaround for GCC 4.4 strict-aliasing fascism */

101
src/Magnum/Math/Quaternion.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Quaternion
* @brief Class @ref Magnum::Math::Quaternion
*/
#include <cmath>
@ -44,11 +44,12 @@ namespace Magnum { namespace Math {
@tparam T Underlying data type
Represents 3D rotation. See @ref transformations for brief introduction.
@see Magnum::Quaternion, Magnum::Quaterniond, DualQuaternion, Matrix4
@see @ref Magnum::Quaternion, @ref Magnum::Quaterniond, @ref DualQuaternion,
@ref Matrix4
*/
template<class T> class Quaternion {
public:
typedef T Type; /**< @brief Underlying data type */
typedef T Type; /**< @brief Underlying data type */
/**
* @brief Dot product
@ -57,6 +58,7 @@ template<class T> class Quaternion {
* p \cdot q = \boldsymbol p_V \cdot \boldsymbol q_V + p_S q_S
* @f]
* @see dot() const
* @todoc Explicit reference when Doxygen can handle const
*/
static T dot(const Quaternion<T>& a, const Quaternion<T>& b) {
/** @todo Use four-component SIMD implementation when available */
@ -69,7 +71,8 @@ template<class T> class Quaternion {
* Expects that both quaternions are normalized. @f[
* \theta = acos \left( \frac{p \cdot q}{|p| |q|} \right) = acos(p \cdot q)
* @f]
* @see isNormalized(), Complex::angle(), Vector::angle()
* @see @ref isNormalized(), @ref Complex::angle(),
* @ref Vector::angle()
*/
static Rad<T> angle(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB);
@ -82,7 +85,7 @@ template<class T> class Quaternion {
* Expects that both quaternions are normalized. @f[
* q_{LERP} = \frac{(1 - t) q_A + t q_B}{|(1 - t) q_A + t q_B|}
* @f]
* @see isNormalized(), slerp(), Math::lerp()
* @see @ref isNormalized(), @ref slerp(), @ref Math::lerp()
*/
static Quaternion<T> lerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t);
@ -97,7 +100,7 @@ template<class T> class Quaternion {
* ~~~~~~~~~~
* \theta = acos \left( \frac{q_A \cdot q_B}{|q_A| \cdot |q_B|} \right) = acos(q_A \cdot q_B)
* @f]
* @see isNormalized(), lerp()
* @see @ref isNormalized(), @ref lerp()
*/
static Quaternion<T> slerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t);
@ -109,9 +112,10 @@ template<class T> class Quaternion {
* Expects that the rotation axis is normalized. @f[
* q = [\boldsymbol a \cdot sin \frac \theta 2, cos \frac \theta 2]
* @f]
* @see angle(), axis(), DualQuaternion::rotation(),
* Matrix4::rotation(), Complex::rotation(), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis(), Vector::isNormalized()
* @see @ref angle(), @ref axis(), @ref DualQuaternion::rotation(),
* @ref Matrix4::rotation(), @ref Complex::rotation(),
* @ref Vector3::xAxis(), @ref Vector3::yAxis(),
* @ref Vector3::zAxis(), @ref Vector::isNormalized()
*/
static Quaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis);
@ -119,7 +123,8 @@ template<class T> class Quaternion {
* @brief Create quaternion from rotation matrix
*
* Expects that the matrix is orthogonal (i.e. pure rotation).
* @see toMatrix(), DualComplex::fromMatrix(), Matrix::isOrthogonal()
* @see @ref toMatrix(), @ref DualComplex::fromMatrix(),
* @ref Matrix::isOrthogonal()
*/
static Quaternion<T> fromMatrix(const Matrix<3, T>& matrix);
@ -147,7 +152,7 @@ template<class T> class Quaternion {
* To be used in transformations later. @f[
* q = [\boldsymbol v, 0]
* @f]
* @see transformVector(), transformVectorNormalized()
* @see @ref transformVector(), @ref transformVectorNormalized()
*/
constexpr explicit Quaternion(const Vector3<T>& vector): _vector(vector), _scalar(T(0)) {}
@ -164,10 +169,10 @@ template<class T> class Quaternion {
/**
* @brief Whether the quaternion is normalized
*
* Quaternion is normalized if it has unit length: @f[
* %Quaternion is normalized if it has unit length: @f[
* |q \cdot q - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon
* @f]
* @see dot(), normalized()
* @see @ref dot(), @ref normalized()
*/
bool isNormalized() const {
return Implementation::isNormalizedSquared(dot());
@ -185,7 +190,7 @@ template<class T> class Quaternion {
* Expects that the quaternion is normalized. @f[
* \theta = 2 \cdot acos q_S
* @f]
* @see isNormalized(), axis(), rotation()
* @see @ref isNormalized(), @ref axis(), @ref rotation()
*/
Rad<T> angle() const;
@ -197,15 +202,15 @@ template<class T> class Quaternion {
* default-constructed quaternion. @f[
* \boldsymbol a = \frac{\boldsymbol q_V}{\sqrt{1 - q_S^2}}
* @f]
* @see isNormalized(), angle(), rotation()
* @see @ref isNormalized(), @ref angle(), @ref rotation()
*/
Vector3<T> axis() const;
/**
* @brief Convert quaternion to rotation matrix
*
* @see fromMatrix(), DualQuaternion::toMatrix(),
* Matrix4::from(const Matrix<3, T>&, const Vector3<T>&)
* @see @ref fromMatrix(), @ref DualQuaternion::toMatrix(),
* @ref Matrix4::from(const Matrix<3, T>&, const Vector3<T>&)
*/
Matrix<3, T> toMatrix() const;
@ -225,7 +230,7 @@ template<class T> class Quaternion {
/**
* @brief Add quaternion
*
* @see operator+=()
* @see @ref operator+=()
*/
Quaternion<T> operator+(const Quaternion<T>& other) const {
return Quaternion<T>(*this) += other;
@ -256,7 +261,7 @@ template<class T> class Quaternion {
/**
* @brief Subtract quaternion
*
* @see operator-=()
* @see @ref operator-=()
*/
Quaternion<T> operator-(const Quaternion<T>& other) const {
return Quaternion<T>(*this) -= other;
@ -278,7 +283,7 @@ template<class T> class Quaternion {
/**
* @brief Multiply with scalar
*
* @see operator*=(T)
* @see @ref operator*=(T)
*/
Quaternion<T> operator*(T scalar) const {
return Quaternion<T>(*this) *= scalar;
@ -300,7 +305,7 @@ template<class T> class Quaternion {
/**
* @brief Divide with scalar
*
* @see operator/=(T)
* @see @ref operator/=(T)
*/
Quaternion<T> operator/(T scalar) const {
return Quaternion<T>(*this) /= scalar;
@ -319,29 +324,32 @@ template<class T> class Quaternion {
/**
* @brief Dot product of the quaternion
*
* Should be used instead of length() for comparing quaternion length
* with other values, because it doesn't compute the square root. @f[
* Should be used instead of @ref length() for comparing quaternion
* length with other values, because it doesn't compute the square
* root. @f[
* q \cdot q = \boldsymbol q_V \cdot \boldsymbol q_V + q_S^2
* @f]
* @see isNormalized(), dot(const Quaternion&, const Quaternion&)
* @see @ref isNormalized(),
* @ref dot(const Quaternion<T>&, const Quaternion<T>&)
*/
T dot() const { return dot(*this, *this); }
/**
* @brief %Quaternion length
*
* See also dot() const which is faster for comparing length with other
* values. @f[
* See also dot() const which is faster for comparing length with
* other values. @f[
* |q| = \sqrt{q \cdot q}
* @f]
* @see isNormalized()
* @see @ref isNormalized()
* @todoc Explicit reference when Doxygen can handle const
*/
T length() const { return std::sqrt(dot()); }
/**
* @brief Normalized quaternion (of unit length)
*
* @see isNormalized()
* @see @ref isNormalized()
*/
Quaternion<T> normalized() const { return (*this)/length(); }
@ -357,7 +365,7 @@ template<class T> class Quaternion {
/**
* @brief Inverted quaternion
*
* See invertedNormalized() which is faster for normalized
* See @ref invertedNormalized() which is faster for normalized
* quaternions. @f[
* q^{-1} = \frac{q^*}{|q|^2} = \frac{q^*}{q \cdot q}
* @f]
@ -367,23 +375,25 @@ template<class T> class Quaternion {
/**
* @brief Inverted normalized quaternion
*
* Equivalent to conjugated(). Expects that the quaternion is
* Equivalent to @ref conjugated(). Expects that the quaternion is
* normalized. @f[
* q^{-1} = \frac{q^*}{|q|^2} = q^*
* @f]
* @see isNormalized(), inverted()
* @see @ref isNormalized(), @ref inverted()
*/
Quaternion<T> invertedNormalized() const;
/**
* @brief Rotate vector with quaternion
*
* See transformVectorNormalized(), which is faster for normalized
* See @ref transformVectorNormalized(), which is faster for normalized
* quaternions. @f[
* v' = qvq^{-1} = q [\boldsymbol v, 0] q^{-1}
* @f]
* @see Quaternion(const Vector3&), vector(), Matrix4::transformVector(),
* DualQuaternion::transformPoint(), Complex::transformVector()
* @see @ref Quaternion(const Vector3<T>&), @ref vector(),
* @ref Matrix4::transformVector(),
* @ref DualQuaternion::transformPoint(),
* @ref Complex::transformVector()
*/
Vector3<T> transformVector(const Vector3<T>& vector) const {
return ((*this)*Quaternion<T>(vector)*inverted()).vector();
@ -392,12 +402,14 @@ template<class T> class Quaternion {
/**
* @brief Rotate vector with normalized quaternion
*
* Faster alternative to transformVector(), expects that the quaternion
* is normalized. @f[
* Faster alternative to @ref transformVector(), expects that the
* quaternion is normalized. @f[
* v' = qvq^{-1} = qvq^* = q [\boldsymbol v, 0] q^*
* @f]
* @see isNormalized(), Quaternion(const Vector3&), vector(), Matrix4::transformVector(),
* DualQuaternion::transformPointNormalized(), Complex::transformVector()
* @see @ref isNormalized(), @ref Quaternion(const Vector3<T>&),
* @ref vector(), @ref Matrix4::transformVector(),
* @ref DualQuaternion::transformPointNormalized(),
* @ref Complex::transformVector()
*/
Vector3<T> transformVectorNormalized(const Vector3<T>& vector) const;
@ -419,7 +431,7 @@ template<class T> class Quaternion {
/** @relates Quaternion
@brief Multiply scalar with quaternion
Same as Quaternion::operator*(T) const.
Same as @ref Quaternion::operator*(T) const.
*/
template<class T> inline Quaternion<T> operator*(T scalar, const Quaternion<T>& quaternion) {
return quaternion*scalar;
@ -431,7 +443,7 @@ template<class T> inline Quaternion<T> operator*(T scalar, const Quaternion<T>&
@f[
\frac a q = [\frac a {\boldsymbol q_V}, \frac a {q_S}]
@f]
@see Quaternion::operator/()
@see @ref Quaternion::operator/()
*/
template<class T> inline Quaternion<T> operator/(T scalar, const Quaternion<T>& quaternion) {
return {scalar/quaternion.vector(), scalar/quaternion.scalar()};
@ -446,12 +458,16 @@ template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug deb
return debug;
}
/** @todoc Remove the workaround when Doxygen is really able to preprocessor */
/* Explicit instantiation for commonly used types */
#ifndef DOXYGEN_GENERATING_OUTPUT
/** @privatesection */
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Quaternion<Float>&);
#ifndef MAGNUM_TARGET_GLES
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Quaternion<Double>&);
#endif
/** @endprivatesection */
#endif
namespace Implementation {
@ -472,10 +488,7 @@ template<class T> Quaternion<T> quaternionFromMatrix(const Matrix<3, T>& m) {
}
/* Diagonal is negative */
std::size_t i = 0;
if(diagonal[1] > diagonal[0]) i = 1;
if(diagonal[2] > diagonal[i]) i = 2;
const std::size_t i = diagonal.max();
const std::size_t j = (i + 1) % 3;
const std::size_t k = (i + 2) % 3;

6
src/Magnum/Math/Range.h

@ -62,7 +62,7 @@ template<UnsignedInt dimensions, class T> class Range {
/**
* Create range from minimal coordinates and size
* @param min Minimal coordinates
* @param size Range size
* @param size %Range size
*/
static Range<dimensions, T> fromSize(const VectorType& min, const VectorType& size) {
return {min, min+size};
@ -122,7 +122,7 @@ template<UnsignedInt dimensions, class T> class Range {
constexpr const VectorType max() const { return _max; } /**< @overload */
/**
* @brief Range size
* @brief %Range size
*
* @see @ref min(), @ref max(), @ref Range2D::sizeX(),
* @ref Range2D::sizeY(), @ref Range3D::sizeX(),
@ -131,7 +131,7 @@ template<UnsignedInt dimensions, class T> class Range {
VectorType size() const { return _max - _min; }
/**
* @brief Range center
* @brief %Range center
*
* @see @ref Range2D::centerX(), @ref Range2D::centerY(),
* @ref Range3D::centerX(), @ref Range3D::centerY(),

66
src/Magnum/Math/RectangularMatrix.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::RectangularMatrix
* @brief Class @ref Magnum::Math::RectangularMatrix, typedef @ref Magnum::Math::Matrix2x3, @ref Magnum::Math::Matrix3x2, @ref Magnum::Math::Matrix2x4, @ref Magnum::Math::Matrix4x2, @ref Magnum::Math::Matrix3x4, @ref Magnum::Math::Matrix4x3
*/
#include "Magnum/Math/Vector.h"
@ -43,8 +43,8 @@ namespace Implementation {
@tparam rows Row count
@tparam T Underlying data type
See @ref matrix-vector for brief introduction. See also Matrix (square) and
Vector.
See @ref matrix-vector for brief introduction. See also @ref Matrix (square)
and @ref Vector.
The data are stored in column-major order, to reflect that, all indices in
math formulas are in reverse order (i.e. @f$ \boldsymbol A_{ji} @f$ instead
@ -65,13 +65,13 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief Size of matrix diagonal
*
* @see fromDiagonal(), diagonal()
* @see @ref fromDiagonal(), @ref diagonal()
*/
const static std::size_t DiagonalSize = (cols < rows ? cols : rows);
/**
* @brief %Matrix from array
* @return Reference to the data as if it was Matrix, thus doesn't
* @return Reference to the data as if it was matrix, thus doesn't
* perform any copying.
*
* @attention Use with caution, the function doesn't check whether the
@ -90,7 +90,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
*
* Rolls the vector into matrix, i.e. first `rows` elements of the
* vector will make first column of resulting matrix.
* @see toVector()
* @see @ref toVector()
*/
static RectangularMatrix<cols, rows, T> fromVector(const Vector<cols*rows, T>& vector) {
return *reinterpret_cast<const RectangularMatrix<cols, rows, T>*>(vector.data());
@ -99,7 +99,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief Construct diagonal matrix
*
* @see diagonal()
* @see @ref diagonal()
*/
constexpr static RectangularMatrix<cols, rows, T> fromDiagonal(const Vector<DiagonalSize, T>& diagonal) {
return RectangularMatrix(typename Implementation::GenerateSequence<cols>::Type(), diagonal);
@ -185,7 +185,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* @return One-dimensional array of `cols*rows` length in column-major
* order.
*
* @see operator[]
* @see @ref operator[]()
*/
T* data() { return _data[0].data(); }
constexpr const T* data() const { return _data[0].data(); } /**< @overload */
@ -193,13 +193,14 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief %Matrix column
*
* Particular elements can be accessed using Vector::operator[], e.g.:
* Particular elements can be accessed using @ref Vector::operator[](),
* e.g.:
* @code
* RectangularMatrix<4, 3, Float> m;
* Float a = m[2][1];
* @endcode
*
* @see row(), data()
* @see @ref row(), @ref data()
*/
Vector<rows, T>& operator[](std::size_t col) { return _data[col]; }
constexpr const Vector<rows, T>& operator[](std::size_t col) const { return _data[col]; } /**< @overload */
@ -207,9 +208,10 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief %Matrix row
*
* Consider using transposed() when accessing rows frequently, as this
* is slower than accessing columns due to the way the matrix is stored.
* @see operator[]()
* Consider using @ref transposed() when accessing rows frequently, as
* this is slower than accessing columns due to the way the matrix is
* stored.
* @see @ref operator[]()
*/
Vector<cols, T> row(std::size_t row) const;
@ -224,8 +226,8 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief Non-equality operator
*
* @see Vector::operator<(), Vector::operator<=(), Vector::operator>=(),
* Vector::operator>()
* @see @ref Vector::operator<(), @ref Vector::operator<=(),
* @ref Vector::operator>=(), @ref Vector::operator>()
*/
bool operator!=(const RectangularMatrix<cols, rows, T>& other) const {
return !operator==(other);
@ -257,7 +259,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief Add matrix
*
* @see operator+=()
* @see @ref operator+=()
*/
RectangularMatrix<cols, rows, T> operator+(const RectangularMatrix<cols, rows, T>& other) const {
return RectangularMatrix<cols, rows, T>(*this)+=other;
@ -280,7 +282,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief Subtract matrix
*
* @see operator-=()
* @see @ref operator-=()
*/
RectangularMatrix<cols, rows, T> operator-(const RectangularMatrix<cols, rows, T>& other) const {
return RectangularMatrix<cols, rows, T>(*this)-=other;
@ -303,7 +305,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief Multiply matrix with number
*
* @see operator*=(T), operator*(T, const RectangularMatrix<cols, rows, T>&)
* @see @ref operator*=(T), @ref operator*(T, const RectangularMatrix<cols, rows, T>&)
*/
RectangularMatrix<cols, rows, T> operator*(T number) const {
return RectangularMatrix<cols, rows, T>(*this) *= number;
@ -326,8 +328,8 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief Divide matrix with number
*
* @see operator/=(T),
* operator/(T, const RectangularMatrix<cols, rows, T>&)
* @see @ref operator/=(T),
* @ref operator/(T, const RectangularMatrix<cols, rows, T>&)
*/
RectangularMatrix<cols, rows, T> operator/(T number) const {
return RectangularMatrix<cols, rows, T>(*this) /= number;
@ -357,14 +359,14 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/**
* @brief Transposed matrix
*
* @see row()
* @see @ref row()
*/
RectangularMatrix<rows, cols, T> transposed() const;
/**
* @brief Values on diagonal
*
* @see fromDiagonal()
* @see @ref fromDiagonal()
*/
constexpr Vector<DiagonalSize, T> diagonal() const;
@ -375,7 +377,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* of the matrix will make first `rows` elements of resulting vector.
* Useful for performing vector operations with the matrix (e.g.
* summing the elements etc.).
* @see fromVector()
* @see @ref fromVector()
*/
Vector<rows*cols, T> toVector() const {
return *reinterpret_cast<const Vector<rows*cols, T>*>(data());
@ -423,7 +425,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
#ifndef CORRADE_GCC46_COMPATIBILITY
/**
@brief Matrix with 2 columns and 3 rows
@brief %Matrix with 2 columns and 3 rows
Convenience alternative to <tt>%RectangularMatrix<2, 3, T></tt>. See
@ref RectangularMatrix for more information.
@ -436,7 +438,7 @@ template<class T> using Matrix2x3 = RectangularMatrix<2, 3, T>;
#endif
/**
@brief Matrix with 3 columns and 2 rows
@brief %Matrix with 3 columns and 2 rows
Convenience alternative to <tt>%RectangularMatrix<3, 2, T></tt>. See
@ref RectangularMatrix for more information.
@ -449,7 +451,7 @@ template<class T> using Matrix3x2 = RectangularMatrix<3, 2, T>;
#endif
/**
@brief Matrix with 2 columns and 4 rows
@brief %Matrix with 2 columns and 4 rows
Convenience alternative to <tt>%RectangularMatrix<2, 4, T></tt>. See
@ref RectangularMatrix for more information.
@ -462,7 +464,7 @@ template<class T> using Matrix2x4 = RectangularMatrix<2, 4, T>;
#endif
/**
@brief Matrix with 4 columns and 2 rows
@brief %Matrix with 4 columns and 2 rows
Convenience alternative to <tt>%RectangularMatrix<4, 2, T></tt>. See
@ref RectangularMatrix for more information.
@ -475,7 +477,7 @@ template<class T> using Matrix4x2 = RectangularMatrix<4, 2, T>;
#endif
/**
@brief Matrix with 3 columns and 4 rows
@brief %Matrix with 3 columns and 4 rows
Convenience alternative to <tt>%RectangularMatrix<3, 4, T></tt>. See
@ref RectangularMatrix for more information.
@ -488,7 +490,7 @@ template<class T> using Matrix3x4 = RectangularMatrix<3, 4, T>;
#endif
/**
@brief Matrix with 4 columns and 3 rows
@brief %Matrix with 4 columns and 3 rows
Convenience alternative to <tt>%RectangularMatrix<4, 3, T></tt>. See
@ref RectangularMatrix for more information.
@ -504,7 +506,7 @@ template<class T> using Matrix4x3 = RectangularMatrix<4, 3, T>;
/** @relates RectangularMatrix
@brief Multiply number with matrix
Same as RectangularMatrix::operator*(T) const.
Same as @ref RectangularMatrix::operator*(T) const.
*/
template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<cols, rows, T> operator*(
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -523,7 +525,7 @@ template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<c
The computation is done column-wise. @f[
\boldsymbol B_j = \frac a {\boldsymbol A_j}
@f]
@see RectangularMatrix::operator/(T) const
@see @ref RectangularMatrix::operator/(T) const
*/
template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<cols, rows, T> operator/(
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -547,7 +549,7 @@ template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<c
Internally the same as multiplying one-column matrix with one-row matrix. @f[
(\boldsymbol {aA})_{ji} = \boldsymbol a_i \boldsymbol A_j
@f]
@see RectangularMatrix::operator*(const RectangularMatrix<size, cols, T>&) const
@see @ref RectangularMatrix::operator*(const RectangularMatrix<size, cols, T>&) const
*/
template<std::size_t size, std::size_t cols, class T> inline RectangularMatrix<cols, size, T> operator*(const Vector<size, T>& vector, const RectangularMatrix<cols, 1, T>& matrix) {
return RectangularMatrix<1, size, T>(vector)*matrix;

2
src/Magnum/Math/Swizzle.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function Magnum::Math::swizzle()
* @brief Function @ref Magnum::Math::swizzle()
*/
#include "Magnum/Math/Vector.h"

8
src/Magnum/Math/Test/FunctionsTest.cpp

@ -213,10 +213,10 @@ void FunctionsTest::lerp() {
CORRADE_COMPARE(Math::lerp(a, b, 0.25f), Vector3(0.0f, 1.0f, 5.0f));
/* Integer vector */
typedef Math::Vector<3, Int> Vector3ub;
Vector3ub c(0, 128, 64);
Vector3ub d(16, 0, 32);
CORRADE_COMPARE(Math::lerp(c, d, 0.25f), Vector3ub(4, 96, 56));
typedef Math::Vector<3, Int> Vector3i;
Vector3i c(0, 128, 64);
Vector3i d(16, 0, 32);
CORRADE_COMPARE(Math::lerp(c, d, 0.25f), Vector3i(4, 96, 56));
/* Vector as interpolation phase */
CORRADE_COMPARE(Math::lerp(a, b, Vector3(0.25f, 0.5f, 0.75f)), Vector3(0.0f, 0.0f, 9.0f));

8
src/Magnum/Math/Test/SwizzleTest.cpp

@ -64,14 +64,14 @@ void SwizzleTest::rgba() {
}
void SwizzleTest::sizes() {
constexpr auto a = swizzle<'y', 'x', 'x'>(Math::Vector<2, Int>(1, 2));
CORRADE_COMPARE(a, (Math::Vector<3, Int>(2, 1, 1)));
constexpr auto a = swizzle<'y', 'x', 'x'>(Vector<2, Int>(1, 2));
CORRADE_COMPARE(a, (Vector<3, Int>(2, 1, 1)));
constexpr auto b = swizzle<'z'>(Vector4i(1, 2, 3, 4));
CORRADE_COMPARE(b, (Math::Vector<1, Int>(3)));
CORRADE_COMPARE(b, (Vector<1, Int>(3)));
constexpr auto c = swizzle<'z', 'x', 'w', 'y', 'z', 'y', 'x'>(Vector4i(1, 2, 3, 4));
CORRADE_COMPARE(c, (Math::Vector<7, Int>(3, 1, 4, 2, 3, 2, 1)));
CORRADE_COMPARE(c, (Vector<7, Int>(3, 1, 4, 2, 3, 2, 1)));
}
}}}

6
src/Magnum/Math/TypeTraits.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::TypeTraits
* @brief Class @ref Magnum::Math::TypeTraits
*/
#include <cmath>
@ -100,8 +100,8 @@ template<class T> struct TypeTraits: Implementation::TypeTraitsDefault<T> {
/**
* @brief Fuzzy compare
*
* Uses fuzzy compare for floating-point types (using epsilon() value),
* pure equality comparison everywhere else.
* Uses fuzzy compare for floating-point types (using @ref epsilon()
* value), pure equality comparison everywhere else.
*/
static bool equals(T a, T b);
#endif

4
src/Magnum/Math/Unit.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Unit
* @brief Class @ref Magnum::Math::Unit
*/
#include "Magnum/Math/TypeTraits.h"
@ -37,7 +37,7 @@ namespace Magnum { namespace Math {
@brief Base class for units
@tparam T Underlying data type
@see Deg, Rad
@see @ref Deg, @ref Rad
*/
template<template<class> class Derived, class T> class Unit {
template<template<class> class, class> friend class Unit;

135
src/Magnum/Math/Vector.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Vector
* @brief Class @ref Magnum::Math::Vector
*/
#include <cmath>
@ -92,7 +92,9 @@ template<std::size_t size, class T> class Vector {
* antiparallel. @f[
* \boldsymbol a \cdot \boldsymbol b = \sum_{i=0}^{n-1} \boldsymbol a_i \boldsymbol b_i
* @f]
* @see dot() const, operator-(), Vector2::perpendicular()
* @see dot() const, @ref operator-(),
* @ref Vector2::perpendicular()
* @todoc Explicit reference when Doxygen can handle const
*/
static T dot(const Vector<size, T>& a, const Vector<size, T>& b) {
return (a*b).sum();
@ -104,7 +106,8 @@ template<std::size_t size, class T> class Vector {
* Expects that both vectors are normalized. @f[
* \theta = acos \left( \frac{\boldsymbol a \cdot \boldsymbol b}{|\boldsymbol a| |\boldsymbol b|} \right) = acos (\boldsymbol a \cdot \boldsymbol b)
* @f]
* @see isNormalized(), Quaternion::angle(), Complex::angle()
* @see @ref isNormalized(), @ref Quaternion::angle(),
* @ref Complex::angle()
*/
static Rad<T> angle(const Vector<size, T>& normalizedA, const Vector<size, T>& normalizedB);
@ -202,7 +205,7 @@ template<std::size_t size, class T> class Vector {
* @brief Raw data
* @return One-dimensional array of `size` length.
*
* @see operator[]()
* @see @ref operator[]()
*/
T* data() {
#ifndef CORRADE_MSVC2013_COMPATIBILITY
@ -224,7 +227,7 @@ template<std::size_t size, class T> class Vector {
/**
* @brief Value at given position
*
* @see data()
* @see @ref data()
*/
T& operator[](std::size_t pos) { return _data[pos]; }
constexpr T operator[](std::size_t pos) const { return _data[pos]; } /**< @overload */
@ -260,7 +263,7 @@ template<std::size_t size, class T> class Vector {
* @f[
* |\boldsymbol a \cdot \boldsymbol a - 0| < \epsilon^2 \cong \epsilon
* @f]
* @see dot(), normalized()
* @see @ref dot(), @ref normalized()
*/
bool isZero() const {
return Implementation::isZeroSquared(dot());
@ -272,7 +275,7 @@ template<std::size_t size, class T> class Vector {
* The vector is normalized if it has unit length: @f[
* |\boldsymbol a \cdot \boldsymbol a - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon
* @f]
* @see dot(), normalized()
* @see @ref dot(), @ref normalized()
*/
bool isNormalized() const {
return Implementation::isNormalizedSquared(dot());
@ -284,7 +287,7 @@ template<std::size_t size, class T> class Vector {
* @f[
* \boldsymbol b_i = -\boldsymbol a_i
* @f]
* @see Vector2::perpendicular()
* @see @ref Vector2::perpendicular()
*/
Vector<size, T> operator-() const;
@ -305,7 +308,7 @@ template<std::size_t size, class T> class Vector {
/**
* @brief Add vector
*
* @see operator+=(), sum()
* @see @ref operator+=(), @ref sum()
*/
Vector<size, T> operator+(const Vector<size, T>& other) const {
return Vector<size, T>(*this) += other;
@ -328,7 +331,7 @@ template<std::size_t size, class T> class Vector {
/**
* @brief Subtract vector
*
* @see operator-=()
* @see @ref operator-=()
*/
Vector<size, T> operator-(const Vector<size, T>& other) const {
return Vector<size, T>(*this) -= other;
@ -340,8 +343,8 @@ template<std::size_t size, class T> class Vector {
* The computation is done in-place. @f[
* \boldsymbol a_i = b \boldsymbol a_i
* @f]
* @see operator*=(const Vector<size, T>&),
* operator*=(Vector<size, Integral>&, FloatingPoint)
* @see @ref operator*=(const Vector<size, T>&),
* @ref operator*=(Vector<size, Integral>&, FloatingPoint)
*/
Vector<size, T>& operator*=(T number) {
for(std::size_t i = 0; i != size; ++i)
@ -353,9 +356,9 @@ template<std::size_t size, class T> class Vector {
/**
* @brief Multiply vector with number
*
* @see operator*(const Vector<size, T>&) const,
* operator*=(T), operator*(T, const Vector<size, T>&),
* operator*(const Vector<size, Integral>&, FloatingPoint)
* @see @ref operator*(const Vector<size, T>&) const,
* @ref operator*=(T), operator*(T, const Vector<size, T>&),
* @ref operator*(const Vector<size, Integral>&, FloatingPoint)
*/
Vector<size, T> operator*(T number) const {
return Vector<size, T>(*this) *= number;
@ -367,8 +370,8 @@ template<std::size_t size, class T> class Vector {
* The computation is done in-place. @f[
* \boldsymbol a_i = \frac{\boldsymbol a_i} b
* @f]
* @see operator/=(const Vector<size, T>&),
* operator/=(Vector<size, Integral>&, FloatingPoint)
* @see @ref operator/=(const Vector<size, T>&),
* @ref operator/=(Vector<size, Integral>&, FloatingPoint)
*/
Vector<size, T>& operator/=(T number) {
for(std::size_t i = 0; i != size; ++i)
@ -380,9 +383,9 @@ template<std::size_t size, class T> class Vector {
/**
* @brief Divide vector with number
*
* @see operator/(const Vector<size, T>&) const,
* operator/=(T), operator/(T, const Vector<size, T>&),
* operator/(const Vector<size, Integral>&, FloatingPoint)
* @see @ref operator/(const Vector<size, T>&) const,
* @ref operator/=(T), operator/(T, const Vector<size, T>&),
* @ref operator/(const Vector<size, Integral>&, FloatingPoint)
*/
Vector<size, T> operator/(T number) const {
return Vector<size, T>(*this) /= number;
@ -394,8 +397,8 @@ template<std::size_t size, class T> class Vector {
* The computation is done in-place. @f[
* \boldsymbol a_i = \boldsymbol a_i \boldsymbol b_i
* @f]
* @see operator*=(T),
* operator*=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
* @see @ref operator*=(T),
* @ref operator*=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
*/
Vector<size, T>& operator*=(const Vector<size, T>& other) {
for(std::size_t i = 0; i != size; ++i)
@ -407,8 +410,8 @@ template<std::size_t size, class T> class Vector {
/**
* @brief Multiply vector component-wise
*
* @see operator*(T) const, operator*=(const Vector<size, T>&),
* operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&),
* @see @ref operator*(T) const, @ref operator*=(const Vector<size, T>&),
* @ref operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&),
* @ref product()
*/
Vector<size, T> operator*(const Vector<size, T>& other) const {
@ -421,8 +424,8 @@ template<std::size_t size, class T> class Vector {
* The computation is done in-place. @f[
* \boldsymbol a_i = \frac{\boldsymbol a_i}{\boldsymbol b_i}
* @f]
* @see operator/=(T),
* operator/=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
* @see @ref operator/=(T),
* @ref operator/=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
*/
Vector<size, T>& operator/=(const Vector<size, T>& other) {
for(std::size_t i = 0; i != size; ++i)
@ -434,8 +437,8 @@ template<std::size_t size, class T> class Vector {
/**
* @brief Divide vector component-wise
*
* @see operator/(T) const, operator/=(const Vector<size, T>&),
* operator/(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
* @see @ref operator/(T) const, @ref operator/=(const Vector<size, T>&),
* @ref operator/(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
*/
Vector<size, T> operator/(const Vector<size, T>& other) const {
return Vector<size, T>(*this) /= other;
@ -444,22 +447,24 @@ template<std::size_t size, class T> class Vector {
/**
* @brief Dot product of the vector
*
* Should be used instead of length() for comparing vector length with
* other values, because it doesn't compute the square root. @f[
* Should be used instead of @ref length() for comparing vector length
* with other values, because it doesn't compute the square root. @f[
* \boldsymbol a \cdot \boldsymbol a = \sum_{i=0}^{n-1} \boldsymbol a_i^2
* @f]
* @see dot(const Vector<size, T>&, const Vector<size, T>&), isNormalized()
* @see @ref dot(const Vector<size, T>&, const Vector<size, T>&),
* @ref isNormalized()
*/
T dot() const { return dot(*this, *this); }
/**
* @brief %Vector length
*
* See also dot() const which is faster for comparing length with other
* values. @f[
* See also @ref dot() const which is faster for comparing length with
* other values. @f[
* |\boldsymbol a| = \sqrt{\boldsymbol a \cdot \boldsymbol a}
* @f]
* @see lengthInverted(), Math::sqrt(), normalized(), resized()
* @see @ref lengthInverted(), @ref Math::sqrt(), @ref normalized(),
* @ref resized()
* @todo something like std::hypot() for possibly better precision?
*/
T length() const { return std::sqrt(dot()); }
@ -470,14 +475,15 @@ template<std::size_t size, class T> class Vector {
* @f[
* \frac{1}{|\boldsymbol a|} = \frac{1}{\sqrt{\boldsymbol a \cdot \boldsymbol a}}
* @f]
* @see length(), Math::sqrtInverted(), normalized(), resized()
* @see @ref length(), @ref Math::sqrtInverted(), @ref normalized(),
* @ref resized()
*/
T lengthInverted() const { return T(1)/length(); }
/**
* @brief Normalized vector (of unit length)
*
* @see isNormalized(), lengthInverted(), resized()
* @see @ref isNormalized(), @ref lengthInverted(), @ref resized()
*/
Vector<size, T> normalized() const { return *this*lengthInverted(); }
@ -485,12 +491,12 @@ template<std::size_t size, class T> class Vector {
* @brief Resized vector
*
* Convenience equivalent to the following code. Due to operation order
* this function is faster than the obvious way of sizing normalized()
* vector.
* this function is faster than the obvious way of sizing
* @ref normalized() vector.
* @code
* vec*(vec.lengthInverted()*length) // the brackets are important
* @endcode
* @see normalized()
* @see @ref normalized()
*/
Vector<size, T> resized(T length) const {
return *this*(lengthInverted()*length);
@ -502,7 +508,7 @@ template<std::size_t size, class T> class Vector {
* Returns vector projected onto @p line. @f[
* \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b
* @f]
* @see dot(), projectedOntoNormalized()
* @see @ref dot(), @ref projectedOntoNormalized()
*/
Vector<size, T> projected(const Vector<size, T>& line) const {
return line*dot(*this, line)/line.dot();
@ -511,26 +517,27 @@ template<std::size_t size, class T> class Vector {
/**
* @brief %Vector projected onto normalized line
*
* Slightly faster alternative to projected(), expects @p line to be
* normalized. @f[
* Slightly faster alternative to @ref projected(), expects @p line to
* be normalized. @f[
* \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b =
* (\boldsymbol a \cdot \boldsymbol b) \boldsymbol b
* @f]
* @see dot()
* @see dot() const
* @todoc Explicit reference when Doxygen can handle const
*/
Vector<size, T> projectedOntoNormalized(const Vector<size, T>& line) const;
/**
* @brief Sum of values in the vector
*
* @see operator+()
* @see @ref operator+()
*/
T sum() const;
/**
* @brief Product of values in the vector
*
* @see operator*(const Vector<size, T>&) const
* @see @ref operator*(const Vector<size, T>&) const
*/
T product() const;
@ -575,7 +582,7 @@ template<std::size_t size, class T> class Vector {
/** @relates Vector
@brief Multiply number with vector
Same as Vector::operator*(T) const.
Same as @ref Vector::operator*(T) const.
*/
template<std::size_t size, class T> inline Vector<size, T> operator*(
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -594,7 +601,7 @@ template<std::size_t size, class T> inline Vector<size, T> operator*(
@f[
\boldsymbol c_i = \frac b {\boldsymbol a_i}
@f]
@see Vector::operator/(T) const
@see @ref Vector::operator/(T) const
*/
template<std::size_t size, class T> inline Vector<size, T> operator/(
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -883,8 +890,8 @@ operator>>(const Vector<size, Integral>& vector,
/** @relates Vector
@brief Multiply integral vector with floating-point number and assign
Similar to Vector::operator*=(T), except that the multiplication is done in
floating-point. The computation is done in-place.
Similar to @ref Vector::operator*=(T), except that the multiplication is done
in floating-point. The computation is done in-place.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -902,8 +909,8 @@ operator*=(Vector<size, Integral>& vector, FloatingPoint number) {
/** @relates Vector
@brief Multiply integral vector with floating-point number
Similar to Vector::operator*(T) const, except that the multiplication is done
in floating-point.
Similar to @ref Vector::operator*(T) const, except that the multiplication is
done in floating-point.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -919,7 +926,7 @@ operator*(const Vector<size, Integral>& vector, FloatingPoint number) {
/** @relates Vector
@brief Multiply floating-point number with integral vector
Same as operator*(const Vector<size, Integral>&, FloatingPoint).
Same as @ref operator*(const Vector<size, Integral>&, FloatingPoint).
*/
template<std::size_t size, class FloatingPoint, class Integral> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -934,7 +941,7 @@ operator*(FloatingPoint number, const Vector<size, Integral>& vector) {
/** @relates Vector
@brief Divide integral vector with floating-point number and assign
Similar to Vector::operator/=(T), except that the division is done in
Similar to @ref Vector::operator/=(T), except that the division is done in
floating-point. The computation is done in-place.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
@ -953,7 +960,7 @@ operator/=(Vector<size, Integral>& vector, FloatingPoint number) {
/** @relates Vector
@brief Divide integral vector with floating-point number
Similar to Vector::operator/(T) const, except that the division is done in
Similar to @ref Vector::operator/(T) const, except that the division is done in
floating-point.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
@ -970,7 +977,7 @@ operator/(const Vector<size, Integral>& vector, FloatingPoint number) {
/** @relates Vector
@brief Multiply integral vector with floating-point vector component-wise and assign
Similar to Vector::operator*=(const Vector<size, T>&), except that the
Similar to @ref Vector::operator*=(const Vector<size, T>&), except that the
multiplication is done in floating-point. The computation is done in-place.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
@ -989,10 +996,10 @@ operator*=(Vector<size, Integral>& a, const Vector<size, FloatingPoint>& b) {
/** @relates Vector
@brief Multiply integral vector with floating-point vector component-wise
Similar to Vector::operator*(const Vector<size, T>&) const, except that the
multiplication is done in floating-point. The result is always integral vector,
convert both arguments to the same floating-point type to have floating-point
result.
Similar to @ref Vector::operator*(const Vector<size, T>&) const, except that
the multiplication is done in floating-point. The result is always integral
vector, convert both arguments to the same floating-point type to have
floating-point result.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -1008,7 +1015,7 @@ operator*(const Vector<size, Integral>& a, const Vector<size, FloatingPoint>& b)
/** @relates Vector
@brief Multiply floating-point vector with integral vector component-wise
Same as operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&).
Same as @ref operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&).
*/
template<std::size_t size, class FloatingPoint, class Integral> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -1023,8 +1030,8 @@ operator*(const Vector<size, FloatingPoint>& a, const Vector<size, Integral>& b)
/** @relates Vector
@brief Divide integral vector with floating-point vector component-wise and assign
Similar to Vector::operator/=(const Vector<size, T>&), except that the division
is done in floating-point. The computation is done in-place.
Similar to @ref Vector::operator/=(const Vector<size, T>&), except that the
division is done in floating-point. The computation is done in-place.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -1042,8 +1049,8 @@ operator/=(Vector<size, Integral>& a, const Vector<size, FloatingPoint>& b) {
/** @relates Vector
@brief Divide integral vector with floating-point vector component-wise
Similar to Vector::operator/(const Vector<size, T>&) const, except that the
division is done in floating-point. The result is always integral vector,
Similar to @ref Vector::operator/(const Vector<size, T>&) const, except that
the division is done in floating-point. The result is always integral vector,
convert both arguments to the same floating-point type to have floating-point
result.
*/

28
src/Magnum/Math/Vector2.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Vector2
* @brief Class @ref Magnum::Math::Vector2
*/
#include "Magnum/Math/Vector.h"
@ -38,7 +38,8 @@ namespace Magnum { namespace Math {
@tparam T Data type
See @ref matrix-vector for brief introduction.
@see Magnum::Vector2, Magnum::Vector2i, Magnum::Vector2ui, Magnum::Vector2d
@see @ref Magnum::Vector2, @ref Magnum::Vector2i, @ref Magnum::Vector2ui,
@ref Magnum::Vector2d
@configurationvalueref{Magnum::Math::Vector2}
*/
template<class T> class Vector2: public Vector<2, T> {
@ -50,15 +51,15 @@ template<class T> class Vector2: public Vector<2, T> {
* @code
* Matrix3::translation(Vector2::xAxis(5.0f)); // same as Matrix3::translation({5.0f, 0.0f});
* @endcode
* @see yAxis(), xScale(), Matrix3::right()
* @see @ref yAxis(), @ref xScale(), @ref Matrix3::right()
*/
constexpr static Vector2<T> xAxis(T length = T(1)) { return {length, T(0)}; }
/**
* @brief %Vector in direction of Y axis (up)
*
* See xAxis() for more information.
* @see yScale(), Matrix3::up()
* See @ref xAxis() for more information.
* @see @ref yScale(), @ref Matrix3::up()
*/
constexpr static Vector2<T> yAxis(T length = T(1)) { return {T(0), length}; }
@ -69,15 +70,15 @@ template<class T> class Vector2: public Vector<2, T> {
* @code
* Matrix3::scaling(Vector2::xScale(-2.0f)); // same as Matrix3::scaling({-2.0f, 1.0f});
* @endcode
* @see yScale(), xAxis()
* @see @ref yScale(), @ref xAxis()
*/
constexpr static Vector2<T> xScale(T scale) { return {scale, T(1)}; }
/**
* @brief Scaling vector in direction of Y axis (height)
*
* See xScale() for more information.
* @see yAxis()
* See @ref xScale() for more information.
* @see @ref yAxis()
*/
constexpr static Vector2<T> yScale(T scale) { return {T(1), scale}; }
@ -85,12 +86,13 @@ template<class T> class Vector2: public Vector<2, T> {
* @brief 2D cross product
*
* 2D version of cross product, also called perp-dot product,
* equivalent to calling Vector3::cross() with Z coordinate set to `0`
* and extracting only Z coordinate from the result (X and Y
* equivalent to calling @ref Vector3::cross() with Z coordinate set to
* `0` and extracting only Z coordinate from the result (X and Y
* coordinates are always zero). @f[
* \boldsymbol a \times \boldsymbol b = \boldsymbol a_\bot \cdot \boldsymbol b = a_xb_y - a_yb_x
* @f]
* @see perpendicular(), dot(const Vector&, const Vector&)
* @see @ref perpendicular(),
* @ref dot(const Vector<size, T>&, const Vector<size, T>&)
*/
static T cross(const Vector2<T>& a, const Vector2<T>& b) {
return Vector<2, T>::dot(a.perpendicular(), b);
@ -135,7 +137,9 @@ template<class T> class Vector2: public Vector<2, T> {
* Returns vector rotated 90° counterclockwise. @f[
* \boldsymbol v_\bot = \begin{pmatrix} -v_y \\ v_x \end{pmatrix}
* @f]
* @see cross(), dot(const Vector&, const Vector&), operator-() const
* @see @ref cross(),
* @ref dot(const Vector<size, T>&, const Vector<size, T>&),
* @ref operator-() const
*/
Vector2<T> perpendicular() const { return {-y(), x()}; }

9
src/Magnum/Math/Vector3.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class Magnum::Math::Vector3
* @brief Class @ref Magnum::Math::Vector3
*/
#include "Magnum/Math/Vector2.h"
@ -39,7 +39,8 @@ namespace Magnum { namespace Math {
@tparam T Data type
See @ref matrix-vector for brief introduction.
@see Magnum::Vector3, Magnum::Vector3i, Magnum::Vector3ui, Magnum::Vector3d
@see @ref Magnum::Vector3, @ref Magnum::Vector3i, @ref Magnum::Vector3ui,
@ref Magnum::Vector3d
@configurationvalueref{Magnum::Math::Vector3}
*/
template<class T> class Vector3: public Vector<3, T> {
@ -107,7 +108,7 @@ template<class T> class Vector3: public Vector<3, T> {
* \boldsymbol a \times \boldsymbol b =
* \begin{pmatrix}a_yb_z - a_zb_y \\ a_zb_y - a_xb_z \\ a_xb_y - a_yb_x \end{pmatrix}
* @f]
* @see Vector2::cross()
* @see @ref Vector2::cross()
*/
static Vector3<T> cross(const Vector3<T>& a, const Vector3<T>& b) {
return swizzle<'y', 'z', 'x'>(a)*swizzle<'z', 'x', 'y'>(b) -
@ -203,7 +204,7 @@ template<class T> class Vector3: public Vector<3, T> {
* @brief XY part of the vector
* @return First two components of the vector
*
* @see swizzle()
* @see @ref swizzle()
*/
Vector2<T>& xy() { return Vector2<T>::from(Vector<3, T>::data()); }
constexpr const Vector2<T> xy() const { return {x(), y()}; } /**< @overload */

3
src/Magnum/Math/Vector4.h

@ -38,7 +38,8 @@ namespace Magnum { namespace Math {
@tparam T Data type
See @ref matrix-vector for brief introduction.
@see Magnum::Vector4, Magnum::Vector4i, Magnum::Vector4ui, Magnum::Vector4d
@see @ref Magnum::Vector4, @ref Magnum::Vector4i, @ref Magnum::Vector4ui,
@ref Magnum::Vector4d
@configurationvalueref{Magnum::Math::Vector4}
*/
template<class T> class Vector4: public Vector<4, T> {

1
src/Magnum/Mesh.cpp

@ -307,6 +307,7 @@ void Mesh::createImplementationVAO() {
//glGenVertexArraysOES(1, &_id);
CORRADE_INTERNAL_ASSERT(false);
#endif
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
void Mesh::destroyImplementationDefault() {}

23
src/Magnum/Mesh.h

@ -743,18 +743,21 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
/**
* @brief Draw the mesh
* @param shader Shader to use for drawing
* @param shader %Shader to use for drawing
*
* Expects that the shader is compatible with this mesh and is fully
* set up. If vertex/index count or instance count is `0`, no draw
* commands are issued. See also
* @ref AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation"
* for more information.
* @see @ref setCount(), @ref setInstanceCount(), @fn_gl{UseProgram},
* @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer},
* @fn_gl{VertexAttribPointer}, @fn_gl{DisableVertexAttribArray}
* or @fn_gl{BindVertexArray} (if @extension{APPLE,vertex_array_object}
* is available), @fn_gl{DrawArrays}/@fn_gl{DrawArraysInstanced}/
* @see @ref setCount(), @ref setInstanceCount(),
* @ref MeshView::draw(AbstractShaderProgram&),
* @ref MeshView::draw(AbstractShaderProgram&, std::initializer_list<std::reference_wrapper<MeshView>>),
* @fn_gl{UseProgram}, @fn_gl{EnableVertexAttribArray},
* @fn_gl{BindBuffer}, @fn_gl{VertexAttribPointer},
* @fn_gl{DisableVertexAttribArray} or @fn_gl{BindVertexArray} (if
* @extension{APPLE,vertex_array_object} is available),
* @fn_gl{DrawArrays}/@fn_gl{DrawArraysInstanced}/
* @fn_gl{DrawArraysInstancedBaseInstance} or @fn_gl{DrawElements}/
* @fn_gl{DrawRangeElements}/@fn_gl{DrawElementsBaseVertex}/
* @fn_gl{DrawRangeElementsBaseVertex}/@fn_gl{DrawElementsInstanced}/
@ -985,17 +988,17 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
#endif
};
/** @debugoperator{Magnum::Mesh} */
/** @debugoperatorenum{Magnum::MeshPrimitive} */
Debug MAGNUM_EXPORT operator<<(Debug debug, MeshPrimitive value);
/** @debugoperator{Magnum::Mesh} */
/** @debugoperatorclassenum{Magnum::Mesh,Magnum::Mesh::IndexType} */
Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::IndexType value);
}
namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::Mesh} */
/** @configurationvalue{Magnum::MeshPrimitive} */
template<> struct MAGNUM_EXPORT ConfigurationValue<Magnum::MeshPrimitive> {
ConfigurationValue() = delete;
@ -1014,7 +1017,7 @@ template<> struct MAGNUM_EXPORT ConfigurationValue<Magnum::MeshPrimitive> {
static Magnum::MeshPrimitive fromString(const std::string& stringValue, ConfigurationValueFlags);
};
/** @configurationvalue{Magnum::Mesh} */
/** @configurationvalue{Magnum::Mesh::IndexType} */
template<> struct MAGNUM_EXPORT ConfigurationValue<Magnum::Mesh::IndexType> {
ConfigurationValue() = delete;

4
src/Magnum/MeshTools/CombineIndexedArrays.h

@ -194,8 +194,8 @@ template<class ...T> std::vector<UnsignedInt> combineIndexedArrays(const std::pa
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @copybrief combineIndexedArrays(const std::pair<const std::vector<UnsignedInt>&, std::vector<T>&>&...)
* @deprecated Use @ref Magnum::MeshTools::combineIndexedArrays(const std::pair<const std::vector<UnsignedInt>&, std::vector<T>&>&...) "combineIndexedArrays(const std::pair<const std::vector<UnsignedInt>&, std::vector<T>&>&...)" instead.
* @copybrief combineIndexedArrays()
* @deprecated Use @ref Magnum::MeshTools::combineIndexedArrays() "combineIndexedArrays(const std::pair<const std::vector<UnsignedInt>&, std::vector<T>&>&...)" instead.
*/
template<class ...T> inline CORRADE_DEPRECATED("use combineIndexedArrays(const std::pair<const std::vector<UnsignedInt>&, std::vector<T>&>&...) instead") std::vector<UnsignedInt> combineIndexedArrays(const std::tuple<const std::vector<UnsignedInt>&, std::vector<T>&>&... indexedArrays) {
return combineIndexedArrays(std::make_pair(std::cref(std::get<0>(indexedArrays)), std::ref(std::get<1>(indexedArrays)))...);

7
src/Magnum/MeshTools/CompressIndices.h

@ -78,14 +78,13 @@ std::tuple<Containers::Array<char>, Mesh::IndexType, UnsignedInt, UnsignedInt> M
@param usage Index buffer usage
@param indices Index array
@deprecated Use general-purpose
@ref Magnum::MeshTools::compressIndices(const std::vector<UnsignedInt>&) "compressIndices(const std::vector<UnsignedInt>&)"
instead.
The same as @ref compressIndices(const std::vector<UnsignedInt>&), but this
function writes the output to given buffer and calls @ref Mesh::setCount() and
@ref Mesh::setIndexBuffer(), thus you don't need to do anything else for mesh
index configuration.
@deprecated Use general-purpose
@ref Magnum::MeshTools::compressIndices(const std::vector<UnsignedInt>&) "compressIndices(const std::vector<UnsignedInt>&)"
instead.
*/
void MAGNUM_MESHTOOLS_EXPORT compressIndices(Mesh& mesh, Buffer& buffer, BufferUsage usage, const std::vector<UnsignedInt>& indices);
#endif

15
src/Magnum/MeshTools/FlipNormals.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function Magnum::MeshTools::flipNormals()
* @brief Function @ref Magnum::MeshTools::flipFaceWinding(), @ref Magnum::MeshTools::flipNormals()
*/
#include <vector>
@ -38,16 +38,21 @@ namespace Magnum { namespace MeshTools {
/**
@brief Flip face winding
@param[in,out] indices Index array to operate on
The same as flipNormals(std::vector<UnsignedInt>&, std::vector<Vector3>&),
The same as @ref flipNormals(std::vector<UnsignedInt>&, std::vector<Vector3>&),
but flips only face winding.
@attention The function requires the mesh to have triangle faces, thus index
count must be divisible by 3.
*/
void MAGNUM_MESHTOOLS_EXPORT flipFaceWinding(std::vector<UnsignedInt>& indices);
/**
@brief Flip mesh normals
@param[in,out] normals Normal array to operate on
The same as flipNormals(std::vector<UnsignedInt>&, std::vector<Vector3>&),
The same as @ref flipNormals(std::vector<UnsignedInt>&, std::vector<Vector3>&),
but flips only normals, not face winding.
*/
void MAGNUM_MESHTOOLS_EXPORT flipNormals(std::vector<Vector3>& normals);
@ -58,8 +63,8 @@ void MAGNUM_MESHTOOLS_EXPORT flipNormals(std::vector<Vector3>& normals);
@param[in,out] normals Normal array to operate on
Flips normal vectors and face winding in index array for face culling to work
properly too. See also flipNormals(std::vector<Vector3>&) and
flipFaceWinding(), which flip normals or face winding only.
properly too. See also @ref flipNormals(std::vector<Vector3>&) and
@ref flipFaceWinding(), which flip normals or face winding only.
@attention The function requires the mesh to have triangle faces, thus index
count must be divisible by 3.

10
src/Magnum/MeshTools/GenerateFlatNormals.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function Magnum::MeshTools::generateFlatNormals()
* @brief Function @ref Magnum::MeshTools::generateFlatNormals()
*/
#include <tuple>
@ -53,11 +53,11 @@ std::vector<UnsignedInt> normalIndices;
std::vector<Vector3> normals;
std::tie(normalIndices, normals) = MeshTools::generateFlatNormals(vertexIndices, positions);
@endcode
You can then use combineIndexedArrays() to combine normal and vertex array to
use the same indices.
You can then use @ref combineIndexedArrays() to combine normal and vertex array
to use the same indices.
@attention Index count must be divisible by 3, otherwise zero length result
is generated.
@attention The function requires the mesh to have triangle faces, thus index
count must be divisible by 3.
*/
std::tuple<std::vector<UnsignedInt>, std::vector<Vector3>> MAGNUM_MESHTOOLS_EXPORT generateFlatNormals(const std::vector<UnsignedInt>& indices, const std::vector<Vector3>& positions);

16
src/Magnum/MeshTools/Interleave.h

@ -193,10 +193,6 @@ template<class T, class ...U> void interleaveInto(Containers::ArrayReference<cha
@param usage Vertex buffer usage
@param attributes Attribute arrays and gaps
@deprecated Use general-purpose
@ref Magnum::MeshTools::interleave(const T&...) "interleave(const T&...)"
instead.
The same as @ref interleave(const T&, const U&...), but this function also
writes the output to given array buffer. If given mesh is not indexed, it also
updates vertex count in the mesh accordingly, so you don't have to call
@ -206,6 +202,10 @@ updates vertex count in the mesh accordingly, so you don't have to call
@ref Mesh::addVertexBuffer() on the mesh afterwards.
@see @ref compressIndices(), @ref compile()
@deprecated Use general-purpose
@ref Magnum::MeshTools::interleave(const T&...) "interleave(const T&...)"
instead.
*/
template<class ...T> CORRADE_DEPRECATED("Use interleave(const T&...) instead") void interleave(Mesh& mesh, Buffer& buffer, BufferUsage usage, const T&... attributes) {
if(!mesh.isIndexed()) mesh.setCount(Implementation::AttributeCount{}(attributes...));
@ -215,16 +215,16 @@ template<class ...T> CORRADE_DEPRECATED("Use interleave(const T&...) instead") v
/**
@brief Write vertex attribute to array buffer and configure the mesh
@deprecated Use general-purpose
@ref Magnum::MeshTools::interleave(const T&...) "interleave(const T&...)"
instead.
Simplified specialization of the above function for only one attribute array,
equivalent to the following:
@code
if(!mesh.isIndexed()) mesh.setCount(attribute.size());
buffer.setData(attribute, usage);
@endcode
@deprecated Use general-purpose
@ref Magnum::MeshTools::interleave(const T&...) "interleave(const T&...)"
instead.
*/
template<class T> CORRADE_DEPRECATED("Use interleave(const T&...) instead") typename std::enable_if<!std::is_convertible<T, std::size_t>::value, void>::type interleave(Mesh& mesh, Buffer& buffer, BufferUsage usage, const T& attribute) {
if(!mesh.isIndexed()) mesh.setCount(attribute.size());

2
src/Magnum/MeshTools/Subdivide.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function Magnum::MeshTools::subdivide()
* @brief Function @ref Magnum::MeshTools::subdivide()
*/
#include <vector>

2
src/Magnum/MeshTools/Test/GenerateFlatNormalsTest.cpp

@ -51,7 +51,7 @@ void GenerateFlatNormalsTest::wrongIndexCount() {
std::vector<Vector3> normals;
std::tie(indices, normals) = MeshTools::generateFlatNormals({
0, 1
}, std::vector<Vector3>{});
}, {});
CORRADE_COMPARE(indices.size(), 0);
CORRADE_COMPARE(normals.size(), 0);

2
src/Magnum/MeshTools/Tipsify.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function Magnum::MeshTools::tipsify()
* @brief Function @ref Magnum::MeshTools::tipsify()
*/
#include <vector>

20
src/Magnum/MeshTools/Transform.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function Magnum::MeshTools::transformVectorsInPlace(), Magnum::MeshTools::transformVectors(), Magnum::MeshTools::transformPointsInPlace(), Magnum::MeshTools::transformPoints()
* @brief Function @ref Magnum::MeshTools::transformVectorsInPlace(), @ref Magnum::MeshTools::transformVectors(), @ref Magnum::MeshTools::transformPointsInPlace(), @ref Magnum::MeshTools::transformPoints()
*/
#include "Magnum/Math/DualQuaternion.h"
@ -43,7 +43,7 @@ with compatible vector type as @p vectors. Expects that @ref Math::Quaternion "Q
is normalized, no further requirements are for other transformation
representations.
Unlike in transformPointsInPlace(), the transformation does not involve
Unlike in @ref transformPointsInPlace(), the transformation does not involve
translation.
Example usage:
@ -53,8 +53,9 @@ auto transformation = Quaternion::rotation(35.0_degf, Vector3::yAxis());
MeshTools::transformVectorsInPlace(rotation, vectors);
@endcode
@see transformVectors(), Matrix3::transformVector(), Matrix4::transformVector(),
Complex::transformVectorNormalized(), Quaternion::transformVectorNormalized()
@see @ref transformVectors(), @ref Matrix3::transformVector(),
@ref Matrix4::transformVector(), @ref Complex::transformVector(),
@ref Quaternion::transformVectorNormalized()
@todo GPU transform feedback implementation (otherwise this is only bad joke)
*/
template<class T, class U> void transformVectorsInPlace(const Math::Quaternion<T>& normalizedQuaternion, U& vectors) {
@ -84,7 +85,7 @@ template<class T, class U> void transformVectorsInPlace(const Math::Matrix4<T>&
@brief Transform vectors using given transformation
Returns transformed vectors instead of modifying them in-place. See
transformVectorsInPlace() for more information.
@ref transformVectorsInPlace() for more information.
*/
template<class T, class U> U transformVectors(const T& transformation, U vectors) {
U result(std::move(vectors));
@ -101,7 +102,7 @@ with compatible vector type as @p vectors. Expects that
@ref Math::DualQuaternion "DualQuaternion" is normalized, no further
requirements are for other transformation representations.
Unlike in transformVectorsInPlace(), the transformation also involves
Unlike in @ref transformVectorsInPlace(), the transformation also involves
translation.
Example usage:
@ -112,8 +113,9 @@ auto transformation = DualQuaternion::rotation(35.0_degf, Vector3::yAxis())*
MeshTools::transformPointsInPlace(rotation, points);
@endcode
@see transformPoints(), Matrix3::transformPoint(), Matrix4::transformPoint(),
DualQuaternion::transformPointNormalized()
@see @ref transformPoints(), @ref Matrix3::transformPoint(),
@ref Matrix4::transformPoint(),
@ref DualQuaternion::transformPointNormalized()
*/
template<class T, class U> void transformPointsInPlace(const Math::DualQuaternion<T>& normalizedDualQuaternion, U& points) {
for(auto it = points.begin(); it != points.end(); ++it)
@ -142,7 +144,7 @@ template<class T, class U> void transformPointsInPlace(const Math::Matrix4<T>& m
@brief Transform points using given transformation
Returns transformed points instead of modifying them in-place. See
transformPointsInPlace() for more information.
@ref transformPointsInPlace() for more information.
*/
template<class T, class U> U transformPoints(const T& transformation, U vectors) {
U result(std::move(vectors));

119
src/Magnum/MeshView.cpp

@ -25,12 +25,117 @@
#include "MeshView.h"
#include <Corrade/Containers/Array.h>
#include <Corrade/Utility/Assert.h>
#include "Magnum/Context.h"
#include "Magnum/Mesh.h"
#include "Implementation/State.h"
#include "Implementation/MeshState.h"
namespace Magnum {
void MeshView::draw(AbstractShaderProgram& shader, std::initializer_list<std::reference_wrapper<MeshView>> meshes) {
/* Why std::initializer_list doesn't have empty()? */
if(!meshes.size()) return;
shader.use();
#ifndef CORRADE_NO_ASSERT
const Mesh* original = &meshes.begin()->get()._original.get();
for(MeshView& mesh: meshes)
CORRADE_ASSERT(&mesh._original.get() == original, "MeshView::draw(): all meshes must be views of the same original mesh", );
#endif
#ifndef MAGNUM_TARGET_GLES
multiDrawImplementationDefault(meshes);
#else
Context::current()->state().mesh->multiDrawImplementation(meshes);
#endif
}
void MeshView::multiDrawImplementationDefault(std::initializer_list<std::reference_wrapper<MeshView>> meshes) {
CORRADE_INTERNAL_ASSERT(meshes.size());
const Implementation::MeshState& state = *Context::current()->state().mesh;
Mesh& original = meshes.begin()->get()._original;
Containers::Array<GLsizei> count{meshes.size()};
Containers::Array<GLvoid*> indices{meshes.size()};
Containers::Array<GLint> baseVertex{meshes.size()};
/* Gather the parameters */
#ifndef MAGNUM_TARGET_GLES
bool hasBaseVertex = false;
#endif
std::size_t i = 0;
for(MeshView& mesh: meshes) {
CORRADE_ASSERT(mesh._instanceCount == 1, "MeshView::draw(): cannot draw multiple instanced meshes", );
count[i] = mesh._count;
indices[i] = reinterpret_cast<GLvoid*>(mesh._indexOffset);
baseVertex[i] = mesh._baseVertex;
if(mesh._baseVertex) {
#ifndef MAGNUM_TARGET_GLES
hasBaseVertex = true;
#else
CORRADE_ASSERT(!original._indexBuffer, "MeshView::draw(): desktop OpenGL is required for base vertex specification in indexed meshes", );
#endif
}
++i;
}
(original.*state.bindImplementation)();
/* Non-indexed meshes */
if(!original._indexBuffer) {
#ifndef MAGNUM_TARGET_GLES
glMultiDrawArrays(GLenum(original._primitive), baseVertex, count, meshes.size());
#else
//glMultiDrawArraysEXT(GLenum(original._primitive), baseVertex, count, meshes.size());
CORRADE_INTERNAL_ASSERT(false);
#endif
/* Indexed meshes */
} else {
/* Indexed meshes with base vertex */
#ifndef MAGNUM_TARGET_GLES
if(hasBaseVertex) {
glMultiDrawElementsBaseVertex(GLenum(original._primitive), count, GLenum(original._indexType), indices, meshes.size(), baseVertex);
/* Indexed meshes */
} else
#endif
{
#ifndef MAGNUM_TARGET_GLES
glMultiDrawElements(GLenum(original._primitive), count, GLenum(original._indexType), indices, meshes.size());
#else
//glMultiDrawElements(GLenum(original._primitive), count, GLenum(original._indexType), indices, meshes.size());
CORRADE_INTERNAL_ASSERT(false);
#endif
}
}
(original.*state.unbindImplementation)();
}
#ifdef MAGNUM_TARGET_GLES
void MeshView::multiDrawImplementationFallback(std::initializer_list<std::reference_wrapper<MeshView>> meshes) {
for(MeshView& mesh: meshes) {
#ifndef MAGNUM_TARGET_GLES2
mesh._original.drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._indexOffset, mesh._indexStart, mesh._indexEnd);
#else
mesh._original.drawInternal(mesh._count, mesh._baseVertex, mesh._instanceCount, mesh._indexOffset);
#endif
}
}
#endif
MeshView& MeshView::setIndexRange(Int first) {
_indexOffset = _original->_indexOffset + first*_original->indexSize();
_indexOffset = _original.get()._indexOffset + first*_original.get().indexSize();
return *this;
}
@ -38,22 +143,22 @@ void MeshView::draw(AbstractShaderProgram& shader) {
shader.use();
#ifndef MAGNUM_TARGET_GLES
_original->drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd);
_original.get().drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd);
#elif !defined(MAGNUM_TARGET_GLES2)
_original->drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd);
_original.get().drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd);
#else
_original->drawInternal(_count, _baseVertex, _instanceCount, _indexOffset);
_original.get().drawInternal(_count, _baseVertex, _instanceCount, _indexOffset);
#endif
}
#ifdef MAGNUM_BUILD_DEPRECATED
void MeshView::draw() {
#ifndef MAGNUM_TARGET_GLES
_original->drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd);
_original.get().drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd);
#elif !defined(MAGNUM_TARGET_GLES2)
_original->drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd);
_original.get().drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd);
#else
_original->drawInternal(_count, _baseVertex, _instanceCount, _indexOffset);
_original.get().drawInternal(_count, _baseVertex, _instanceCount, _indexOffset);
#endif
}
#endif

37
src/Magnum/MeshView.h

@ -29,12 +29,17 @@
* @brief Class @ref Magnum::MeshView
*/
#include <functional>
#include <initializer_list>
#include "Magnum/Magnum.h"
#include "Magnum/OpenGL.h"
#include "Magnum/visibility.h"
namespace Magnum {
namespace Implementation { struct MeshState; }
/**
@brief %Mesh view
@ -52,7 +57,31 @@ You must ensure that the original mesh remains available for whole view
lifetime.
*/
class MAGNUM_EXPORT MeshView {
friend struct Implementation::MeshState;
public:
/**
* @brief Draw multiple meshes at once
*
* In OpenGL ES, if @es_extension2{EXT,multi_draw_arrays,multi_draw_arrays}
* is not present, the functionality is emulated using sequence of
* @ref draw(AbstractShaderProgram&) calls.
* @attention All meshes must be views of the same original mesh and
* must not be instanced.
* @see @ref draw(AbstractShaderProgram&), @fn_gl{UseProgram},
* @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer},
* @fn_gl{VertexAttribPointer}, @fn_gl{DisableVertexAttribArray}
* or @fn_gl{BindVertexArray} (if @extension{APPLE,vertex_array_object}
* is available), @fn_gl{MultiDrawArrays} or
* @fn_gl{MultiDrawElements}/@fn_gl{MultiDrawElementsBaseVertex}
*/
static void draw(AbstractShaderProgram& shader, std::initializer_list<std::reference_wrapper<MeshView>> meshes);
/** @overload */
static void draw(AbstractShaderProgram&& shader, std::initializer_list<std::reference_wrapper<MeshView>> meshes) {
draw(shader, meshes);
}
/**
* @brief Constructor
* @param original Original, already configured mesh
@ -212,6 +241,7 @@ class MAGNUM_EXPORT MeshView {
* @brief Draw the mesh
*
* See @ref Mesh::draw() for more information.
* @see @ref draw(AbstractShaderProgram&, std::initializer_list<std::reference_wrapper<MeshView>>)
*/
void draw(AbstractShaderProgram& shader);
void draw(AbstractShaderProgram&& shader) { draw(shader); } /**< @overload */
@ -226,7 +256,10 @@ class MAGNUM_EXPORT MeshView {
#endif
private:
Mesh* _original;
static MAGNUM_LOCAL void multiDrawImplementationDefault(std::initializer_list<std::reference_wrapper<MeshView>> meshes);
static MAGNUM_LOCAL void multiDrawImplementationFallback(std::initializer_list<std::reference_wrapper<MeshView>> meshes);
std::reference_wrapper<Mesh> _original;
Int _count, _baseVertex, _instanceCount;
#ifndef MAGNUM_TARGET_GLES
@ -238,7 +271,7 @@ class MAGNUM_EXPORT MeshView {
#endif
};
inline MeshView::MeshView(Mesh& original): _original(&original), _count(0), _baseVertex(0), _instanceCount{1},
inline MeshView::MeshView(Mesh& original): _original(original), _count(0), _baseVertex(0), _instanceCount{1},
#ifndef MAGNUM_TARGET_GLES
_baseInstance{0},
#endif

2
src/Magnum/MultisampleTexture.h

@ -65,7 +65,7 @@ Template class for 2D mulitsample texture and 2D multisample texture array.
Used only from shaders for manual multisample resolve and other operations. See
also @ref AbstractTexture documentation for more information.
@section Texture-usage Usage
@section MultisampleTexture-usage Usage
As multisample textures have no sampler state, the only thing you need is to
set storage:

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

Loading…
Cancel
Save