Browse Source

Updated the main documentation pages for the new theme.

Not fully proofreading them yet, takes too much time.
pull/225/head
Vladimír Vondruš 9 years ago
parent
commit
341a2cb2df
  1. 92
      README.md
  2. 9
      doc/00-page-order.dox
  3. 13
      doc/best-practices.dox
  4. 337
      doc/building.dox
  5. 156
      doc/cmake.dox
  6. 2
      doc/coding-style.dox
  7. 41
      doc/compilation-speedup.dox
  8. 12
      doc/debug-tools.dox
  9. 20
      doc/features.dox
  10. BIN
      doc/getting-started-blue.png
  11. 199
      doc/getting-started.dox
  12. BIN
      doc/getting-started.png
  13. 84
      doc/mainpage.dox
  14. 305
      doc/matrix-vector.dox
  15. 16
      doc/method-chaining.dox
  16. 9
      doc/openal-support.dox
  17. 5
      doc/openal.dox
  18. 51
      doc/opengl-mapping.dox
  19. 36
      doc/opengl-support.dox
  20. 60
      doc/opengl-wrapping.dox
  21. 88
      doc/opengl.dox
  22. 84
      doc/platform.dox
  23. 41
      doc/plugins.dox
  24. 85
      doc/portability.dox
  25. 142
      doc/scenegraph.dox
  26. 33
      doc/shaders.dox
  27. 75
      doc/shapes.dox
  28. 10
      doc/tips.dox
  29. 73
      doc/transformations.dox
  30. 8
      doc/troubleshooting.dox
  31. 107
      doc/types.dox
  32. 10
      doc/utilities.dox

92
README.md

@ -1,4 +1,4 @@
Magnum is 2D/3D graphics engine written in C++11/C++14 and modern OpenGL. Its Magnum is a 2D/3D graphics engine written in C++11/C++14 and modern OpenGL. Its
goal is to simplify low-level graphics development and interaction with OpenGL goal is to simplify low-level graphics development and interaction with OpenGL
using recent C++11/C++14 features and to abstract away platform-specific using recent C++11/C++14 features and to abstract away platform-specific
issues. issues.
@ -8,36 +8,35 @@ issues.
DESIGN GOALS DESIGN GOALS
============ ============
* **2D is not an ugly stepchild** * **2D is not an ugly stepchild.** Many engines out there were created as
Many engines out there were created as pure 2D or 3D and the alternative is pure 2D or 3D and the alternative is usually just an afterthought, if
usually just an afterthought, if it is present at all. If you want to do present at all. If you want to do your next project in 2D only, you have to
your next project in 2D only, you have to either relearn another engine either relearn another engine from scratch or emulate it in 3D, leaving
from scratch or emulate it in 3D, leaving many things overly complicated. many things overly complicated. Magnum treats 2D equivalently to 3D so you
Magnum treats 2D equivalently to 3D so you can reuse what you already can reuse what you already learned for 3D and even combine 2D and 3D in one
learned for 3D and even combine 2D and 3D in one project. project.
* **Forward compatibility** * **Forward compatibility.** If newer technology makes things faster, simpler
If newer technology makes things faster, simpler or more intuitive, it is or more intuitive, it is the way to go. Magnum by default relies on decent
the way to go. Magnum by default relies on decent C++11 support and modern C++11 support and modern OpenGL features and if some feature isn't
OpenGL features and if some feature isn't available, it tries to emulate it available, it tries to emulate it using older functionality. However, you
using older functionality. However, you are not restricted to use the older are not restricted to use the older functionality directly, if you really
functionality directly, if you really want to. want to.
* **Intuitive, but not restrictive API** * **Intuitive, but not restrictive API.** Scripting languages are often
Scripting languages are often preferred to C/C++ because they are designed preferred to C/C++ because they are designed to have less complicated APIs
to have less complicated APIs and less boilerplate code. Magnum is and less boilerplate code. Magnum is designed with intuitivity in mind, but
designed with intuitivity in mind, but also with speed and static checks also with speed and static checks that strongly-typed native code offers.
that strongly-typed native code offers. It wraps OpenGL into less verbose It wraps OpenGL into less verbose and more type-safe API, which is easier
and more type-safe API, which is easier to use. Usually the most common way to use. Usually the most common way is the most simple, but if you need
is the most simple, but if you need full control, you can have it. full control, you can have it.
* **Extensible and replaceable components** * **Extensible and replaceable components.** If you want to use different
If you want to use different mathematical library for specific purposes, mathematical library for specific purposes, that new windowing toolkit,
that new windowing toolkit, your own file formats or another physics your own file formats or another physics library, you can. Conversion of
library, you can. Conversion of math structures between different libraries math structures between different libraries can be done on top of pre-made
can be done on top of pre-made skeleton classes, support for file formats skeleton classes, support for file formats is done using plugins and
is done using plugins and platform support is done by writing simple platform support is done by writing simple wrapper class.
wrapper class.
SUPPORTED PLATFORMS SUPPORTED PLATFORMS
=================== ===================
@ -54,10 +53,10 @@ Platforms:
* **Linux** and embedded Linux (natively using GLX/EGL and Xlib or through * **Linux** and embedded Linux (natively using GLX/EGL and Xlib or through
SDL2, GLFW or GLUT toolkit) [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum) [![Coverage Status](https://coveralls.io/repos/github/mosra/magnum/badge.svg?branch=master)](https://coveralls.io/github/mosra/magnum?branch=master) SDL2, GLFW or GLUT toolkit) [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum) [![Coverage Status](https://coveralls.io/repos/github/mosra/magnum/badge.svg?branch=master)](https://coveralls.io/github/mosra/magnum?branch=master)
* **Windows** on both MSVC and MinGW, natively or using ANGLE (through SDL2, GLFW or GLUT toolkit) [![Build Status](https://ci.appveyor.com/api/projects/status/5b477m034cfaskse/branch/master?svg=true)](https://ci.appveyor.com/project/mosra/magnum/branch/master) * **Windows** with both MSVC and MinGW, natively or using ANGLE (through SDL2, GLFW or GLUT toolkit) [![Build Status](https://ci.appveyor.com/api/projects/status/5b477m034cfaskse/branch/master?svg=true)](https://ci.appveyor.com/project/mosra/magnum/branch/master)
* **macOS** (through SDL2 or GLFW toolkit) [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum) * **macOS** (through SDL2 or GLFW toolkit) [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum)
* **iOS** (through SDL2 toolkit) [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum) * **iOS** (through SDL2 toolkit) [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum)
* **Android** 2.3 (API Level 9) and higher [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum) * **Android** [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum)
* **Windows RT** (Store/Phone) using ANGLE (through SDL2 toolkit) [![Build Status](https://ci.appveyor.com/api/projects/status/5b477m034cfaskse/branch/master?svg=true)](https://ci.appveyor.com/project/mosra/magnum/branch/master) * **Windows RT** (Store/Phone) using ANGLE (through SDL2 toolkit) [![Build Status](https://ci.appveyor.com/api/projects/status/5b477m034cfaskse/branch/master?svg=true)](https://ci.appveyor.com/project/mosra/magnum/branch/master)
* **Web** (asm.js or WebAssembly), through [Emscripten](http://kripken.github.io/emscripten-site/) [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum) * **Web** (asm.js or WebAssembly), through [Emscripten](http://kripken.github.io/emscripten-site/) [![Build Status](https://travis-ci.org/mosra/magnum.svg?branch=master)](https://travis-ci.org/mosra/magnum)
@ -79,10 +78,10 @@ FEATURES
INSTALLATION INSTALLATION
============ ============
You can either use packaging scripts, which are stored in `package/` You can either use packaging scripts, which are stored in the `package/`
subdirectory, or compile and install everything manually. Note that subdirectory, or compile and install everything manually using the guide below.
[Magnum documentation](http://doc.magnum.graphics/magnum/) contains more Note that the [Magnum documentation](http://doc.magnum.graphics/magnum/)
comprehensive guide for building, packaging and crosscompiling. contains more comprehensive guide for building, packaging and crosscompiling.
Minimal dependencies Minimal dependencies
-------------------- --------------------
@ -94,7 +93,7 @@ Minimal dependencies
* **Corrade** - Plugin management and utility library. You can get it at * **Corrade** - Plugin management and utility library. You can get it at
https://github.com/mosra/corrade. https://github.com/mosra/corrade.
Note that full feature set is available only on GCC 4.8.1 and Clang 3.1. Note that the full feature set is available only on GCC 4.8.1 and Clang 3.1.
Compilation, installation Compilation, installation
------------------------- -------------------------
@ -109,8 +108,9 @@ installed using these four commands:
make make
make install make install
See Doxygen documentation for more information about enabling or disabling See the [Doxygen documentation](http://doc.magnum.graphics/magnum/building.html)
additional features and targeting different platforms such as OpenGL ES. for more information about enabling or disabling additional features and
targeting different platforms such as OpenGL ES.
Building and running unit tests Building and running unit tests
------------------------------- -------------------------------
@ -126,10 +126,8 @@ in build directory. Everything should pass ;-)
Building documentation Building documentation
---------------------- ----------------------
The documentation is written in **Doxygen** (version 1.8 with Markdown support The documentation is written in **Doxygen** and additionally uses **TeX** for
is used, but older versions should do good job too) and additionally uses math formulas. The documentation can be build by running:
**Graphviz** for class diagrams and **TeX** for math formulas. The
documentation can be build by running:
doxygen doxygen
@ -150,7 +148,7 @@ The engine itself is kept as small as possible with only little dependencies.
Additional functionality, often depending on external libraries, is provided in Additional functionality, often depending on external libraries, is provided in
separate repositories. separate repositories.
* **Corrade** -- main Magnum dependency, multiplatform utility library: * **Corrade** -- main Magnum dependency, a multiplatform utility library:
https://github.com/mosra/corrade https://github.com/mosra/corrade
[![Linux/macOS/iOS/Android/Emscripten Build Status](https://travis-ci.org/mosra/corrade.svg?branch=master)](https://travis-ci.org/mosra/corrade) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/afjjlsgtk6jjxulp/branch/master?svg=true)](https://ci.appveyor.com/project/mosra/corrade/branch/master) [![Linux/macOS/iOS/Android/Emscripten Build Status](https://travis-ci.org/mosra/corrade.svg?branch=master)](https://travis-ci.org/mosra/corrade) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/afjjlsgtk6jjxulp/branch/master?svg=true)](https://ci.appveyor.com/project/mosra/corrade/branch/master)
* **Magnum Bootstrap** -- bootstrap projects for many use cases, helping you * **Magnum Bootstrap** -- bootstrap projects for many use cases, helping you
@ -184,7 +182,7 @@ CONTACT
Want to learn more about the library? Found a bug or want to share an awesome Want to learn more about the library? Found a bug or want to share an awesome
idea? Feel free to visit the project website or contact the team at: idea? Feel free to visit the project website or contact the team at:
* Website -- http://magnum.graphics * Website -- http://magnum.graphics/
* GitHub -- https://github.com/mosra/magnum * GitHub -- https://github.com/mosra/magnum
* Gitter -- https://gitter.im/mosra/magnum * Gitter -- https://gitter.im/mosra/magnum
* IRC -- join `#magnum-engine` channel on freenode * IRC -- join `#magnum-engine` channel on freenode
@ -201,5 +199,5 @@ See [CREDITS.md](CREDITS.md) file for details. Big thanks to everyone involved!
LICENSE LICENSE
======= =======
Magnum is licensed under MIT/Expat license, see [COPYING](COPYING) file for Magnum is licensed under the MIT/Expat license, see [COPYING](COPYING) file for
details. details.

9
doc/00-page-order.dox

@ -9,10 +9,6 @@
@page utilities Utilities @page utilities Utilities
@page opengl OpenGL @page opengl OpenGL
@page openal OpenAL @page openal OpenAL
@page debugoperators Debug output operators for custom types
@page configurationvalues Configuration value parsers and writers for custom types
@page deprecated Deprecated list
@page coding-style Coding style
@page changelog Changelog @page changelog Changelog
@page changelog-plugins Plugins changelog @page changelog-plugins Plugins changelog
@ -20,4 +16,9 @@
@page changelog-extras Extras changelog @page changelog-extras Extras changelog
@page changelog-examples Examples changelog @page changelog-examples Examples changelog
@page coding-style Coding style
@page debugoperators Debug output operators for custom types
@page configurationvalues Configuration value parsers and writers for custom types
@page deprecated Deprecated list
*/ */

13
doc/best-practices.dox

@ -25,10 +25,10 @@
namespace Magnum { namespace Magnum {
/** @page best-practices Best practices, pitfalls and platform-specific information /** @page best-practices Best practices, pitfalls and platform-specific information
@brief Performance advices and solutions for platform-specific issues.
@brief Performance advices and solutions for platform-specific issues
@tableofcontents @tableofcontents
@m_footernavigation
Here is collection of carefully selected notes, links to official guidelines Here is collection of carefully selected notes, links to official guidelines
and other articles with valuable information to help developers create better and other articles with valuable information to help developers create better
@ -61,9 +61,9 @@ information.
@subsection best-practices-ios iOS @subsection best-practices-ios iOS
- GLSL `texelFetch()` returns zero results if you have a texture with integer - GLSL @glsl texelFetch() @ce returns zero results if you have a texture with
type and the filtering is not @ref Sampler::Filter::Nearest. Yes, it integer type and the filtering is not @ref Sampler::Filter::Nearest. Yes,
shouldn't matter, but it does. it shouldn't matter, but it does.
- OpenGL ES 3.0 contexts don't support rendering to 32-bit float textures. - OpenGL ES 3.0 contexts don't support rendering to 32-bit float textures.
However, it is possible to work around that issue by creating 32-bit However, it is possible to work around that issue by creating 32-bit
unsigned integer texture unsigned integer texture
@ -73,7 +73,7 @@ information.
@subsection best-practices-angle ANGLE (WebGL) @subsection best-practices-angle ANGLE (WebGL)
- [WebGL Insights -- ANGLE](https://books.google.cz/books?id=6crECQAAQBAJ&lpg=PP1&pg=PA3&redir_esc=y#v=onepage&q&f=true) - [WebGL Insights --- ANGLE](https://books.google.cz/books?id=6crECQAAQBAJ&lpg=PP1&pg=PA3&redir_esc=y#v=onepage&q&f=true)
@subsection best-practices-webgl WebGL (Emscripten) @subsection best-practices-webgl WebGL (Emscripten)
@ -102,6 +102,5 @@ buffer attachments. See @ref Buffer, @ref Framebuffer,
@subsection best-practices-tegra NVidia Tegra hardware @subsection best-practices-tegra NVidia Tegra hardware
- [Optimize OpenGL ES 2.0 Performance for Tegra](http://docs.nvidia.com/tegra/index.html#GLES2_Perf_Main.html) - [Optimize OpenGL ES 2.0 Performance for Tegra](http://docs.nvidia.com/tegra/index.html#GLES2_Perf_Main.html)
*/ */
} }

337
doc/building.dox

@ -29,6 +29,7 @@ namespace Magnum {
@brief Guide how to download and build Magnum on different platforms. @brief Guide how to download and build Magnum on different platforms.
@tableofcontents @tableofcontents
@m_footernavigation
Minimal set of tools and libraries required for building is: Minimal set of tools and libraries required for building is:
@ -48,7 +49,9 @@ The source is available on GitHub: https://github.com/mosra/magnum. Clone the
repository with your favorite IDE or Git GUI, download currrent snapshot as repository with your favorite IDE or Git GUI, download currrent snapshot as
compressed archive or use the command line: compressed archive or use the command line:
git clone git://github.com/mosra/magnum.git @code{.sh}
git clone git://github.com/mosra/magnum.git
@endcode
@section building-compilation Compilation, installation @section building-compilation Compilation, installation
@ -61,12 +64,14 @@ assuming you have at least basic knowledge of CMake.
On Unix-based OSs, the library (for example with support for SDL2 applications) On Unix-based OSs, the library (for example with support for SDL2 applications)
can be built and installed using these four commands: can be built and installed using these four commands:
mkdir build && cd build @code{.sh}
cmake .. \ mkdir build && cd build
-DCMAKE_INSTALL_PREFIX=/usr \ cmake .. \
-DWITH_SDL2APPLICATION=ON -DCMAKE_INSTALL_PREFIX=/usr \
make -DWITH_SDL2APPLICATION=ON
make install make
make install
@endcode
See @ref building-features "below" for additional configuration options. See @ref building-features "below" for additional configuration options.
@ -101,10 +106,12 @@ The most straightforward way to build and install the library is again via the
command-line. The bonus point is that you don't even need to wait for Visual command-line. The bonus point is that you don't even need to wait for Visual
Studio to load: Studio to load:
mkdir build && cd build @code{.bat}
cmake -DCMAKE_INSTALL_PREFIX="C:/Sys" .. mkdir build && cd build
cmake --build . cmake -DCMAKE_INSTALL_PREFIX="C:/Sys" ..
cmake --build . --target install cmake --build .
cmake --build . --target install
@endcode
If you want to build and install from Visual Studio, just open the `Magnum.sln` If you want to build and install from Visual Studio, just open the `Magnum.sln`
project file generated by CMake in the build directory. project file generated by CMake in the build directory.
@ -153,20 +160,20 @@ By default the engine is built for desktop OpenGL. Using `TARGET_*` CMake
parameters you can target other platforms. Note that some features are parameters you can target other platforms. Note that some features are
available for desktop OpenGL only, see @ref requires-gl. available for desktop OpenGL only, see @ref requires-gl.
- `TARGET_GLES` -- Target OpenGL ES. - `TARGET_GLES` --- Target OpenGL ES.
- `TARGET_GLES2` -- Target OpenGL ES 2.0. Currently enabled by default when - `TARGET_GLES2` --- Target OpenGL ES 2.0. Currently enabled by default when
`TARGET_GLES` is set. `TARGET_GLES` is set.
- `TARGET_DESKTOP_GLES` -- Target OpenGL ES on desktop, i.e. use OpenGL ES - `TARGET_DESKTOP_GLES` --- Target OpenGL ES on desktop, i.e. use OpenGL ES
emulation in desktop OpenGL library. Available on Linux and Windows, though emulation in desktop OpenGL library. Available on Linux and Windows, though
might not be supported by all drivers. might not be supported by all drivers.
- `TARGET_HEADLESS` -- Build command-line utilities for use on a headless - `TARGET_HEADLESS` --- Build command-line utilities for use on a headless
machine. Basically it means that EGL with no display attachment is being machine. Basically it means that EGL with no display attachment is being
used everywhere instead of platform-specific toolkits like CGL, GLX or WGL. used everywhere instead of platform-specific toolkits like CGL, GLX or WGL.
Supported mainly on OpenGL ES drivers, for desktop OpenGL the only driver Supported mainly on OpenGL ES drivers, for desktop OpenGL the only driver
that supports this configuration is NVidia >= 355. that supports this configuration is NVidia >= 355.
By default the engine is built in a way that allows having multiple By default the engine is built in a way that allows having multiple
thread-local Magnum contents. This might cause some performance penalties -- if thread-local Magnum contents. This might cause some performance penalties --- if
you are sure that you will never need such feature, you can disable it via the you are sure that you will never need such feature, you can disable it via the
`BUILD_MULTITHREADED` option. `BUILD_MULTITHREADED` option.
@ -179,19 +186,19 @@ By default the engine is built with nearly everything except @ref Audio
library, plugins and application libraries (see below). Using `WITH_*` CMake library, plugins and application libraries (see below). Using `WITH_*` CMake
parameters you can specify which parts will be built and which not: parameters you can specify which parts will be built and which not:
- `WITH_AUDIO` - @ref Audio library. Depends on **OpenAL** library, not built - `WITH_AUDIO` --- @ref Audio library. Depends on **OpenAL** library, not
by default. built by default.
- `WITH_DEBUGTOOLS` - @ref DebugTools library - `WITH_DEBUGTOOLS` --- @ref DebugTools library
- `WITH_MESHTOOLS` - @ref MeshTools library - `WITH_MESHTOOLS` --- @ref MeshTools library
- `WITH_PRIMITIVES` - @ref Primitives library - `WITH_PRIMITIVES` --- @ref Primitives library
- `WITH_SCENEGRAPH` - @ref SceneGraph library. Enabled automatically if - `WITH_SCENEGRAPH` --- @ref SceneGraph library. Enabled automatically if
`WITH_SHAPES` is enabled. `WITH_SHAPES` is enabled.
- `WITH_SHADERS` - @ref Shaders library - `WITH_SHADERS` --- @ref Shaders library
- `WITH_SHAPES` - @ref Shapes library. Enables also building of SceneGraph - `WITH_SHAPES` --- @ref Shapes library. Enables also building of SceneGraph
library. Enabled automatically if `WITH_DEBUGTOOLS` is enabled. library. Enabled automatically if `WITH_DEBUGTOOLS` is enabled.
- `WITH_TEXT` - @ref Text library. Enables also building of TextureTools - `WITH_TEXT` --- @ref Text library. Enables also building of TextureTools
library. library.
- `WITH_TEXTURETOOLS` - @ref TextureTools library. Enabled automatically if - `WITH_TEXTURETOOLS` --- @ref TextureTools library. Enabled automatically if
`WITH_TEXT` or `WITH_DISTANCEFIELDCONVERTER` is enabled. `WITH_TEXT` or `WITH_DISTANCEFIELDCONVERTER` is enabled.
There are more involved component dependencies that are not described here (for There are more involved component dependencies that are not described here (for
@ -204,32 +211,32 @@ None of the @ref Platform "application libraries" is built by default (and you
need at least one). Choose the one which suits your requirements and your need at least one). Choose the one which suits your requirements and your
platform best: platform best:
- `WITH_ANDROIDAPPLICATION` - @ref Platform::AndroidApplication "AndroidApplication" - `WITH_ANDROIDAPPLICATION` --- @ref Platform::AndroidApplication "AndroidApplication"
- `WITH_GLFWAPPLICATION` - @ref Platform::GlfwApplication "GlfwApplication" - `WITH_GLFWAPPLICATION` --- @ref Platform::GlfwApplication "GlfwApplication"
- `WITH_GLUTAPPLICATION` - @ref Platform::GlutApplication "GlutApplication" - `WITH_GLUTAPPLICATION` --- @ref Platform::GlutApplication "GlutApplication"
- `WITH_GLXAPPLICATION` - @ref Platform::GlxApplication "GlxApplication" - `WITH_GLXAPPLICATION` --- @ref Platform::GlxApplication "GlxApplication"
- `WITH_SDL2APPLICATION` - @ref Platform::Sdl2Application "Sdl2Application" - `WITH_SDL2APPLICATION` --- @ref Platform::Sdl2Application "Sdl2Application"
- `WITH_XEGLAPPLICATION` - @ref Platform::XEglApplication "XEglApplication" - `WITH_XEGLAPPLICATION` --- @ref Platform::XEglApplication "XEglApplication"
- `WITH_WINDOWLESSCGLAPPLICATION` - @ref Platform::WindowlessCglApplication "WindowlessCglApplication" - `WITH_WINDOWLESSCGLAPPLICATION` --- @ref Platform::WindowlessCglApplication "WindowlessCglApplication"
- `WITH_WINDOWLESSEGLAPPLICATION` - @ref Platform::WindowlessEglApplication "WindowlessEglApplication" - `WITH_WINDOWLESSEGLAPPLICATION` --- @ref Platform::WindowlessEglApplication "WindowlessEglApplication"
- `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" - `WITH_WINDOWLESSGLXAPPLICATION` --- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `WITH_WINDOWLESSIOSAPPLICATION` - @ref Platform::WindowlessIosApplication "WindowlessIosApplication" - `WITH_WINDOWLESSIOSAPPLICATION` --- @ref Platform::WindowlessIosApplication "WindowlessIosApplication"
- `WITH_WINDOWLESSWGLAPPLICATION` - @ref Platform::WindowlessWglApplication "WindowlessWglApplication" - `WITH_WINDOWLESSWGLAPPLICATION` --- @ref Platform::WindowlessWglApplication "WindowlessWglApplication"
- `WITH_WINDOWLESSWINDOWSEGLAPPLICATION` - @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication" - `WITH_WINDOWLESSWINDOWSEGLAPPLICATION` --- @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication"
None of the context libraries is built by default. You need them only if you None of the context libraries is built by default. You need them only if you
choose to not use any application library (see @ref platform-custom for more choose to not use any application library (see @ref platform-custom for more
information): information):
- `WITH_CGLCONTEXT` -- CGL context - `WITH_CGLCONTEXT` --- CGL context
- `WITH_EGLCONTEXT` -- EGL context - `WITH_EGLCONTEXT` --- EGL context
- `WITH_GLXCONTEXT` -- GLX context - `WITH_GLXCONTEXT` --- GLX context
- `WITH_WGLCONTEXT` -- WGL context - `WITH_WGLCONTEXT` --- WGL context
There are also extensions to @ref Corrade::TestSuite::Tester for testing GPU There are also extensions to @ref Corrade::TestSuite::Tester for testing GPU
code: code:
- `WITH_OPENGLTESTER` -- @ref OpenGLTester class. Enables building of one of - `WITH_OPENGLTESTER` --- @ref OpenGLTester class. Enables building of one of
`Platform::Windowless*Application` libraries based on platform. `Platform::Windowless*Application` libraries based on platform.
Magnum also contains a set of dependency-less plugins for importing essential Magnum also contains a set of dependency-less plugins for importing essential
@ -237,41 +244,41 @@ file formats. Additional plugins are provided in separate plugin repository,
see @ref building-plugins for more information. None of the plugins is built by see @ref building-plugins for more information. None of the plugins is built by
default. default.
- `WITH_MAGNUMFONT` -- @ref Text::MagnumFont "MagnumFont" plugin. Available - `WITH_MAGNUMFONT` --- @ref Text::MagnumFont "MagnumFont" plugin. Available
only if `WITH_TEXT` is enabled. Enables also building of only if `WITH_TEXT` is enabled. Enables also building of
@ref Trade::TgaImporter "TgaImporter" plugin. @ref Trade::TgaImporter "TgaImporter" plugin.
- `WITH_MAGNUMFONTCONVERTER` -- @ref Text::MagnumFontConverter "MagnumFontConverter" - `WITH_MAGNUMFONTCONVERTER` --- @ref Text::MagnumFontConverter "MagnumFontConverter"
plugin. Available only if `WITH_TEXT` is enabled. Enables also building of plugin. Available only if `WITH_TEXT` is enabled. Enables also building of
@ref Trade::TgaImageConverter "TgaImageConverter" plugin. @ref Trade::TgaImageConverter "TgaImageConverter" plugin.
- `WITH_OBJIMPORTER` -- @ref Trade::ObjImporter "ObjImporter" plugin. - `WITH_OBJIMPORTER` --- @ref Trade::ObjImporter "ObjImporter" plugin.
- `WITH_TGAIMPORTER` -- @ref Trade::TgaImporter "TgaImporter" plugin. - `WITH_TGAIMPORTER` --- @ref Trade::TgaImporter "TgaImporter" plugin.
- `WITH_TGAIMAGECONVERTER` -- @ref Trade::TgaImageConverter "TgaImageConverter" - `WITH_TGAIMAGECONVERTER` --- @ref Trade::TgaImageConverter "TgaImageConverter"
plugin. plugin.
- `WITH_WAVAUDIOIMPORTER` -- @ref Audio::WavImporter "WavAudioImporter" - `WITH_WAVAUDIOIMPORTER` --- @ref Audio::WavImporter "WavAudioImporter"
plugin. Available only if `WITH_AUDIO` is enabled. plugin. Available only if `WITH_AUDIO` is enabled.
There are also a few command-line utilities, also disabled by default: There are also a few command-line utilities, also disabled by default:
- `WITH_MAGNUMINFO` - @ref magnum-info "magnum-info" executable, provides - `WITH_MAGNUMINFO` --- @ref magnum-info "magnum-info" executable, provides
information about the engine and OpenGL capabilities. Depends on some information about the engine and OpenGL capabilities. Depends on some
windowless application library. windowless application library.
- `WITH_AL_INFO` -- @ref magnum-al-info "magnum-al-info" executable, provides - `WITH_AL_INFO` --- @ref magnum-al-info "magnum-al-info" executable,
information about OpenAL capabilities. provides information about OpenAL capabilities.
- `WITH_DISTANCEFIELDCONVERTER` - @ref magnum-distancefieldconverter "magnum-distancefieldconverter" - `WITH_DISTANCEFIELDCONVERTER` --- @ref magnum-distancefieldconverter "magnum-distancefieldconverter"
executable for converting black&white images to distance field textures. executable for converting black&white images to distance field textures.
Enables also building of @ref TextureTools library. Available only on Enables also building of @ref TextureTools library. Available only on
desktop GL, depends on some windowless application library. desktop GL, depends on some windowless application library.
- `WITH_FONTCONVERTER` - @ref magnum-fontconverter "magnum-fontconverter" - `WITH_FONTCONVERTER` --- @ref magnum-fontconverter "magnum-fontconverter"
executable for converting fonts to raster ones. Enables also building of executable for converting fonts to raster ones. Enables also building of
@ref Text library. Available only on desktop GL, depends on some windowless @ref Text library. Available only on desktop GL, depends on some windowless
application library. application library.
- `WITH_IMAGECONVERTER` - @ref magnum-imageconverter "magnum-imageconverter" - `WITH_IMAGECONVERTER` --- @ref magnum-imageconverter "magnum-imageconverter"
executable for converting images of different formats. executable for converting images of different formats.
Some of these utilities operate with plugins and they search for them in the Some of these utilities operate with plugins and they search for them in the
default plugin locations. You can override those locations using default plugin locations. You can override those locations using
`MAGNUM_PLUGINS_DIR` and `MAGNUM_PLUGINS_[DEBUG|RELEASE]_DIR` variables, much `MAGNUM_PLUGINS_DIR` and `MAGNUM_PLUGINS_[DEBUG|RELEASE]_DIR` variables, much
like when using Magnum from dependent projects -- see @ref cmake for more like when using Magnum from dependent projects --- see @ref cmake for more
information. In particular, if you specify them as relative paths, the path information. In particular, if you specify them as relative paths, the path
will be taken relative to executable location, which is useful for making will be taken relative to executable location, which is useful for making
relocatable installations. relocatable installations.
@ -288,7 +295,9 @@ If you want to build also unit tests (which are not built by default), enable
"TestSuite" framework and can be run either manually (the binaries are located "TestSuite" framework and can be run either manually (the binaries are located
in `Test/` subdirectories of build directory) or using in `Test/` subdirectories of build directory) or using
ctest --output-on-failure @code{.sh}
ctest --output-on-failure
@endcode
in build directory. On Windows the tests require the library to be installed in build directory. On Windows the tests require the library to be installed
with DLLs accessible through `PATH`. See with DLLs accessible through `PATH`. See
@ -302,7 +311,9 @@ disable building of them with `BUILD_AL_TESTS`. The tests are suffixed with
`ALTest` so they can be also selectively included/excluded when running CTest, `ALTest` so they can be also selectively included/excluded when running CTest,
e.g.: e.g.:
ctest -E ALTest # run everything except tests requiring OpenAL context @code{.sh}
ctest -E ALTest # run everything except tests requiring OpenAL context
@endcode
Platforms which have windowless GL context creation implemented (currently all Platforms which have windowless GL context creation implemented (currently all
platforms except @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten", platforms except @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten",
@ -312,16 +323,19 @@ functionality. You can enable them with `BUILD_GL_TESTS`. All GL tests are
suffixed with `GLTest` so they can be also selectively included/excluded when suffixed with `GLTest` so they can be also selectively included/excluded when
running CTest, e.g.: running CTest, e.g.:
ctest -R GLTest # run only tests requiring OpenGL context @code{.sh}
ctest -R GLTest # run only tests requiring OpenGL context
@endcode
@subsection building-doc Building documentation @subsection building-doc Building documentation
The documentation (which you are currently reading) is written in **Doxygen** The documentation (which you are currently reading) is written in **Doxygen**
(version 1.8 with Markdown support is used, but older versions should do good and additionally uses **LaTeX** for math formulas. Documentation using the
job too) and additionally uses **TeX** for math formulas. The documentation can stock HTML theme can be build by running
be build by running
doxygen @code{.sh}
doxygen
@endcode
in root directory (i.e. where `Doxyfile` is). Resulting HTML documentation in root directory (i.e. where `Doxyfile` is). Resulting HTML documentation
will be in `build/doc/` directory. You might need to create `build/` directory will be in `build/doc/` directory. You might need to create `build/` directory
@ -331,14 +345,19 @@ with Corrade's one. If related projects (`magnum-plugins`, `magnum-integration`
and `magnum-examples`, see below) are places along these, their documentation and `magnum-examples`, see below) are places along these, their documentation
will be also included in generated output. will be also included in generated output.
The documentation can be also generated using the [m.css Doxygen theme](http://mcss.mosra.cz/doxygen/).
Use `Doxyfile-mcss` for local build, the `Doxyfile-public` is meant for the
publicly available documentation at http://doc.magnum.graphics/magnum/.
@section building-related Related projects @section building-related Related projects
The engine itself is kept as small as possible with only little dependencies. The engine itself is kept as small as possible with only little dependencies.
Additional functionality, often depending on external libraries, is provided in Additional functionality, often depending on external libraries, is provided in
separate repositories. Various importer plugins for image, audio and 3D model separate repositories. Various importer plugins for image, audio and 3D model
formats are maintained in @ref building-plugins "Plugins repository", formats are maintained in @ref building-plugins "Plugins repository",
Integration with various external math and physics libraries is provided by integration with various external math and physics libraries is provided by
@ref building-integration "Integration library". @ref building-integration "Integration library" and other extra features are
in the @ref building-extras "Extras library".
@section building-packages Prepared packages @section building-packages Prepared packages
@ -349,8 +368,8 @@ build. The package is also in AUR under the same name.
There are also a few development PKGBUILDs in `package/archlinux`, which allow There are also a few development PKGBUILDs in `package/archlinux`, which allow
you to build and install the package directly from source tree without you to build and install the package directly from source tree without
downloading anything. The native PKGBUILDs also contain `check()` function downloading anything. The native PKGBUILDs also contain @cb{.sh} check() @ce
which will run all unit tests before packaging. function which will run all unit tests before packaging.
@subsection building-packages-gentoo Gentoo ebuilds @subsection building-packages-gentoo Gentoo ebuilds
@ -364,8 +383,10 @@ addition also `dpkg-dev` and `debhelper` packages. Building is easy, just
change directory to package root, link or copy `package/debian` directory there change directory to package root, link or copy `package/debian` directory there
and run `dpkg-buildpackage`: and run `dpkg-buildpackage`:
ln -s package/debian . @code{.sh}
dpkg-buildpackage ln -s package/debian .
dpkg-buildpackage
@endcode
This will compile binary and development packages, which will then appear in This will compile binary and development packages, which will then appear in
parent directory. If you need to modify CMake flags (enabling/disabling some parent directory. If you need to modify CMake flags (enabling/disabling some
@ -376,7 +397,9 @@ features, for example), modify the last entry in `debian/rules`.
macOS Homebrew formulas are in `package/homebrew` directory. Either use the macOS Homebrew formulas are in `package/homebrew` directory. Either use the
`*.rb` files directly or use the tap at https://github.com/mosra/homebrew-magnum : `*.rb` files directly or use the tap at https://github.com/mosra/homebrew-magnum :
brew install --HEAD mosra/magnum/magnum @code{.sh}
brew install --HEAD mosra/magnum/magnum
@endcode
@section building-windows-angle Building for ANGLE on Windows @section building-windows-angle Building for ANGLE on Windows
@ -388,12 +411,15 @@ build it. Put the resulting `libGLESv2`/`libEGL` libraries and
to enable `TARGET_GLES`. The engine is built for OpenGL ES 2.0 by default, to enable `TARGET_GLES`. The engine is built for OpenGL ES 2.0 by default,
switch to 3.0 by disabling `TARGET_GLES2`. switch to 3.0 by disabling `TARGET_GLES2`.
mkdir build-angle && cd build-angle @code{.bat}
cmake .. \ mkdir build-angle && cd build-angle
-DCMAKE_PREFIX_PATH=<path-to-ANGLE-installation> \ cmake .. ^
-DTARGET_GLES=ON -DTARGEET_GLES2=OFF \ -DCMAKE_PREFIX_PATH=<path-to-ANGLE-installation> ^
-DWITH_SDL2APPLICATION=ON -DTARGET_GLES=ON ^
cmake --build . -DTARGEET_GLES2=OFF ^
-DWITH_SDL2APPLICATION=ON
cmake --build .
@endcode
@section building-crosscompiling Crosscompiling @section building-crosscompiling Crosscompiling
@ -407,8 +433,9 @@ following commands, or, if you build from source archive, download snapshot of
toolchains repository from https://github.com/mosra/toolchains and put the toolchains repository from https://github.com/mosra/toolchains and put the
contents in `toolchains/` subdirectory. contents in `toolchains/` subdirectory.
git submodule init @code{.sh}
git submodule update git submodule update --init
@endcode
Note that CMake for some reason treats `CMAKE_PREFIX_PATH` and Note that CMake for some reason treats `CMAKE_PREFIX_PATH` and
`CMAKE_INSTALL_PREFIX` differently while crosscompiling and you may need to add `CMAKE_INSTALL_PREFIX` differently while crosscompiling and you may need to add
@ -423,25 +450,26 @@ installation path for WinRT dependencies is in `C:/Sys-winrt`.
You need at least Windows 8.1, Visual Studio 2013 and Windows 8.1 Store/Phone You need at least Windows 8.1, Visual Studio 2013 and Windows 8.1 Store/Phone
SDK installed. Windows RT applications support OpenGL only through ANGLE, which SDK installed. Windows RT applications support OpenGL only through ANGLE, which
is currently limited to OpenGL ES. Download and build ANGLE @ref building-windows-angle "according to instructions above", is currently limited to OpenGL ES. Download and build ANGLE
but use project files from the `winrt/` directory instead. Version 2.0.4 of SDL @ref building-windows-angle "according to instructions above", but use project
has support for WinRT applications, download the source from files from the `winrt/` directory instead. Version 2.0.4 of SDL has support for
https://www.libsdl.org/download-2.0.php and use project files from the WinRT applications, download the source from https://www.libsdl.org/download-2.0.php
`VisualC-WinRT` directory. Because WinRT applications run in a sandbox, it's and use project files from the `VisualC-WinRT` directory. Because WinRT
recommended to build the library as static so you don't have to bundle all the applications run in a sandbox, it's recommended to build the library as static
DLLs. Example: so you don't have to bundle all the DLLs. Example:
mkdir build-winrt @code{.bat}
cd build-winrt mkdir build-winrt && cd build-winrt
cmake .. ^ cmake .. ^
-DCMAKE_SYSTEM_NAME=WindowsStore ^ -DCMAKE_SYSTEM_NAME=WindowsStore ^
-DCMAKE_SYSTEM_VERSION=10 ^ -DCMAKE_SYSTEM_VERSION=10 ^
-DCORRADE_RC_EXECUTABLE="C:/Sys/bin/corrade-rc.exe" ^ -DCORRADE_RC_EXECUTABLE="C:/Sys/bin/corrade-rc.exe" ^
-DCMAKE_INSTALL_PREFIX="C:/Sys-winrt" ^ -DCMAKE_INSTALL_PREFIX="C:/Sys-winrt" ^
-DBUILD_STATIC=ON ^ -DBUILD_STATIC=ON ^
-DWITH_SDL2APPLICATION=ON ^ -DWITH_SDL2APPLICATION=ON ^
-G "Visual Studio 14 2015" .. -G "Visual Studio 14 2015" ..
cmake --build . cmake --build .
@endcode
Change `WindowsStore` to `WindowsPhone` if you want to build for Windows Phone Change `WindowsStore` to `WindowsPhone` if you want to build for Windows Phone
instead. When done, you can install the package using `cmake --build . --target install` instead. When done, you can install the package using `cmake --build . --target install`
@ -460,25 +488,29 @@ building your projects for WinRT.
You will need MinGW-w64 versions of the compiler and all dependent libraries You will need MinGW-w64 versions of the compiler and all dependent libraries
(Corrade), i.e. these ArchLinux packages: (Corrade), i.e. these ArchLinux packages:
- `mingw-w64-gcc` - `mingw-w64-gcc`
- `mingw-w64-corrade` - `mingw-w64-corrade`
Then create build directories for 32b/64b build and run cmake and build command Then create build directories for 32b/64b build and run cmake and build command
in them. You may need to modify the `basic-mingw-w64-32.cmake`/`basic-mingw-w64-64.cmake` in them. You may need to modify the `basic-mingw-w64-32.cmake`/`basic-mingw-w64-64.cmake`
files and `CMAKE_INSTALL_PREFIX` to suit your distribution filesystem files and `CMAKE_INSTALL_PREFIX` to suit your distribution filesystem
hierarchy and specify path where Corrade is installed in `CMAKE_PREFIX_PATH`. hierarchy and specify path where Corrade is installed in `CMAKE_PREFIX_PATH`.
mkdir build-mingw-w64-32 && cd build-mingw-w64-32 @code{.sh}
cmake .. \ mkdir build-mingw-w64-32 && cd build-mingw-w64-32
-DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw-w64-32.cmake \ cmake .. \
-DCMAKE_INSTALL_PREFIX=/usr/i686-w64-mingw32 -DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw-w64-32.cmake \
cmake --build . -DCMAKE_INSTALL_PREFIX=/usr/i686-w64-mingw32
cmake --build .
mkdir build-mingw-w64-64 && cd build-mingw-w64-64 @endcode
cmake .. \
-DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw-w64-64.cmake \ @code{.sh}
-DCMAKE_INSTALL_PREFIX=/usr/x86_64-w64-mingw32 mkdir build-mingw-w64-64 && cd build-mingw-w64-64
cmake --build . cmake .. \
-DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw-w64-64.cmake \
-DCMAKE_INSTALL_PREFIX=/usr/x86_64-w64-mingw32
cmake --build .
@endcode
Then you can install the package using `cmake --build . --target install` to Then you can install the package using `cmake --build . --target install` to
make it available for depending projects. make it available for depending projects.
@ -504,14 +536,16 @@ set `CMAKE_INSTALL_PREFIX` to path contained in `EMSCRIPTEN_TOOLCHAIN_PATH`.
WebGL 1.0 (GLES 2.0 equivalent) is enabled by default, switch to 2.0 (GLES 3.0 WebGL 1.0 (GLES 2.0 equivalent) is enabled by default, switch to 2.0 (GLES 3.0
equivalent) by disabling `TARGET_GLES2`. equivalent) by disabling `TARGET_GLES2`.
mkdir build-emscripten && cd build-emscripten @code{.sh}
cmake .. \ mkdir build-emscripten && cd build-emscripten
-DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Emscripten.cmake" \ cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Emscripten.cmake" \
-DCMAKE_PREFIX_PATH=/usr/lib/emscripten/system \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/lib/emscripten/system \ -DCMAKE_PREFIX_PATH=/usr/lib/emscripten/system \
-DWITH_SDL2APPLICATION=ON -DCMAKE_INSTALL_PREFIX=/usr/lib/emscripten/system \
cmake --build . -DWITH_SDL2APPLICATION=ON
cmake --build .
@endcode
Then you can install the library using `cmake --build . --target install` to Then you can install the library using `cmake --build . --target install` to
make it available for depending projects. make it available for depending projects.
@ -548,17 +582,19 @@ Please note that `BUILD_MULTITHREADED` is supported only since Xcode 7.3 and
doesn't work on `i386` iOS Simulator, you need to disable it in order to build doesn't work on `i386` iOS Simulator, you need to disable it in order to build
for older platforms. for older platforms.
mkdir build-ios && cd build-ios @code{.sh}
cmake .. \ mkdir build-ios && cd build-ios
-DCMAKE_TOOLCHAIN_FILE=../toolchains/generic/iOS.cmake \ cmake .. \
-DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk \ -DCMAKE_TOOLCHAIN_FILE=../toolchains/generic/iOS.cmake \
-DCMAKE_OSX_ARCHITECTURES="arm64;armv7;armv7s" \ -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk \
-DCMAKE_INSTALL_PREFIX=~/ios-libs \ -DCMAKE_OSX_ARCHITECTURES="arm64;armv7;armv7s" \
-DBUILD_STATIC=ON -DBUILD_PLUGINS_STATIC=ON \ -DCMAKE_INSTALL_PREFIX=~/ios-libs \
-DTARGET_GLES2=OFF \ -DBUILD_STATIC=ON -DBUILD_PLUGINS_STATIC=ON \
-DWITH_SDL2APPLICATION=ON \ -DTARGET_GLES2=OFF \
-G Xcode -DWITH_SDL2APPLICATION=ON \
cmake --build . -G Xcode
cmake --build .
@endcode
Then you can install the library using `cmake --build . --target install` to Then you can install the library using `cmake --build . --target install` to
make it available for depending projects. make it available for depending projects.
@ -584,25 +620,29 @@ Note that `BUILD_STATIC` is implicitly enabled, because manually loading all
depending shared libraries using JNI would be too inconvenient. The engine is depending shared libraries using JNI would be too inconvenient. The engine is
built for OpenGL ES 2.0 by default, switch to 3.0 by disabling `TARGET_GLES2`. built for OpenGL ES 2.0 by default, switch to 3.0 by disabling `TARGET_GLES2`.
mkdir build-android-arm && cd build-android-arm @code{.sh}
cmake .. \ mkdir build-android-arm && cd build-android-arm
-DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Android-ARM.cmake" \ cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Android-ARM.cmake" \
-DCMAKE_PREFIX_PATH=/opt/android-ndk/platforms/android-19/arch-arm/usr \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-19/arch-arm/usr \ -DCMAKE_PREFIX_PATH=/opt/android-ndk/platforms/android-19/arch-arm/usr \
-DTARGET_GLES=ON -DTARGET_GLES2=OFF \ -DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-19/arch-arm/usr \
-DWITH_ANDROIDAPPLICATION=ON -DTARGET_GLES=ON -DTARGET_GLES2=OFF \
cmake --build . -DWITH_ANDROIDAPPLICATION=ON
cmake --build .
mkdir build-android-x86 && cd build-android-x86 @endcode
cmake .. \
-DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Android-x86.cmake" \ @code{.sh}
-DCMAKE_BUILD_TYPE=Release \ mkdir build-android-x86 && cd build-android-x86
-DCMAKE_PREFIX_PATH=/opt/android-ndk/platforms/android-19/arch-x86/usr \ cmake .. \
-DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-19/arch-x86/usr \ -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Android-x86.cmake" \
-DTARGET_GLES=ON -DTARGET_GLES2=OFF \ -DCMAKE_BUILD_TYPE=Release \
-DWITH_ANDROIDAPPLICATION=ON -DCMAKE_PREFIX_PATH=/opt/android-ndk/platforms/android-19/arch-x86/usr \
cmake --build . -DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-19/arch-x86/usr \
-DTARGET_GLES=ON -DTARGET_GLES2=OFF \
-DWITH_ANDROIDAPPLICATION=ON
cmake --build .
@endcode
Then you can install the library using `cmake --build . --target install` to Then you can install the library using `cmake --build . --target install` to
make it available for depending projects. make it available for depending projects.
@ -629,7 +669,6 @@ reports available online at https://coveralls.io/github/mosra/magnum.
In `package/ci/` there is an `appveyor.yml` file with Windows desktop MSVC, In `package/ci/` there is an `appveyor.yml` file with Windows desktop MSVC,
MinGW, Windows desktop GLES2/GLES3 and Windows RT GLES2/GLES3 configuration. MinGW, Windows desktop GLES2/GLES3 and Windows RT GLES2/GLES3 configuration.
Online at https://ci.appveyor.com/project/mosra/magnum. Online at https://ci.appveyor.com/project/mosra/magnum.
*/ */
} }

156
doc/cmake.dox

@ -28,6 +28,7 @@ namespace Magnum {
@brief Guide how to find and use Magnum with CMake build system @brief Guide how to find and use Magnum with CMake build system
@tableofcontents @tableofcontents
@m_footernavigation
Magnum uses CMake build system for both building and integration into your Magnum uses CMake build system for both building and integration into your
projects. The logic is in module `FindMagnum.cmake` distributed with the engine projects. The logic is in module `FindMagnum.cmake` distributed with the engine
@ -50,80 +51,82 @@ separate them with semicolons.
Basic usage is: Basic usage is:
find_package(Magnum REQUIRED) @code{.cmake}
find_package(Magnum REQUIRED)
@endcode
This module tries to find base Magnum library and then defines: This module tries to find base Magnum library and then defines:
- `Magnum_FOUND` -- Whether the library was found - `Magnum_FOUND` --- Whether the library was found
- `Magnum::Magnum` -- Base library imported target - `Magnum::Magnum` --- Base library imported target
- `MAGNUM_DEPLOY_PREFIX` -- Prefix where to put final application - `MAGNUM_DEPLOY_PREFIX` --- Prefix where to put final application
executables, defaults to empty string. If a relative path is used, it's executables, defaults to empty string. If a relative path is used, it's
relative to `CMAKE_INSTALL_PREFIX`. relative to `CMAKE_INSTALL_PREFIX`.
- `MAGNUM_PLUGINS_DEBUG_DIR` -- Base directory with dynamic plugins for debug - `MAGNUM_PLUGINS_DEBUG_DIR` --- Base directory with dynamic plugins for debug
builds, defaults to `magnum-d/` subdirectory of dir where Magnum library builds, defaults to `magnum-d/` subdirectory of dir where Magnum library
was found was found
- `MAGNUM_PLUGINS_RELEASE_DIR` -- Base directory with dynamic plugins for - `MAGNUM_PLUGINS_RELEASE_DIR` --- Base directory with dynamic plugins for
release builds, defaults to `magnum/` subdirectory of dir where Magnum release builds, defaults to `magnum/` subdirectory of dir where Magnum
library was found library was found
- `MAGNUM_PLUGINS_DIR` -- Base directory with dynamic plugins, defaults to - `MAGNUM_PLUGINS_DIR` --- Base directory with dynamic plugins, defaults to
`MAGNUM_PLUGINS_RELEASE_DIR` in release builds and multi-configuration `MAGNUM_PLUGINS_RELEASE_DIR` in release builds and multi-configuration
builds or to `MAGNUM_PLUGINS_DEBUG_DIR` in debug builds. You can modify all builds or to `MAGNUM_PLUGINS_DEBUG_DIR` in debug builds. You can modify all
three variable (e.g. set them to `.` when deploying on Windows with plugins three variable (e.g. set them to `.` when deploying on Windows with plugins
stored relatively to the executable), the following `MAGNUM_PLUGINS_*_DIR` stored relatively to the executable), the following `MAGNUM_PLUGINS_*_DIR`
variables depend on it. variables depend on it.
- `MAGNUM_PLUGINS_FONT[|_DEBUG|_RELEASE]_DIR` -- Directory with dynamic font - `MAGNUM_PLUGINS_FONT[|_DEBUG|_RELEASE]_DIR` --- Directory with dynamic font
plugins plugins
- `MAGNUM_PLUGINS_FONTCONVERTER[|_DEBUG|_RELEASE]_DIR` -- Directory with - `MAGNUM_PLUGINS_FONTCONVERTER[|_DEBUG|_RELEASE]_DIR` --- Directory with
dynamic font converter plugins dynamic font converter plugins
- `MAGNUM_PLUGINS_IMAGECONVERTER[|_DEBUG|_RELEASE]_DIR` -- Directory with - `MAGNUM_PLUGINS_IMAGECONVERTER[|_DEBUG|_RELEASE]_DIR` --- Directory with
dynamic image converter plugins dynamic image converter plugins
- `MAGNUM_PLUGINS_IMPORTER[|_DEBUG|_RELEASE]_DIR` -- Directory with dynamic - `MAGNUM_PLUGINS_IMPORTER[|_DEBUG|_RELEASE]_DIR` --- Directory with dynamic
importer plugins importer plugins
- `MAGNUM_PLUGINS_AUDIOIMPORTER[|_DEBUG|_RELEASE]_DIR` -- Directory with - `MAGNUM_PLUGINS_AUDIOIMPORTER[|_DEBUG|_RELEASE]_DIR` --- Directory with
dynamic audio importer plugins dynamic audio importer plugins
However, this command will try to find only the base library, not the optional However, this command will try to find only the base library, not the optional
components. The base library depends on Corrade and OpenGL libraries (or components. The base library depends on @ref corrade-cmake Corrade and OpenGL
OpenGL ES libraries). Additional dependencies are specified by the components. libraries (or OpenGL ES libraries). Additional dependencies are specified by
The optional components are: the components. The optional components are:
- `Audio` -- @ref Audio library - `Audio` --- @ref Audio library
- `DebugTools` -- @ref DebugTools library - `DebugTools` --- @ref DebugTools library
- `MeshTools` -- @ref MeshTools library - `MeshTools` --- @ref MeshTools library
- `Primitives` -- @ref Primitives library - `Primitives` --- @ref Primitives library
- `SceneGraph` -- @ref SceneGraph library - `SceneGraph` --- @ref SceneGraph library
- `Shaders` -- @ref Shaders library - `Shaders` --- @ref Shaders library
- `Shapes` -- @ref Shapes library - `Shapes` --- @ref Shapes library
- `Text` -- @ref Text library - `Text` --- @ref Text library
- `TextureTools` -- @ref TextureTools library - `TextureTools` --- @ref TextureTools library
Platform namespace is split into more components: Platform namespace is split into more components:
- `GlfwApplication` -- @ref Platform::GlfwApplication "GlfwApplication" - `GlfwApplication` --- @ref Platform::GlfwApplication "GlfwApplication"
- `GlutApplication` -- @ref Platform::GlutApplication "GlutApplication" - `GlutApplication` --- @ref Platform::GlutApplication "GlutApplication"
- `GlxApplication` -- @ref Platform::GlxApplication "GlxApplication" - `GlxApplication` --- @ref Platform::GlxApplication "GlxApplication"
- `Sdl2Application` -- @ref Platform::Sdl2Application "Sdl2Application" - `Sdl2Application` --- @ref Platform::Sdl2Application "Sdl2Application"
- `XEglApplication` -- @ref Platform::XEglApplication "XEglApplication" - `XEglApplication` --- @ref Platform::XEglApplication "XEglApplication"
- `WindowlessCglApplication` -- @ref Platform::WindowlessCglApplication "WindowlessCglApplication" - `WindowlessCglApplication` --- @ref Platform::WindowlessCglApplication "WindowlessCglApplication"
- `WindowlessEglApplication` -- @ref Platform::WindowlessEglApplication "WindowlessEglApplication" - `WindowlessEglApplication` --- @ref Platform::WindowlessEglApplication "WindowlessEglApplication"
- `WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" - `WindowlessGlxApplication` --- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `WindowlessIosApplication` -- @ref Platform::WindowlessIosApplication "WindowlessIosApplication" - `WindowlessIosApplication` --- @ref Platform::WindowlessIosApplication "WindowlessIosApplication"
- `WindowlessWglApplication` -- @ref Platform::WindowlessWglApplication "WindowlessWglApplication" - `WindowlessWglApplication` --- @ref Platform::WindowlessWglApplication "WindowlessWglApplication"
- `WindowlessWindowsEglApplication` -- @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication" - `WindowlessWindowsEglApplication` --- @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication"
For manual context creation (without application wrappers) there are also For manual context creation (without application wrappers) there are also
platform-specific context libraries (see @ref platform-custom for more platform-specific context libraries (see @ref platform-custom for more
information): information):
- `CglContext` -- CGL context - `CglContext` --- CGL context
- `EglContext` -- EGL context - `EglContext` --- EGL context
- `GlxContext` -- GLX context - `GlxContext` --- GLX context
- `WglContext` -- WGL context - `WglContext` --- WGL context
There are also extensions to @ref Corrade::TestSuite::Tester for testing GPU There are also extensions to @ref Corrade::TestSuite::Tester for testing GPU
code: code:
- `OpenGLTester` -- @ref OpenGLTester class - `OpenGLTester` --- @ref OpenGLTester class
The library also contains a set of plugins for importing essential file The library also contains a set of plugins for importing essential file
formats. Additional plugins are provided in separate plugin repository, see formats. Additional plugins are provided in separate plugin repository, see
@ -135,22 +138,22 @@ loads them dynamically. However, if they are built as static (see
executable and then explicitly imported. Also if you are going to use them as executable and then explicitly imported. Also if you are going to use them as
dependencies, you need to find the dependency and then link to it. dependencies, you need to find the dependency and then link to it.
- `MagnumFont` -- @ref Text::MagnumFont "MagnumFont" plugin - `MagnumFont` --- @ref Text::MagnumFont "MagnumFont" plugin
- `MagnumFontConverter` -- @ref Text::MagnumFontConverter "MagnumFontConverter" - `MagnumFontConverter` --- @ref Text::MagnumFontConverter "MagnumFontConverter"
plugin plugin
- `ObjImporter` -- @ref Trade::ObjImporter "ObjImporter" plugin - `ObjImporter` --- @ref Trade::ObjImporter "ObjImporter" plugin
- `TgaImageConverter` -- @ref Trade::TgaImageConverter "TgaImageConverter" - `TgaImageConverter` --- @ref Trade::TgaImageConverter "TgaImageConverter"
plugin plugin
- `TgaImporter` -- @ref Trade::TgaImporter "TgaImporter" plugin - `TgaImporter` --- @ref Trade::TgaImporter "TgaImporter" plugin
- `WavAudioImporter` -- @ref Audio::WavImporter "WavAudioImporter" plugin - `WavAudioImporter` --- @ref Audio::WavImporter "WavAudioImporter" plugin
Lastly, a few utility executables are available: Lastly, a few utility executables are available:
- `distancefieldconverter` -- @ref magnum-distancefieldconverter executable - `distancefieldconverter` --- @ref magnum-distancefieldconverter executable
- `fontconverter` -- @ref magnum-fontconverter executable - `fontconverter` --- @ref magnum-fontconverter executable
- `imageconverter` -- @ref magnum-imageconverter executable - `imageconverter` --- @ref magnum-imageconverter executable
- `info` -- @ref magnum-info executable - `info` --- @ref magnum-info executable
- `al-info` -- @ref magnum-al-info executable - `al-info` --- @ref magnum-al-info executable
Note that [each namespace](namespaces.html), all @ref Platform libraries and Note that [each namespace](namespaces.html), all @ref Platform libraries and
each plugin class contain more detailed information about dependencies, each plugin class contain more detailed information about dependencies,
@ -159,12 +162,14 @@ in build and use it with CMake.
Example usage with specifying additional components is: Example usage with specifying additional components is:
find_package(Magnum REQUIRED MeshTools Primitives Sdl2Application) @code{.cmake}
find_package(Magnum REQUIRED MeshTools Primitives Sdl2Application)
@endcode
For each component is then defined: For each component is then defined:
- `Magnum_*_FOUND` -- Whether the component was found - `Magnum_*_FOUND` --- Whether the component was found
- `Magnum::*` -- Component imported target - `Magnum::*` --- Component imported target
If exactly one `*Application` or exactly one `Windowless*Application` component If exactly one `*Application` or exactly one `Windowless*Application` component
is requested and found, its target is available in convenience alias is requested and found, its target is available in convenience alias
@ -186,34 +191,34 @@ Features of found Magnum library are exposed in these CMake variables, they
are also available as preprocessor variables if including are also available as preprocessor variables if including
@ref Magnum/Magnum.h "Magnum/Magnum.h": @ref Magnum/Magnum.h "Magnum/Magnum.h":
- `MAGNUM_BUILD_DEPRECATED` -- Defined if compiled with deprecated APIs - `MAGNUM_BUILD_DEPRECATED` --- Defined if compiled with deprecated APIs
included included
- `MAGNUM_BUILD_STATIC` -- Defined if compiled as static libraries. Default - `MAGNUM_BUILD_STATIC` --- Defined if compiled as static libraries. Default
are shared libraries. are shared libraries.
- `MAGNUM_BUILD_MULTITHREADED` -- Defined if compiled in a way that allows - `MAGNUM_BUILD_MULTITHREADED` --- Defined if compiled in a way that allows
having multiple thread-local Magnum contexts. The default. having multiple thread-local Magnum contexts. The default.
- `MAGNUM_TARGET_GLES` -- Defined if compiled for OpenGL ES - `MAGNUM_TARGET_GLES` --- Defined if compiled for OpenGL ES
- `MAGNUM_TARGET_GLES2` -- Defined if compiled for OpenGL ES 2.0 - `MAGNUM_TARGET_GLES2` --- Defined if compiled for OpenGL ES 2.0
- `MAGNUM_TARGET_GLES3` -- Defined if compiled for OpenGL ES 3.0 - `MAGNUM_TARGET_GLES3` --- Defined if compiled for OpenGL ES 3.0
- `MAGNUM_TARGET_DESKTOP_GLES` -- Defined if compiled with OpenGL ES - `MAGNUM_TARGET_DESKTOP_GLES` --- Defined if compiled with OpenGL ES
emulation on desktop OpenGL emulation on desktop OpenGL
- `MAGNUM_TARGET_WEBGL` -- Defined if compiled for WebGL - `MAGNUM_TARGET_WEBGL` --- Defined if compiled for WebGL
- `MAGNUM_TARGET_HEADLESS` -- Defined if compiled for headless machines. See - `MAGNUM_TARGET_HEADLESS` --- Defined if compiled for headless machines. See
@ref MAGNUM_TARGET_HEADLESS documentation for more information. @ref MAGNUM_TARGET_HEADLESS documentation for more information.
Workflows without imported targets are deprecated and the following variables Workflows without imported targets are deprecated and the following variables
are included just for backwards compatibility and only if are included just for backwards compatibility and only if
@ref MAGNUM_BUILD_DEPRECATED is enabled: @ref MAGNUM_BUILD_DEPRECATED is enabled:
- `MAGNUM_LIBRARIES` -- Expands to `Magnum::Magnum` target. Use `Magnum::Magnum` - `MAGNUM_LIBRARIES` --- Expands to `Magnum::Magnum` target. Use `Magnum::Magnum`
target directly instead. target directly instead.
- `MAGNUM_*_LIBRARIES` -- Expands to `Magnum::*` target. Use `Magnum::*` - `MAGNUM_*_LIBRARIES` --- Expands to `Magnum::*` target. Use `Magnum::*`
target directly instead. target directly instead.
- `MAGNUM_APPLICATION_LIBRARIES` / `MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES` - `MAGNUM_APPLICATION_LIBRARIES` / `MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES`
-- Expands to `Magnum::Application` / `Magnum::WindowlessApplication` --- Expands to `Magnum::Application` / `Magnum::WindowlessApplication`
target. Use `Magnum::Application` / `Magnum::WindowlessApplication` target target. Use `Magnum::Application` / `Magnum::WindowlessApplication` target
directly instead. directly instead.
- `MAGNUM_CONTEXT_LIBRARIES` -- Expands to `Magnum::Context` target. Use - `MAGNUM_CONTEXT_LIBRARIES` --- Expands to `Magnum::Context` target. Use
`Magnum::Context` target directly instead. `Magnum::Context` target directly instead.
Corrade library provides also its own set of CMake macros and variables, see Corrade library provides also its own set of CMake macros and variables, see
@ -225,27 +230,22 @@ and @ref cmake-extras "Extras repository" have also their own CMake modules.
The `modules/` directory contains more useful CMake modules: The `modules/` directory contains more useful CMake modules:
- `FindOpenAL.cmake` -- CMake module for finding OpenAL. This is a forked - `FindOpenAL.cmake` --- CMake module for finding OpenAL. This is a forked
version of the upstream module that works properly with version of the upstream module that works properly with
@ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". Copy this to your module @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". Copy this to your module
directory if you want to use the @ref Audio library on Emscripten. directory if you want to use the @ref Audio library on Emscripten.
- `FindGLFW.cmake` -- CMake module for finding GLFW. Copy this to your module - `FindGLFW.cmake` --- CMake module for finding GLFW. Copy this to your module
directory if you want to use @ref Platform::GlfwApplication. directory if you want to use @ref Platform::GlfwApplication.
- `FindEGL.cmake` -- CMake module for finding EGL. Copy this to your - `FindEGL.cmake` --- CMake module for finding EGL. Copy this to your
module directory if you want to target embedded platforms such as module directory if you want to target embedded platforms such as
@ref CORRADE_TARGET_IOS "iOS", @ref CORRADE_TARGET_ANDROID "Android", @ref CORRADE_TARGET_IOS "iOS", @ref CORRADE_TARGET_ANDROID "Android",
@ref CORRADE_TARGET_WINDOWS_RT "Windows RT" or @ref CORRADE_TARGET_WINDOWS_RT "Windows RT" or
@ref CORRADE_TARGET_EMSCRIPTEN "Emscripten" or if you want to use EGL @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten" or if you want to use EGL
instead of GLX/WGL/CGL on a desktop platform. instead of GLX/WGL/CGL on a desktop platform.
- `FindOpenGLES2.cmake`, `FindOpenGLES3.cmake` -- CMake module for finding - `FindOpenGLES2.cmake`, `FindOpenGLES3.cmake` --- CMake module for finding
OpenGL ES 2.0 / 3.0 library. Copy this to your module directory if you want OpenGL ES 2.0 / 3.0 library. Copy this to your module directory if you want
to target @ref MAGNUM_TARGET_GLES "OpenGL ES". to target @ref MAGNUM_TARGET_GLES "OpenGL ES".
- `FindSDL2.cmake` -- CMake module for finding SDL 2. Copy this to your - `FindSDL2.cmake` --- CMake module for finding SDL 2. Copy this to your
module directory if you want to use @ref Platform::Sdl2Application. module directory if you want to use @ref Platform::Sdl2Application.
See also relevant section for @ref corrade-cmake-modules "Corrade",
@ref cmake-plugins-modules "Plugins", @ref cmake-integration-modules "Integration"
and @ref cmake-extras-modules "Extras" projects.
*/ */
} }

2
doc/coding-style.dox

@ -206,7 +206,7 @@ and in most cases only for internal use.
All unit tests use Corrade's @ref Corrade::TestSuite "TestSuite". All unit tests use Corrade's @ref Corrade::TestSuite "TestSuite".
Don't forget to test all `constexpr` methods -- many compilers don't implicitly Don't forget to test all `constexpr` methods --- many compilers don't implicitly
check whether the `constexpr` keyword can be used but then complain when you check whether the `constexpr` keyword can be used but then complain when you
force the expression to be constant. It's better not to have given method force the expression to be constant. It's better not to have given method
marked as `constexpr` than have it marked it errorneously. It's usually not marked as `constexpr` than have it marked it errorneously. It's usually not

41
doc/compilation-speedup.dox

@ -27,9 +27,12 @@ namespace Magnum {
/** @page compilation-speedup Speeding up compilation /** @page compilation-speedup Speeding up compilation
@brief Techniques for reducing compilation times. @brief Techniques for reducing compilation times.
@tableofcontents
@m_footernavigation
@section compilation-forward-declarations Forward declarations instead of includes @section compilation-forward-declarations Forward declarations instead of includes
Essential thing when speeding up compilation is reducing number of `#``include` Essential thing when speeding up compilation is reducing number of @cpp #include @ce
directives in both headers and source files. Magnum is strictly applying this directives in both headers and source files. Magnum is strictly applying this
policy in all header files, so all types which are not directly used in the policy in all header files, so all types which are not directly used in the
header have only forward declarations. header have only forward declarations.
@ -37,21 +40,31 @@ header have only forward declarations.
For example, when including @ref Magnum.h, you get shortcut typedefs for For example, when including @ref Magnum.h, you get shortcut typedefs for
floating-point vectors and matrices like @ref Vector3 and @ref Matrix4, but to floating-point vectors and matrices like @ref Vector3 and @ref Matrix4, but to
actually use any of them, you have to include the respective header, e.g. actually use any of them, you have to include the respective header, e.g.
@ref Math/Vector3.h. @ref Magnum/Math/Vector3.h.
You are encouraged to use forward declarations also in your code. However, for You are encouraged to use forward declarations also in your code. However, for
some types it can be too cumbersome -- e.g. too many template parameters, some types it can be too cumbersome --- e.g. too many template parameters,
typedefs etc. In this case a header with forward declarations is usually typedefs etc. In this case a header with forward declarations is usually
available, each namespace has its own: available, each namespace has its own:
- @ref Math/Math.h - @ref Corrade/Corrade.h
- @ref Magnum.h - @ref Corrade/Containers/Containers.h
- @ref DebugTools/DebugTools.h - @ref Corrade/Interconnect/Interconnect.h
- @ref SceneGraph/SceneGraph.h - @ref Corrade/PluginManager/PluginManager.h
- @ref Shaders/Shaders.h - @ref Corrade/TestSuite/TestSuite.h
- @ref Shapes/Shapes.h - @ref Corrade/Utility/Utility.h
- @ref Text/Text.h - @ref Magnum/Magnum.h
- @ref Trade/Trade.h - @ref Magnum/Audio/Audio.h
- @ref Magnum/DebugTools/DebugTools.h
- @ref Magnum/Math/Math.h
- @ref Magnum/OvrIntegration/OvrIntegration.h
- @ref Magnum/Platform/Platform.h
- @ref Magnum/SceneGraph/SceneGraph.h
- @ref Magnum/Shaders/Shaders.h
- @ref Magnum/Shapes/Shapes.h
- @ref Magnum/Text/Text.h
- @ref Magnum/Trade/Trade.h
- @ref Magnum/Ui/Ui.h
@section compilation-speedup-templates Templates @section compilation-speedup-templates Templates
@ -92,7 +105,8 @@ we want to use @ref SceneGraph::Object "Object" from @ref SceneGraph with
@ref Double instead of @ref Float as underlying type, because our scene will @ref Double instead of @ref Float as underlying type, because our scene will
span the whole universe. We include the implementation file in dedicated source span the whole universe. We include the implementation file in dedicated source
file and explicitly instantiate the template: file and explicitly instantiate the template:
@code
@code{.cpp}
// Object.cpp // Object.cpp
#include "SceneGraph/Object.hpp" #include "SceneGraph/Object.hpp"
#include "SceneGraph/MatrixTransformation3D.h" #include "SceneGraph/MatrixTransformation3D.h"
@ -109,7 +123,7 @@ precious compilation time.
@subsection compilation-speedup-extern-templates Extern templates @subsection compilation-speedup-extern-templates Extern templates
Keyword `extern template` is a new thing in C++11, attempting to solve Keyword @cpp extern template @ce is a new thing in C++11, attempting to solve
compilation time problems related to templated code. However, on some compilers compilation time problems related to templated code. However, on some compilers
it causes conflicting symbol errors when used on whole classes, thus in Magnum it causes conflicting symbol errors when used on whole classes, thus in Magnum
it's used only for specific functions. it's used only for specific functions.
@ -117,6 +131,5 @@ it's used only for specific functions.
This is completely transparent to end user, so no special care is needed. This is completely transparent to end user, so no special care is needed.
Extern template is used for example for @ref debugoperators "debug operators" Extern template is used for example for @ref debugoperators "debug operators"
for common types of matrices and vectors. for common types of matrices and vectors.
*/ */
} }

12
doc/debug-tools.dox

@ -27,7 +27,8 @@ namespace Magnum {
/** @page debug-tools Debugging helpers /** @page debug-tools Debugging helpers
@brief Convenience classes to help you during development. @brief Convenience classes to help you during development.
- Previous page: @ref shapes @tableofcontents
@m_footernavigation
@ref DebugTools library provides various helper classes to help you with @ref DebugTools library provides various helper classes to help you with
prototyping and debugging applications without the need to write too much prototyping and debugging applications without the need to write too much
@ -35,8 +36,6 @@ common code. They probably have no usage in production code, but can be useful
in development. See documentation of @ref DebugTools namespace for more in development. See documentation of @ref DebugTools namespace for more
information about building and usage with CMake. information about building and usage with CMake.
@tableofcontents
@section debug-tools-renderers Debug renderers @section debug-tools-renderers Debug renderers
Debug renderers provide a way to visualize objects and object features in Debug renderers provide a way to visualize objects and object features in
@ -58,8 +57,9 @@ same options with more renderers. If no options are specified or resource with
given key doesn't exist, default fallback is used. given key doesn't exist, default fallback is used.
Example usage: visualizing object position, rotation and scaling using Example usage: visualizing object position, rotation and scaling using
@link DebugTools::ObjectRenderer @endlink: @ref DebugTools::ObjectRenderer :
@code
@code{.cpp}
// Global instance of debug resource manager, drawable group for the renderers // Global instance of debug resource manager, drawable group for the renderers
DebugTools::ResourceManager manager; DebugTools::ResourceManager manager;
SceneGraph::DrawableGroup3D debugDrawables; SceneGraph::DrawableGroup3D debugDrawables;
@ -77,7 +77,5 @@ new DebugTools::ObjectRenderer2D(*object, "my", debugDrawables);
See @ref DebugTools::ObjectRenderer and @ref DebugTools::ShapeRenderer for more See @ref DebugTools::ObjectRenderer and @ref DebugTools::ShapeRenderer for more
information. information.
- Previous page: @ref shapes
*/ */
} }

20
doc/features.dox

@ -27,15 +27,15 @@ namespace Magnum {
/** @page features Feature overview /** @page features Feature overview
@brief Fundamental principles and design goals. @brief Fundamental principles and design goals.
- @subpage platform -- @copybrief platform - @subpage platform --- @copybrief platform
- @subpage types -- @copybrief types - @subpage types --- @copybrief types
- @subpage matrix-vector -- @copybrief matrix-vector - @subpage matrix-vector --- @copybrief matrix-vector
- @subpage transformations -- @copybrief transformations - @subpage transformations --- @copybrief transformations
- @subpage plugins -- @copybrief plugins - @subpage plugins --- @copybrief plugins
- @subpage opengl-wrapping -- @copybrief opengl-wrapping - @subpage opengl-wrapping --- @copybrief opengl-wrapping
- @subpage shaders -- @copybrief shaders - @subpage shaders --- @copybrief shaders
- @subpage scenegraph -- @copybrief scenegraph - @subpage scenegraph --- @copybrief scenegraph
- @subpage shapes -- @copybrief shapes - @subpage shapes --- @copybrief shapes
- @subpage debug-tools -- @copybrief debug-tools - @subpage debug-tools --- @copybrief debug-tools
*/ */
} }

BIN
doc/getting-started-blue.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

199
doc/getting-started.dox

@ -36,34 +36,31 @@ many use cases, helping you get up and running in no time.
@section getting-started-bootstrap Download bootstrap project @section getting-started-bootstrap Download bootstrap project
The [bootstrap repository](https://github.com/mosra/magnum-bootstrap) is The [bootstrap repository](https://github.com/mosra/magnum-bootstrap) is
located on GitHub. The `master` branch contains just an README file and the located on GitHub. The `master` branch contains just a README file and the
actual bootstrap projects are in various other branches, each covering some actual bootstrap projects are in various other branches, each covering some
particular use case. For the first project you need the `base` branch, which particular use case. For the first project you need the `base` branch, which
contains only the essential files. Download the branch [as an archive](https://github.com/mosra/magnum-bootstrap/archive/base.zip) contains only the essential files. Download the branch
and extract it somewhere. Do it rather than cloning the full repository, as [as an archive](https://github.com/mosra/magnum-bootstrap/archive/base.zip) and
it's better to init your own repository from scratch with clean history. extract it somewhere. Do it rather than cloning the full repository, as it's
better to init your new project from scratch with clean Git history.
If you want to (or have to) use GLUT instead of SDL2, download the `base-glut`
branch [archive](https://github.com/mosra/magnum-bootstrap/archive/base-glut.zip)
instead of `base` branch. The code will be slightly different from what is
presented below, but the changes are only minor (two modified lines) and the
main principles are the same.
@section getting-started-download Download, build and install Corrade and Magnum @section getting-started-download Download, build and install Corrade and Magnum
Magnum libraries support both separate compilation/installation and CMake Magnum libraries support both separate compilation/installation and CMake
subprojects. We'll use the subproject approach now, because adding the subprojects. We'll use the subproject approach now --- adding the dependencies
dependencies means just cloning them into your project tree: means just cloning them into your project tree:
cd /path/to/the/extracted/bootstrap/project @code{.sh}
git clone git://github.com/mosra/corrade.git cd /path/to/the/extracted/bootstrap/project
git clone git://github.com/mosra/magnum.git git clone git://github.com/mosra/corrade.git
git clone git://github.com/mosra/magnum.git
@endcode
Then open the `CMakeLists.txt` file in the root of bootstrap project and add Then open the `CMakeLists.txt` file in the root of bootstrap project and add
these two new subdirectories using `add_subdirectory()` so the file looks like these two new subdirectories using @cmake add_subdirectory() @ce so the file
this: looks like this:
@code @code{.cmake}
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 2.8.12)
project(MyApplication) project(MyApplication)
@ -74,16 +71,22 @@ add_subdirectory(magnum)
add_subdirectory(src) add_subdirectory(src)
@endcode @endcode
If you want to install Corrade and Magnum separately instead of cloning them @note In the long run it's better to install Corrade and Magnum separately
into your project tree, just follow @ref building "the full installation guide". instead of cloning them into your project tree, as that can vastly improve
Don't forget to enable `WITH_SDL2APPLICATION` (or `WITH_GLUTAPPLICATION`, if your iteration times. Follow @ref building "the full installation guide" if
you are using GLUT) when building Magnum so the bootstrap project can use it you want to go that route; don't forget to enable `WITH_SDL2APPLICATION`
later. when building Magnum so the bootstrap project can use it later. There are
also ready-to-use packages for various OSes and distributions.
@note If you have that, you don't need to clone the subprojects and modify the
`CMakeLists.txt` file like above, you might only need to set
`CMAKE_PREFIX_PATH` if you installed Corrade and Magnum to a non-standard
location.
@section getting-started-review Review project structure @section getting-started-review Review project structure
The base project consists of just six files in two subfolders. Magnum uses The base project consists of just six files in two subfolders. Magnum uses the
CMake build system, see @ref cmake for more information. CMake build system, you can read more about it in @ref cmake.
modules/FindCorrade.cmake modules/FindCorrade.cmake
modules/FindMagnum.cmake modules/FindMagnum.cmake
@ -92,25 +95,27 @@ CMake build system, see @ref cmake for more information.
src/CMakeLists.txt src/CMakeLists.txt
CMakeLists.txt CMakeLists.txt
In root there is project-wide `CMakeLists.txt`, which you have seen above. It In root there is the project-wide `CMakeLists.txt`, which you have seen above.
just sets up project name, specifies module directory and delegates everything It just sets up project name, specifies module directory and delegates
important to `CMakeLists.txt` in `src/` subdirectory. everything important to `CMakeLists.txt` in the `src/` subdirectory.
Directory `modules/` contains CMake modules for finding the needed The `modules/` directory contains CMake modules for finding the needed
dependencies. Unlike modules for finding e.g. OpenGL, which are part of dependencies. Unlike modules for finding e.g. OpenGL, which are part of
standard CMake installation, these aren't part of it and thus must be standard CMake installation, these aren't part of it and thus must be
distributed with the project. These files are just verbatim copied from Magnum distributed with the project. These files are just verbatim copied from Magnum
repository. repository.
@note These modules are just the bare minimum you need for starting. If you @note These modules are just the bare minimum you need for starting. If you
plan to use additional functionality not part of the core library or target plan to use additional functionality that isn't part of the core library or
specific platforms, you may need to copy additional modules. See @ref cmake, you are targeting specific platforms, you may need to include additional
@ref cmake-plugins, @ref cmake-integration and @ref cmake-extras for more modules. See @ref cmake, @ref cmake-plugins, @ref cmake-integration and
information. @ref cmake-extras for more information.
Directory `src/` contains the actual project. To keep things simple, the The `src/` directory contains the actual project. To keep things simple, the
project consists of just one source file with the most minimal code possible: project consists of just a single `MyApplication.cpp` file with the most
@code minimal code possible:
@code{.cpp}
#include <Magnum/DefaultFramebuffer.h> #include <Magnum/DefaultFramebuffer.h>
#include <Magnum/Platform/Sdl2Application.h> #include <Magnum/Platform/Sdl2Application.h>
@ -139,11 +144,12 @@ void MyApplication::drawEvent() {
MAGNUM_APPLICATION_MAIN(MyApplication) MAGNUM_APPLICATION_MAIN(MyApplication)
@endcode @endcode
The application essentially does nothing, just clears screen framebuffer to The application essentially does nothing, just clears the screen framebuffer to
default (dark gray) color and then does buffer swap to actually display it on default (dark gray) color and then does buffer swap to actually display it on
the screen. The `src/CMakeLists.txt` file finds Magnum, creates the executable the screen. The `src/CMakeLists.txt` file finds Magnum, creates the executable
and links it to all needed libraries: and links it to all needed libraries:
@code
@code{.cmake}
find_package(Magnum REQUIRED Sdl2Application) find_package(Magnum REQUIRED Sdl2Application)
set_directory_properties(PROPERTIES CORRADE_USE_PEDANTIC_FLAGS ON) set_directory_properties(PROPERTIES CORRADE_USE_PEDANTIC_FLAGS ON)
@ -158,60 +164,72 @@ In the following tutorials the code will be explained more thoroughly.
@section getting-started-build Build it and run @section getting-started-build Build it and run
@subsection getting-started-linux Linux, macOS and other Unix-based OSs
In Linux (and other Unix-based OSs) you can build the application along with In Linux (and other Unix-based OSs) you can build the application along with
the subprojects using the following three commands: create out-of-source build the subprojects using the following three commands: create out-of-source build
directory, run cmake, enable SDL2 application in the Magnum subproject and then directory, run `cmake`, enable SDL2 application in the Magnum subproject and
build everything. The compiled application binary will then appear in `src/` then build everything. The compiled application binary will then appear in
subdirectory of the build dir: `src/` subdirectory of the build dir:
mkdir -p build && cd build @code{.sh}
cmake .. -DWITH_SDL2APPLICATION=ON mkdir -p build && cd build
cmake --build . cmake .. -DWITH_SDL2APPLICATION=ON
./src/MyApplication cmake --build .
./src/MyApplication
@endcode
@note If you installed Corrade and Magnum separately (instead of putting them @note If you installed Corrade and Magnum separately (instead of putting them
in the project as subprojects), the `-DWITH_SDL2APPLICATION=ON` is not in the project as subprojects), the `-DWITH_SDL2APPLICATION=ON` is not
needed as that was already done when compiling & installing Magnum before. needed as that was already done when compiling & installing Magnum before.
On Windows you can use either MSVC or MinGW-w64 compiler and prebuilt SDL2 @subsection getting-started-windows Windows
binaries can be downloaded at https://libsdl.org/download-2.0.php. It's then up
to you whether you will use command-line, QtCreator or Visual Studio. With On Windows you can use either MSVC 2015+ or MinGW-w64. Prebuilt SDL2 binaries
Visual Studio the most straightforward way to create the project file is via can be downloaded at https://libsdl.org/download-2.0.php, dependeding on where
the command-line: you extract them you may need to specify `CMAKE_PREFIX_PATH` so CMake is able
to find them. For running the executable properly, Windows also need to have
mkdir build && cd build all dependency DLLs copied along it. That can be done by setting
cmake .. -DWITH_SDL2APPLICATION=ON `CMAKE_RUNTIME_OUTPUT_DIRECTORY`. It's then up to you whether you will use a
command line, Visual Studio or for example QtCreator. With Visual Studio the
most straightforward way to generate the project file is via the command line:
@code{.bat}
mkdir build && cd build
cmake .. ^
-DWITH_SDL2APPLICATION=ON ^
-DCMAKE_PREFIX_PATH="C:/Users/you/where/you/extracted/SDL2-2.0.5" ^
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY="bin"
@endcode
You can also use CMake GUI. Then open the `MyApplication.sln` project file You can also use CMake GUI. Then open the `MyApplication.sln` project file
generated by CMake in the build directory. generated by CMake in the `build/` directory.
With QtCreator just open project's root `CMakeLists.txt` file. It then asks you With QtCreator just open project's root `CMakeLists.txt` file. It then asks you
where to create build directory, allows you to specify initial CMake parameters where to create build directory, allows you to specify initial CMake parameters
(e.g. the `-DWITH_SDL2APPLICATION=ON` parameter) and then you can just press *Configure* (`-DWITH_SDL2APPLICATION=ON` and others) and then you can just press *Configure*
and everything is ready to be built. and everything is ready to be built.
If you have SDL2 in a non-standard location and CMake can't find it, you need @note If you installed Corrade and Magnum separately, the install directory
to specify where SDL `include/` and `lib/` directories are through containing the DLLs needs to be in @cb{.bat} %PATH% @ce in order to
`CMAKE_PREFIX_PATH`. So, for example, on Windows, the full CMake invocation properly run the executable. You can also enable `BUILD_STATIC` to compile
might look like this: everything as static, see @ref building "the full installation guide" for
details.
cmake .. -DCMAKE_PREFIX_PATH="C:/Users/you/Downloads/SDL2-2.0.4" -DWITH_SDL2APPLICATION=ON @section getting-started-running Running the application
On Windows you may get errors about missing DLLs when running the application. If everything went well and the application starts, you will see a blank window
The solution is either compiling everything as static (enable `BUILD_STATIC` like this:
CMake option) or installing the dependencies somewhere. To install them, change
`CMAKE_INSTALL_PREFIX` to your liking and run the `install` target. Then run
the application with `bin/` subdirectory of installation prefix as working dir
or add the `bin/` subdirectory to `PATH`.
@image html getting-started.png @image html getting-started.png
@image latex getting-started.png @image latex getting-started.png
Now you can try to change something in the code. Without going too deep into Now you can try to change something in the code. Without going too deep into
the concepts of graphics programming, we can change clear color to something the concepts of graphics programming, we can change the clear color to
else and also print basic information about the GPU the engine is running on. something else and also print basic information about the GPU the engine is
First include the needed headers: running on. First include the needed headers:
@code
@code{.cpp}
#include <Magnum/Context.h> #include <Magnum/Context.h>
#include <Magnum/Renderer.h> #include <Magnum/Renderer.h>
#include <Magnum/Version.h> #include <Magnum/Version.h>
@ -220,19 +238,24 @@ First include the needed headers:
And in the constructor (which is currently empty) change the clear color and And in the constructor (which is currently empty) change the clear color and
print something to debug output: print something to debug output:
@code
using namespace Magnum::Math::Literals;
Renderer::setClearColor(Color3::fromHsv(216.0_degf, 0.85f, 1.0f)); @code{.cpp}
using namespace Magnum::Math::Literals;
Renderer::setClearColor(0xa5c9ea_rgbf);
Debug() << "Hello! This application is running on" << Context::current().version() Debug() << "Hello! This application is running on" << Context::current().version()
<< "using" << Context::current().rendererString(); << "using" << Context::current().rendererString();
@endcode @endcode
After rebuilding and starting the application, the clear color changes to After rebuilding and starting the application, the clear color changes to
blueish one and something like this would be printed to the console: blueish one and something like this would be printed to the console:
> Hello! This application is running on OpenGL 4.5 using GeForce GT 740M @code{.shell-session}
$ ./MyApplication
[...]
Hello! This application is running on OpenGL 4.5 using GeForce GT 740M
@endcode
@image html getting-started-blue.png @image html getting-started-blue.png
@image latex getting-started-blue.png @image latex getting-started-blue.png
@ -240,22 +263,22 @@ blueish one and something like this would be printed to the console:
@section getting-started-tutorials Follow tutorials and learn the principles @section getting-started-tutorials Follow tutorials and learn the principles
Now that you have your first application up and running, the best way to Now that you have your first application up and running, the best way to
continue is to render your first triangle in @ref example-index "step-by-step tutorial". continue is to render your first triangle in a @ref examples-triangle "step-by-step tutorial".
Then you can dig deeper and try other examples, read about Then you can dig deeper and try other examples, read about
@ref features "fundamental principles" in the documentation and start @ref features "fundamental principles" in the documentation and start
experimenting on your own! experimenting on your own!
@section getting-started-more Additional information @section getting-started-more Additional information
- @subpage building - @subpage building --- @copybrief building
- @subpage building-plugins - @subpage building-plugins --- @copybrief building-plugins
- @subpage building-integration - @subpage building-integration --- @copybrief building-integration
- @subpage building-examples - @subpage building-extras --- @copybrief building-extras
- @subpage building-extras - @subpage building-examples --- @copybrief building-examples
- @subpage cmake - @subpage cmake --- @copybrief cmake
- @subpage cmake-plugins - @subpage cmake-plugins --- @copybrief cmake-plugins
- @subpage cmake-integration - @subpage cmake-integration --- @copybrief cmake-integration
- @subpage cmake-extras - @subpage cmake-extras --- @copybrief cmake-extras
*/ */
} }

BIN
doc/getting-started.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

84
doc/mainpage.dox

@ -26,43 +26,42 @@
namespace Magnum { namespace Magnum {
/** @mainpage /** @mainpage
Magnum is 2D/3D graphics engine written in C++11/C++14 and modern OpenGL. Its Magnum is a 2D/3D graphics engine written in C++11/C++14 and modern OpenGL. Its
goal is to simplify low-level graphics development and interaction with OpenGL goal is to simplify low-level graphics development and interaction with OpenGL
using recent C++11/C++14 features and to abstract away platform-specific using recent C++11/C++14 features and to abstract away platform-specific
issues. issues.
@section mainpage-design-goals Design goals @section mainpage-design-goals Design goals
- **2D is not an ugly stepchild** - **2D is not an ugly stepchild.** Many engines out there were created as
Many engines out there were created as pure 2D or 3D and the alternative is pure 2D or 3D and the alternative is usually just an afterthought, if it is
usually just an afterthought, if it is present at all. If you want to do present at all. If you want to do your next project in 2D only, you have to
your next project in 2D only, you have to either relearn another engine either relearn another engine from scratch or emulate it in 3D, leaving
from scratch or emulate it in 3D, leaving many things overly complicated. many things overly complicated. Magnum treats 2D equivalently to 3D so you
Magnum treats 2D equivalently to 3D so you can reuse what you already can reuse what you already learned for 3D and even combine 2D and 3D in one
learned for 3D and even combine 2D and 3D in one project. project.
- **Forward compatibility** - **Forward compatibility.** If newer technology makes things faster, simpler
If newer technology makes things faster, simpler or more intuitive, it is or more intuitive, it is the way to go. Magnum by default relies on decent
the way to go. Magnum by default relies on decent C++11 support and modern C++11 support and modern OpenGL features and if some feature isn't
OpenGL features and if some feature isn't available, it tries to emulate it available, it tries to emulate it using older functionality. However, you
using older functionality. However, you are not restricted to use the older are not restricted to use the older functionality directly, if you really
functionality directly, if you really want to. want to.
- **Intuitive, but not restrictive API** - **Intuitive, but not restrictive API.** Scripting languages are often
Scripting languages are often preferred to C/C++ because they are designed preferred to C/C++ because they are designed to have less complicated APIs
to have less complicated APIs and less boilerplate code. Magnum is and less boilerplate code. Magnum is designed with intuitivity in mind, but
designed with intuitivity in mind, but also with speed and static checks also with speed and static checks that strongly-typed native code offers.
that strongly-typed native code offers. It wraps OpenGL into less verbose It wraps OpenGL into less verbose and more type-safe API, which is easier
and more type-safe API, which is easier to use. Usually the most common way to use. Usually the most common way is the most simple, but if you need
is the most simple, but if you need full control, you can have it. full control, you can have it.
- **Extensible and replaceable components** - **Extensible and replaceable components.** If you want to use different
If you want to use different mathematical library for specific purposes, mathematical library for specific purposes, that new windowing toolkit,
that new windowing toolkit, your own file formats or another physics your own file formats or another physics library, you can. Conversion of
library, you can. Conversion of math structures between different libraries math structures between different libraries can be done on top of pre-made
can be done on top of pre-made skeleton classes, support for file formats skeleton classes, support for file formats is done using plugins and
is done using plugins and platform support is done by writing simple platform support is done by writing simple wrapper class.
wrapper class.
@section mainpage-platforms Supported platforms @section mainpage-platforms Supported platforms
@ -78,10 +77,11 @@ Platforms:
- **Linux** and embedded Linux (natively using GLX/EGL and Xlib or through - **Linux** and embedded Linux (natively using GLX/EGL and Xlib or through
SDL2, GLFW or GLUT toolkit) SDL2, GLFW or GLUT toolkit)
- **Windows** using both MSVC and MinGW, natively or using ANGLE (through SDL2, GLFW or GLUT toolkit) - **Windows** using both MSVC and MinGW, natively or using ANGLE (through
SDL2, GLFW or GLUT toolkit)
- **macOS** (through SDL2 or GLFW toolkit) - **macOS** (through SDL2 or GLFW toolkit)
- **iOS** (through SDL2 toolkit) - **iOS** (through SDL2 toolkit)
- **Android** 2.3 (API Level 9) and higher - **Android**
- **Windows RT** (Store/Phone) using ANGLE (through SDL2 toolkit) - **Windows RT** (Store/Phone) using ANGLE (through SDL2 toolkit)
- **Web** (asm.js or WebAssembly), through [Emscripten](http://kripken.github.io/emscripten-site/) - **Web** (asm.js or WebAssembly), through [Emscripten](http://kripken.github.io/emscripten-site/)
@ -113,18 +113,18 @@ make the library as consistent and maintainable as possible.
Feel free to get more information or contact the team at: Feel free to get more information or contact the team at:
- Website -- http://magnum.graphics - Website --- http://magnum.graphics
- GitHub -- https://github.com/mosra/magnum - GitHub --- https://github.com/mosra/magnum
- Gitter -- https://gitter.im/mosra/magnum - Gitter --- https://gitter.im/mosra/magnum
- IRC -- join `#magnum-engine` channel on freenode - IRC --- join `#magnum-engine` channel on freenode
- Google Groups -- https://groups.google.com/forum/#!forum/magnum-engine - Google Groups --- https://groups.google.com/forum/#!forum/magnum-engine
- Twitter -- https://twitter.com/czmosra - Twitter --- https://twitter.com/czmosra
- E-mail -- mosra@centrum.cz - E-mail --- mosra@centrum.cz
- Jabber -- mosra@jabbim.cz - Jabber --- mosra@jabbim.cz
@section mainpage-license License @section mainpage-license License
Magnum is licensed under MIT/Expat license: Magnum is licensed under the MIT/Expat license:
> >
> Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 > Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017

305
doc/matrix-vector.dox

@ -27,8 +27,8 @@ namespace Magnum {
/** @page matrix-vector Operations with matrices and vectors /** @page matrix-vector Operations with matrices and vectors
@brief Introduction to essential classes of the graphics pipeline. @brief Introduction to essential classes of the graphics pipeline.
- Previous page: @ref types @tableofcontents
- Next page: @ref transformations @m_footernavigation
Matrices and vectors are the most important part of graphics programming and Matrices and vectors are the most important part of graphics programming and
one of goals of Magnum is to make their usage as intuitive as possible. They one of goals of Magnum is to make their usage as intuitive as possible. They
@ -36,32 +36,31 @@ are contained in @ref Math namespace and common variants also have aliases in
root @ref Magnum namespace. See documentation of these namespaces for more root @ref Magnum namespace. See documentation of these namespaces for more
information about usage with CMake. information about usage with CMake.
@tableofcontents
@section matrix-vector-hierarchy Matrix and vector classes @section matrix-vector-hierarchy Matrix and vector classes
Magnum has three main matrix and vector classes: @ref Math::RectangularMatrix, Magnum has three main matrix and vector classes: @ref Math::RectangularMatrix,
(square) @ref Math::Matrix and @ref Math::Vector. To achieve greatest code (square) @ref Math::Matrix and @ref Math::Vector. To achieve greatest code
reuse, Matrix is internally square RectangularMatrix and RectangularMatrix reuse, @ref Math::Matrix is internally square @ref Math::RectangularMatrix and
is internally array of one or more Vector instances. Both vectors and matrices @ref Math::RectangularMatrix is internally array of one or more @ref Math::Vector
can have arbitrary size (known at compile time) and can store any arithmetic instances. Both vectors and matrices can have arbitrary size (known at compile
type. time) and can store any arithmetic type.
Each subclass brings some specialization to its superclass and for most common Each subclass brings some specialization to its superclass. For the most common
vector and matrix sizes there are specialized classes @ref Math::Matrix3 and vector and matrix sizes there are specialized classes @ref Math::Matrix3 and
@ref Math::Matrix4, implementing various transformations in 2D and 3D, @ref Math::Matrix4, implementing various transformations in 2D and 3D and
@ref Math::Vector2, @ref Math::Vector3 and @ref Math::Vector4, implementing @ref Math::Vector2, @ref Math::Vector3 and @ref Math::Vector4, implementing
direct access to named components. Functions of each class try to return the direct access to named components. Functions of each class try to return the
most specialized type known to make subsequent operations more convenient -- most specialized type known to make subsequent operations more convenient ---
columns of RectangularMatrix are returned as Vector, but when accessing columns of @ref Math::RectangularMatrix are returned as @ref Math::Vector, but
columns of e.g. Matrix3, they are returned as Vector3. when accessing columns of e.g. @ref Math::Matrix3, they are returned as
@ref Math::Vector3.
There are also even more specialized subclasses, e.g. @ref Math::Color3 and There are also even more specialized subclasses, e.g. @ref Math::Color3 and
@ref Math::Color4 for color handling and conversion. @ref Math::Color4 for color handling and conversion.
Commonly used types have convenience aliases in @ref Magnum namespace, so you Commonly used types have convenience aliases in @ref Magnum namespace, so you
can write e.g. @ref Vector3i instead of @ref Math::Vector3 "Math::Vector3<Int>". can write e.g. @ref Vector3i instead of @ref Math::Vector3 "Math::Vector3<Int>".
See @ref types and namespace documentation for more information. See @ref types and @ref Magnum namespace documentation for more information.
@section matrix-vector-construction Constructing matrices and vectors @section matrix-vector-construction Constructing matrices and vectors
@ -70,19 +69,21 @@ Default constructors of @ref Math::RectangularMatrix and @ref Math::Vector (and
@ref Math::Color4) create zero-filled objects. @ref Math::Matrix (and @ref Math::Color4) create zero-filled objects. @ref Math::Matrix (and
@ref Math::Matrix3, @ref Math::Matrix4) is by default constructed as identity @ref Math::Matrix3, @ref Math::Matrix4) is by default constructed as identity
matrix. matrix.
@code
Matrix2x3 a; // zero-filled
Vector3i b; // zero-filled
Matrix3 identity; // diagonal set to 1 @code{.cpp}
Matrix3 zero(Matrix::Zero); // zero-filled Matrix2x3 a; // zero-filled
Vector3i b; // zero-filled
Matrix3 identity; // diagonal set to 1
Matrix3 zero{Math::ZeroInit}; // zero-filled
@endcode @endcode
Most common and most efficient way to create vector is to pass all values to Most common and most efficient way to create vector is to pass all values to
constructor, matrix is created by passing all column vectors to the constructor, matrix is created by passing all column vectors to the
constructor. All constructors check number of passed arguments and the errors constructor. All constructors check number of passed arguments and the errors
are catched at compile time. are catched at compile time.
@code
@code{.cpp}
Vector3i vec(0, 1, 2); Vector3i vec(0, 1, 2);
Matrix3 mat({0.0f, 1.9f, 2.2f}, Matrix3 mat({0.0f, 1.9f, 2.2f},
@ -92,55 +93,50 @@ Matrix3 mat({0.0f, 1.9f, 2.2f},
You can specify all components of vector or whole diagonal of square matrix You can specify all components of vector or whole diagonal of square matrix
with single value or create diagonal matrix from vector: with single value or create diagonal matrix from vector:
@code
Matrix3 diag(Matrix3::Identity, 2.0f); // diagonal set to 2.0f, zeros elsewhere @code{.cpp}
Vector3i fill(10); // {10, 10, 10} Matrix3 diag(Matrix3::Identity, 2.0f); // diagonal is 2.0f, zeros elsewhere
Vector3i fill(10); // {10, 10, 10}
auto diag2 = Matrix3::fromDiagonal({3.0f, 2.0f, 1.0f}); auto diag2 = Matrix3::fromDiagonal({3.0f, 2.0f, 1.0f});
@endcode @endcode
There are also shortcuts to create a vector with all but one component set to There are also shortcuts to create a vector with all but one component set to
zero or one, useful for transformations: zero or one, useful for transformations:
@code
auto x = Vector3::xAxis(); // {1.0f, 0.0f, 0.0f}
auto y = Vector2::yAxis(3.0f); // {0.0f, 3.0f}
auto z = Vector3::zScale(3.0f); // {1.0f, 1.0f, 3.0f}
@endcode
It is possible to create matrices from other matrices and vectors with the same @code{.cpp}
row count; vectors from vector and scalar: auto x = Vector3::xAxis(); // {1.0f, 0.0f, 0.0f}
@code auto y = Vector2::yAxis(3.0f); // {0.0f, 3.0f}
Math::Matrix2x3<Int> a; auto z = Vector3::zScale(3.0f); // {1.0f, 1.0f, 3.0f}
Math::Vector3<Int> b, c;
Math::Matrix3<Int> mat(a, b);
Math::Vector<8, Int> vec(1, b, 2, c);
@endcode @endcode
@todo Implement this ^ already. It is also possible to create matrices and vectors from an C-style array. The
function does simple type cast without any copying, so it's possible to
conveniently operate on the array itself:
It is also possible to create them from an C-style array. The function does @code{.cpp}
simple type cast without any copying, so it's possible to conveniently operate
on the array itself:
@code
Int[] mat = { 2, 4, 6, Int[] mat = { 2, 4, 6,
1, 3, 5 }; 1, 3, 5 };
Math::Matrix2x3<Int>::from(mat) *= 2; // mat == { 4, 8, 12, 2, 6, 10 } Math::Matrix2x3<Int>::from(mat) *= 2; // { 4, 8, 12, 2, 6, 10 }
@endcode @endcode
Note that, unlike constructors, this function has no way to check whether the @attention Note that, unlike constructors, this function has no way to check
array is long enough to contain all elements, so use with caution. whether the array is long enough to contain all elements, so use with
caution.
To make handling of colors easier, their behavior is a bit different with a To make handling of colors easier, their behavior is a bit different with a
richer feature set. Implicit construction of @ref Color4 from @ref Color3 will richer feature set. Implicit construction of @ref Color4 from @ref Color3 will
set the alpha to full value (thus `1.0f` for @ref Color4 and `255` for set the alpha to full value (thus @cpp 1.0f @ce for @ref Color4 and @cpp 255 @ce
@ref Color4ub): for @ref Color4ub):
@code
@code{.cpp}
Color4 a = Color3{0.2f, 0.7f, 0.5f}; // {0.2f, 0.7f, 0.5f, 1.0f} Color4 a = Color3{0.2f, 0.7f, 0.5f}; // {0.2f, 0.7f, 0.5f, 1.0f}
Color4ub b = Color3ub{0x33, 0xb2, 0x7f}; // {0x33, 0xb2, 0x7f, 0xff} Color4ub b = Color3ub{0x33, 0xb2, 0x7f}; // {0x33, 0xb2, 0x7f, 0xff}
@endcode @endcode
Similarly to axes in vectors, you can create single color shades too, or create Similarly to axes in vectors, you can create single color shades too, or create
a RGB color from HSV representation: a RGB color from HSV representation:
@code
@code{.cpp}
auto green = Color3::green(); // {0.0f, 1.0f, 0.0f} auto green = Color3::green(); // {0.0f, 1.0f, 0.0f}
auto cyan = Color4::cyan(0.5f, 0.95f); // {0.5f, 1.0f, 1.0f, 0.95f} auto cyan = Color4::cyan(0.5f, 0.95f); // {0.5f, 1.0f, 1.0f, 0.95f}
auto fadedRed = Color3::fromHSV(219.0_degf, 0.50f, 0.57f) auto fadedRed = Color3::fromHSV(219.0_degf, 0.50f, 0.57f)
@ -158,7 +154,8 @@ and don't do any gamma correction on it. For sRGB input, there is
@link Literals::operator""_srgbf() operator""_srgbf() @endlink / @link Literals::operator""_srgbf() operator""_srgbf() @endlink /
@link Literals::operator""_srgbaf() operator""_srgbaf() @endlink, see their @link Literals::operator""_srgbaf() operator""_srgbaf() @endlink, see their
documentation for more information. documentation for more information.
@code
@code{.cpp}
Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f} Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f}
Color4 b = 0x33b27fcc_rgbaf; // {0.2f, 0.7f, 0.5f, 0.8f} Color4 b = 0x33b27fcc_rgbaf; // {0.2f, 0.7f, 0.5f, 0.8f}
Color4 c = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f} Color4 c = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f}
@ -168,7 +165,8 @@ Color4 c = 0x33b27fcc_srgbaf; // {0.0331048f, 0.445201f, 0.212231f, 0.8f}
Column vectors of matrices and vector components can be accessed using square Column vectors of matrices and vector components can be accessed using square
brackets: brackets:
@code
@code{.cpp}
Matrix3x2 a; Matrix3x2 a;
a[2] /= 2.0f; // third column (column major indexing, see explanation below) a[2] /= 2.0f; // third column (column major indexing, see explanation below)
a[0][1] = 5.3f; // first column, second element a[0][1] = 5.3f; // first column, second element
@ -179,13 +177,15 @@ b[1] = 1; // second element
Row vectors can be accessed too, but only for reading, and the access is slower Row vectors can be accessed too, but only for reading, and the access is slower
due to the way the matrix is stored (see @ref matrix-vector-column-major "explanation below"): due to the way the matrix is stored (see @ref matrix-vector-column-major "explanation below"):
@code
@code{.cpp}
Vector2i c = a.row(2); // third row Vector2i c = a.row(2); // third row
@endcode @endcode
Fixed-size vector subclasses have functions for accessing named components Fixed-size vector subclasses have functions for accessing named components
and subparts: and subparts:
@code
@code{.cpp}
Vector4i a; Vector4i a;
Int x = a.x(); Int x = a.x();
a.y() += 5; a.y() += 5;
@ -193,43 +193,48 @@ a.y() += 5;
Vector3i xyz = a.xyz(); Vector3i xyz = a.xyz();
xyz.xy() *= 5; xyz.xy() *= 5;
@endcode @endcode
Color3 and Color4 name their components `rgba` instead of `xyzw`.
For more involved operations with components there is the @ref swizzle() @ref Color3 and @ref Color4 name their components `rgba` instead of `xyzw`.
For more involved operations with components there is the @ref Math::swizzle()
function: function:
@code
@code{.cpp}
Vector4i original(-1, 2, 3, 4); Vector4i original(-1, 2, 3, 4);
Vector4i bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 } Vector4i bgra = Math::swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 }
Math::Vector<6, Int> w10xyz = swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); // { 4, 1, 0, -1, 2, 3 } Math::Vector<6, Int> w10xyz = Math::swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); // { 4, 1, 0, -1, 2, 3 }
@endcode @endcode
@section matrix-vector-conversion Converting between different underlying types @section matrix-vector-conversion Converting between different underlying types
All vector, matrix and other classes in @ref Math namespace and also All vector, matrix and other classes in @ref Math namespace are able to be
@ref Color3 and @ref Color4 classes are able to be constructed from type with constructed from an instance with different underlying type (e.g. convert
different underlying type (e.g. convert between integer and floating-point or between integer and floating-point or betweeen @ref Float and @ref Double).
betweeen @ref Float and @ref Double). Unlike with plain C++ data types, the Unlike with plain C++ data types, the conversion is done via *explicit*
conversion is done via *explicit* constructor. That might sound inconvenient, constructor. That might sound inconvenient, but doing the conversion explicitly
but doing the conversion explicitly avoids common issues like precision loss avoids common issues like precision loss (or, on the other hand, doing
(or, on the other hand, doing computations in unnecessarily high precision). computations in unnecessarily high precision).
To further emphasise the intent of conversion (so it doesn't look like accident To further emphasise the intent of conversion (so it doesn't look like accident
or typo), you are encouraged to use `auto b = Type{a}` instead of `Type b{a}`. or typo), you are encouraged to use @cpp auto b = Type{a} @ce instead of
@code @cpp Type b{a} @ce.
@code{.cpp}
Vector3 a{2.2f, 0.25f, -5.1f}; Vector3 a{2.2f, 0.25f, -5.1f};
//Vector3i b = a; // error, implicit conversion not allowed //Vector3i b = a; // error, implicit conversion not allowed
auto c = Vector3i{a}; // {2, 0, -5} auto c = Vector3i{a}; // {2, 0, -5}
auto d = Vector3d{a}; // {2.2, 0.25, -5.1} auto d = Vector3d{a}; // {2.2, 0.25, -5.1}
@endcode @endcode
For packing and unpacking there are @ref Math::pack() and @ref Math::unpack() For packing and unpacking there are @ref Math::pack() and @ref Math::unpack()
functions: functions:
@code
@code{.cpp}
Color3 a{0.8f, 1.0f, 0.3f}; Color3 a{0.8f, 1.0f, 0.3f};
auto b = Math::unpack<Color3ub>(a); // {204, 255, 76} auto b = Math::pack<Color3ub>(a); // {204, 255, 76}
Color3ub c{64, 127, 89}; Color3ub c{64, 127, 89};
auto d = Math::pack<Color3>(c); // {0.251, 0.498, 0.349} auto d = Math::unpack<Color3>(c); // {0.251f, 0.498f, 0.349}
@endcode @endcode
See @ref matrix-vector-componentwise "below" for more information about other See @ref matrix-vector-componentwise "below" for more information about other
@ -240,41 +245,46 @@ available component-wise operations.
Vectors can be added, subtracted, negated and multiplied or divided with Vectors can be added, subtracted, negated and multiplied or divided with
scalars, as is common in mathematics, Magnum also adds the ability to divide scalars, as is common in mathematics, Magnum also adds the ability to divide
scalar with vector: scalar with vector:
@code
Vector3 a(1.0f, 2.0f, 3.0f); @code{.cpp}
Vector3 b = a*5.0f - Vector3(3.0f, -0.5f, -7.5f); // b == {5.0f, 9.5f, 7.5f} Vector3 a{1.0f, 2.0f, 3.0f};
Vector3 c = 1.0f/a; // c == {1.0f, 0.5f, 0.333f} Vector3 b = a*5.0f - Vector3{3.0f, -0.5f, -7.5f}; // {5.0f, 9.5f, 7.5f}
Vector3 c = 1.0f/a; // {1.0f, 0.5f, 0.333f}
@endcode @endcode
As in GLSL, vectors can be also multiplied or divided component-wise: As in GLSL, vectors can be also multiplied or divided component-wise:
@code
Vector3 a(1.0f, 2.0f, 3.0f); @code{.cpp}
Vector3 b = a*Vector3(-0.5f, 2.0f, -7.0f); // b == {-0.5f, 4.0f, -21.0f} Vector3 a{1.0f, 2.0f, 3.0f};
Vector3 b = a*Vector3{-0.5f, 2.0f, -7.0f}; // {-0.5f, 4.0f, -21.0f}
@endcode @endcode
When working with integral vectors (i.e. 24bit RGB values), it is often When working with integral vectors (i.e. 24bit RGB values), it is often
desirable to multiply them with floating-point values but with integral result. desirable to multiply them with floating-point values but with integral result.
In Magnum all mulitplication/division operations involving integral vectors In Magnum, all multiplication/division operations involving integral vectors
will have integral result, you need to convert both arguments to the same will have integral result, you need to convert both arguments to the same
floating-point type to have floating-point result. floating-point type to have floating-point result.
@code
Color3ub color(80, 116, 34); @code{.cpp}
Color3ub lighter = color*1.5f; // lighter = {120, 174, 51} Color3ub color{80, 116, 34};
Color3ub lighter = color*1.5f; // {120, 174, 51}
Vector3i a(4, 18, -90);
Vector3 multiplier(2.2f, 0.25f, 0.1f); Vector3i a{4, 18, -90};
Vector3i b = a*multiplier; // b == {8, 4, -9} Vector3 multiplier{2.2f, 0.25f, 0.1f};
Vector3 c = Vector3(a)*multiplier; // c == {8.0f, 4.5f, -9.0f} Vector3i b = a*multiplier; // {8, 4, -9}
Vector3 c = Vector3(a)*multiplier; // {8.0f, 4.5f, -9.0f}
@endcode @endcode
You can use also all bitwise operations on integral vectors: You can also use all bitwise operations on integral vectors:
@code
Vector2i size(256, 256); @code{.cpp}
Vector2i mipLevel3Size = size >> 3; // == {32, 32} Vector2i size{256, 256};
Vector2i mipLevel3Size = size >> 3; // {32, 32}
@endcode @endcode
Matrices can be added, subtracted and multiplied with matrix multiplication. Matrices can be added, subtracted and multiplied with matrix multiplication.
@code
@code{.cpp}
Matrix3x2 a; Matrix3x2 a;
Matrix3x2 b; Matrix3x2 b;
Matrix3x2 c = a + (-b); Matrix3x2 c = a + (-b);
@ -286,7 +296,8 @@ Matrix3x3 f = b*d;
You can also multiply (properly sized) vectors with matrices. These operations You can also multiply (properly sized) vectors with matrices. These operations
are just convenience shortcuts for multiplying with single-column matrices: are just convenience shortcuts for multiplying with single-column matrices:
@code
@code{.cpp}
Matrix3x4 a; Matrix3x4 a;
Vector3 b; Vector3 b;
Vector4 c = a*b; Vector4 c = a*b;
@ -298,55 +309,62 @@ Matrix4x3 e = b*d;
@section matrix-vector-componentwise Component-wise and inter-vector operations @section matrix-vector-componentwise Component-wise and inter-vector operations
As shown above, vectors can be added and multiplied component-wise using the As shown above, vectors can be added and multiplied component-wise using the
`+` or `*` operator. You can use @ref Math::Vector::sum() "sum()" and @cpp + @ce or @cpp * @ce operator. You can use @ref Math::Vector::sum() "sum()"
@ref Math::Vector::product() "product()" for sum or product of components in and @ref Math::Vector::product() "product()" for sum or product of components
one vector: in one vector:
@code
Float a = Vector3{1.5f, 0.3f, 8.0f}.sum(); // 8.8f @code{.cpp}
Int b = Vector3i{32, -5, 7}.product() // 1120 Float a = Vector3{1.5f, 0.3f, 8.0f}.sum(); // 8.8f
Int b = Vector3i{32, -5, 7}.product() // 1120
@endcode @endcode
Component-wise minimum and maximum of two vectors can be done using Component-wise minimum and maximum of two vectors can be done using
@ref Math::min(), @ref Math::max() or @ref Math::minmax(), similarly with @ref Math::min(), @ref Math::max() or @ref Math::minmax(), similarly with
@ref Vector::min() "min()", @ref Vector::max() "max()" and @ref Vector::min() "min()", @ref Vector::max() "max()" and
@ref Vector2::minmax() "minmax()" for components in one vector. @ref Vector2::minmax() "minmax()" for components in one vector.
@code
@code{.cpp}
Vector3i a{-5, 7, 24}; Vector3i a{-5, 7, 24};
Vector3i b{8, -2, 12}; Vector3i b{8, -2, 12};
Vector3i min = Math::min(a, b); // {-5, -2, 12} Vector3i min = Math::min(a, b); // {-5, -2, 12}
Int max = a.max(); // 24 Int max = a.max(); // 24
@endcode @endcode
The vectors can be also compared component-wise, the result is returned in The vectors can be also compared component-wise, the result is returned in
@ref Math::BoolVector class: @ref Math::BoolVector class:
@code
BoolVector<3> largerOrEqual = a >= b; // {false, true, true} @code{.cpp}
bool anySmaller = (a < b).any(); // true BoolVector<3> largerOrEqual = a >= b; // {false, true, true}
bool allLarger = (a > b).all(); // false bool anySmaller = (a < b).any(); // true
bool allLarger = (a > b).all(); // false
@endcode @endcode
There are also function for component-wise rounding, sign operations, square There are also function for component-wise rounding, sign operations, square
root, various interpolation and (de)normalization functionality: root, various interpolation and (de)normalization functionality:
@code
@code{.cpp}
Vector3 a{5.5f, -0.3f, 75.0f}; Vector3 a{5.5f, -0.3f, 75.0f};
Vector3 b = Math::round(a); // {5.0f, 0.0f, 75.0f} Vector3 b = Math::round(a); // {5.0f, 0.0f, 75.0f}
Vector3 c = Math::abs(a); // {5.5f, -0.3f, 75.0f} Vector3 c = Math::abs(a); // {5.5f, -0.3f, 75.0f}
Vector3 d = Math::clamp(a, -0.2f, 55.0f); // {5.5f, -0.2f, 55.0f} Vector3 d = Math::clamp(a, -0.2f, 55.0f); // {5.5f, -0.2f, 55.0f}
@endcode @endcode
Component-wise functions are implemented only for vectors and not for matrices Component-wise functions are implemented only for vectors and not for matrices
to keep the math library in sane and maintainable size. Instead, you can to keep the math library in sane and maintainable size. Instead, you can
reinterpret the matrix as vector and do the operation on it (and vice versa): reinterpret the matrix as vector and do the operation on it (and vice versa):
@code
@code{.cpp}
Matrix3x2 mat; Matrix3x2 mat;
Math::Vector<6, Float> vec = mat.toVector(); Math::Vector<6, Float> vec = mat.toVector();
// ... // ...
mat = Matrix3x2::fromVector(vec); mat = Matrix3x2::fromVector(vec);
@endcode @endcode
Note that all component-wise functions in Math namespace work also for scalars: Note that all component-wise functions in @ref Math namespace work also for
@code scalars:
@code{.cpp}
std::pair<Int, Int> minmax = Math::minmax(24, -5); // -5, 24 std::pair<Int, Int> minmax = Math::minmax(24, -5); // -5, 24
Int a = Math::lerp(0, 360, 0.75f); // 270 Int a = Math::lerp(0, 360, 0.75f); // 270
auto b = Math::denormalize<UnsignedByte>(0.89f); // 226 auto b = Math::denormalize<UnsignedByte>(0.89f); // 226
@ -358,34 +376,37 @@ OpenGL matrices are column-major, thus it is reasonable to have matrices in
Magnum also column major (and vectors as columns). This has naturally some Magnum also column major (and vectors as columns). This has naturally some
implications and it may differ from what is common in mathematics: implications and it may differ from what is common in mathematics:
- Order of template arguments in specification of @ref Math::RectangularMatrix <ul><li>
is also column-major: Order of template arguments in specification of @ref Math::RectangularMatrix
@code is also column-major:
Math::RectangularMatrix<2, 5, Int> mat; // two columns, five rows
@endcode @code{.cpp}
- Order of components in matrix constructors is also column-major, further Math::RectangularMatrix<2, 5, Int> mat; // two columns, five rows
emphasized by requirement that you have to pass directly column vectors: @endcode
@code </li><li>
Math::Matrix3<Int> mat({0, 1, 2}, Order of components in matrix constructors is also column-major, further
{3, 4, 5}, emphasized by requirement that you have to pass directly column vectors:
{6, 7, 8}); // first column is {0, 1, 2}
@endcode @code{.cpp}
- Element accessing order is also column-major, thus the bracket operator is Math::Matrix3<Int> mat({0, 1, 2},
accessing columns. Returned vector has also its own bracket operator, which {3, 4, 5},
is then indexing rows. {6, 7, 8}); // first column is {0, 1, 2}
@code @endcode
mat[0] *= 2; // first column </li><li>
mat[2][0] = 5; // first element of third column Element accessing order is also column-major, thus the bracket operator is
@endcode accessing columns. Returned vector has also its own bracket operator, which
- Various algorithms which commonly operate on matrix rows (such as is then indexing rows.
@ref Algorithms::gaussJordanInPlace() "Gauss-Jordan elimination") have faster
alternatives which operate on columns. It's then up to user decision to @code{.cpp}
operate with transposed matrices or use the slower non-transposed mat[0] *= 2; // first column
alternative of the algorithm. mat[2][0] = 5; // first element of third column
@endcode
&nbsp; </li><li>
Various algorithms which commonly operate on matrix rows (such as
- Previous page: @ref types @ref Algorithms::gaussJordanInPlace() "Gauss-Jordan elimination") have
- Next page: @ref transformations faster alternatives which operate on columns. It's then up to user decision
to operate with transposed matrices or use the slower non-transposed
alternative of the algorithm.
</li></ul>
*/ */
} }

16
doc/method-chaining.dox

@ -25,9 +25,10 @@
namespace Magnum { namespace Magnum {
/** @page method-chaining Method chaining /** @page method-chaining Method chaining
@brief Little feature helping to reduce typing and encourage best practices. @brief Little feature helping to reduce typing and encourage best practices.
@m_footernavigation
Method chaining ([Wikipedia](http://en.wikipedia.org/wiki/Method_chaining)) is a Method chaining ([Wikipedia](http://en.wikipedia.org/wiki/Method_chaining)) is a
feature which allows you to chain method calls one after another without feature which allows you to chain method calls one after another without
repeatedly specifying variable the method is called on. Its primary goal is to repeatedly specifying variable the method is called on. Its primary goal is to
@ -42,7 +43,8 @@ reduce unneeded bind calls, Magnum binds the object only if it is not already
bound somewhere. Method chaining encourages you to configure whole object in bound somewhere. Method chaining encourages you to configure whole object in
one run, effectively reducing the number of needed bindings. Consider the one run, effectively reducing the number of needed bindings. Consider the
following example: following example:
@code
@code{.cpp}
Texture2D carDiffuseTexture, carSpecularTexture, carBumpTexture; Texture2D carDiffuseTexture, carSpecularTexture, carBumpTexture;
carDiffuseTexture.setStorage(5, TextureFormat::SRGB8); carDiffuseTexture.setStorage(5, TextureFormat::SRGB8);
@ -62,7 +64,8 @@ textures at once, but on the other hand the code is cluttered with repeated
names and after each configuration step the texture must be rebound to another. names and after each configuration step the texture must be rebound to another.
With method chaining used the code looks much lighter and each object is With method chaining used the code looks much lighter and each object is
configured in one run, reducing count of bind calls from 9 to 3. configured in one run, reducing count of bind calls from 9 to 3.
@code
@code{.cpp}
carDiffuseTexture.setStorage(5, TextureFormat::SRGB8) carDiffuseTexture.setStorage(5, TextureFormat::SRGB8)
.setSubImage(0, {}, diffuse) .setSubImage(0, {}, diffuse)
.generateMipmap(); .generateMipmap();
@ -82,11 +85,12 @@ Method chaining is also used in @ref SceneGraph and other libraries and in some
cases it allows you to just "configure and forget" without even saving the cases it allows you to just "configure and forget" without even saving the
created object to some variable, for example when adding static object to an created object to some variable, for example when adding static object to an
scene: scene:
@code
@code{.cpp}
Scene3D scene; Scene3D scene;
(new MyObject(&scene)) (*(new MyObject(&scene)))
->rotateX(90.0_degf) .rotateX(90.0_degf)
.translate({-1.5f, 0.5f, 7.0f}); .translate({-1.5f, 0.5f, 7.0f});
@endcode @endcode
*/ */

9
doc/openal-support.dox

@ -24,10 +24,13 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
namespace Magnum {
/** @page openal-support OpenAL support state /** @page openal-support OpenAL support state
@brief List of (un)supported OpenAL features and extensions. @brief List of (un)supported OpenAL features and extensions.
@tableofcontents @tableofcontents
@m_footernavigation
@section openal-support-state OpenAL implementation state @section openal-support-state OpenAL implementation state
@ -36,6 +39,8 @@ functions and enum values are exposed through the API.
@subsection openal-extension-support Extensions @subsection openal-extension-support Extensions
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
@alc_extension{ENUMERATION,EXT} | done @alc_extension{ENUMERATION,EXT} | done
@ -47,10 +52,12 @@ Extension | Status
@subsection openal-extension-support-soft OpenAL Soft Extensions @subsection openal-extension-support-soft OpenAL Soft Extensions
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
@alc_extension{SOFTX,HRTF} | done @alc_extension{SOFTX,HRTF} | done
@alc_extension{SOFT,HRTF} | done @alc_extension{SOFT,HRTF} | done
*/ */
}

5
doc/openal.dox

@ -42,9 +42,10 @@ but some specific functionality has greater requirements. Following is the list
of features requiring specific OpenAL extensions. of features requiring specific OpenAL extensions.
- @subpage requires-al-extension - @subpage requires-al-extension
*/
@page requires-al-extension Functionality requiring specific OpenAL extension /** @page requires-al-extension Functionality requiring specific OpenAL extension
@m_footernavigation
*/ */
} }

51
doc/opengl-mapping.dox

@ -29,17 +29,20 @@ namespace Magnum {
@brief List of OpenGL commands corresponding to particular Magnum API. @brief List of OpenGL commands corresponding to particular Magnum API.
@tableofcontents @tableofcontents
@m_footernavigation
Legend: Legend:
- *not needed* -- given feature is implemented in a way that makes the - *not needed* --- given feature is implemented in a way that makes the
function unnecessary function unnecessary
- *not queryable*, *not supported* -- see @ref opengl-unsupported - *not queryable*, *not supported* --- see @ref opengl-unsupported
- (empty) -- given feature is not yet implemented - (empty) --- given feature is not yet implemented
@section opengl-mapping-functions Functions @section opengl-mapping-functions Functions
@subsection opengl-mapping-functions-a A @subsection opengl-mapping-functions-a A
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{ActiveShaderProgram} | not needed as @fn_gl{ProgramUniform} calls are used @fn_gl{ActiveShaderProgram} | not needed as @fn_gl{ProgramUniform} calls are used
@ -48,6 +51,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-b B @subsection opengl-mapping-functions-b B
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{BeginConditionalRender}, `glEndConditionalRender()` | @ref SampleQuery::beginConditionalRender(), \n @ref SampleQuery::endConditionalRender() @fn_gl{BeginConditionalRender}, `glEndConditionalRender()` | @ref SampleQuery::beginConditionalRender(), \n @ref SampleQuery::endConditionalRender()
@ -80,6 +85,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-c C @subsection opengl-mapping-functions-c C
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{CheckFramebufferStatus}, \n `glCheckNamedFramebufferStatus()`, \n @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access} | @ref DefaultFramebuffer::checkStatus(), \n @ref Framebuffer::checkStatus() @fn_gl{CheckFramebufferStatus}, \n `glCheckNamedFramebufferStatus()`, \n @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access} | @ref DefaultFramebuffer::checkStatus(), \n @ref Framebuffer::checkStatus()
@ -110,6 +117,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-d D @subsection opengl-mapping-functions-d D
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{DebugMessageCallback} | @ref DebugOutput::setCallback() @fn_gl{DebugMessageCallback} | @ref DebugOutput::setCallback()
@ -131,6 +140,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-e E @subsection opengl-mapping-functions-e E
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{Enable}, `glDisable()` | @ref Renderer::setFeature() @fn_gl{Enable}, `glDisable()` | @ref Renderer::setFeature()
@ -138,6 +149,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-f F @subsection opengl-mapping-functions-f F
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{FenceSync}, @fn_gl{DeleteSync} | | @fn_gl{FenceSync}, @fn_gl{DeleteSync} | |
@ -154,6 +167,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-g G @subsection opengl-mapping-functions-g G
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{GenBuffers}, \n @fn_gl{CreateBuffers}, \n @fn_gl{DeleteBuffers} | @ref Buffer constructor and destructor @fn_gl{GenBuffers}, \n @fn_gl{CreateBuffers}, \n @fn_gl{DeleteBuffers} | @ref Buffer constructor and destructor
@ -227,12 +242,16 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-h H @subsection opengl-mapping-functions-h H
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{Hint} | @ref Renderer::setHint() @fn_gl{Hint} | @ref Renderer::setHint()
@subsection opengl-mapping-functions-i I @subsection opengl-mapping-functions-i I
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{InvalidateBufferData} | @ref Buffer::invalidateData() @fn_gl{InvalidateBufferData} | @ref Buffer::invalidateData()
@ -248,6 +267,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-l L @subsection opengl-mapping-functions-l L
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{LineWidth} | @ref Renderer::setLineWidth() @fn_gl{LineWidth} | @ref Renderer::setLineWidth()
@ -256,6 +277,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-m M @subsection opengl-mapping-functions-m M
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl_extension{MakeImageHandleResident,ARB,bindless_texture} | | @fn_gl_extension{MakeImageHandleResident,ARB,bindless_texture} | |
@ -270,12 +293,16 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-o O @subsection opengl-mapping-functions-o O
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{ObjectLabel}, \n @fn_gl{ObjectPtrLabel}, \n @fn_gl_extension{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{ObjectLabel}, \n @fn_gl{ObjectPtrLabel}, \n @fn_gl_extension{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()
@subsection opengl-mapping-functions-p P @subsection opengl-mapping-functions-p P
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{PatchParameter} | | @fn_gl{PatchParameter} | |
@ -295,12 +322,16 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-q Q @subsection opengl-mapping-functions-q Q
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{QueryCounter} | @ref TimeQuery::timestamp() @fn_gl{QueryCounter} | @ref TimeQuery::timestamp()
@subsection opengl-mapping-functions-r R @subsection opengl-mapping-functions-r R
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{ReadBuffer}, \n `glNamedFramebufferReadBuffer()`, \n @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access} | @ref DefaultFramebuffer::mapForRead(), \n @ref Framebuffer::mapForRead() @fn_gl{ReadBuffer}, \n `glNamedFramebufferReadBuffer()`, \n @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access} | @ref DefaultFramebuffer::mapForRead(), \n @ref Framebuffer::mapForRead()
@ -311,6 +342,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-s S @subsection opengl-mapping-functions-s S
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{SampleCoverage} | | @fn_gl{SampleCoverage} | |
@ -328,6 +361,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-t T @subsection opengl-mapping-functions-t T
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{TexBuffer}, \n `glTextureBuffer()`, \n @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, \n @fn_gl{TexBufferRange}, \n `glTextureBufferRange()`, \n @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} | @ref BufferTexture::setBuffer() @fn_gl{TexBuffer}, \n `glTextureBuffer()`, \n @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, \n @fn_gl{TexBufferRange}, \n `glTextureBufferRange()`, \n @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} | @ref BufferTexture::setBuffer()
@ -345,6 +380,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-u U @subsection opengl-mapping-functions-u U
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{Uniform}, \n @fn_gl{ProgramUniform}, \n @fn_gl_extension{ProgramUniform,EXT,direct_state_access} | @ref AbstractShaderProgram::setUniform() @fn_gl{Uniform}, \n @fn_gl{ProgramUniform}, \n @fn_gl_extension{ProgramUniform,EXT,direct_state_access} | @ref AbstractShaderProgram::setUniform()
@ -356,6 +393,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-v V @subsection opengl-mapping-functions-v V
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{ValidateProgram} | @ref AbstractShaderProgram::validate() @fn_gl{ValidateProgram} | @ref AbstractShaderProgram::validate()
@ -373,6 +412,8 @@ OpenGL function | Matching API
@subsection opengl-mapping-functions-w W @subsection opengl-mapping-functions-w W
@m_class{m-fullwidth}
OpenGL function | Matching API OpenGL function | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@fn_gl{WaitSync} | | @fn_gl{WaitSync} | |
@ -381,7 +422,9 @@ OpenGL function | Matching API
@todo Things marked only as *not queryable* should have at least setter @todo Things marked only as *not queryable* should have at least setter
@fn_gl{Get} parameter | Matching API @m_class{m-fullwidth}
glGet() parameter | Matching API
--------------------------------------- | ------------ --------------------------------------- | ------------
@def_gl{ACTIVE_TEXTURE}, \n @def_gl{TEXTURE_BINDING_1D_ARRAY}, \n @def_gl{TEXTURE_BINDING_1D}, \n @def_gl{TEXTURE_BINDING_2D_ARRAY}, \n @def_gl{TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY}, \n @def_gl{TEXTURE_BINDING_2D_MULTISAMPLE}, \n @def_gl{TEXTURE_BINDING_2D} , \n @def_gl{TEXTURE_BINDING_3D}, \n @def_gl{TEXTURE_BINDING_BUFFER}, \n @def_gl{TEXTURE_BINDING_BUFFER}, \n @def_gl{TEXTURE_BINDING_CUBE_MAP}, \n @def_gl{TEXTURE_BINDING_RECTANGLE} | not queryable but tracked internally @def_gl{ACTIVE_TEXTURE}, \n @def_gl{TEXTURE_BINDING_1D_ARRAY}, \n @def_gl{TEXTURE_BINDING_1D}, \n @def_gl{TEXTURE_BINDING_2D_ARRAY}, \n @def_gl{TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY}, \n @def_gl{TEXTURE_BINDING_2D_MULTISAMPLE}, \n @def_gl{TEXTURE_BINDING_2D} , \n @def_gl{TEXTURE_BINDING_3D}, \n @def_gl{TEXTURE_BINDING_BUFFER}, \n @def_gl{TEXTURE_BINDING_BUFFER}, \n @def_gl{TEXTURE_BINDING_CUBE_MAP}, \n @def_gl{TEXTURE_BINDING_RECTANGLE} | not queryable but tracked internally
@def_gl{ALIASED_LINE_WIDTH_RANGE} | | @def_gl{ALIASED_LINE_WIDTH_RANGE} | |

36
doc/opengl-support.dox

@ -27,6 +27,7 @@
@brief List of (un)supported OpenGL features and extensions. @brief List of (un)supported OpenGL features and extensions.
@tableofcontents @tableofcontents
@m_footernavigation
@section opengl-support-state OpenGL implementation state @section opengl-support-state OpenGL implementation state
@ -47,6 +48,8 @@ following:
@todo @extension{EXT,texture_array} overlaps with @extension{ARB,framebuffer_object} @todo @extension{EXT,texture_array} overlaps with @extension{ARB,framebuffer_object}
@todo Add @extension{ARB,depth_buffer_float} and implement the missing @fn_gl{DepthRange} function, but keep (and implement) @extension{NV,depth_buffer_float} for non-linear depth buffer @todo Add @extension{ARB,depth_buffer_float} and implement the missing @fn_gl{DepthRange} function, but keep (and implement) @extension{NV,depth_buffer_float} for non-linear depth buffer
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 1.30 | done GLSL 1.30 | done
@ -74,6 +77,8 @@ GLSL 1.30 | done
@subsection opengl-support-31 OpenGL 3.1 @subsection opengl-support-31 OpenGL 3.1
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 1.40 | done GLSL 1.40 | done
@ -87,6 +92,8 @@ GLSL 1.40 | done
@subsection opengl-support-32 OpenGL 3.2 @subsection opengl-support-32 OpenGL 3.2
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 1.50 | done GLSL 1.50 | done
@ -102,6 +109,8 @@ GLSL 1.50 | done
@subsection opengl-support-33 OpenGL 3.3 @subsection opengl-support-33 OpenGL 3.3
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 3.30 | done GLSL 3.30 | done
@ -118,6 +127,8 @@ GLSL 3.30 | done
@subsection opengl-support-40 OpenGL 4.0 @subsection opengl-support-40 OpenGL 4.0
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 4.00 | done GLSL 4.00 | done
@ -137,6 +148,8 @@ GLSL 4.00 | done
@subsection opengl-support-41 OpenGL 4.1 @subsection opengl-support-41 OpenGL 4.1
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 4.10 | done GLSL 4.10 | done
@ -149,6 +162,8 @@ GLSL 4.10 | done
@subsection opengl-support-42 OpenGL 4.2 @subsection opengl-support-42 OpenGL 4.2
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 4.20 | done GLSL 4.20 | done
@ -167,6 +182,8 @@ GLSL 4.20 | done
@subsection opengl-support-43 OpenGL 4.3 @subsection opengl-support-43 OpenGL 4.3
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 4.30 | done GLSL 4.30 | done
@ -198,6 +215,8 @@ GLSL 4.30 | done
@todo Also fallback to @extension{AMD,query_buffer_object} @todo Also fallback to @extension{AMD,query_buffer_object}
@todo @extension{AMD,pinned_memory} "fallback" for @extension{ARB,buffer_storage} @todo @extension{AMD,pinned_memory} "fallback" for @extension{ARB,buffer_storage}
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 4.40 | done GLSL 4.40 | done
@ -213,6 +232,8 @@ GLSL 4.40 | done
@subsection opengl-support-45 OpenGL 4.5 @subsection opengl-support-45 OpenGL 4.5
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
GLSL 4.50 | done GLSL 4.50 | done
@ -230,6 +251,8 @@ GLSL 4.50 | done
@subsection opengl-support-extensions ARB / Khronos OpenGL extensions @subsection opengl-support-extensions ARB / Khronos OpenGL extensions
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
@extension{ARB,robustness} | done @extension{ARB,robustness} | done
@ -256,6 +279,8 @@ Extension | Status
@todo @extension{ATI,meminfo}, @extension{NVX,gpu_memory_info}, GPU temperature @todo @extension{ATI,meminfo}, @extension{NVX,gpu_memory_info}, GPU temperature
@todo @extension{AMD,performance_monitor}, @extension{INTEL,performance_query} @todo @extension{AMD,performance_monitor}, @extension{INTEL,performance_query}
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
@extension{AMD,transform_feedback3_lines_triangles} | done (nothing to do) @extension{AMD,transform_feedback3_lines_triangles} | done (nothing to do)
@ -289,6 +314,8 @@ supported. ESSL 3.10 is supported.
@subsection opengl-support-es30-extensions OpenGL ES 2.0 extensions to match ES 3.0 functionality @subsection opengl-support-es30-extensions OpenGL ES 2.0 extensions to match ES 3.0 functionality
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
@extension{ANGLE,framebuffer_blit} | done @extension{ANGLE,framebuffer_blit} | done
@ -346,6 +373,8 @@ Extension | Status
@todo Support also IMG_multisampled_render_to_texture? It has different enum @todo Support also IMG_multisampled_render_to_texture? It has different enum
values (!) values (!)
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
@extension{ANDROID,extension_pack_es31a} | done (nothing to do) @extension{ANDROID,extension_pack_es31a} | done (nothing to do)
@ -416,6 +445,8 @@ supported.
@subsection opengl-support-webgl20-extensions WebGL 1.0 extensions to match WebGL 2.0 functionality @subsection opengl-support-webgl20-extensions WebGL 1.0 extensions to match WebGL 2.0 functionality
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
@webgl_extension{ANGLE,instanced_arrays} | done @webgl_extension{ANGLE,instanced_arrays} | done
@ -434,6 +465,8 @@ Extension | Status
@subsection opengl-support-webgl-extensions WebGL extensions to match desktop functionality @subsection opengl-support-webgl-extensions WebGL extensions to match desktop functionality
@m_class{m-fullwidth}
Extension | Status Extension | Status
------------------------------------------- | ------ ------------------------------------------- | ------
@webgl_extension{EXT,texture_filter_anisotropic} | done @webgl_extension{EXT,texture_filter_anisotropic} | done
@ -493,11 +526,12 @@ add any performance gains, is not supported in Magnum. See also
- @extension{NV,draw_texture} can be done with framebuffer blitting and - @extension{NV,draw_texture} can be done with framebuffer blitting and
doesn't make any full-screen postprocessing easier, as shaders are doesn't make any full-screen postprocessing easier, as shaders are
excluded. excluded.
*/ */
/** @page opengl-deprecated Deprecated OpenGL API list /** @page opengl-deprecated Deprecated OpenGL API list
@m_footernavigation
See also @ref opengl-unsupported and @ref deprecated. See also @ref opengl-unsupported and @ref deprecated.
*/ */

60
doc/opengl-wrapping.dox

@ -27,16 +27,14 @@ namespace Magnum {
/** @page opengl-wrapping OpenGL wrapping layer /** @page opengl-wrapping OpenGL wrapping layer
@brief Overview of the base OpenGL wrapper API @brief Overview of the base OpenGL wrapper API
- Previous page: @ref plugins @tableofcontents
- Next page: @ref shaders @m_footernavigation
OpenGL wrapper classes are core part of Magnum. Their purpose is to simplify OpenGL wrapper classes are core part of Magnum. Their purpose is to simplify
interaction with the OpenGL API using type-safe C++11 features, abstracting interaction with the OpenGL API using type-safe C++11 features, abstracting
away extension and platform differences, tracking the state for optimum away extension and platform differences, tracking the state for optimum
performance and selecting the best available code path for given system. performance and selecting the best available code path for given system.
@tableofcontents
Magnum provides wrappers for most native OpenGL objects like buffers, textures, Magnum provides wrappers for most native OpenGL objects like buffers, textures,
meshes, queries, transform feedback objects, shaders etc., but makes it meshes, queries, transform feedback objects, shaders etc., but makes it
possible to use raw GL calls or combine Magnum with third-party OpenGL possible to use raw GL calls or combine Magnum with third-party OpenGL
@ -59,20 +57,22 @@ the object this way does not require any active context and its state is then
equivalent to the moved-from state. It is useful in case you need to construct equivalent to the moved-from state. It is useful in case you need to construct
the object before creating context (such as class members) or if you know you the object before creating context (such as class members) or if you know you
would overwrite it later with another object: would overwrite it later with another object:
@code
@code{.cpp}
Mesh mesh{NoCreate}; Mesh mesh{NoCreate};
Buffer vertices{NoCreate}, indices{NoCreate}; Buffer vertices{NoCreate}, indices{NoCreate};
std::tie(mesh, vertices, indices) = importSomeMesh(); std::tie(mesh, vertices, indices) = importSomeMesh();
@endcode @endcode
If you need to preserve the underlying OpenGL object after destruction, you can If you need to preserve the underlying OpenGL object after destruction, you can
call `release()`. It returns ID of the underlying object, the instance is then call @cpp release() @ce. It returns ID of the underlying object, the instance
equivalent to moved-from state and you are responsible for proper deletion is then equivalent to moved-from state and you are responsible for proper
of the returned OpenGL object (note that it is possible to just query ID of the deletion of the returned OpenGL object (note that it is possible to just query
underlying without releasing it using `id()`). It is also possible to do the ID of the underlying without releasing it using `id()`). It is also possible to
opposite -- wrapping existing OpenGL object ID into Magnum object instance do the opposite --- wrapping existing OpenGL object ID into Magnum object
using `wrap()`. instance using @cpp wrap() @ce.
@code
@code{.cpp}
// Transferring the instance to external library // Transferring the instance to external library
{ {
Buffer buffer; Buffer buffer;
@ -89,20 +89,21 @@ using `wrap()`.
} }
@endcode @endcode
The `NoInit` constructor, `wrap()` and `release()` functions are available for The @cpp NoCreate @ce constructor, @cpp wrap() @ce and @cpp release() @ce
all OpenGL classes except @ref Shader and @ref AbstractShaderProgram, where functions are available for all OpenGL classes except @ref Shader and
wrapping external instances makes less sense. @ref AbstractShaderProgram, where wrapping external instances makes less sense.
@section opengl-state-tracking State tracking and interaction with third-party code @section opengl-state-tracking State tracking and interaction with third-party code
It is possible (and encouraged) to combine Magnum with third-party libraries or It is possible (and encouraged) to combine Magnum with third-party libraries or
even raw OpenGL calls -- trying features that are not yet implemented in even raw OpenGL calls --- trying features that are not yet implemented in
Magnum, using some specialized GUI library etc. But bear in mind that to Magnum, using some specialized GUI library etc. But bear in mind that to
improve performance and avoid redundant state changes, Magnum internally tracks improve performance and avoid redundant state changes, Magnum internally tracks
OpenGL state such as currently bound objects, activated renderer features etc. OpenGL state such as currently bound objects, activated renderer features etc.
When combining Magnum with third-party code, the internal state tracker may get When combining Magnum with third-party code, the internal state tracker may get
confused and you need to reset it using @ref Context::resetState(): confused and you need to reset it using @ref Context::resetState():
@code
@code{.cpp}
Buffer buffer; Buffer buffer;
// Raw OpenGL calls // Raw OpenGL calls
@ -117,14 +118,14 @@ Context::current()->resetState(Context::State::Buffers);
auto data = buffer.map<UnsignedInt>(...); auto data = buffer.map<UnsignedInt>(...);
@endcode @endcode
Note that it is currently not possible to do the opposite -- reseting all state Note that it is currently not possible to do the opposite --- reseting all state
touched by Magnum to previous values -- as it would involve impractically large touched by Magnum to previous values --- as it would involve impractically large
amount of queries and state switches with serious performance impact. amount of queries and state switches with serious performance impact.
Magnum by default uses VAOs -- each time a @ref Mesh is drawn or configured, Magnum by default uses VAOs --- each time a @ref Mesh is drawn or configured,
its VAO is bound, but it is *not* unbound afterwards to avoid needless state its VAO is bound, but it is *not* unbound afterwards to avoid needless state
changes. This may introduce problems when using third-party OpenGL code that changes. This may introduce problems when using third-party OpenGL code that
does not use VAOs -- it will break internal state of Mesh that was used most does not use VAOs --- it will break internal state of Mesh that was used most
recently. The solution, besides state resetting, is to create a new VAO and recently. The solution, besides state resetting, is to create a new VAO and
bind it every time the third-party OpenGL code is called. bind it every time the third-party OpenGL code is called.
@ -133,17 +134,18 @@ bind it every time the third-party OpenGL code is called.
While the majority of Magnum API stays the same on all platforms and driver While the majority of Magnum API stays the same on all platforms and driver
capabilities, large portion of the functionality needs to be realized under the capabilities, large portion of the functionality needs to be realized under the
hood using various different OpenGL API calls based on available extensions. If hood using various different OpenGL API calls based on available extensions. If
required extension is not available, there are two possible outcomes -- either required extension is not available, there are two possible outcomes --- either
given API is simply not available or it is emulated using older functionality. given API is simply not available or it is emulated using older functionality.
In the first case, to avoid performance overhead, Magnum does not check that In the first case, to avoid performance overhead, Magnum does not check that
you use only the APIs that are implemented in the driver -- you are expected to you use only the APIs that are implemented in the driver --- you are expected to
do the checks. Documentation of each type, function and enum value explicitly do the checks. Documentation of each type, function and enum value explicitly
states whether the functionality is available everywhere or whether particular states whether the functionality is available everywhere or whether particular
GL version/extension is required. The information is also aggregated on GL version/extension is required. The information is also aggregated on
@ref opengl-required-extensions documentation page. Use @ref opengl-required-extensions documentation page. Use
@ref Context::isVersionSupported() or @ref Context::isExtensionSupported(): @ref Context::isVersionSupported() or @ref Context::isExtensionSupported():
@code
@code{.cpp}
TextureFormat format; TextureFormat format;
if(Context::current()->isExtensionSupported<Extensions::GL::ARB_depth_buffer_float>()) if(Context::current()->isExtensionSupported<Extensions::GL::ARB_depth_buffer_float>())
format = TextureFormat::DepthComponent32F; format = TextureFormat::DepthComponent32F;
@ -152,11 +154,11 @@ else
@endcode @endcode
@attention Using API that requires OpenGL version or extension that is not @attention Using API that requires OpenGL version or extension that is not
provided by the driver results in undefined behavior -- the best you can provided by the driver results in undefined behavior --- the best you can
get is GL error, it may lead to strange behavior and even crashes when get is GL error, it may lead to strange behavior and even crashes when
calling GL functions that are not available. calling GL functions that are not available.
Some functionality can be emulated by Magnum -- it detects available extensions Some functionality can be emulated by Magnum --- it detects available extensions
and selects best possible code path for optimal performance. On startup, the and selects best possible code path for optimal performance. On startup, the
application prints list of extensions that were used to improve the default application prints list of extensions that were used to improve the default
functionality. The most prominent feature is @extension{ARB,direct_state_access} functionality. The most prominent feature is @extension{ARB,direct_state_access}
@ -170,7 +172,8 @@ functionality is @ref DebugMessage "debug output" which is simply no-op when
required extensions are not available, @ref Texture::setStorage() emulation on required extensions are not available, @ref Texture::setStorage() emulation on
platforms that don't support it etc. The goal is to abstract away the (mostly platforms that don't support it etc. The goal is to abstract away the (mostly
unimportant) differences for easier porting. unimportant) differences for easier porting.
@code
@code{.cpp}
Texture2D texture; Texture2D texture;
// - on OpenGL 4.5+/ARB_direct_state_access this calls glTextureStorage2D() // - on OpenGL 4.5+/ARB_direct_state_access this calls glTextureStorage2D()
@ -181,8 +184,5 @@ Texture2D texture;
texture.setStorage(4, TextureFormat::RGBA8, {256, 256}); texture.setStorage(4, TextureFormat::RGBA8, {256, 256});
@endcode @endcode
- Previous page: @ref plugins
- Next page: @ref shaders
*/ */
} }

88
doc/opengl.dox

@ -74,51 +74,97 @@ is supported on older Intel GPUs even if they are capable of OpenGL 2.1 only).
@see @ref building, @ref cmake, @ref MAGNUM_TARGET_GLES, @see @ref building, @ref cmake, @ref MAGNUM_TARGET_GLES,
@ref MAGNUM_TARGET_GLES2 @ref MAGNUM_TARGET_GLES2
*/
/** @page requires-gl30 Functionality requiring OpenGL 3.0
* @m_footernavigation
*/
/** @page requires-gl31 Functionality requiring OpenGL 3.1
* @m_footernavigation
*/
/** @page requires-gl32 Functionality requiring OpenGL 3.2
* @m_footernavigation
*/
/** @page requires-gl33 Functionality requiring OpenGL 3.3
* @m_footernavigation
*/
/** @page requires-gl40 Functionality requiring OpenGL 4.0
* @m_footernavigation
*/
/** @page requires-gl41 Functionality requiring OpenGL 4.1
* @m_footernavigation
*/
/** @page requires-gl42 Functionality requiring OpenGL 4.2
* @m_footernavigation
*/
/** @page requires-gl43 Functionality requiring OpenGL 4.3
* @m_footernavigation
*/
@page requires-gl30 Functionality requiring OpenGL 3.0 /** @page requires-gl44 Functionality requiring OpenGL 4.4
@page requires-gl31 Functionality requiring OpenGL 3.1 * @m_footernavigation
@page requires-gl32 Functionality requiring OpenGL 3.2 */
@page requires-gl33 Functionality requiring OpenGL 3.3
@page requires-gl40 Functionality requiring OpenGL 4.0
@page requires-gl41 Functionality requiring OpenGL 4.1
@page requires-gl42 Functionality requiring OpenGL 4.2
@page requires-gl43 Functionality requiring OpenGL 4.3
@page requires-gl44 Functionality requiring OpenGL 4.4
@page requires-gl45 Functionality requiring OpenGL 4.5
@page requires-extension Functionality requiring specific OpenGL extension /** @page requires-gl45 Functionality requiring OpenGL 4.5
* @m_footernavigation
*/
@page requires-gl Functionality requiring desktop OpenGL /** @page requires-extension Functionality requiring specific OpenGL extension
* @m_footernavigation
*/
/** @page requires-gl Functionality requiring desktop OpenGL
@m_footernavigation
The following symbols are not defined when targeting OpenGL ES or WebGL. The following symbols are not defined when targeting OpenGL ES or WebGL.
@see @ref MAGNUM_TARGET_GLES @see @ref MAGNUM_TARGET_GLES
*/
@page requires-gles20 Functionality requiring OpenGL ES 2.0 or WebGL 1.0 /** @page requires-gles20 Functionality requiring OpenGL ES 2.0 or WebGL 1.0
@m_footernavigation
The following symbols are not defined when targeting OpenGL ES 3.0, WebGL 2.0 The following symbols are not defined when targeting OpenGL ES 3.0, WebGL 2.0
or desktop OpenGL. or desktop OpenGL.
@see @ref MAGNUM_TARGET_GLES2 @see @ref MAGNUM_TARGET_GLES2
*/
@page requires-gles30 Functionality requiring OpenGL ES 3.0 /** @page requires-gles30 Functionality requiring OpenGL ES 3.0
@m_footernavigation
@see @ref MAGNUM_TARGET_GLES3 @see @ref MAGNUM_TARGET_GLES3
*/
@page requires-gles31 Functionality requiring OpenGL ES 3.1 /** @page requires-gles31 Functionality requiring OpenGL ES 3.1
@m_footernavigation
The following symbols are not defined when targeting OpenGL ES 2.0. The following symbols are not defined when targeting OpenGL ES 2.0.
*/
@page requires-es-extension Functionality requiring specific OpenGL ES extension /** @page requires-es-extension Functionality requiring specific OpenGL ES extension
* @m_footernavigation
*/
@page requires-gles Functionality requiring OpenGL ES or desktop OpenGL /** @page requires-gles Functionality requiring OpenGL ES or desktop OpenGL
@m_footernavigation
The following symbols are not defined when targeting WebGL. The following symbols are not defined when targeting WebGL.
@see @ref MAGNUM_TARGET_WEBGL, @ref requires-gl @see @ref MAGNUM_TARGET_WEBGL, @ref requires-gl
*/
@page requires-webgl20 Functionality requiring WebGL 2.0 /** @page requires-webgl20 Functionality requiring WebGL 2.0
* @m_footernavigation
@page requires-webgl-extension Functionality requiring specific WebGL extension */
*/ /** @page requires-webgl-extension Functionality requiring specific WebGL extension
* @m_footernavigation
*/

84
doc/platform.dox

@ -27,7 +27,8 @@ namespace Magnum {
/** @page platform Platform support /** @page platform Platform support
@brief Integration into windowing toolkits and creation of windowless contexts. @brief Integration into windowing toolkits and creation of windowless contexts.
- Next page: @ref types @tableofcontents
@m_footernavigation
@ref Platform namespace contains classes integrating Magnum engine into @ref Platform namespace contains classes integrating Magnum engine into
various toolkits, both windowed and windowless. Each class has slightly various toolkits, both windowed and windowless. Each class has slightly
@ -35,8 +36,6 @@ different dependencies and platform requirements, see documentation of
@ref Platform namespace and particular `*Application` classes for more @ref Platform namespace and particular `*Application` classes for more
information about building and usage with CMake. information about building and usage with CMake.
@tableofcontents
All the classes have common API to achieve static polymorphism, so basically All the classes have common API to achieve static polymorphism, so basically
you can use different toolkits on different platforms and the only thing you you can use different toolkits on different platforms and the only thing you
need to change is the class name, everything else is the same. Basic usage is need to change is the class name, everything else is the same. Basic usage is
@ -49,14 +48,14 @@ de-facto standard and most widely used toolkit is SDL2, which is implemented in
@ref Platform::Sdl2Application. As said above, the usage is similar for all @ref Platform::Sdl2Application. As said above, the usage is similar for all
toolkits, you must provide one-argument constructor and implement at least toolkits, you must provide one-argument constructor and implement at least
@ref Platform::Sdl2Application::drawEvent() "drawEvent()" function. The class @ref Platform::Sdl2Application::drawEvent() "drawEvent()" function. The class
can be then used directly in `main()`, but for convenience and portability it's can be then used directly in @cpp main() @ce, but for convenience and
better to use @ref MAGNUM_SDL2APPLICATION_MAIN() macro. portability it's better to use @ref MAGNUM_SDL2APPLICATION_MAIN() macro.
To simplify the porting, the library provides `Platform::Application` typedef To simplify the porting, the library provides @cpp Platform::Application @ce
and `MAGNUM_APPLICATION_MAIN()` macro (but only if only one application header typedef and @cpp MAGNUM_APPLICATION_MAIN() @ce macro (but only if only one
is included, to avoid ambiguity). Changing the code to use different toolkit is application header is included, to avoid ambiguity). Changing the code to use
then matter of replacing only the `#``include` statement (and changing different toolkit is then matter of replacing only the @cpp #include @ce
one line in CMake build script, as you see later). statement (and changing one line in CMake build script, as you see later).
Barebone application implementation which will just clear the window to dark Barebone application implementation which will just clear the window to dark
blue color is shown in the following code listing. blue color is shown in the following code listing.
@ -65,7 +64,7 @@ blue color is shown in the following code listing.
`base` branch of [Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap) `base` branch of [Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap)
repository. repository.
@code @code{.cpp}
#include <Magnum/DefaultFramebuffer.h> #include <Magnum/DefaultFramebuffer.h>
#include <Magnum/Renderer.h> #include <Magnum/Renderer.h>
#include <Magnum/Math/Color.h> #include <Magnum/Math/Color.h>
@ -105,7 +104,8 @@ as the window has fixed size in most cases. To respond to size change for
example by resizing the default framebuffer, you need to reimplement example by resizing the default framebuffer, you need to reimplement
@ref Platform::Sdl2Application::viewportEvent() "viewportEvent()" function and @ref Platform::Sdl2Application::viewportEvent() "viewportEvent()" function and
pass the new size to the framebuffer: pass the new size to the framebuffer:
@code
@code{.cpp}
class MyApplication: public Platform::Application { class MyApplication: public Platform::Application {
// ... // ...
@ -131,18 +131,18 @@ Windows. To make things simple, as an example we will use only
below for fully portable example. below for fully portable example.
You need to implement just @ref Platform::WindowlessGlxApplication::exec() "exec()" You need to implement just @ref Platform::WindowlessGlxApplication::exec() "exec()"
function. The class can be then used directly in `main()`, but again, for function. The class can be then used directly in @cpp main() @ce, but again,
convenience and portability it's better to use for convenience and portability it's better to use
@ref MAGNUM_WINDOWLESSGLXAPPLICATION_MAIN() macro. @ref MAGNUM_WINDOWLESSGLXAPPLICATION_MAIN() macro.
Similarly as with windowed applications, to simplify the porting, the library Similarly as with windowed applications, to simplify the porting, the library
provides `Platform::WindowlessApplication` typedef and `MAGNUM_WINDOWLESSAPPLICATION_MAIN()` provides @cpp Platform::WindowlessApplication @ce typedef and
macro, but only if just one windowless application header is included. Changing @cpp MAGNUM_WINDOWLESSAPPLICATION_MAIN() @ce macro, but only if just one
the code to use different toolkit is then matter of replacing only the windowless application header is included. Changing the code to use different
`#``include` statement. Aliases for windowless applications are toolkit is then matter of replacing only the @cpp #include @ce statement.
separated from aliases for windowed applications, because projects commonly Aliases for windowless applications are separated from aliases for windowed
contain both graphics application and command-line tools (for data preparation applications, because projects commonly contain both graphics application and
etc.). command-line tools (for data preparation etc.).
Barebone application which will just print out current OpenGL version and Barebone application which will just print out current OpenGL version and
renderer string and exits is in the following code listing. renderer string and exits is in the following code listing.
@ -153,7 +153,7 @@ renderer string and exits is in the following code listing.
is available in `windowless` branch of [Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap) is available in `windowless` branch of [Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap)
repository. repository.
@code @code{.cpp}
#include <Magnum/Context.h> #include <Magnum/Context.h>
#include <Magnum/Platform/WindowlessGlxApplication.h> #include <Magnum/Platform/WindowlessGlxApplication.h>
@ -191,9 +191,9 @@ aliases (or `Magnum::WindowlessApplication` for windowless applications), but
only if only one application (windowless application) component is requested to only if only one application (windowless application) component is requested to
avoid ambiguity. Changing the build script to use different toolkit is then avoid ambiguity. Changing the build script to use different toolkit is then
matter of replacing only the requested `*Application` component (and one matter of replacing only the requested `*Application` component (and one
`#``include` line in the actual code, as said above). @cpp #include @ce line in the actual code, as said above).
@code @code{.cmake}
find_package(Magnum REQUIRED Sdl2Application) find_package(Magnum REQUIRED Sdl2Application)
add_executable(myapplication MyApplication.cpp) add_executable(myapplication MyApplication.cpp)
@ -209,7 +209,8 @@ window size 800x600 pixels). If you want something else, you can pass
@ref Platform::Sdl2Application::Configuration "Configuration" instance to @ref Platform::Sdl2Application::Configuration "Configuration" instance to
application constructor. Using method chaining it can be done conveniently like application constructor. Using method chaining it can be done conveniently like
this: this:
@code
@code{.cpp}
MyApplication::MyApplication(int& argc, char** argv): MyApplication::MyApplication(int& argc, char** argv):
Platform::Application(argc, argv, Configuration() Platform::Application(argc, argv, Configuration()
.setTitle("My Application") .setTitle("My Application")
@ -223,7 +224,8 @@ However, sometimes you would need to configure the application based on some
configuration file or system introspection. In that case you can pass `nullptr` configuration file or system introspection. In that case you can pass `nullptr`
instead of @ref Platform::Sdl2Application::Configuration "Configuration" instead of @ref Platform::Sdl2Application::Configuration "Configuration"
instance and then specify it later with @ref Platform::Sdl2Application::createContext() "createContext()": instance and then specify it later with @ref Platform::Sdl2Application::createContext() "createContext()":
@code
@code{.cpp}
MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc, argv, nullptr) { MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc, argv, nullptr) {
// ... // ...
@ -241,7 +243,8 @@ context using @ref Platform::Sdl2Application::tryCreateContext() "tryCreateConte
The only difference is that this function returns `false` instead of exiting. The only difference is that this function returns `false` instead of exiting.
You can for example try enabling MSAA and if the context creation fails, fall You can for example try enabling MSAA and if the context creation fails, fall
back to no-AA rendering: back to no-AA rendering:
@code
@code{.cpp}
MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc, argv, nullptr) { MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc, argv, nullptr) {
// ... // ...
@ -263,14 +266,14 @@ the application wrappers in @ref Platform namespace, you can initialize Magnum
manually. First create OpenGL context and then create instance of manually. First create OpenGL context and then create instance of
@ref Platform::Context class, which will take care of proper initialization and @ref Platform::Context class, which will take care of proper initialization and
feature detection. The instance must be alive for whole application lifetime. feature detection. The instance must be alive for whole application lifetime.
Example `main()` function with manual initialization is in the following code Example @cpp main() @ce function with manual initialization is in the following
listing. code listing.
@note Fully contained application using with manual Magnum initialization on @note Fully contained application using with manual Magnum initialization on
top of Qt toolkit is available in `base-qt` branch of top of Qt toolkit is available in `base-qt` branch of
[Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap) repository. [Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap) repository.
@code @code{.cpp}
int main(int argc, char** argv) { int main(int argc, char** argv) {
// Create OpenGL context ... // Create OpenGL context ...
@ -295,10 +298,10 @@ pointer loading using platform-specific APIs. In that case you also need to
find particular `*Context` library, add its include dir and then link to it. find particular `*Context` library, add its include dir and then link to it.
These platform-specific libraries are available: These platform-specific libraries are available:
- `CglContext` -- CGL context (macOS) - `CglContext` --- CGL context (macOS)
- `EglContext` -- EGL context (everywhere except Emscripten) - `EglContext` --- EGL context (everywhere except Emscripten)
- `GlxContext` -- GLX context (X11-based Unix) - `GlxContext` --- GLX context (X11-based Unix)
- `WglContext` -- WGL context (Windows) - `WglContext` --- WGL context (Windows)
Systems not listed here (such as Emscripten) don't need any `Context` library, Systems not listed here (such as Emscripten) don't need any `Context` library,
because dynamic function pointer loading is not available on these. because dynamic function pointer loading is not available on these.
@ -306,9 +309,10 @@ because dynamic function pointer loading is not available on these.
For example, when you create the OpenGL context using GLX, you need to find For example, when you create the OpenGL context using GLX, you need to find
`GlxContext` component, and link to `Magnum::GlxContext` target. Similarly to `GlxContext` component, and link to `Magnum::GlxContext` target. Similarly to
application libraries, you can also use generic `Magnum::Context` target, application libraries, you can also use generic `Magnum::Context` target,
providing you requested only one `*Context` component in the `find_package()` providing you requested only one `*Context` component in the @cmake find_package() @ce
call. Complete example: call. Complete example:
@code
@code{.cmake}
find_package(Magnum REQUIRED GlxContext) find_package(Magnum REQUIRED GlxContext)
add_executable(myapplication MyCustomApplication.cpp) add_executable(myapplication MyCustomApplication.cpp)
@ -330,13 +334,13 @@ create a GL context instance, then making it current and finally instantiating
the @ref Platform::Context instance to initialize Magnum. the @ref Platform::Context instance to initialize Magnum.
Similarly as with the applications, to simplify the porting, the library Similarly as with the applications, to simplify the porting, the library
provides `Platform::WindowlessGLContext` typedef, but only if just one provides @cpp Platform::WindowlessGLContext @ce typedef, but only if just one
windowless application header is included. windowless application header is included.
@attention With this approach it is possible to switch between different GL @attention With this approach it is possible to switch between different GL
contexts, but make sure that Magnum is used only with its OpenGL context. contexts, but make sure that Magnum is used only with its OpenGL context.
@code @code{.cpp}
int main(int argc, char** argv) { int main(int argc, char** argv) {
Platform::WindowlessGLContext glContext{{}}; Platform::WindowlessGLContext glContext{{}};
glContext.makeCurrent(); glContext.makeCurrent();
@ -369,7 +373,7 @@ current (for example for the main application rendering). See also
@note Context creation is not thread safe on all platforms, that's why it still @note Context creation is not thread safe on all platforms, that's why it still
has to be done on the main thread. has to be done on the main thread.
@code @code{.cpp}
int main() { int main() {
Platform::WindowlessGLContext glContext{{}}; Platform::WindowlessGLContext glContext{{}};
@ -385,7 +389,5 @@ int main() {
worker.join(); worker.join();
} }
@endcode @endcode
- Next page: @ref types
*/ */
} }

41
doc/plugins.dox

@ -27,8 +27,8 @@ namespace Magnum {
/** @page plugins Loading and using plugins /** @page plugins Loading and using plugins
@brief Extending Magnum with additional functionality @brief Extending Magnum with additional functionality
- Previous page: @ref transformations @tableofcontents
- Next page: @ref opengl-wrapping @m_footernavigation
The base Magnum library contains math support, scene graph implementation and The base Magnum library contains math support, scene graph implementation and
is able to interact with graphics and audio hardware. However, the base library is able to interact with graphics and audio hardware. However, the base library
@ -37,8 +37,6 @@ are simply too many formats to have them included directly in the library.
Instead, the library provides plugin API and you can load plugin which will Instead, the library provides plugin API and you can load plugin which will
then be able to read or write the particular file format. then be able to read or write the particular file format.
@tableofcontents
The @ref building "Magnum repository" contains a few basic plugins for opening The @ref building "Magnum repository" contains a few basic plugins for opening
the some formats, such as TGA images or WAV audio files. These plugins are the some formats, such as TGA images or WAV audio files. These plugins are
included because the file formats are so simple that no external library is included because the file formats are so simple that no external library is
@ -54,22 +52,22 @@ might not be available on all platforms.
Magnum contains these plugin interfaces: Magnum contains these plugin interfaces:
- @ref Trade::AbstractImporter -- importers for general 2D and 3D scene, - @ref Trade::AbstractImporter --- importers for general 2D and 3D scene,
mesh, material, texture and image data. See `*Importer` classes in mesh, material, texture and image data. See `*Importer` classes in
@ref Trade namespace for available importer plugins. These are installed in @ref Trade namespace for available importer plugins. These are installed in
`MAGNUM_PLUGINS_IMPORTER_DIR` directory. `MAGNUM_PLUGINS_IMPORTER_DIR` directory.
- @ref Trade::AbstractImageConverter -- conversion among various image - @ref Trade::AbstractImageConverter --- conversion among various image
formats. See `*ImageConverter` classes in @ref Trade namespace for list of formats. See `*ImageConverter` classes in @ref Trade namespace for list of
available image converter plugins. These are installed in available image converter plugins. These are installed in
`MAGNUM_PLUGINS_IMAGECONVERTER_DIR` directory. `MAGNUM_PLUGINS_IMAGECONVERTER_DIR` directory.
- @ref Text::AbstractFont -- font loading and glyph layouting. See `*Font` - @ref Text::AbstractFont --- font loading and glyph layouting. See `*Font`
classes in @ref Text namespace for available font plugins. These are classes in @ref Text namespace for available font plugins. These are
installed in `MAGNUM_PLUGINS_FONT_DIR` directory. installed in `MAGNUM_PLUGINS_FONT_DIR` directory.
- @ref Text::AbstractFontConverter -- font and glyph cache conversion. See - @ref Text::AbstractFontConverter --- font and glyph cache conversion. See
`*FontConverter` classes in @ref Text namespace for available font `*FontConverter` classes in @ref Text namespace for available font
converter plugins. These are installed in `MAGNUM_PLUGINS_FONTCONVERTER_DIR` converter plugins. These are installed in `MAGNUM_PLUGINS_FONTCONVERTER_DIR`
directory. directory.
- @ref Audio::AbstractImporter -- importers for audio formats. See - @ref Audio::AbstractImporter --- importers for audio formats. See
`*Importer` classes in @ref Audio namespace for available audio importer `*Importer` classes in @ref Audio namespace for available audio importer
plugins. These are installed in `MAGNUM_PLUGINS_AUDIOIMPORTER_DIR` plugins. These are installed in `MAGNUM_PLUGINS_AUDIOIMPORTER_DIR`
directory. directory.
@ -92,7 +90,8 @@ information.
You can provide the variable to your sources using CMake configuration file. You can provide the variable to your sources using CMake configuration file.
Create `configure.h.cmake` file in your source directory with contents similar Create `configure.h.cmake` file in your source directory with contents similar
to these: to these:
@code
@code{.cpp}
#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DIR}" #define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DIR}"
@endcode @endcode
@ -103,7 +102,8 @@ build and you have to select between `MAGNUM_PLUGINS_*_DIR` and
preprocessor variable. This will ensure that you use debug plugin directory for preprocessor variable. This will ensure that you use debug plugin directory for
debug build on multi-configuration build sytems and fall back to autodetection debug build on multi-configuration build sytems and fall back to autodetection
for the rest: for the rest:
@code
@code{.cpp}
#ifdef CORRADE_IS_DEBUG_BUILD #ifdef CORRADE_IS_DEBUG_BUILD
#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}" #define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}"
#else #else
@ -120,7 +120,8 @@ Then process the file in your `CMakeLists.txt`. The result
(`${MAGNUM_PLUGINS_IMPORTER_DIR}` / `${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}` gets (`${MAGNUM_PLUGINS_IMPORTER_DIR}` / `${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}` gets
replaced with the actual value) is put into build directory, so don't forget to replaced with the actual value) is put into build directory, so don't forget to
add it to include path: add it to include path:
@code
@code{.cmake}
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/configure.h) ${CMAKE_CURRENT_BINARY_DIR}/configure.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
@ -129,7 +130,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
Then you can instantiate the manager, load particular plugin and create an Then you can instantiate the manager, load particular plugin and create an
instance of it. Keep in mind that the manager instance must exist for whole instance of it. Keep in mind that the manager instance must exist for whole
lifetime of all plugin instances created from it. lifetime of all plugin instances created from it.
@code
@code{.cpp}
#include "configure.h" #include "configure.h"
// ... // ...
@ -156,7 +158,8 @@ plugin needs to load the glyph atlas using @ref Trade::TgaImporter "TgaImporter"
plugin. The dependency loading is done automatically, but you need to create plugin. The dependency loading is done automatically, but you need to create
instance of corresponding plugin manager in particular plugin dir so the instance of corresponding plugin manager in particular plugin dir so the
dependency can be found. Example: dependency can be found. Example:
@code
@code{.cpp}
PluginManager::Manager<Trade::AbstractImporter> importerManager(MAGNUM_PLUGINS_IMPORTER_DIR); PluginManager::Manager<Trade::AbstractImporter> importerManager(MAGNUM_PLUGINS_IMPORTER_DIR);
PluginManager::Manager<Text::AbstractFont> fontManager(MAGNUM_PLUGINS_FONT_DIR); PluginManager::Manager<Text::AbstractFont> fontManager(MAGNUM_PLUGINS_FONT_DIR);
@ -178,7 +181,8 @@ The plugins are built as static if `BUILD_STATIC` CMake parameter is enabled
usage is basically the same as above, but you need to explicitly find the usage is basically the same as above, but you need to explicitly find the
plugin and link it into the executable in your `CMakeLists.txt`. See @ref cmake plugin and link it into the executable in your `CMakeLists.txt`. See @ref cmake
and @ref cmake-plugins for additional information. and @ref cmake-plugins for additional information.
@code
@code{.cmake}
find_package(MagnumPlugins REQUIRED PngImporter) find_package(MagnumPlugins REQUIRED PngImporter)
add_executable(MyApp ...) add_executable(MyApp ...)
@ -196,7 +200,8 @@ It's needed to register the static plugin with @ref CORRADE_PLUGIN_IMPORT() in
some function which will be executed before you use the plugin, otherwise the some function which will be executed before you use the plugin, otherwise the
plugin will not be found. See the macro documentation for information about plugin will not be found. See the macro documentation for information about
automatic importing and namespace issues. automatic importing and namespace issues.
@code
@code{.cpp}
int main(int argc, char** argv) { int main(int argc, char** argv) {
CORRADE_PLUGIN_IMPORT(TgaImporter) CORRADE_PLUGIN_IMPORT(TgaImporter)
@ -214,9 +219,5 @@ If you want to develop a plugin which depends on another, you need to find the
original plugin, add its include dirs to include path and link to it, similarly original plugin, add its include dirs to include path and link to it, similarly
to how static plugins are found above. See @ref cmake and @ref cmake-plugins to how static plugins are found above. See @ref cmake and @ref cmake-plugins
for more information. for more information.
- Previous page: @ref transformations
- Next page: @ref opengl-wrapping
*/ */
} }

85
doc/portability.dox

@ -28,13 +28,14 @@ namespace Magnum {
@brief How to support different platforms and different OpenGL capabilities within one codebase. @brief How to support different platforms and different OpenGL capabilities within one codebase.
@tableofcontents @tableofcontents
@m_footernavigation
@section portability-target Target-specific code @section portability-target Target-specific code
If Magnum is compiled with e.g. OpenGL ES 2.0 support, some features present If Magnum is compiled with e.g. OpenGL ES 2.0 support, some features present
in desktop version are not available. It means that some classes, functions in desktop version are not available. It means that some classes, functions
and enum values are simply not included in headers. It is designed this way to and enum values are simply not included in headers. It is designed this way to
make porting easier -- it is better to fail at compile time on e.g. undefined make porting easier --- it is better to fail at compile time on e.g. undefined
enum value than fail at runtime in some corner case because given texture enum value than fail at runtime in some corner case because given texture
format is not supported. format is not supported.
@ -46,7 +47,8 @@ If you include @ref Magnum.h, you get these predefined macros:
- @ref MAGNUM_TARGET_WEBGL if targeting WebGL - @ref MAGNUM_TARGET_WEBGL if targeting WebGL
Example usage: Example usage:
@code
@code{.cpp}
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
Renderer::setPolygonMode(Renderer::PolygonMode::Lines); Renderer::setPolygonMode(Renderer::PolygonMode::Lines);
// draw mesh as wireframe... // draw mesh as wireframe...
@ -62,15 +64,13 @@ also @ref requires-gl, @ref requires-gles20 and @ref requires-gles30.
Magnum is attempting to be future-proof and as intuitive for users as Magnum is attempting to be future-proof and as intuitive for users as
possible. Many features from C++11 are used to simplify things and make them possible. Many features from C++11 are used to simplify things and make them
faster and more secure, but on the other hand it requires fairly recent faster and more secure, but on the other hand it requires a compiler with good
compiler with good enough support of the new standard. Currently Magnum is enough support of the standard. Currently Magnum is written with at least GCC
written with GCC 4.8 and Clang 3.1 in mind, but support for some other 4.8, Clang 3.1 and MSVC 2015 in mind. See @ref Corrade.h for more information.
compilers is also available and handled by Corrade library. See @ref Corrade.h
for more information.
Each feature is marked accordingly if it is not available on some compilers, Each feature is marked accordingly if it is not available on some compilers,
see @ref SceneGraph::DrawableGroup3D for an example. It is up to you (or your see @ref SceneGraph::DrawableGroup3D for an example. It is up to you (or your
platform) which compiler your code will support, code written for e.g. GCC 4.7 platform) which compiler your code will support, code written for e.g. GCC 4.8
will work also on Magnum compiled with support for newer compilers, although will work also on Magnum compiled with support for newer compilers, although
newer compilers may catch errors that weren't spotted by earlier versions. newer compilers may catch errors that weren't spotted by earlier versions.
@ -80,12 +80,13 @@ which you can use for platform-aware code.
@section portability-extensions Extension-aware code @section portability-extensions Extension-aware code
Some functionality is depending on support of particular extension and thus Some functionality is depending on support of a particular OpenGL extension and
the decision cannot be made at compile time. Header @ref Extensions.h contains thus the decision cannot be made at compile time. Header @ref Extensions.h
list of extensions, which you can pass to @ref Context::isExtensionSupported() contains list of extensions, which you can pass to
and decide based on that: @ref Context::isExtensionSupported() and decide based on that:
@code
if(Context::instance()->isExtensionSupported<GL::ARB::geometry_shader4>()) { @code{.cpp}
if(Context::current().isExtensionSupported<GL::ARB::geometry_shader4>()) {
// draw mesh with wireframe on top in one pass using geometry shader... // draw mesh with wireframe on top in one pass using geometry shader...
} else { } else {
// draw underlying mesh... // draw underlying mesh...
@ -96,13 +97,14 @@ if(Context::instance()->isExtensionSupported<GL::ARB::geometry_shader4>()) {
You can also decide on particular OpenGL version using @ref Context::isVersionSupported(), You can also decide on particular OpenGL version using @ref Context::isVersionSupported(),
but remember that some features from that version might be available even if but remember that some features from that version might be available even if
the drivers don't expose that version. the drivers don't fully expose that version.
On the other hand, if you don't want to write fallback code for unsupported On the other hand, if you don't want to write fallback code for unsupported
extensions, you can use macros @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED() or extensions, you can use macros @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED() or
@ref MAGNUM_ASSERT_VERSION_SUPPORTED() to add mandatory requirement of given @ref MAGNUM_ASSERT_VERSION_SUPPORTED() to add mandatory requirement of given
extension or version: extension or version:
@code
@code{.cpp}
MAGNUM_ASSERT_EXTENSION_SUPPORTED(GL::ARB::geometry_shader4); MAGNUM_ASSERT_EXTENSION_SUPPORTED(GL::ARB::geometry_shader4);
// just use geometry shader and don't care about old hardware // just use geometry shader and don't care about old hardware
@endcode @endcode
@ -118,20 +120,25 @@ available, but also have proper fallback when it's not, see for example
@section portability-shaders Writing portable shaders @section portability-shaders Writing portable shaders
Shaders are probably the most painful thing to port. There are many issues to Shaders are probably the most painful thing to port. There are many issues to
address - different shader syntax (`in`/`out` vs. `attribute` and `varying` address --- different shader syntax (@glsl in @ce / @glsl out @ce vs.
etc.), explicit vs. implicit methods to specify vertex attribute, uniform and @glsl attribute @ce and @glsl varying @ce etc.), explicit vs. implicit methods
texture uniform locations, required precision qualifiers in OpenGL ES etc. to specify vertex attribute, uniform and texture uniform locations, required
precision qualifiers in OpenGL ES etc.
Shader class allows you to explicitly specify shader version and based on that Shader class allows you to explicitly specify shader version and based on that
you can decide on the syntax in your shader code. You can also use you can decide on the syntax in your shader code. You can also use
@ref Context::supportedVersion() to conveniently select highest supported @ref Context::supportedVersion() to conveniently select the first supported
version from a list: version from a list:
@code
@code{.cpp}
// MyShader.cpp // MyShader.cpp
Version version = Context::instance()->supportedVersion({Version::GL430, Version::GL330, Version::GL210}); Version version = Context::current().supportedVersion({Version::GL430,
Version::GL330,
Version::GL210});
attachShader(Shader::fromFile(version, "MyShader.vert")); attachShader(Shader::fromFile(version, "MyShader.vert"));
@endcode @endcode
@code
@code{.vert}
// MyShader.vert // MyShader.vert
#if __VERSION__ < 130 #if __VERSION__ < 130
#define in attribute #define in attribute
@ -149,12 +156,13 @@ void main() {
@endcode @endcode
It is often desirable to query extension presence based on actually used GLSL It is often desirable to query extension presence based on actually used GLSL
version -- while the extension might be supported in the driver, it might not version --- while the extension might be supported in the driver, it might not
be available in given GLSL version (e.g. causing compilation errors). You can be available in given GLSL version (e.g. causing compilation errors). You can
use @ref Context::isExtensionSupported(Version) const to check that the use @ref Context::isExtensionSupported(Version) const to check that the
extension is present in given version: extension is present in given version:
@code
if(!Context::instance()->isExtensionSupported<Extensions::GL::ARB::explicit_attrib_location>(version)) { @code{.cpp}
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::explicit_attrib_location>(version)) {
bindAttributeLocation(Position::Location, "position"); bindAttributeLocation(Position::Location, "position");
// ... // ...
} }
@ -165,21 +173,21 @@ specifying attribute location, uniform location and texture binding unit in
various OpenGL versions. various OpenGL versions.
All shaders in @ref Shaders namespace support desktop OpenGL starting from All shaders in @ref Shaders namespace support desktop OpenGL starting from
version 2.1 and also OpenGL ES 2.0 and 3.0. Feel free to look into their version 2.1 and also OpenGL ES 2.0 and 3.0 (or WebGL 1.0 / 2.0). Feel free to
sources to see how portability is handled there. look into their sources to see how portability is handled there.
@section portability-applications Platform-specific application support @section portability-applications Platform-specific application support
Your application might run on Windows box, on some embedded Linux or even in Your application might run on Windows box, on some embedded Linux or even in
browser - each platform has different requirements how to create entry point browser --- each platform has different requirements how to create an entry
to the application, how to handle input events, how to create window and point to the application, how to handle input events, how to create window and
OpenGL context etc. Namespace @ref Platform contains application base classes OpenGL context etc. Namespace @ref Platform contains application base classes
which are abstracting out most of it for your convenience. which are abstracting out most of it for your convenience.
All the classes support limited form of static polymorphism, which means you All the classes support limited form of static polymorphism, which means you
can just switch to another base class and in many cases you won't need to can just switch to another base class and in many cases you won't need to
change any other code. It has its limitations, though - some toolkits don't change any other code. It has its limitations, though --- some toolkits don't
support all keys, mouse movement events etc. support all special keys, mouse movement events etc.
As mentioned in @ref platform, all the classes, macros and CMake variables have As mentioned in @ref platform, all the classes, macros and CMake variables have
generic aliases, thus using different toolkit is in most cases only matter of generic aliases, thus using different toolkit is in most cases only matter of
@ -189,7 +197,8 @@ Example application, which targets both embedded Linux (using plain X and EGL)
and desktop (using SDL2 toolkit). Thanks to static polymorphism most of the and desktop (using SDL2 toolkit). Thanks to static polymorphism most of the
functions will work on both without changes, the main difference might (or functions will work on both without changes, the main difference might (or
might not, depending what you use) be in particular event handlers: might not, depending what you use) be in particular event handlers:
@code
@code{.cpp}
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
#include <Platform/Sdl2Application.h> #include <Platform/Sdl2Application.h>
#else #else
@ -211,10 +220,11 @@ class MyApplication: public Platform::Application {
MAGNUM_APPLICATION_MAIN(MyApplication) MAGNUM_APPLICATION_MAIN(MyApplication)
@endcode @endcode
And corresponding CMake code. Note that we need to call `find_package()` twice, And corresponding CMake code. Note that we need to call @cmake find_package() @ce
first to get variable `MAGNUM_TARGET_GLES` and then again to find proper twice, first to get the @ref MAGNUM_TARGET_GLES variable and then again to find
application library based on its value: proper application library based on its value:
@code
@code{.cmake}
find_package(Magnum REQUIRED) find_package(Magnum REQUIRED)
if(MAGNUM_TARGET_GLES) if(MAGNUM_TARGET_GLES)
@ -228,6 +238,5 @@ target_link_libraries(myapplication
Magnum::Magnum Magnum::Magnum
Magnum::Application) Magnum::Application)
@endcode @endcode
*/ */
} }

142
doc/scenegraph.dox

@ -27,15 +27,13 @@ namespace Magnum {
/** @page scenegraph Using scene graph /** @page scenegraph Using scene graph
@brief Overview of scene management capabilities. @brief Overview of scene management capabilities.
- Previous page: @ref shaders
- Next page: @ref shapes
Scene graph provides way to hiearchically manage your objects, their Scene graph provides way to hiearchically manage your objects, their
transformation, physics interaction, animation and rendering. The library is transformation, physics interaction, animation and rendering. The library is
contained in @ref SceneGraph namespace, see its documentation for more contained in @ref SceneGraph namespace, see its documentation for more
information about building and usage with CMake. information about building and usage with CMake.
@tableofcontents @tableofcontents
@m_footernavigation
There are naturally many possible feature combinations (2D vs. 3D, different There are naturally many possible feature combinations (2D vs. 3D, different
transformation representations, animated vs. static, object can have collision transformation representations, animated vs. static, object can have collision
@ -44,10 +42,10 @@ and to make everything possible without combinatiorial explosion and allow the
users to provide their own features, scene graph in Magnum is composed of users to provide their own features, scene graph in Magnum is composed of
three main components: three main components:
- objects, providing parent/children hierarchy - objects, providing parent/children hierarchy
- transformations, implementing particular transformation type - transformations, implementing particular transformation type
- features, providing rendering capabilities, collision detection, physics - features, providing rendering capabilities, collision detection, physics
etc. etc.
@note Fully contained applications with initial scene graph setup are available @note Fully contained applications with initial scene graph setup are available
in `scenegraph2D` and `scenegraph3D` branches of in `scenegraph2D` and `scenegraph3D` branches of
@ -62,7 +60,7 @@ in @ref SceneGraph are templated on underlying type. However, in most cases
so you don't have to explicitly specify it. so you don't have to explicitly specify it.
Scene graph has various transformation implementations for both 2D and 3D. Each Scene graph has various transformation implementations for both 2D and 3D. Each
implementation has its own advantages and disadvantages -- for example when implementation has its own advantages and disadvantages --- for example when
using matrices you can have nearly arbitrary transformations, but composing using matrices you can have nearly arbitrary transformations, but composing
transformations, computing their inverse and accounting for floating-point transformations, computing their inverse and accounting for floating-point
drift is rather costly operation. On the other hand quaternions won't allow you drift is rather costly operation. On the other hand quaternions won't allow you
@ -74,30 +72,31 @@ needs, see source of builtin transformation classes for more information.
Magnum provides the following transformation classes. See documentation of each Magnum provides the following transformation classes. See documentation of each
class for more detailed information: class for more detailed information:
- @ref SceneGraph::BasicMatrixTransformation2D "SceneGraph::MatrixTransformation2D" -- - @ref SceneGraph::BasicMatrixTransformation2D "SceneGraph::MatrixTransformation2D" ---
arbitrary 2D transformations but with slow inverse transformations and no arbitrary 2D transformations but with slow inverse transformations and no
floating-point drift reduction floating-point drift reduction
- @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D" -- - @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D" ---
arbitrary 3D transformations but with slow inverse transformations and no arbitrary 3D transformations but with slow inverse transformations and no
floating-point drift reduction floating-point drift reduction
- @ref SceneGraph::BasicRigidMatrixTransformation2D "SceneGraph::RigidMatrixTransformation2D" -- - @ref SceneGraph::BasicRigidMatrixTransformation2D "SceneGraph::RigidMatrixTransformation2D" ---
2D translation, rotation and reflection (no scaling), with relatively fast 2D translation, rotation and reflection (no scaling), with relatively fast
inverse transformations and floating-point drift reduction inverse transformations and floating-point drift reduction
- @ref SceneGraph::BasicRigidMatrixTransformation3D "SceneGraph::RigidMatrixTransformation3D" -- - @ref SceneGraph::BasicRigidMatrixTransformation3D "SceneGraph::RigidMatrixTransformation3D" ---
3D translation, rotation and reflection (no scaling), with relatively fast 3D translation, rotation and reflection (no scaling), with relatively fast
inverse transformations and floating-point drift reduction inverse transformations and floating-point drift reduction
- @ref SceneGraph::BasicDualComplexTransformation "SceneGraph::DualComplexTransformation" -- - @ref SceneGraph::BasicDualComplexTransformation "SceneGraph::DualComplexTransformation" ---
2D translation and rotation with fast inverse transformations and 2D translation and rotation with fast inverse transformations and
floating-point drift reduction floating-point drift reduction
- @ref SceneGraph::BasicDualQuaternionTransformation "SceneGraph::DualQuaternionTransformation" -- - @ref SceneGraph::BasicDualQuaternionTransformation "SceneGraph::DualQuaternionTransformation" ---
3D translation and rotation with fast inverse transformation and 3D translation and rotation with fast inverse transformation and
floating-point drift reduction floating-point drift reduction
- @ref SceneGraph::TranslationTransformation "SceneGraph::TranslationTransformation*D" -- - @ref SceneGraph::TranslationTransformation "SceneGraph::TranslationTransformation*D" ---
Just 2D/3D translation (no rotation, scaling or anything else) Just 2D/3D translation (no rotation, scaling or anything else)
Common usage of transformation classes is to typedef Scene and Object with Common usage of transformation classes is to typedef Scene and Object with
desired transformation type to save unnecessary typing later: desired transformation type to save unnecessary typing later:
@code
@code{.cpp}
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D; typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
@endcode @endcode
@ -110,7 +109,8 @@ The object type is subclassed from the transformation type and so the
`Object3D` type will then contain all members from both @ref SceneGraph::Object `Object3D` type will then contain all members from both @ref SceneGraph::Object
and @ref SceneGraph::MatrixTransformation3D. For convenience you can use method and @ref SceneGraph::MatrixTransformation3D. For convenience you can use method
chaining: chaining:
@code
@code{.cpp}
Scene3D scene; Scene3D scene;
Object3D object; Object3D object;
@ -133,20 +133,22 @@ Parent object can be either passed in constructor or set using
naturally cannot have parent object. Parent and children relationships can be naturally cannot have parent object. Parent and children relationships can be
observed through @ref SceneGraph::Object::parent() and observed through @ref SceneGraph::Object::parent() and
@ref SceneGraph::Object::children(). @ref SceneGraph::Object::children().
@code
@code{.cpp}
Scene3D scene; Scene3D scene;
Object3D* first = new Object3D{&scene}; Object3D* first = new Object3D{&scene};
Object3D* second = new Object3D{first}; Object3D* second = new Object3D{first};
@endcode @endcode
The hierarchy takes care of memory management -- when an object is destroyed, The hierarchy takes care of memory management --- when an object is destroyed,
all its children are destroyed too. See detailed explanation of all its children are destroyed too. See detailed explanation of
@ref scenegraph-object-construction-order "construction and destruction order" @ref scenegraph-object-construction-order "construction and destruction order"
below for information about possible issues. To reflect the implicit memory below for information about possible issues. To reflect the implicit memory
management in the code better, you can use @ref SceneGraph::Object::addChild() management in the code better, you can use @ref SceneGraph::Object::addChild()
instead of the naked `new` call in the code above: instead of the naked `new` call in the code above:
@code
@code{.cpp}
Scene3D scene; Scene3D scene;
Object3D& first = scene.addChild<Object3D>(); Object3D& first = scene.addChild<Object3D>();
@ -162,21 +164,21 @@ have to add a *feature* to it.
Magnum provides the following builtin features. See documentation of each class Magnum provides the following builtin features. See documentation of each class
for more detailed information and usage examples: for more detailed information and usage examples:
- @ref SceneGraph::AbstractCamera "SceneGraph::Camera*D" -- Handles - @ref SceneGraph::AbstractCamera "SceneGraph::Camera*D" --- Handles
projection matrix, aspect ratio correction etc.. Used for rendering parts projection matrix, aspect ratio correction etc.. Used for rendering parts
of the scene. of the scene.
- @ref SceneGraph::Drawable "SceneGraph::Drawable*D" -- Adds drawing - @ref SceneGraph::Drawable "SceneGraph::Drawable*D" --- Adds drawing
functionality to given object. Group of drawables can be then rendered functionality to given object. Group of drawables can be then rendered
using the camera feature. using the camera feature.
- @ref SceneGraph::Animable "SceneGraph::Animable*D" -- Adds animation - @ref SceneGraph::Animable "SceneGraph::Animable*D" --- Adds animation
functionality to given object. Group of animables can be then controlled functionality to given object. Group of animables can be then controlled
using @ref SceneGraph::AnimableGroup "SceneGraph::AnimableGroup*D". using @ref SceneGraph::AnimableGroup "SceneGraph::AnimableGroup*D".
- @ref Shapes::Shape -- Adds collision shape to given object. Group of shapes - @ref Shapes::Shape --- Adds collision shape to given object. Group of shapes
can be then controlled using @ref Shapes::ShapeGroup "Shapes::ShapeGroup*D". can be then controlled using @ref Shapes::ShapeGroup "Shapes::ShapeGroup*D".
See @ref shapes for more information. See @ref shapes for more information.
- @ref DebugTools::ObjectRenderer "DebugTools::ObjectRenderer*D", - @ref DebugTools::ObjectRenderer "DebugTools::ObjectRenderer*D",
@ref DebugTools::ShapeRenderer "DebugTools::ShapeRenderer*D", @ref DebugTools::ShapeRenderer "DebugTools::ShapeRenderer*D",
@ref DebugTools::ForceRenderer "DebugTools::ForceRenderer*D" -- Visualize @ref DebugTools::ForceRenderer "DebugTools::ForceRenderer*D" --- Visualize
object properties, object shape or force vector for debugging purposes. See object properties, object shape or force vector for debugging purposes. See
@ref debug-tools for more information. @ref debug-tools for more information.
@ -184,7 +186,8 @@ Each feature takes reference to *holder object* in constructor, so adding a
feature to an object might look just like the following, as in some cases you feature to an object might look just like the following, as in some cases you
don't even need to keep the pointer to it. List of object features is don't even need to keep the pointer to it. List of object features is
accessible through @ref SceneGraph::Object::features(). accessible through @ref SceneGraph::Object::features().
@code
@code{.cpp}
Object3D& o; Object3D& o;
new MyFeature{o, ...}; new MyFeature{o, ...};
@endcode @endcode
@ -198,7 +201,8 @@ itself using multiple inheritance, so you can conveniently add all the active
features you want and implement needed functions in your own @ref SceneGraph::Object features you want and implement needed functions in your own @ref SceneGraph::Object
subclass without having to subclass each feature individually (and making the subclass without having to subclass each feature individually (and making the
code overly verbose). Simplified example: code overly verbose). Simplified example:
@code
@code{.cpp}
class BouncingBall: public Object3D, SceneGraph::Drawable3D, SceneGraph::Animable3D { class BouncingBall: public Object3D, SceneGraph::Drawable3D, SceneGraph::Animable3D {
public: public:
explicit BouncingBall(Object3D* parent): Object3D{parent}, SceneGraph::Drawable3D{*this}, SceneGraph::Animable3D{*this} {} explicit BouncingBall(Object3D* parent): Object3D{parent}, SceneGraph::Drawable3D{*this}, SceneGraph::Animable3D{*this} {}
@ -222,7 +226,8 @@ member and inherited) are destroyed. See detailed explanation of
for information about possible issues. Also, there is a for information about possible issues. Also, there is a
@ref SceneGraph::AbstractObject::addFeature() counterpart to @ref SceneGraph::AbstractObject::addFeature() counterpart to
@ref SceneGraph::Object::addChild(): @ref SceneGraph::Object::addChild():
@code
@code{.cpp}
Object3D& o; Object3D& o;
o.addFeature<MyFeature>(...); o.addFeature<MyFeature>(...);
@endcode @endcode
@ -230,12 +235,12 @@ o.addFeature<MyFeature>(...);
@subsection scenegraph-features-caching Transformation caching in features @subsection scenegraph-features-caching Transformation caching in features
Some features need to operate with absolute transformations and their Some features need to operate with absolute transformations and their
inversions -- for example camera needs its inverse transformation to render the inversions --- for example camera needs its inverse transformation to render the
scene, collision detection needs to know about positions of surrounding scene, collision detection needs to know about positions of surrounding
objects etc. To avoid computing the transformations from scratch every time, objects etc. To avoid computing the transformations from scratch every time,
the feature can cache them. the feature can cache them.
The cached data stay until the object is marked as dirty -- that is by changing The cached data stay until the object is marked as dirty --- that is by changing
transformation, changing parent or explicitly calling @ref SceneGraph::Object::setDirty(). transformation, changing parent or explicitly calling @ref SceneGraph::Object::setDirty().
If the object is marked as dirty, all its children are marked as dirty too and If the object is marked as dirty, all its children are marked as dirty too and
@ref SceneGraph::AbstractFeature::markDirty() is called on every feature. @ref SceneGraph::AbstractFeature::markDirty() is called on every feature.
@ -246,13 +251,14 @@ dirty parents. The function goes through all object features and calls
enabled on given feature. If the object is already clean, enabled on given feature. If the object is already clean,
@ref SceneGraph::Object::setClean() does nothing. @ref SceneGraph::Object::setClean() does nothing.
Most probably you will need caching in @ref SceneGraph::Object itself -- which Most probably you will need caching in @ref SceneGraph::Object itself --- which
doesn't support it on its own -- however you can take advantage of multiple doesn't support it on its own --- however you can take advantage of multiple
inheritance and implement it using @ref SceneGraph::AbstractFeature. In order inheritance and implement it using @ref SceneGraph::AbstractFeature. In order
to have caching, you must enable it first, because by default the caching is to have caching, you must enable it first, because by default the caching is
disabled. You can enable it using @ref SceneGraph::AbstractFeature::setCachedTransformations() disabled. You can enable it using @ref SceneGraph::AbstractFeature::setCachedTransformations()
and then implement corresponding cleaning function(s): and then implement corresponding cleaning function(s):
@code
@code{.cpp}
class CachingObject: public Object3D, SceneGraph::AbstractFeature3D { class CachingObject: public Object3D, SceneGraph::AbstractFeature3D {
public: public:
explicit CachingObject(Object3D* parent): Object3D{parent}, SceneGraph::AbstractFeature3D{*this} { explicit CachingObject(Object3D* parent): Object3D{parent}, SceneGraph::AbstractFeature3D{*this} {
@ -288,15 +294,15 @@ being specialized for all relevant transformation implementations. The
following interfaces are available, each having its own set of virtual following interfaces are available, each having its own set of virtual
functions to control the transformation: functions to control the transformation:
- @ref SceneGraph::AbstractTransformation "SceneGraph::AbstractTransformation*D" -- - @ref SceneGraph::AbstractTransformation "SceneGraph::AbstractTransformation*D" ---
base for all transformations base for all transformations
- @ref SceneGraph::AbstractTranslation "SceneGraph::AbstractTranslation*D" -- - @ref SceneGraph::AbstractTranslation "SceneGraph::AbstractTranslation*D" ---
base for all transformations providing translation base for all transformations providing translation
- @ref SceneGraph::AbstractBasicTranslationRotation2D "SceneGraph::AbstractTranslationRotation2D", - @ref SceneGraph::AbstractBasicTranslationRotation2D "SceneGraph::AbstractTranslationRotation2D",
@ref SceneGraph::AbstractBasicTranslationRotation3D "SceneGraph::AbstractTranslationRotation3D" -- @ref SceneGraph::AbstractBasicTranslationRotation3D "SceneGraph::AbstractTranslationRotation3D" ---
base for all transformations providing translation and rotation base for all transformations providing translation and rotation
- @ref SceneGraph::AbstractBasicTranslationRotationScaling2D "SceneGraph::AbstractBasicTranslationRotationScaling2D", - @ref SceneGraph::AbstractBasicTranslationRotationScaling2D "SceneGraph::AbstractBasicTranslationRotationScaling2D",
@ref SceneGraph::AbstractBasicTranslationRotationScaling3D "SceneGraph::AbstractBasicTranslationRotationScaling3D" -- @ref SceneGraph::AbstractBasicTranslationRotationScaling3D "SceneGraph::AbstractBasicTranslationRotationScaling3D" ---
base for all transformations providing translation, rotation and scaling base for all transformations providing translation, rotation and scaling
These interfaces provide virtual functions which can be used to modify object These interfaces provide virtual functions which can be used to modify object
@ -309,7 +315,8 @@ that.
In the following example we are able to get pointer to both In the following example we are able to get pointer to both
@ref SceneGraph::AbstractObject and needed transformation from one @ref SceneGraph::AbstractObject and needed transformation from one
constructor parameter using small trick: constructor parameter using small trick:
@code
@code{.cpp}
class TransformingFeature: public SceneGraph::AbstractFeature3D { class TransformingFeature: public SceneGraph::AbstractFeature3D {
public: public:
template<class T> TransformingFeature(SceneGraph::Object<T>& object): template<class T> TransformingFeature(SceneGraph::Object<T>& object):
@ -319,6 +326,7 @@ class TransformingFeature: public SceneGraph::AbstractFeature3D {
SceneGraph::AbstractTranslationRotation3D& transformation; SceneGraph::AbstractTranslationRotation3D& transformation;
}; };
@endcode @endcode
If we take for example @ref SceneGraph::Object "SceneGraph::Object<MatrixTransformation3D>", If we take for example @ref SceneGraph::Object "SceneGraph::Object<MatrixTransformation3D>",
it is derived from @ref SceneGraph::AbstractObject "SceneGraph::AbstractObject3D" it is derived from @ref SceneGraph::AbstractObject "SceneGraph::AbstractObject3D"
and @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D", and @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D",
@ -333,21 +341,24 @@ should be aware of:
@subsection scenegraph-object-construction-order Object hierarchy @subsection scenegraph-object-construction-order Object hierarchy
When objects are created on the heap (the preferred way, using `new`), they When objects are created on the heap (the preferred way, using @cpp new @ce),
can be constructed in any order and they will be destroyed when their parent they can be constructed in any order and they will be destroyed when their
is destroyed. When creating them on the stack, however, they will be destroyed parent is destroyed. When creating them on the stack, however, they will be
when they go out of scope. Normally, the natural order of creation is not a destroyed when they go out of scope. Normally, the natural order of creation is
problem: not a problem:
@code
@code{.cpp}
{ {
Scene3D scene; Scene3D scene;
Object3D object(&scene); Object3D object(&scene);
} }
@endcode @endcode
The object is created last, so it will be destroyed first, removing itself The object is created last, so it will be destroyed first, removing itself
from `scene`'s children list, causing no problems when destroying `scene` from `scene`'s children list, causing no problems when destroying `scene`
object later. However, if their order is swapped, it will cause problems: object later. However, if their order is swapped, it will cause problems:
@code
@code{.cpp}
{ {
Object3D object; Object3D object;
Scene3D scene; Scene3D scene;
@ -355,6 +366,7 @@ object later. However, if their order is swapped, it will cause problems:
object.setParent(&scene); object.setParent(&scene);
} // crash! } // crash!
@endcode @endcode
The scene will be destroyed first, deleting all its children, which is wrong, The scene will be destroyed first, deleting all its children, which is wrong,
because `object` is created on stack. If this doesn't already crash, the because `object` is created on stack. If this doesn't already crash, the
`object` destructor is called (again), making things even worse. `object` destructor is called (again), making things even worse.
@ -364,32 +376,38 @@ because `object` is created on stack. If this doesn't already crash, the
When destroying the object, all its features are destroyed. For features added When destroying the object, all its features are destroyed. For features added
as member it's no issue, features added using multiple inheritance must be as member it's no issue, features added using multiple inheritance must be
inherited after the Object class: inherited after the Object class:
@code
@code{.cpp}
class MyObject: public Object3D, MyFeature { class MyObject: public Object3D, MyFeature {
public: public:
MyObject(Object3D* parent): Object3D(parent), MyFeature(*this) {} MyObject(Object3D* parent): Object3D(parent), MyFeature(*this) {}
}; };
@endcode @endcode
When constructing MyObject, Object3D constructor is called first and then
MyFeature constructor adds itself to Object3D's list of features. When When constructing `MyObject`, `Object3D` constructor is called first and then
destroying MyObject, its destructor is called and then the destructors of `MyFeature` constructor adds itself to `Object3D`'s list of features. When
ancestor classes -- first MyFeature destructor, which will remove itself from destroying `MyObject`, its destructor is called and then the destructors of
Object3D's list, then Object3D destructor. ancestor classes --- first `MyFeature` destructor, which will remove itself
from `Object3D`'s list, then `Object3D` destructor.
However, if we would inherit MyFeature first, it will cause problems:
@code However, if we would inherit `MyFeature` first, it will cause problems:
@code{.cpp}
class MyObject: MyFeature, public Object3D { class MyObject: MyFeature, public Object3D {
public: public:
MyObject(Object3D* parent): MyFeature(*this), Object3D(parent) {} // crash! MyObject(Object3D* parent): MyFeature(*this), Object3D(parent) {} // crash!
}; };
@endcode @endcode
MyFeature tries to add itself to feature list in not-yet-constructed Object3D,
causing undefined behavior. Then, if this doesn't already crash, Object3D is `MyFeature` tries to add itself to feature list in not-yet-constructed
created, creating empty feature list, making the feature invisible. `Object3D`, causing undefined behavior. Then, if this doesn't already crash,
`Object3D` is created, creating empty feature list, making the feature
invisible.
If we would construct them in swapped order (if it is even possible), it If we would construct them in swapped order (if it is even possible), it
wouldn't help either: wouldn't help either:
@code
@code{.cpp}
class MyObject: MyFeature, public Object3D { class MyObject: MyFeature, public Object3D {
public: public:
MyObject(Object3D* parent): Object3D(parent), MyFeature(*this) {} MyObject(Object3D* parent): Object3D(parent), MyFeature(*this) {}
@ -397,11 +415,9 @@ class MyObject: MyFeature, public Object3D {
// crash on destruction! // crash on destruction!
}; };
@endcode @endcode
On destruction, Object3D destructor is called first, deleting MyFeature,
which is wrong, because MyFeature is in the same object. After that (if the
program didn't already crash) destructor of MyFeature is called (again).
- Previous page: @ref shaders On destruction, `Object3D` destructor is called first, deleting `MyFeature`,
- Next page: @ref shapes which is wrong, because `MyFeature` is in the same object. After that (if the
program didn't already crash) destructor of `MyFeature` is called (again).
*/ */
} }

33
doc/shaders.dox

@ -27,24 +27,22 @@ namespace Magnum {
/** @page shaders Builtin shaders /** @page shaders Builtin shaders
@brief Overview and basic usage of builtin shaders. @brief Overview and basic usage of builtin shaders.
- Previous page: @ref opengl-wrapping
- Next page: @ref scenegraph
@tableofcontents @tableofcontents
@m_footernavigation
Magnum contains a set of general-purpose shaders for easy prototyping, UI Magnum contains a set of general-purpose shaders for easy prototyping, UI
rendering and data visualization/debugging in both 2D and 3D scenes. The rendering and data visualization/debugging in both 2D and 3D scenes. The
following shaders are available, see documentation of each class for sample following shaders are available, see documentation of each class for sample
output and example setup: output and example setup:
- @ref Shaders::Flat "Shaders::Flat*D" -- flat shading using single color or - @ref Shaders::Flat "Shaders::Flat*D" --- flat shading using single color or
texture texture
- @ref Shaders::Vector "Shaders::Vector*D" -- colored vector graphics - @ref Shaders::Vector "Shaders::Vector*D" --- colored vector graphics
- @ref Shaders::DistanceFieldVector "Shaders::DistanceFieldVector*D" -- - @ref Shaders::DistanceFieldVector "Shaders::DistanceFieldVector*D" --
colored and outlined vector graphics colored and outlined vector graphics
- @ref Shaders::VertexColor "Shaders::VertexColor*D" -- vertex-colored meshes - @ref Shaders::VertexColor "Shaders::VertexColor*D" --- vertex-colored meshes
- @ref Shaders::Phong -- Phong shading using colors or textures, 3D only - @ref Shaders::Phong --- Phong shading using colors or textures, 3D only
- @ref Shaders::MeshVisualizer -- wireframe visualization, 3D only - @ref Shaders::MeshVisualizer --- wireframe visualization, 3D only
All the builtin shaders can be used on unextended OpenGL 2.1 and OpenGL ES 2.0 All the builtin shaders can be used on unextended OpenGL 2.1 and OpenGL ES 2.0
/ WebGL 1.0, but they try to use the most recent technology available to have / WebGL 1.0, but they try to use the most recent technology available to have
@ -59,7 +57,8 @@ Each shader expects some set of vertex attributes, thus when adding vertex
buffer into the mesh, you need to specify which shader attributes are on which buffer into the mesh, you need to specify which shader attributes are on which
position in the buffer. See @ref Mesh::addVertexBuffer() for details and usage position in the buffer. See @ref Mesh::addVertexBuffer() for details and usage
examples. Example mesh configuration for @ref Shaders::Phong shader: examples. Example mesh configuration for @ref Shaders::Phong shader:
@code
@code{.cpp}
struct Vertex { struct Vertex {
Vector3 position; Vector3 position;
Vector3 normal; Vector3 normal;
@ -81,8 +80,9 @@ Each shader then has its own set of configuration functions. Some configuration
is static, specified commonly as flags in constructor, directly affecting is static, specified commonly as flags in constructor, directly affecting
compiled shader code. Other configuration is specified through uniforms and compiled shader code. Other configuration is specified through uniforms and
various binding points, commonly exposed through various setters. Example various binding points, commonly exposed through various setters. Example
configuration and rendering using @ref Shaders::Phong "Shaders::Phong": configuration and rendering using @ref Shaders::Phong :
@code
@code{.cpp}
Matrix4 transformationMatrix, projectionMatrix; Matrix4 transformationMatrix, projectionMatrix;
Texture2D diffuseTexture, specularTexture; Texture2D diffuseTexture, specularTexture;
@ -104,19 +104,22 @@ for *generic* shader and then render it with any compatible shader. Definition
of generic attributes is available in @ref Shaders::Generic class. of generic attributes is available in @ref Shaders::Generic class.
Configuration of the above mesh using generic attributes could then look like Configuration of the above mesh using generic attributes could then look like
this: this:
@code
@code{.cpp}
mesh.addVertexBuffer(vertices, 0, mesh.addVertexBuffer(vertices, 0,
Shaders::Generic3D::Position{}, Shaders::Generic3D::Position{},
Shaders::Generic3D::Normal{}, Shaders::Generic3D::Normal{},
Shaders::Generic3D::TextureCoordinates{}); Shaders::Generic3D::TextureCoordinates{});
@endcode @endcode
Note that in this particular case both configurations are equivalent, because Note that in this particular case both configurations are equivalent, because
@ref Shaders::Phong also uses generic vertex attribute definitions. @ref Shaders::Phong also uses generic vertex attribute definitions.
Then you can render the mesh using @ref Shaders::Phong shader like above, or Then you can render the mesh using @ref Shaders::Phong shader like above, or
use for example @ref Shaders::Flat3D or even @ref Shaders::MeshVisualizer with use for example @ref Shaders::Flat3D or even @ref Shaders::MeshVisualizer with
the same mesh reconfiguration. The unused attributes will be simply ignored. the same mesh reconfiguration. The unused attributes will be simply ignored.
@code
@code{.cpp}
Shaders::MeshVisualizer visualizerShader{Shaders::MeshVisualizer::Wireframe}; Shaders::MeshVisualizer visualizerShader{Shaders::MeshVisualizer::Wireframe};
visualizerShader.setColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) visualizerShader.setColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f))
.setWireframeColor(Color3{0.95f}) .setWireframeColor(Color3{0.95f})
@ -128,9 +131,5 @@ mesh.draw(visualizerShader);
The @ref MeshTools::compile() utility configures meshes using generic vertex The @ref MeshTools::compile() utility configures meshes using generic vertex
attribute definitions to make them usable with any shader. attribute definitions to make them usable with any shader.
- Previous page: @ref opengl-wrapping
- Next page: @ref scenegraph
*/ */
} }

75
doc/shapes.dox

@ -27,16 +27,14 @@ namespace Magnum {
/** @page shapes Collision detection /** @page shapes Collision detection
@brief Collection of simple shapes for high performance collision detection. @brief Collection of simple shapes for high performance collision detection.
- Previous page: @ref scenegraph @tableofcontents
- Next page: @ref debug-tools @m_footernavigation
The essential thing in collision detection is to define a complex object with The essential thing in collision detection is to define a complex object with
collection of simple shapes, for which it is easy to detect collisions. The collection of simple shapes, for which it is easy to detect collisions. The
library is contained in @ref Shapes namespace, see its documentation for more library is contained in @ref Shapes namespace, see its documentation for more
information about building and usage with CMake. information about building and usage with CMake.
@tableofcontents
These shapes can be either one-, two- or three-dimensional and they can be These shapes can be either one-, two- or three-dimensional and they can be
grouped together using various operations. grouped together using various operations.
@ -44,31 +42,31 @@ grouped together using various operations.
Magnum provides a set of simple shapes for collision detection, similarly to Magnum provides a set of simple shapes for collision detection, similarly to
what is found in many other collision detection libraries. Additionally some what is found in many other collision detection libraries. Additionally some
shapes are provided in inverted form -- e.g. inverted box detects collisions on shapes are provided in inverted form --- e.g. inverted box detects collisions on
outside instead of inside, which might be useful for example to create bounds outside instead of inside, which might be useful for example to create bounds
around platformer game level. around platformer game level.
@subsection shapes-1D One-dimensional shapes @subsection shapes-1D One-dimensional shapes
- @ref Shapes::Point "Shapes::Point*D" -- @copybrief Shapes::Point - @ref Shapes::Point "Shapes::Point*D" --- @copybrief Shapes::Point
- @ref Shapes::Line "Shapes::Line*D" -- @copybrief Shapes::Line - @ref Shapes::Line "Shapes::Line*D" --- @copybrief Shapes::Line
- @ref Shapes::LineSegment "Shapes::LineSegment*D" -- @copybrief Shapes::LineSegment - @ref Shapes::LineSegment "Shapes::LineSegment*D" --- @copybrief Shapes::LineSegment
Because of numerical instability it's not possible to detect collisions of Because of numerical instability it's not possible to detect collisions of
line and point. Collision of two lines can be detected only in 2D. line and point. Collision of two lines can be detected only in 2D.
@subsection shapes-2D Two-dimensional shapes @subsection shapes-2D Two-dimensional shapes
- Shapes::Plane -- @copybrief Shapes::Plane - @ref Shapes::Plane --- @copybrief Shapes::Plane
@subsection shapes-3D Three-dimensional shapes @subsection shapes-3D Three-dimensional shapes
- @ref Shapes::Sphere "Shapes::Sphere*D" -- @copybrief Shapes::Sphere - @ref Shapes::Sphere "Shapes::Sphere*D" --- @copybrief Shapes::Sphere
- @ref Shapes::InvertedSphere "Shapes::InvertedSphere*D" -- @copybrief Shapes::InvertedSphere - @ref Shapes::InvertedSphere "Shapes::InvertedSphere*D" --- @copybrief Shapes::InvertedSphere
- @ref Shapes::Cylinder "Shapes::Cylinder*D" -- @copybrief Shapes::Cylinder - @ref Shapes::Cylinder "Shapes::Cylinder*D" --- @copybrief Shapes::Cylinder
- @ref Shapes::Capsule "Shapes::Capsule*D" -- @copybrief Shapes::Capsule - @ref Shapes::Capsule "Shapes::Capsule*D" --- @copybrief Shapes::Capsule
- @ref Shapes::AxisAlignedBox "Shapes::AxisAlignedBox*D" -- @copybrief Shapes::AxisAlignedBox - @ref Shapes::AxisAlignedBox "Shapes::AxisAlignedBox*D" --- @copybrief Shapes::AxisAlignedBox
- @ref Shapes::Box "Shapes::Box*D" -- @copybrief Shapes::Box - @ref Shapes::Box "Shapes::Box*D" --- @copybrief Shapes::Box
The easiest (and most efficient) shape combination for detecting collisions The easiest (and most efficient) shape combination for detecting collisions
is point and sphere, followed by two spheres. Computing collision of two boxes is point and sphere, followed by two spheres. Computing collision of two boxes
@ -77,17 +75,18 @@ is least efficient.
@section shapes-composition Creating shape compositions @section shapes-composition Creating shape compositions
Shapes can be composed together using one of three available logical Shapes can be composed together using one of three available logical
operations: AND, OR and NOT. These operations are mapped to `&&`, `||` and `!` operations: AND, OR and NOT. These operations are mapped to @cpp && @ce, @cpp || @ce
operators, so for example creating negation of logical OR of line segment and and @cpp ! @ce operators, so for example creating negation of logical OR of
point is simple as this: line segment and point is simple as this:
@code
@code{.cpp}
Shapes::LineSegment3D segment; Shapes::LineSegment3D segment;
Shapes::Point3D point; Shapes::Point3D point;
Shapes::Composition3D composition = !(segment || point); Shapes::Composition3D composition = !(segment || point);
@endcode @endcode
@note Logical operations are not the same as set operations -- intersection of @note Logical operations are not the same as set operations --- intersection of
two spheres will not generate any collision if they are disjoint, but two spheres will not generate any collision if they are disjoint, but
logical AND will if the object collides with both of them. logical AND will if the object collides with both of them.
@ -98,9 +97,10 @@ collision detection, because it might be testing collision with more shapes
than necessary. It's then good to specify simplified version of such shape, than necessary. It's then good to specify simplified version of such shape,
so the collision detection is done on the complex one if and only if collision so the collision detection is done on the complex one if and only if collision
was detected with the simplified shape. It is in fact logical AND using the was detected with the simplified shape. It is in fact logical AND using the
`&&` operator -- the collision is initially detected on first (simplified) @cpp && @ce operator --- the collision is initially detected on first
shape and then on the other: (simplified) shape and then on the other:
@code
@code{.cpp}
Shapes::Sphere3D sphere; Shapes::Sphere3D sphere;
Shapes::Box3D box; Shapes::Box3D box;
Shapes::AxisAlignedBox3D simplified; Shapes::AxisAlignedBox3D simplified;
@ -111,9 +111,10 @@ Shapes::Composition3D composition = simplified && (sphere || box);
@section shapes-collisions Detecting shape collisions @section shapes-collisions Detecting shape collisions
Shape pairs which have collision occurence detection implemented can be tested Shape pairs which have collision occurence detection implemented can be tested
for collision using the `%` operator. The operator returns boolean describing for collision using the @cpp % @ce operator. The operator returns boolean
whether the collision happened or not. Example: describing whether the collision happened or not. Example:
@code
@code{.cpp}
Shapes::Point3D point; Shapes::Point3D point;
Shapes::Sphere3D sphere; Shapes::Sphere3D sphere;
@ -127,7 +128,8 @@ detailed collision detection you can use the `/` operator, which returns
@ref Shapes::Collision object. Note that unlike with the `%` operator mentioned @ref Shapes::Collision object. Note that unlike with the `%` operator mentioned
above, this operation is not commutative. See @ref Shapes::Collision class above, this operation is not commutative. See @ref Shapes::Collision class
documentation for more information about the returned data. Example: documentation for more information about the returned data. Example:
@code
@code{.cpp}
const Shapes::Collision3D c = point/sphere; const Shapes::Collision3D c = point/sphere;
if(c) { if(c) {
Vector3 translation = c.separationNormal()*c.separationDistance(); Vector3 translation = c.separationNormal()*c.separationDistance();
@ -140,13 +142,14 @@ if(c) {
Shape can be attached to object in the scene using @ref Shapes::Shape feature. Shape can be attached to object in the scene using @ref Shapes::Shape feature.
In conjunction with @ref Shapes::ShapeGroup you can use In conjunction with @ref Shapes::ShapeGroup you can use
@ref Shapes::Shape::collides() and @ref Shapes::Shape::collision() similarly to @ref Shapes::Shape::collides() and @ref Shapes::Shape::collision() similarly to
the `%` and `/` operators above. Please note that the shape group caches the the @cpp % @ce and @cpp / @ce operators above. Please note that the shape group
absolute transformations of all shapes and thus you need to explicitly call caches the absolute transformations of all shapes and thus you need to
@ref Shapes::ShapeGroup::setClean() before computing the collisions if you did explicitly call @ref Shapes::ShapeGroup::setClean() before computing the
any modifications to the objects in the scene. collisions if you did any modifications to the objects in the scene.
Scenegraph-flavored equivalent to the above code: Scenegraph-flavored equivalent to the above code:
@code
@code{.cpp}
Shapes::ShapeGroup3D shapes; Shapes::ShapeGroup3D shapes;
Object3D& a; Object3D& a;
auto aShape = new Shapes::Shape<Shapes::Sphere3D>(a, {{}, 23.0f}, &shapes); auto aShape = new Shapes::Shape<Shapes::Sphere3D>(a, {{}, 23.0f}, &shapes);
@ -163,14 +166,10 @@ if(aShape->collides(*bShape)) {
@endcode @endcode
There is also @ref Shapes::ShapeGroup::firstCollision() function which returns There is also @ref Shapes::ShapeGroup::firstCollision() function which returns
arbitrary first collision for given shape in whole group (or `nullptr`, if arbitrary first collision for given shape in whole group (or @cpp nullptr @ce,
there isn't any collision). if there isn't any collision).
You can also use @ref DebugTools::ShapeRenderer to visualize the shapes for You can also use @ref DebugTools::ShapeRenderer to visualize the shapes for
debugging purposes. See also @ref scenegraph for introduction. debugging purposes. See also @ref scenegraph for introduction.
- Previous page: @ref scenegraph
- Next page: @ref debug-tools
*/ */
} }

10
doc/tips.dox

@ -27,11 +27,11 @@ namespace Magnum {
/** @page tips Tips and tricks /** @page tips Tips and tricks
@brief Hints for better productivity and performance. @brief Hints for better productivity and performance.
- @subpage method-chaining -- @copybrief method-chaining - @subpage method-chaining --- @copybrief method-chaining
- @subpage portability -- @copybrief portability - @subpage portability --- @copybrief portability
- @subpage best-practices -- @copybrief best-practices - @subpage best-practices --- @copybrief best-practices
- @subpage compilation-speedup -- @copybrief compilation-speedup - @subpage compilation-speedup --- @copybrief compilation-speedup
- @subpage troubleshooting -- @copybrief troubleshooting - @subpage troubleshooting --- @copybrief troubleshooting
*/ */
} }

73
doc/transformations.dox

@ -27,16 +27,14 @@ namespace Magnum {
/** @page transformations 2D and 3D transformations /** @page transformations 2D and 3D transformations
@brief Introduction to essential operations on vectors and points. @brief Introduction to essential operations on vectors and points.
- Previous page: @ref matrix-vector @tableofcontents
- Next page: @ref plugins @m_footernavigation
Transformations are essential operations involved in scene management -- object Transformations are essential operations involved in scene management --- object
relations, hierarchies, animations etc. They extend basic vectors and matrices relations, hierarchies, animations etc. They extend basic vectors and matrices
in @ref Math namespace, see its documentation for more information about usage in @ref Math namespace, see its documentation for more information about usage
with CMake. with CMake.
@tableofcontents
Magnum provides classes for transformations in both 2D and 3D. Each class is Magnum provides classes for transformations in both 2D and 3D. Each class is
suited for different purposes, but their usage is nearly the same to make your suited for different purposes, but their usage is nearly the same to make your
life simpler. This page will explain the basic operation and differences life simpler. This page will explain the basic operation and differences
@ -47,7 +45,7 @@ between various representations.
The first and most straightforward way to represent transformations is to use The first and most straightforward way to represent transformations is to use
homogeneous transformation matrix, i.e. @ref Matrix3 for 2D and @ref Matrix4 homogeneous transformation matrix, i.e. @ref Matrix3 for 2D and @ref Matrix4
for 3D. The matrices are able to represent all possible types of for 3D. The matrices are able to represent all possible types of
transformations -- rotation, translation, scaling, reflection etc. and also transformations --- rotation, translation, scaling, reflection etc. and also
projective transformation, thus they are used at the very core of graphics projective transformation, thus they are used at the very core of graphics
pipeline and are supported natively in OpenGL. pipeline and are supported natively in OpenGL.
@ -56,12 +54,12 @@ transformation, which has implications on both memory usage and performance
(relatively slow matrix multiplication). It is also relatively hard to extract (relatively slow matrix multiplication). It is also relatively hard to extract
transformation properties (such as rotation angle/axis) from them, interpolate transformation properties (such as rotation angle/axis) from them, interpolate
between them or compute inverse transformation. They suffer badly from between them or compute inverse transformation. They suffer badly from
so-called floating-point drift -- e.g. after a few combined rotations the so-called floating-point drift --- e.g. after a few combined rotations the
transformation won't be pure rotation anymore, but will involve also a bit of transformation won't be pure rotation anymore, but will involve also a bit of
scaling, shearing and whatnot. scaling, shearing and whatnot.
However, you can trade some transformation features for improved performance However, you can trade some transformation features for improved performance
and better behavior -- for just a rotation you can use @ref Complex in 2D and and better behavior --- for just a rotation you can use @ref Complex in 2D and
@ref Quaternion in 3D, or @ref DualComplex and @ref DualQuaternion if you want @ref Quaternion in 3D, or @ref DualComplex and @ref DualQuaternion if you want
also translation. It is not possible to represent scaling, reflection or other also translation. It is not possible to represent scaling, reflection or other
transformations with them, but they occupy only 2 or 4 floats (4 or 8 floats in transformations with them, but they occupy only 2 or 4 floats (4 or 8 floats in
@ -88,7 +86,8 @@ you don't need to worry about them in initialization.
2D rotation is represented solely by its angle in counterclockwise direction 2D rotation is represented solely by its angle in counterclockwise direction
and rotation transformation can be created by calling @ref Matrix3::rotation(), and rotation transformation can be created by calling @ref Matrix3::rotation(),
@ref Complex::rotation() or @ref DualComplex::rotation(), for example: @ref Complex::rotation() or @ref DualComplex::rotation(), for example:
@code
@code{.cpp}
auto a = Matrix3::rotation(23.0_degf); auto a = Matrix3::rotation(23.0_degf);
auto b = Complex::rotation(Rad(Constants::piHalf())); auto b = Complex::rotation(Rad(Constants::piHalf()));
auto c = DualComplex::rotation(-1.57_radf); auto c = DualComplex::rotation(-1.57_radf);
@ -102,7 +101,8 @@ avoid redundant normalization. Shortcuts @ref Vector3::xAxis(),
Matrix representation has also @ref Matrix4::rotationX(), Matrix representation has also @ref Matrix4::rotationX(),
@ref Matrix4::rotationY() and @ref Matrix4::rotationZ() which are faster than @ref Matrix4::rotationY() and @ref Matrix4::rotationZ() which are faster than
using the generic function for rotation around primary axes. Examples: using the generic function for rotation around primary axes. Examples:
@code
@code{.cpp}
auto a = Quaternion::rotation(60.0_degf, Vector3::xAxis()); auto a = Quaternion::rotation(60.0_degf, Vector3::xAxis());
auto b = DualQuaternion::rotation(-1.0_degf, Vector3(1.0f, 0.5f, 3.0f).normalized()); auto b = DualQuaternion::rotation(-1.0_degf, Vector3(1.0f, 0.5f, 3.0f).normalized());
auto c = Matrix4::rotationZ(angle); auto c = Matrix4::rotationZ(angle);
@ -119,7 +119,8 @@ then translating back. Read below for more information.
@ref Matrix3::translation() or @ref DualComplex::translation(). You can use @ref Matrix3::translation() or @ref DualComplex::translation(). You can use
@ref Vector2::xAxis() or @ref Vector2::yAxis() to translate only along given @ref Vector2::xAxis() or @ref Vector2::yAxis() to translate only along given
axis. Examples: axis. Examples:
@code
@code{.cpp}
auto a = Matrix3::translation(Vector2::xAxis(-5.0f)); auto a = Matrix3::translation(Vector2::xAxis(-5.0f));
auto b = DualComplex::translation({-1.0f, 0.5f}); auto b = DualComplex::translation({-1.0f, 0.5f});
@endcode @endcode
@ -127,7 +128,8 @@ auto b = DualComplex::translation({-1.0f, 0.5f});
3D translation is defined by three-dimensional vector and can be created with 3D translation is defined by three-dimensional vector and can be created with
@ref Matrix4::translation() or @ref DualQuaternion::translation(). You can use @ref Matrix4::translation() or @ref DualQuaternion::translation(). You can use
@ref Vector3::xAxis() and friends also here. Examples: @ref Vector3::xAxis() and friends also here. Examples:
@code
@code{.cpp}
auto a = Matrix4::translation(vector); auto a = Matrix4::translation(vector);
auto b = DualQuaternion::translation(Vector3::zAxis(1.3f)); auto b = DualQuaternion::translation(Vector3::zAxis(1.3f));
@endcode @endcode
@ -140,7 +142,8 @@ You can use @ref Vector3::xScale(), @ref Vector3::yScale(), @ref Vector3::zScale
or their 2D counterparts to scale along one axis and leave the rest unchanged or their 2D counterparts to scale along one axis and leave the rest unchanged
or call explicit one-parameter vector constructor to scale uniformly on all or call explicit one-parameter vector constructor to scale uniformly on all
axes. Examples: axes. Examples:
@code
@code{.cpp}
auto a = Matrix3::scaling(Vector2::xScale(2.0f)); auto a = Matrix3::scaling(Vector2::xScale(2.0f));
auto b = Matrix4::scaling({2.0f, -2.0f, 1.5f}); auto b = Matrix4::scaling({2.0f, -2.0f, 1.5f});
auto c = Matrix4::scaling(Vector3(10.0f)); auto c = Matrix4::scaling(Vector3(10.0f));
@ -151,7 +154,8 @@ three-dimensional vector of unit length) and they are also represented by
matrices. Reflection is created with @ref Matrix3::reflection() or matrices. Reflection is created with @ref Matrix3::reflection() or
@ref Matrix4::reflection(). You can use @ref Vector3::xAxis() and friends also @ref Matrix4::reflection(). You can use @ref Vector3::xAxis() and friends also
here. Examples: here. Examples:
@code
@code{.cpp}
auto a = Matrix3::reflection(Vector2::yAxis()); auto a = Matrix3::reflection(Vector2::yAxis());
auto b = Matrix4::reflection(axis.normalized()); auto b = Matrix4::reflection(axis.normalized());
@endcode @endcode
@ -174,7 +178,8 @@ unit cube, and perspective projection. Perspective projection is created with
@ref Matrix4::perspectiveProjection() and is defined either by field-of-view, @ref Matrix4::perspectiveProjection() and is defined either by field-of-view,
aspect ratio and distance to near and far plane of view frustum or by size of aspect ratio and distance to near and far plane of view frustum or by size of
near plane, its distance and distance to far plane. Some examples: near plane, its distance and distance to far plane. Some examples:
@code
@code{.cpp}
auto a = Matrix3::projection({4.0f, 3.0f}); auto a = Matrix3::projection({4.0f, 3.0f});
auto b = Matrix4::orthographicProjection({4.0f, 3.0f, 100.0f}); auto b = Matrix4::orthographicProjection({4.0f, 3.0f, 100.0f});
auto c = Matrix4::perspectiveProjection(35.0_degf, 1.333f, 0.001f, 100.0f); auto c = Matrix4::perspectiveProjection(35.0_degf, 1.333f, 0.001f, 100.0f);
@ -184,11 +189,12 @@ auto c = Matrix4::perspectiveProjection(35.0_degf, 1.333f, 0.001f, 100.0f);
Transformations (of the same representation) can be composed simply by Transformations (of the same representation) can be composed simply by
multiplying them, it works the same for matrices, complex numbers, quaternions multiplying them, it works the same for matrices, complex numbers, quaternions
and their dual counterparts. Order of multiplication matters -- the and their dual counterparts. Order of multiplication matters --- the
transformation on the right-hand side of multiplication is applied first, the transformation on the right-hand side of multiplication is applied first, the
transformation on the left-hand side is applied second. For example, rotation transformation on the left-hand side is applied second. For example, rotation
followed by translation is done like this: followed by translation is done like this:
@code
@code{.cpp}
auto a = DualComplex::translation(Vector2::yAxis(2.0f))* auto a = DualComplex::translation(Vector2::yAxis(2.0f))*
DualComplex::rotation(25.0_degf); DualComplex::rotation(25.0_degf);
auto b = Matrix4::translation(Vector3::yAxis(5.0f))* auto b = Matrix4::translation(Vector3::yAxis(5.0f))*
@ -214,7 +220,8 @@ Vector transformation does not involve translation, in 2D can be done using
using @ref Matrix4::transformVector() and @ref Quaternion::transformVector(). using @ref Matrix4::transformVector() and @ref Quaternion::transformVector().
For transformation with normalized quaternion you can use faster alternative For transformation with normalized quaternion you can use faster alternative
@ref Quaternion::transformVectorNormalized(). Example: @ref Quaternion::transformVectorNormalized(). Example:
@code
@code{.cpp}
auto transformation = Matrix3::rotation(-30.0_degf)*Matrix3::scaling(Vector2(3.0f)); auto transformation = Matrix3::rotation(-30.0_degf)*Matrix3::scaling(Vector2(3.0f));
Vector2 transformed = transformation.transformVector({1.5f, -7.9f}); Vector2 transformed = transformation.transformVector({1.5f, -7.9f});
@endcode @endcode
@ -223,7 +230,8 @@ Point transformation involves also translation, in 2D is done with
@ref Matrix3::transformPoint() and @ref DualComplex::transformPoint(), in 3D @ref Matrix3::transformPoint() and @ref DualComplex::transformPoint(), in 3D
with @ref Matrix4::transformPoint() and @ref DualQuaternion::transformPoint(). with @ref Matrix4::transformPoint() and @ref DualQuaternion::transformPoint().
Also here you can use faster alternative @ref DualQuaternion::transformPointNormalized(): Also here you can use faster alternative @ref DualQuaternion::transformPointNormalized():
@code
@code{.cpp}
auto transformation = DualQuaternion::rotation(-30.0_degf, Vector3::xAxis())* auto transformation = DualQuaternion::rotation(-30.0_degf, Vector3::xAxis())*
DualQuaternion::translation(Vector3::yAxis(3.0f)); DualQuaternion::translation(Vector3::yAxis(3.0f));
Vector3 transformed = transformation.transformPointNormalized({1.5f, 3.0f, -7.9f}); Vector3 transformed = transformation.transformPointNormalized({1.5f, 3.0f, -7.9f});
@ -234,7 +242,8 @@ Vector3 transformed = transformation.transformPointNormalized({1.5f, 3.0f, -7.9f
It is possible to extract some transformation properties from transformation It is possible to extract some transformation properties from transformation
matrices, particularly translation vector, rotation/scaling part of the matrix matrices, particularly translation vector, rotation/scaling part of the matrix
(or pure rotation if the matrix has uniform scaling) and also base vectors: (or pure rotation if the matrix has uniform scaling) and also base vectors:
@code
@code{.cpp}
Matrix4 a; Matrix4 a;
auto rotationScaling = transformation.rotationScaling(); auto rotationScaling = transformation.rotationScaling();
Vector3 up = transformation.up(); Vector3 up = transformation.up();
@ -244,6 +253,7 @@ Matrix3 b;
auto rotation = b.rotation(); auto rotation = b.rotation();
Float xTranslation = b.translation().x(); Float xTranslation = b.translation().x();
@endcode @endcode
Extracting scaling and rotation from arbitrary transformation matrices is Extracting scaling and rotation from arbitrary transformation matrices is
harder and can be done using @ref Math::Algorithms::svd(). Extracting rotation harder and can be done using @ref Math::Algorithms::svd(). Extracting rotation
angle (and axis in 3D) from rotation part is possible using by converting it to angle (and axis in 3D) from rotation part is possible using by converting it to
@ -251,7 +261,8 @@ complex number or quaternion, see below.
You can also recreate transformation matrix from rotation and translation You can also recreate transformation matrix from rotation and translation
parts: parts:
@code
@code{.cpp}
Matrix3 c = Matrix3::from(rotation, {1.0f, 3.0f}); Matrix3 c = Matrix3::from(rotation, {1.0f, 3.0f});
@endcode @endcode
@ -261,7 +272,8 @@ you to extract rotation angle using @ref Complex::angle() or
Their dual versions allow to extract both rotation and translation part using Their dual versions allow to extract both rotation and translation part using
@ref DualComplex::rotation() const, @ref DualQuaternion::rotation() const, @ref DualComplex::rotation() const, @ref DualQuaternion::rotation() const,
@ref DualComplex::translation() const and @ref DualQuaternion::translation() const. @ref DualComplex::translation() const and @ref DualQuaternion::translation() const.
@code
@code{.cpp}
DualComplex a; DualComplex a;
Rad rotationAngle = a.rotation().angle(); Rad rotationAngle = a.rotation().angle();
Vector2 translation = a.translation(); Vector2 translation = a.translation();
@ -274,7 +286,8 @@ You can convert Complex and Quaternion to rotation matrix using
@ref Complex::toMatrix() and @ref Quaternion::toMatrix() or their dual version @ref Complex::toMatrix() and @ref Quaternion::toMatrix() or their dual version
to rotation and translation matrix using @ref DualComplex::toMatrix() and to rotation and translation matrix using @ref DualComplex::toMatrix() and
@ref DualQuaternion::toMatrix(): @ref DualQuaternion::toMatrix():
@code
@code{.cpp}
Quaternion a; Quaternion a;
auto rotation = Matrix4::from(a.toMatrix(), {}); auto rotation = Matrix4::from(a.toMatrix(), {});
@ -286,7 +299,8 @@ Conversion the other way around is possible only from rotation matrices using
@ref Complex::fromMatrix() or @ref Quaternion::fromMatrix() and from rotation @ref Complex::fromMatrix() or @ref Quaternion::fromMatrix() and from rotation
and translation matrices using @ref DualComplex::fromMatrix() and and translation matrices using @ref DualComplex::fromMatrix() and
@ref DualQuaternion::fromMatrix(): @ref DualQuaternion::fromMatrix():
@code
@code{.cpp}
Matrix3 rotation; Matrix3 rotation;
auto a = Complex::fromMatrix(rotation.rotationScaling()); auto a = Complex::fromMatrix(rotation.rotationScaling());
@ -301,7 +315,7 @@ auto b = DualQuaternion::fromMatrix(transformation);
@section transformations-normalization Normalizing transformations @section transformations-normalization Normalizing transformations
When doing multiplicative transformations, e.g. adding rotating to an When doing multiplicative transformations, e.g. adding rotating to a
transformation many times during an animation, the resulting transformation will transformation many times during an animation, the resulting transformation will
accumulate rounding errors and behave strangely. For transformation matrices accumulate rounding errors and behave strangely. For transformation matrices
this can't always be fixed, because they can represent any transformation (and this can't always be fixed, because they can represent any transformation (and
@ -311,7 +325,8 @@ can be reorthogonalized using @ref Math::Algorithms::gramSchmidtOrthogonalize()
(or @ref Math::Algorithms::gramSchmidtOrthonormalize(), if you don't have any (or @ref Math::Algorithms::gramSchmidtOrthonormalize(), if you don't have any
scaling). You can also use @ref Math::Algorithms::svd() to more precisely (but scaling). You can also use @ref Math::Algorithms::svd() to more precisely (but
way more slowly) account for the drift. Example: way more slowly) account for the drift. Example:
@code
@code{.cpp}
Matrix4 transformation; Matrix4 transformation;
Math::Algorithms::gramSchmidtOrthonormalizeInPlace(transformation); Math::Algorithms::gramSchmidtOrthonormalizeInPlace(transformation);
@endcode @endcode
@ -321,12 +336,10 @@ using @ref Complex::normalized(), @ref Quaternion::normalized(),
@ref DualComplex::normalized() and @ref DualQuaternion::normalized(). @ref DualComplex::normalized() and @ref DualQuaternion::normalized().
Transformation quaternions and complex numbers are always of unit length, thus Transformation quaternions and complex numbers are always of unit length, thus
normalizing them reduces the drift. normalizing them reduces the drift.
@code
@code{.cpp}
DualQuaternion transformation; DualQuaternion transformation;
transformation = transformation.normalized(); transformation = transformation.normalized();
@endcode @endcode
- Previous page: @ref matrix-vector
- Next page: @ref plugins
*/ */
} }

8
doc/troubleshooting.dox

@ -25,9 +25,10 @@
namespace Magnum { namespace Magnum {
/** @page troubleshooting Troubleshooting /** @page troubleshooting Troubleshooting
@brief Various tricks to overcome common building and rendering issues. @brief Various tricks to overcome common building and rendering issues.
@m_footernavigation
@section troubleshooting-building Building issues @section troubleshooting-building Building issues
If your project suddenly stops building after Magnum upgrade, check these If your project suddenly stops building after Magnum upgrade, check these
@ -64,7 +65,7 @@ crashes on GL calls, you might want to try these things:
- If nothing is drawn, use @ref PrimitiveQuery to check that at least some - If nothing is drawn, use @ref PrimitiveQuery to check that at least some
primitives were generated. Use @ref SampleQuery to check whether fragments primitives were generated. Use @ref SampleQuery to check whether fragments
were drawn. were drawn.
- Verify that the mesh is properly set up -- nonzero vertex/index count, - Verify that the mesh is properly set up --- nonzero vertex/index count,
matching type in buffer and @ref Mesh::addVertexBuffer() "vertex specification", matching type in buffer and @ref Mesh::addVertexBuffer() "vertex specification",
properly set up @ref Mesh::setIndexBuffer() "index buffer" and index count properly set up @ref Mesh::setIndexBuffer() "index buffer" and index count
for indexed mesh. If you specified index range, be sure that all indices for indexed mesh. If you specified index range, be sure that all indices
@ -72,7 +73,7 @@ crashes on GL calls, you might want to try these things:
- Try disabling @ref Renderer::Feature::DepthTest "depth test", - Try disabling @ref Renderer::Feature::DepthTest "depth test",
@ref Renderer::Feature::FaceCulling "face culling" and other renderer @ref Renderer::Feature::FaceCulling "face culling" and other renderer
features that might affect the fragments. features that might affect the fragments.
- Verify that your projection and transformation matrix is properly set up -- - Verify that your projection and transformation matrix is properly set up ---
try drawing points instead of triangles, to see if they are at least at try drawing points instead of triangles, to see if they are at least at
proper places. proper places.
- @ref AbstractShaderProgram::validate() "Validate the shader", check that - @ref AbstractShaderProgram::validate() "Validate the shader", check that
@ -96,6 +97,5 @@ crashes on GL calls, you might want to try these things:
- Use ApiTrace to trace the program call by call, verify buffer and texture - Use ApiTrace to trace the program call by call, verify buffer and texture
contents, vertex binding and count of generated primitives, rendered contents, vertex binding and count of generated primitives, rendered
fragments and time spent in various calls. fragments and time spent in various calls.
*/ */
} }

107
doc/types.dox

@ -27,38 +27,36 @@ namespace Magnum {
/** @page types Type system /** @page types Type system
@brief Type aliases, naming and compatibility with OpenGL and GLSL types. @brief Type aliases, naming and compatibility with OpenGL and GLSL types.
- Previous page: @ref platform @tableofcontents
- Next page: @ref matrix-vector @m_footernavigation
The root @ref Magnum namespace defines a few aliases for essential types. See The root @ref Magnum namespace defines a few aliases for essential types. See
its documentation for more information about usage with CMake. its documentation for more information about usage with CMake.
@tableofcontents
@section types-builtin Builtin types @section types-builtin Builtin types
Magnum provides typedefs for builtin integral and floating-point arithmetic Magnum provides typedefs for builtin integral and floating-point arithmetic
types to ensure portability (e.g. @ref Int is *always* 32bit), maintain types to ensure portability (e.g. @ref Int is *always* 32bit), maintain
consistency and reduce confusion (e.g. `std::int32_t`, `int` and `GLint` all consistency and reduce confusion (e.g. @ref std::int32_t, @cpp int @ce and
refer to the same type). @cpp GLint @ce all refer to the same type).
| Magnum type | Size | Equivalent GLSL type | | Magnum type | Size | Equivalent GLSL type |
| ------------------ | -------------- | -------------------- | | ------------------ | -------------- | ----------------------- |
| @ref UnsignedByte | 8bit unsigned | | | @ref UnsignedByte | 8bit unsigned | |
| @ref Byte | 8bit signed | | | @ref Byte | 8bit signed | |
| @ref UnsignedShort | 16bit unsigned | | | @ref UnsignedShort | 16bit unsigned | |
| @ref Short | 16bit signed | | | @ref Short | 16bit signed | |
| @ref UnsignedInt | 32bit unsigned | `uint` | | @ref UnsignedInt | 32bit unsigned | @glsl uint @ce <b></b> |
| @ref Int | 32bit signed | `int` | | @ref Int | 32bit signed | @glsl int @ce <b></b> |
| @ref UnsignedLong | 64bit unsigned | | | @ref UnsignedLong | 64bit unsigned | |
| @ref Long | 64bit signed | | | @ref Long | 64bit signed | |
| @ref Half | 16bit | (*none*) | | @ref Half | 16bit | (*none*) |
| @ref Float | 32bit | `float` | | @ref Float | 32bit | @glsl float @ce <b></b> |
| @ref Double | 64bit | `double` | | @ref Double | 64bit | @glsl double @ce <b></b> |
Types not meant to be used in arithmetic (such as `bool` or `std::size_t`) or Types not meant to be used in arithmetic (such as @cpp bool @ce or
types which cannot be directly passed to GLSL shaders (such as `long double`) @cpp std::size_t @ce) or types which cannot be directly passed to GLSL shaders
have no typedefs. (such as @cpp long double @ce) have no typedefs.
Types from the above table are then used to define other types. All following Types from the above table are then used to define other types. All following
types are aliases of corresponding types in @ref Math namespace. No suffix types are aliases of corresponding types in @ref Math namespace. No suffix
@ -70,23 +68,23 @@ underlying type.
| Magnum vector type | Equivalent GLSL type | | Magnum vector type | Equivalent GLSL type |
| ---------------------------------------------- | ------------------------- | | ---------------------------------------------- | ------------------------- |
| @ref Vector2, @ref Vector3, @ref Color3 @ref Vector4, @ref Color4 | `vec2`, `vec3`, `vec4` | | @ref Vector2, @ref Vector3, @ref Color3 @ref Vector4, @ref Color4 | @glsl vec2 @ce, @glsl vec3 @ce, @glsl vec4 @ce |
| @ref Vector2ui, @ref Vector3ui, @ref Vector4ui | `uvec2`, `uvec3`, `uvec4` | | @ref Vector2ui, @ref Vector3ui, @ref Vector4ui | @glsl uvec2 @ce, @glsl uvec3 @ce, @glsl uvec4 @ce |
| @ref Vector2i, @ref Vector3i, @ref Vector4i | `ivec2`, `ivec3`, `ivec4` | | @ref Vector2i, @ref Vector3i, @ref Vector4i | @glsl ivec2 @ce, @glsl ivec3 @ce, @glsl ivec4 @ce |
| @ref Vector2d, @ref Vector3d, @ref Vector4d | `dvec2`, `dvec3`, `dvec4` | | @ref Vector2d, @ref Vector3d, @ref Vector4d | @glsl dvec2 @ce, @glsl dvec3 @ce, @glsl dvec4 @ce |
| @ref Color3ub, @ref Color4ub | (*none*) | | @ref Color3ub, @ref Color4ub | (*none*) |
| Magnum matrix type | Equivalent GLSL type | | Magnum matrix type | Equivalent GLSL type |
| ---------------------------------------------------------------- | ------------------------------------ | | ---------------------------------------------------------------- | ------------------------------------- |
| @ref Matrix2x2 or @ref Matrix2x2d | `mat2`/`mat2x2` or `dmat2`/`dmat2x2` | | @ref Matrix2x2 or @ref Matrix2x2d | @glsl mat2 @ce / @glsl mat2x2 @ce or @glsl dmat2 @ce / @glsl dmat2x2 @ce |
| @ref Matrix3 / @ref Matrix3x3 or @ref Matrix3d / @ref Matrix3x3d | `mat3`/`mat3x3` or `dmat3`/`dmat3x3` | | @ref Matrix3 / @ref Matrix3x3 or @ref Matrix3d / @ref Matrix3x3d | @glsl mat3 @ce / @glsl mat3x3 @ce or @glsl dmat3 @ce / @glsl dmat3x3 @ce |
| @ref Matrix4 / @ref Matrix4x4 or @ref Matrix4d / @ref Matrix4x4d | `mat4`/`mat4x4` or `dmat4`/`dmat4x4` | | @ref Matrix4 / @ref Matrix4x4 or @ref Matrix4d / @ref Matrix4x4d | @glsl mat4 @ce / @glsl mat4x4 @ce or @glsl dmat4 @ce / @glsl dmat4x4 @ce |
| @ref Matrix2x3 or @ref Matrix2x3d | `mat2x3` or `dmat2x3` | | @ref Matrix2x3 or @ref Matrix2x3d | @glsl mat2x3 @ce or @glsl dmat2x3 @ce |
| @ref Matrix3x2 or @ref Matrix3x2d | `mat3x2` or `dmat3x2` | | @ref Matrix3x2 or @ref Matrix3x2d | @glsl mat3x2 @ce or @glsl dmat3x2 @ce |
| @ref Matrix2x4 or @ref Matrix2x4d | `mat2x4` or `dmat2x4` | | @ref Matrix2x4 or @ref Matrix2x4d | @glsl mat2x4 @ce or @glsl dmat2x4 @ce |
| @ref Matrix4x2 or @ref Matrix4x2d | `mat4x2` or `dmat4x2` | | @ref Matrix4x2 or @ref Matrix4x2d | @glsl mat4x2 @ce or @glsl dmat4x2 @ce |
| @ref Matrix3x4 or @ref Matrix3x4d | `mat3x4` or `dmat3x4` | | @ref Matrix3x4 or @ref Matrix3x4d | @glsl mat3x4 @ce or @glsl dmat3x4 @ce |
| @ref Matrix4x3 or @ref Matrix4x3d | `mat4x3` or `dmat4x3` | | @ref Matrix4x3 or @ref Matrix4x3d | @glsl mat4x3 @ce or @glsl dmat4x3 @ce |
Any super- or sub-class of the same size and underlying type can be used Any super- or sub-class of the same size and underlying type can be used
equivalently (e.g. @ref Math::Vector "Math::Vector<Float>" or @ref Color3 equivalently (e.g. @ref Math::Vector "Math::Vector<Float>" or @ref Color3
@ -103,7 +101,8 @@ For easier entering of (s)RGB colors in hexadecimal format there are
@link Math::Literals::operator""_rgbaf() _rgbaf @endlink literals in @link Math::Literals::operator""_rgbaf() _rgbaf @endlink literals in
@ref Math::Literals namespace. See their documentation for more information @ref Math::Literals namespace. See their documentation for more information
about the differences. about the differences.
@code
@code{.cpp}
using namespace Math::Literals; using namespace Math::Literals;
Color3 a = 0x33b27f_srgbf; // {0.0331048f, 0.445201f, 0.212231f} Color3 a = 0x33b27f_srgbf; // {0.0331048f, 0.445201f, 0.212231f}
@ -115,8 +114,8 @@ Color4ub a = 0x33b27fcc_rgba; // {0x33, 0xb2, 0x7f, 0xcc}
Scalar types with GLSL equivalent are verified to be exactly the same as Scalar types with GLSL equivalent are verified to be exactly the same as
corresponding `GL*` types. Matrix and vector classes have the same binary corresponding `GL*` types. Matrix and vector classes have the same binary
representation as corresponding array of numeric values without any additional representation as corresponding array of numeric values without any additional
data or padding (e.g. `sizeof(Vector3i) == sizeof(Int[3])`), all matrices are data or padding (e.g. @cpp sizeof(Vector3i) == sizeof(Int[3]) @ce), all
stored in column-major order. matrices are stored in column-major order.
This means that all scalar, matrix and vector types can be used directly for This means that all scalar, matrix and vector types can be used directly for
filling GPU buffers and textures without any need for data extraction or filling GPU buffers and textures without any need for data extraction or
@ -131,7 +130,7 @@ the @ref Deg and @ref Rad classes (or @ref Degd and @ref Radd with @ref Double
as underlying type). Their only purpose is to avoid common degree-vs-radian as underlying type). Their only purpose is to avoid common degree-vs-radian
bugs (i.e. entering degree value where radians should be) and make the bugs (i.e. entering degree value where radians should be) and make the
conversion between these two representations easier. They are just a tiny conversion between these two representations easier. They are just a tiny
`inline` `constexpr` wrapper around the native type and they support all @cpp inline constexpr @ce wrapper around the native type and they support all
meaningful numeric operations, so using them won't have any performance or meaningful numeric operations, so using them won't have any performance or
usability impact in practice. usability impact in practice.
@ -141,7 +140,8 @@ or use custom @link Math::Literals::operator""_degf() _degf @endlink /
@link Math::Literals::operator""_deg() _deg @endlink and @link Math::Literals::operator""_radf() _radf @endlink @link Math::Literals::operator""_deg() _deg @endlink and @link Math::Literals::operator""_radf() _radf @endlink
/ @link Math::Literals::operator""_rad() _rad @endlink literals that are / @link Math::Literals::operator""_rad() _rad @endlink literals that are
provided in the @ref Math::Literals namespace: provided in the @ref Math::Literals namespace:
@code
@code{.cpp}
using namespace Math::Literals; using namespace Math::Literals;
//Deg a = 60.0f // error, no implicit conversion from Float //Deg a = 60.0f // error, no implicit conversion from Float
@ -158,7 +158,8 @@ auto c = Double{pi}; // okay
They can be implicitly converted to each other, but conversion to different They can be implicitly converted to each other, but conversion to different
underlying type is *explicit* to avoid precision loss (or, on the other hand, underlying type is *explicit* to avoid precision loss (or, on the other hand,
unnecessarily high precision) during computations: unnecessarily high precision) during computations:
@code
@code{.cpp}
Rad d = 60.0_degf; // 1.0471976f Rad d = 60.0_degf; // 1.0471976f
auto e = Degd{pi}; // 180.0 auto e = Degd{pi}; // 180.0
@ -167,10 +168,11 @@ auto f = Rad{pi}; // 3.141592654f
@endcode @endcode
These classes are used exclusively in all functions taking and returning angles These classes are used exclusively in all functions taking and returning angles
-- trigonometry, angle computation, rotating transformation etc. Thanks to --- trigonometry, angle computation, rotating transformation etc. Thanks to
implicit conversion you can seamlessly use either radians or degrees without implicit conversion you can seamlessly use either radians or degrees without
any need to care about what input the function expects: any need to care about what input the function expects:
@code
@code{.cpp}
Float a = Math::sin(1.32457_radf); Float a = Math::sin(1.32457_radf);
Complex b = Complex::rotation(60.0_degf); Complex b = Complex::rotation(60.0_degf);
@endcode @endcode
@ -182,7 +184,8 @@ half-float values easier. It provides either explicit constructors and
conversion operators from/to @ref Float and @ref UnsignedShort and you can also conversion operators from/to @ref Float and @ref UnsignedShort and you can also
use the @link Math::Literals::operator""_h() _h @endlink literal that is use the @link Math::Literals::operator""_h() _h @endlink literal that is
provided in the @ref Math::Literals namespace: provided in the @ref Math::Literals namespace:
@code
@code{.cpp}
using namespace Math::Literals; using namespace Math::Literals;
Half a = 3.5_h; // 0x4300 internally Half a = 3.5_h; // 0x4300 internally
@ -208,7 +211,7 @@ underlying structure or converting them to types supported by GLSL (e.g.
quaternion to matrix). quaternion to matrix).
For your convenience, there is also alias for class with often used constants For your convenience, there is also alias for class with often used constants
-- @ref Constants or @ref Constantsd. --- @ref Constants or @ref Constantsd.
@section types-initialization Initialization @section types-initialization Initialization
@ -225,7 +228,8 @@ explicit:
overwrite the contents anyway, works for all types). overwrite the contents anyway, works for all types).
Example: Example:
@code
@code{.cpp}
// These are equivalent // These are equivalent
Vector3 a1; Vector3 a1;
Vector3 a1{Math::ZeroInit}; Vector3 a1{Math::ZeroInit};
@ -241,8 +245,5 @@ if(orthographic)
else else
projection = Matrix4::perspectiveProjection(...); projection = Matrix4::perspectiveProjection(...);
@endcode @endcode
- Previous page: @ref platform
- Next page: @ref matrix-vector
*/ */
} }

10
doc/utilities.dox

@ -27,11 +27,11 @@ namespace Magnum {
/** @page utilities Utilities /** @page utilities Utilities
@brief Command-line utilities for system information and data conversion @brief Command-line utilities for system information and data conversion
- @subpage magnum-info -- @copybrief magnum-info - @subpage magnum-info --- @copybrief magnum-info
- @subpage magnum-al-info -- @copybrief magnum-al-info - @subpage magnum-al-info --- @copybrief magnum-al-info
- @subpage magnum-distancefieldconverter -- @copybrief magnum-distancefieldconverter - @subpage magnum-distancefieldconverter --- @copybrief magnum-distancefieldconverter
- @subpage magnum-fontconverter -- @copybrief magnum-fontconverter - @subpage magnum-fontconverter --- @copybrief magnum-fontconverter
- @subpage magnum-imageconverter -- @copybrief magnum-imageconverter - @subpage magnum-imageconverter --- @copybrief magnum-imageconverter
*/ */
} }

Loading…
Cancel
Save