diff --git a/README.md b/README.md index 3dd81f144..9f00b1bf3 100644 --- a/README.md +++ b/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 using recent C++11/C++14 features and to abstract away platform-specific issues. @@ -8,36 +8,35 @@ issues. DESIGN GOALS ============ -* **2D is not an ugly stepchild** - Many engines out there were created as pure 2D or 3D and the alternative is - usually just an afterthought, if it is present at all. If you want to do - your next project in 2D only, you have to either relearn another engine - from scratch or emulate it in 3D, leaving many things overly complicated. - Magnum treats 2D equivalently to 3D so you can reuse what you already - learned for 3D and even combine 2D and 3D in one project. - -* **Forward compatibility** - If newer technology makes things faster, simpler or more intuitive, it is - the way to go. Magnum by default relies on decent C++11 support and modern - OpenGL features and if some feature isn't available, it tries to emulate it - using older functionality. However, you are not restricted to use the older - functionality directly, if you really want to. - -* **Intuitive, but not restrictive API** - Scripting languages are often preferred to C/C++ because they are designed - to have less complicated APIs and less boilerplate code. Magnum is - designed with intuitivity in mind, but also with speed and static checks - that strongly-typed native code offers. It wraps OpenGL into less verbose - and more type-safe API, which is easier to use. Usually the most common way - is the most simple, but if you need full control, you can have it. - -* **Extensible and replaceable components** - If you want to use different mathematical library for specific purposes, - that new windowing toolkit, your own file formats or another physics - library, you can. Conversion of math structures between different libraries - can be done on top of pre-made skeleton classes, support for file formats - is done using plugins and platform support is done by writing simple - wrapper class. +* **2D is not an ugly stepchild.** Many engines out there were created as + pure 2D or 3D and the alternative is usually just an afterthought, if + present at all. If you want to do your next project in 2D only, you have to + either relearn another engine from scratch or emulate it in 3D, leaving + many things overly complicated. Magnum treats 2D equivalently to 3D so you + can reuse what you already learned for 3D and even combine 2D and 3D in one + project. + +* **Forward compatibility.** If newer technology makes things faster, simpler + or more intuitive, it is the way to go. Magnum by default relies on decent + C++11 support and modern OpenGL features and if some feature isn't + available, it tries to emulate it using older functionality. However, you + are not restricted to use the older functionality directly, if you really + want to. + +* **Intuitive, but not restrictive API.** Scripting languages are often + preferred to C/C++ because they are designed to have less complicated APIs + and less boilerplate code. Magnum is designed with intuitivity in mind, but + also with speed and static checks that strongly-typed native code offers. + It wraps OpenGL into less verbose and more type-safe API, which is easier + to use. Usually the most common way is the most simple, but if you need + full control, you can have it. + +* **Extensible and replaceable components.** If you want to use different + mathematical library for specific purposes, that new windowing toolkit, + your own file formats or another physics library, you can. Conversion of + math structures between different libraries can be done on top of pre-made + skeleton classes, support for file formats is done using plugins and + platform support is done by writing simple wrapper class. SUPPORTED PLATFORMS =================== @@ -54,10 +53,10 @@ Platforms: * **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) -* **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) * **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) * **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 ============ -You can either use packaging scripts, which are stored in `package/` -subdirectory, or compile and install everything manually. Note that -[Magnum documentation](http://doc.magnum.graphics/magnum/) contains more -comprehensive guide for building, packaging and crosscompiling. +You can either use packaging scripts, which are stored in the `package/` +subdirectory, or compile and install everything manually using the guide below. +Note that the [Magnum documentation](http://doc.magnum.graphics/magnum/) +contains more comprehensive guide for building, packaging and crosscompiling. Minimal dependencies -------------------- @@ -94,7 +93,7 @@ Minimal dependencies * **Corrade** - Plugin management and utility library. You can get it at 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 ------------------------- @@ -109,8 +108,9 @@ installed using these four commands: make make install -See Doxygen documentation for more information about enabling or disabling -additional features and targeting different platforms such as OpenGL ES. +See the [Doxygen documentation](http://doc.magnum.graphics/magnum/building.html) +for more information about enabling or disabling additional features and +targeting different platforms such as OpenGL ES. Building and running unit tests ------------------------------- @@ -126,10 +126,8 @@ in build directory. Everything should pass ;-) Building documentation ---------------------- -The documentation is written in **Doxygen** (version 1.8 with Markdown support -is used, but older versions should do good job too) and additionally uses -**Graphviz** for class diagrams and **TeX** for math formulas. The -documentation can be build by running: +The documentation is written in **Doxygen** and additionally uses **TeX** for +math formulas. The documentation can be build by running: 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 separate repositories. -* **Corrade** -- main Magnum dependency, multiplatform utility library: +* **Corrade** -- main Magnum dependency, a multiplatform utility library: 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) * **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 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 * Gitter -- https://gitter.im/mosra/magnum * 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 ======= -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. diff --git a/doc/00-page-order.dox b/doc/00-page-order.dox index 4e46a4d2f..6ab134e28 100644 --- a/doc/00-page-order.dox +++ b/doc/00-page-order.dox @@ -9,10 +9,6 @@ @page utilities Utilities @page opengl OpenGL @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-plugins Plugins changelog @@ -20,4 +16,9 @@ @page changelog-extras Extras 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 + */ diff --git a/doc/best-practices.dox b/doc/best-practices.dox index f4431e2e9..171d2c20b 100644 --- a/doc/best-practices.dox +++ b/doc/best-practices.dox @@ -25,10 +25,10 @@ namespace Magnum { /** @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 +@m_footernavigation Here is collection of carefully selected notes, links to official guidelines and other articles with valuable information to help developers create better @@ -61,9 +61,9 @@ information. @subsection best-practices-ios iOS -- GLSL `texelFetch()` returns zero results if you have a texture with integer - type and the filtering is not @ref Sampler::Filter::Nearest. Yes, it - shouldn't matter, but it does. +- GLSL @glsl texelFetch() @ce returns zero results if you have a texture with + integer type and the filtering is not @ref Sampler::Filter::Nearest. Yes, + it shouldn't matter, but it does. - 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 unsigned integer texture @@ -73,7 +73,7 @@ information. @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) @@ -102,6 +102,5 @@ buffer attachments. See @ref Buffer, @ref Framebuffer, @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) - */ } diff --git a/doc/building.dox b/doc/building.dox index 0ff4a6a6b..7bf494839 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -29,6 +29,7 @@ namespace Magnum { @brief Guide how to download and build Magnum on different platforms. @tableofcontents +@m_footernavigation 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 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 @@ -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) can be built and installed using these four commands: - mkdir build && cd build - cmake .. \ - -DCMAKE_INSTALL_PREFIX=/usr \ - -DWITH_SDL2APPLICATION=ON - make - make install +@code{.sh} +mkdir build && cd build +cmake .. \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DWITH_SDL2APPLICATION=ON +make +make install +@endcode 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 Studio to load: - mkdir build && cd build - cmake -DCMAKE_INSTALL_PREFIX="C:/Sys" .. - cmake --build . - cmake --build . --target install +@code{.bat} +mkdir build && cd build +cmake -DCMAKE_INSTALL_PREFIX="C:/Sys" .. +cmake --build . +cmake --build . --target install +@endcode If you want to build and install from Visual Studio, just open the `Magnum.sln` 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 available for desktop OpenGL only, see @ref requires-gl. -- `TARGET_GLES` -- Target OpenGL ES. -- `TARGET_GLES2` -- Target OpenGL ES 2.0. Currently enabled by default when +- `TARGET_GLES` --- Target OpenGL ES. +- `TARGET_GLES2` --- Target OpenGL ES 2.0. Currently enabled by default when `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 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 used everywhere instead of platform-specific toolkits like CGL, GLX or WGL. Supported mainly on OpenGL ES drivers, for desktop OpenGL the only driver that supports this configuration is NVidia >= 355. 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 `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 parameters you can specify which parts will be built and which not: -- `WITH_AUDIO` - @ref Audio library. Depends on **OpenAL** library, not built - by default. -- `WITH_DEBUGTOOLS` - @ref DebugTools library -- `WITH_MESHTOOLS` - @ref MeshTools library -- `WITH_PRIMITIVES` - @ref Primitives library -- `WITH_SCENEGRAPH` - @ref SceneGraph library. Enabled automatically if +- `WITH_AUDIO` --- @ref Audio library. Depends on **OpenAL** library, not + built by default. +- `WITH_DEBUGTOOLS` --- @ref DebugTools library +- `WITH_MESHTOOLS` --- @ref MeshTools library +- `WITH_PRIMITIVES` --- @ref Primitives library +- `WITH_SCENEGRAPH` --- @ref SceneGraph library. Enabled automatically if `WITH_SHAPES` is enabled. -- `WITH_SHADERS` - @ref Shaders library -- `WITH_SHAPES` - @ref Shapes library. Enables also building of SceneGraph +- `WITH_SHADERS` --- @ref Shaders library +- `WITH_SHAPES` --- @ref Shapes library. Enables also building of SceneGraph 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. -- `WITH_TEXTURETOOLS` - @ref TextureTools library. Enabled automatically if +- `WITH_TEXTURETOOLS` --- @ref TextureTools library. Enabled automatically if `WITH_TEXT` or `WITH_DISTANCEFIELDCONVERTER` is enabled. 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 platform best: -- `WITH_ANDROIDAPPLICATION` - @ref Platform::AndroidApplication "AndroidApplication" -- `WITH_GLFWAPPLICATION` - @ref Platform::GlfwApplication "GlfwApplication" -- `WITH_GLUTAPPLICATION` - @ref Platform::GlutApplication "GlutApplication" -- `WITH_GLXAPPLICATION` - @ref Platform::GlxApplication "GlxApplication" -- `WITH_SDL2APPLICATION` - @ref Platform::Sdl2Application "Sdl2Application" -- `WITH_XEGLAPPLICATION` - @ref Platform::XEglApplication "XEglApplication" -- `WITH_WINDOWLESSCGLAPPLICATION` - @ref Platform::WindowlessCglApplication "WindowlessCglApplication" -- `WITH_WINDOWLESSEGLAPPLICATION` - @ref Platform::WindowlessEglApplication "WindowlessEglApplication" -- `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" -- `WITH_WINDOWLESSIOSAPPLICATION` - @ref Platform::WindowlessIosApplication "WindowlessIosApplication" -- `WITH_WINDOWLESSWGLAPPLICATION` - @ref Platform::WindowlessWglApplication "WindowlessWglApplication" -- `WITH_WINDOWLESSWINDOWSEGLAPPLICATION` - @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication" +- `WITH_ANDROIDAPPLICATION` --- @ref Platform::AndroidApplication "AndroidApplication" +- `WITH_GLFWAPPLICATION` --- @ref Platform::GlfwApplication "GlfwApplication" +- `WITH_GLUTAPPLICATION` --- @ref Platform::GlutApplication "GlutApplication" +- `WITH_GLXAPPLICATION` --- @ref Platform::GlxApplication "GlxApplication" +- `WITH_SDL2APPLICATION` --- @ref Platform::Sdl2Application "Sdl2Application" +- `WITH_XEGLAPPLICATION` --- @ref Platform::XEglApplication "XEglApplication" +- `WITH_WINDOWLESSCGLAPPLICATION` --- @ref Platform::WindowlessCglApplication "WindowlessCglApplication" +- `WITH_WINDOWLESSEGLAPPLICATION` --- @ref Platform::WindowlessEglApplication "WindowlessEglApplication" +- `WITH_WINDOWLESSGLXAPPLICATION` --- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" +- `WITH_WINDOWLESSIOSAPPLICATION` --- @ref Platform::WindowlessIosApplication "WindowlessIosApplication" +- `WITH_WINDOWLESSWGLAPPLICATION` --- @ref Platform::WindowlessWglApplication "WindowlessWglApplication" +- `WITH_WINDOWLESSWINDOWSEGLAPPLICATION` --- @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication" 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 information): -- `WITH_CGLCONTEXT` -- CGL context -- `WITH_EGLCONTEXT` -- EGL context -- `WITH_GLXCONTEXT` -- GLX context -- `WITH_WGLCONTEXT` -- WGL context +- `WITH_CGLCONTEXT` --- CGL context +- `WITH_EGLCONTEXT` --- EGL context +- `WITH_GLXCONTEXT` --- GLX context +- `WITH_WGLCONTEXT` --- WGL context There are also extensions to @ref Corrade::TestSuite::Tester for testing GPU 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. 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 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 @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 @ref Trade::TgaImageConverter "TgaImageConverter" plugin. -- `WITH_OBJIMPORTER` -- @ref Trade::ObjImporter "ObjImporter" plugin. -- `WITH_TGAIMPORTER` -- @ref Trade::TgaImporter "TgaImporter" plugin. -- `WITH_TGAIMAGECONVERTER` -- @ref Trade::TgaImageConverter "TgaImageConverter" +- `WITH_OBJIMPORTER` --- @ref Trade::ObjImporter "ObjImporter" plugin. +- `WITH_TGAIMPORTER` --- @ref Trade::TgaImporter "TgaImporter" plugin. +- `WITH_TGAIMAGECONVERTER` --- @ref Trade::TgaImageConverter "TgaImageConverter" plugin. -- `WITH_WAVAUDIOIMPORTER` -- @ref Audio::WavImporter "WavAudioImporter" +- `WITH_WAVAUDIOIMPORTER` --- @ref Audio::WavImporter "WavAudioImporter" plugin. Available only if `WITH_AUDIO` is enabled. 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 windowless application library. -- `WITH_AL_INFO` -- @ref magnum-al-info "magnum-al-info" executable, provides - information about OpenAL capabilities. -- `WITH_DISTANCEFIELDCONVERTER` - @ref magnum-distancefieldconverter "magnum-distancefieldconverter" +- `WITH_AL_INFO` --- @ref magnum-al-info "magnum-al-info" executable, + provides information about OpenAL capabilities. +- `WITH_DISTANCEFIELDCONVERTER` --- @ref magnum-distancefieldconverter "magnum-distancefieldconverter" executable for converting black&white images to distance field textures. Enables also building of @ref TextureTools library. Available only on 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 @ref Text library. Available only on desktop GL, depends on some windowless application library. -- `WITH_IMAGECONVERTER` - @ref magnum-imageconverter "magnum-imageconverter" +- `WITH_IMAGECONVERTER` --- @ref magnum-imageconverter "magnum-imageconverter" executable for converting images of different formats. Some of these utilities operate with plugins and they search for them in the default plugin locations. You can override those locations using `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 will be taken relative to executable location, which is useful for making 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 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 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, 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 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 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 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 -job too) and additionally uses **TeX** for math formulas. The documentation can -be build by running +and additionally uses **LaTeX** for math formulas. Documentation using the +stock HTML theme can be build by running - doxygen +@code{.sh} +doxygen +@endcode in root directory (i.e. where `Doxyfile` is). Resulting HTML documentation 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 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 The engine itself is kept as small as possible with only little dependencies. Additional functionality, often depending on external libraries, is provided in separate repositories. Various importer plugins for image, audio and 3D model formats are maintained in @ref building-plugins "Plugins repository", -Integration with various external math and physics libraries is provided by -@ref building-integration "Integration library". +integration with various external math and physics libraries is provided by +@ref building-integration "Integration library" and other extra features are +in the @ref building-extras "Extras library". @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 you to build and install the package directly from source tree without -downloading anything. The native PKGBUILDs also contain `check()` function -which will run all unit tests before packaging. +downloading anything. The native PKGBUILDs also contain @cb{.sh} check() @ce +function which will run all unit tests before packaging. @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 and run `dpkg-buildpackage`: - ln -s package/debian . - dpkg-buildpackage +@code{.sh} +ln -s package/debian . +dpkg-buildpackage +@endcode This will compile binary and development packages, which will then appear in 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 `*.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 @@ -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, switch to 3.0 by disabling `TARGET_GLES2`. - mkdir build-angle && cd build-angle - cmake .. \ - -DCMAKE_PREFIX_PATH= \ - -DTARGET_GLES=ON -DTARGEET_GLES2=OFF \ - -DWITH_SDL2APPLICATION=ON - cmake --build . +@code{.bat} +mkdir build-angle && cd build-angle +cmake .. ^ + -DCMAKE_PREFIX_PATH= ^ + -DTARGET_GLES=ON ^ + -DTARGEET_GLES2=OFF ^ + -DWITH_SDL2APPLICATION=ON +cmake --build . +@endcode @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 contents in `toolchains/` subdirectory. - git submodule init - git submodule update +@code{.sh} +git submodule update --init +@endcode Note that CMake for some reason treats `CMAKE_PREFIX_PATH` and `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 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", -but use project files from the `winrt/` directory instead. Version 2.0.4 of SDL -has support for WinRT applications, download the source from -https://www.libsdl.org/download-2.0.php and use project files from the -`VisualC-WinRT` directory. Because WinRT applications run in a sandbox, it's -recommended to build the library as static so you don't have to bundle all the -DLLs. Example: - - mkdir build-winrt - cd build-winrt - cmake .. ^ - -DCMAKE_SYSTEM_NAME=WindowsStore ^ - -DCMAKE_SYSTEM_VERSION=10 ^ - -DCORRADE_RC_EXECUTABLE="C:/Sys/bin/corrade-rc.exe" ^ - -DCMAKE_INSTALL_PREFIX="C:/Sys-winrt" ^ - -DBUILD_STATIC=ON ^ - -DWITH_SDL2APPLICATION=ON ^ - -G "Visual Studio 14 2015" .. - cmake --build . +is currently limited to OpenGL ES. Download and build ANGLE +@ref building-windows-angle "according to instructions above", but use project +files from the `winrt/` directory instead. Version 2.0.4 of SDL has support for +WinRT applications, download the source from https://www.libsdl.org/download-2.0.php +and use project files from the `VisualC-WinRT` directory. Because WinRT +applications run in a sandbox, it's recommended to build the library as static +so you don't have to bundle all the DLLs. Example: + +@code{.bat} +mkdir build-winrt && cd build-winrt +cmake .. ^ + -DCMAKE_SYSTEM_NAME=WindowsStore ^ + -DCMAKE_SYSTEM_VERSION=10 ^ + -DCORRADE_RC_EXECUTABLE="C:/Sys/bin/corrade-rc.exe" ^ + -DCMAKE_INSTALL_PREFIX="C:/Sys-winrt" ^ + -DBUILD_STATIC=ON ^ + -DWITH_SDL2APPLICATION=ON ^ + -G "Visual Studio 14 2015" .. +cmake --build . +@endcode 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` @@ -460,25 +488,29 @@ building your projects for WinRT. You will need MinGW-w64 versions of the compiler and all dependent libraries (Corrade), i.e. these ArchLinux packages: -- `mingw-w64-gcc` -- `mingw-w64-corrade` +- `mingw-w64-gcc` +- `mingw-w64-corrade` 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` files and `CMAKE_INSTALL_PREFIX` to suit your distribution filesystem hierarchy and specify path where Corrade is installed in `CMAKE_PREFIX_PATH`. - mkdir build-mingw-w64-32 && cd build-mingw-w64-32 - cmake .. \ - -DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw-w64-32.cmake \ - -DCMAKE_INSTALL_PREFIX=/usr/i686-w64-mingw32 - cmake --build . - - mkdir build-mingw-w64-64 && cd build-mingw-w64-64 - cmake .. \ - -DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw-w64-64.cmake \ - -DCMAKE_INSTALL_PREFIX=/usr/x86_64-w64-mingw32 - cmake --build . +@code{.sh} +mkdir build-mingw-w64-32 && cd build-mingw-w64-32 +cmake .. \ + -DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw-w64-32.cmake \ + -DCMAKE_INSTALL_PREFIX=/usr/i686-w64-mingw32 +cmake --build . +@endcode + +@code{.sh} +mkdir build-mingw-w64-64 && cd build-mingw-w64-64 +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 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 equivalent) by disabling `TARGET_GLES2`. - mkdir build-emscripten && cd build-emscripten - cmake .. \ - -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Emscripten.cmake" \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_PREFIX_PATH=/usr/lib/emscripten/system \ - -DCMAKE_INSTALL_PREFIX=/usr/lib/emscripten/system \ - -DWITH_SDL2APPLICATION=ON - cmake --build . +@code{.sh} +mkdir build-emscripten && cd build-emscripten +cmake .. \ + -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Emscripten.cmake" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH=/usr/lib/emscripten/system \ + -DCMAKE_INSTALL_PREFIX=/usr/lib/emscripten/system \ + -DWITH_SDL2APPLICATION=ON +cmake --build . +@endcode Then you can install the library using `cmake --build . --target install` to 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 for older platforms. - mkdir build-ios && cd build-ios - cmake .. \ - -DCMAKE_TOOLCHAIN_FILE=../toolchains/generic/iOS.cmake \ - -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk \ - -DCMAKE_OSX_ARCHITECTURES="arm64;armv7;armv7s" \ - -DCMAKE_INSTALL_PREFIX=~/ios-libs \ - -DBUILD_STATIC=ON -DBUILD_PLUGINS_STATIC=ON \ - -DTARGET_GLES2=OFF \ - -DWITH_SDL2APPLICATION=ON \ - -G Xcode - cmake --build . +@code{.sh} +mkdir build-ios && cd build-ios +cmake .. \ + -DCMAKE_TOOLCHAIN_FILE=../toolchains/generic/iOS.cmake \ + -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk \ + -DCMAKE_OSX_ARCHITECTURES="arm64;armv7;armv7s" \ + -DCMAKE_INSTALL_PREFIX=~/ios-libs \ + -DBUILD_STATIC=ON -DBUILD_PLUGINS_STATIC=ON \ + -DTARGET_GLES2=OFF \ + -DWITH_SDL2APPLICATION=ON \ + -G Xcode +cmake --build . +@endcode Then you can install the library using `cmake --build . --target install` to 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 built for OpenGL ES 2.0 by default, switch to 3.0 by disabling `TARGET_GLES2`. - mkdir build-android-arm && cd build-android-arm - cmake .. \ - -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Android-ARM.cmake" \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_PREFIX_PATH=/opt/android-ndk/platforms/android-19/arch-arm/usr \ - -DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-19/arch-arm/usr \ - -DTARGET_GLES=ON -DTARGET_GLES2=OFF \ - -DWITH_ANDROIDAPPLICATION=ON - cmake --build . - - mkdir build-android-x86 && cd build-android-x86 - cmake .. \ - -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Android-x86.cmake" \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_PREFIX_PATH=/opt/android-ndk/platforms/android-19/arch-x86/usr \ - -DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-19/arch-x86/usr \ - -DTARGET_GLES=ON -DTARGET_GLES2=OFF \ - -DWITH_ANDROIDAPPLICATION=ON - cmake --build . +@code{.sh} +mkdir build-android-arm && cd build-android-arm +cmake .. \ + -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Android-ARM.cmake" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH=/opt/android-ndk/platforms/android-19/arch-arm/usr \ + -DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-19/arch-arm/usr \ + -DTARGET_GLES=ON -DTARGET_GLES2=OFF \ + -DWITH_ANDROIDAPPLICATION=ON +cmake --build . +@endcode + +@code{.sh} +mkdir build-android-x86 && cd build-android-x86 +cmake .. \ + -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Android-x86.cmake" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH=/opt/android-ndk/platforms/android-19/arch-x86/usr \ + -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 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, MinGW, Windows desktop GLES2/GLES3 and Windows RT GLES2/GLES3 configuration. Online at https://ci.appveyor.com/project/mosra/magnum. - */ } diff --git a/doc/cmake.dox b/doc/cmake.dox index bd9c0a090..23999a96b 100644 --- a/doc/cmake.dox +++ b/doc/cmake.dox @@ -28,6 +28,7 @@ namespace Magnum { @brief Guide how to find and use Magnum with CMake build system @tableofcontents +@m_footernavigation Magnum uses CMake build system for both building and integration into your projects. The logic is in module `FindMagnum.cmake` distributed with the engine @@ -50,80 +51,82 @@ separate them with semicolons. 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: -- `Magnum_FOUND` -- Whether the library was found -- `Magnum::Magnum` -- Base library imported target -- `MAGNUM_DEPLOY_PREFIX` -- Prefix where to put final application +- `Magnum_FOUND` --- Whether the library was found +- `Magnum::Magnum` --- Base library imported target +- `MAGNUM_DEPLOY_PREFIX` --- Prefix where to put final application executables, defaults to empty string. If a relative path is used, it's 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 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 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 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 stored relatively to the executable), the following `MAGNUM_PLUGINS_*_DIR` 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 -- `MAGNUM_PLUGINS_FONTCONVERTER[|_DEBUG|_RELEASE]_DIR` -- Directory with +- `MAGNUM_PLUGINS_FONTCONVERTER[|_DEBUG|_RELEASE]_DIR` --- Directory with dynamic font converter plugins -- `MAGNUM_PLUGINS_IMAGECONVERTER[|_DEBUG|_RELEASE]_DIR` -- Directory with +- `MAGNUM_PLUGINS_IMAGECONVERTER[|_DEBUG|_RELEASE]_DIR` --- Directory with dynamic image converter plugins -- `MAGNUM_PLUGINS_IMPORTER[|_DEBUG|_RELEASE]_DIR` -- Directory with dynamic +- `MAGNUM_PLUGINS_IMPORTER[|_DEBUG|_RELEASE]_DIR` --- Directory with dynamic importer plugins -- `MAGNUM_PLUGINS_AUDIOIMPORTER[|_DEBUG|_RELEASE]_DIR` -- Directory with +- `MAGNUM_PLUGINS_AUDIOIMPORTER[|_DEBUG|_RELEASE]_DIR` --- Directory with dynamic audio importer plugins 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 -OpenGL ES libraries). Additional dependencies are specified by the components. -The optional components are: - -- `Audio` -- @ref Audio library -- `DebugTools` -- @ref DebugTools library -- `MeshTools` -- @ref MeshTools library -- `Primitives` -- @ref Primitives library -- `SceneGraph` -- @ref SceneGraph library -- `Shaders` -- @ref Shaders library -- `Shapes` -- @ref Shapes library -- `Text` -- @ref Text library -- `TextureTools` -- @ref TextureTools library +components. The base library depends on @ref corrade-cmake Corrade and OpenGL +libraries (or OpenGL ES libraries). Additional dependencies are specified by +the components. The optional components are: + +- `Audio` --- @ref Audio library +- `DebugTools` --- @ref DebugTools library +- `MeshTools` --- @ref MeshTools library +- `Primitives` --- @ref Primitives library +- `SceneGraph` --- @ref SceneGraph library +- `Shaders` --- @ref Shaders library +- `Shapes` --- @ref Shapes library +- `Text` --- @ref Text library +- `TextureTools` --- @ref TextureTools library Platform namespace is split into more components: -- `GlfwApplication` -- @ref Platform::GlfwApplication "GlfwApplication" -- `GlutApplication` -- @ref Platform::GlutApplication "GlutApplication" -- `GlxApplication` -- @ref Platform::GlxApplication "GlxApplication" -- `Sdl2Application` -- @ref Platform::Sdl2Application "Sdl2Application" -- `XEglApplication` -- @ref Platform::XEglApplication "XEglApplication" -- `WindowlessCglApplication` -- @ref Platform::WindowlessCglApplication "WindowlessCglApplication" -- `WindowlessEglApplication` -- @ref Platform::WindowlessEglApplication "WindowlessEglApplication" -- `WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" -- `WindowlessIosApplication` -- @ref Platform::WindowlessIosApplication "WindowlessIosApplication" -- `WindowlessWglApplication` -- @ref Platform::WindowlessWglApplication "WindowlessWglApplication" -- `WindowlessWindowsEglApplication` -- @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication" +- `GlfwApplication` --- @ref Platform::GlfwApplication "GlfwApplication" +- `GlutApplication` --- @ref Platform::GlutApplication "GlutApplication" +- `GlxApplication` --- @ref Platform::GlxApplication "GlxApplication" +- `Sdl2Application` --- @ref Platform::Sdl2Application "Sdl2Application" +- `XEglApplication` --- @ref Platform::XEglApplication "XEglApplication" +- `WindowlessCglApplication` --- @ref Platform::WindowlessCglApplication "WindowlessCglApplication" +- `WindowlessEglApplication` --- @ref Platform::WindowlessEglApplication "WindowlessEglApplication" +- `WindowlessGlxApplication` --- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" +- `WindowlessIosApplication` --- @ref Platform::WindowlessIosApplication "WindowlessIosApplication" +- `WindowlessWglApplication` --- @ref Platform::WindowlessWglApplication "WindowlessWglApplication" +- `WindowlessWindowsEglApplication` --- @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication" For manual context creation (without application wrappers) there are also platform-specific context libraries (see @ref platform-custom for more information): -- `CglContext` -- CGL context -- `EglContext` -- EGL context -- `GlxContext` -- GLX context -- `WglContext` -- WGL context +- `CglContext` --- CGL context +- `EglContext` --- EGL context +- `GlxContext` --- GLX context +- `WglContext` --- WGL context There are also extensions to @ref Corrade::TestSuite::Tester for testing GPU code: -- `OpenGLTester` -- @ref OpenGLTester class +- `OpenGLTester` --- @ref OpenGLTester class The library also contains a set of plugins for importing essential file 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 dependencies, you need to find the dependency and then link to it. -- `MagnumFont` -- @ref Text::MagnumFont "MagnumFont" plugin -- `MagnumFontConverter` -- @ref Text::MagnumFontConverter "MagnumFontConverter" +- `MagnumFont` --- @ref Text::MagnumFont "MagnumFont" plugin +- `MagnumFontConverter` --- @ref Text::MagnumFontConverter "MagnumFontConverter" plugin -- `ObjImporter` -- @ref Trade::ObjImporter "ObjImporter" plugin -- `TgaImageConverter` -- @ref Trade::TgaImageConverter "TgaImageConverter" +- `ObjImporter` --- @ref Trade::ObjImporter "ObjImporter" plugin +- `TgaImageConverter` --- @ref Trade::TgaImageConverter "TgaImageConverter" plugin -- `TgaImporter` -- @ref Trade::TgaImporter "TgaImporter" plugin -- `WavAudioImporter` -- @ref Audio::WavImporter "WavAudioImporter" plugin +- `TgaImporter` --- @ref Trade::TgaImporter "TgaImporter" plugin +- `WavAudioImporter` --- @ref Audio::WavImporter "WavAudioImporter" plugin Lastly, a few utility executables are available: -- `distancefieldconverter` -- @ref magnum-distancefieldconverter executable -- `fontconverter` -- @ref magnum-fontconverter executable -- `imageconverter` -- @ref magnum-imageconverter executable -- `info` -- @ref magnum-info executable -- `al-info` -- @ref magnum-al-info executable +- `distancefieldconverter` --- @ref magnum-distancefieldconverter executable +- `fontconverter` --- @ref magnum-fontconverter executable +- `imageconverter` --- @ref magnum-imageconverter executable +- `info` --- @ref magnum-info executable +- `al-info` --- @ref magnum-al-info executable Note that [each namespace](namespaces.html), all @ref Platform libraries and 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: - find_package(Magnum REQUIRED MeshTools Primitives Sdl2Application) +@code{.cmake} +find_package(Magnum REQUIRED MeshTools Primitives Sdl2Application) +@endcode For each component is then defined: -- `Magnum_*_FOUND` -- Whether the component was found -- `Magnum::*` -- Component imported target +- `Magnum_*_FOUND` --- Whether the component was found +- `Magnum::*` --- Component imported target If exactly one `*Application` or exactly one `Windowless*Application` component 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 @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 -- `MAGNUM_BUILD_STATIC` -- Defined if compiled as static libraries. Default +- `MAGNUM_BUILD_STATIC` --- Defined if compiled as static libraries. Default 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. -- `MAGNUM_TARGET_GLES` -- Defined if compiled for OpenGL ES -- `MAGNUM_TARGET_GLES2` -- Defined if compiled for OpenGL ES 2.0 -- `MAGNUM_TARGET_GLES3` -- Defined if compiled for OpenGL ES 3.0 -- `MAGNUM_TARGET_DESKTOP_GLES` -- Defined if compiled with OpenGL ES +- `MAGNUM_TARGET_GLES` --- Defined if compiled for OpenGL ES +- `MAGNUM_TARGET_GLES2` --- Defined if compiled for OpenGL ES 2.0 +- `MAGNUM_TARGET_GLES3` --- Defined if compiled for OpenGL ES 3.0 +- `MAGNUM_TARGET_DESKTOP_GLES` --- Defined if compiled with OpenGL ES emulation on desktop OpenGL -- `MAGNUM_TARGET_WEBGL` -- Defined if compiled for WebGL -- `MAGNUM_TARGET_HEADLESS` -- Defined if compiled for headless machines. See +- `MAGNUM_TARGET_WEBGL` --- Defined if compiled for WebGL +- `MAGNUM_TARGET_HEADLESS` --- Defined if compiled for headless machines. See @ref MAGNUM_TARGET_HEADLESS documentation for more information. Workflows without imported targets are deprecated and the following variables are included just for backwards compatibility and only if @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. -- `MAGNUM_*_LIBRARIES` -- Expands to `Magnum::*` target. Use `Magnum::*` +- `MAGNUM_*_LIBRARIES` --- Expands to `Magnum::*` target. Use `Magnum::*` target directly instead. - `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 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. 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: -- `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 @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". Copy this to your module 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. -- `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 @ref CORRADE_TARGET_IOS "iOS", @ref CORRADE_TARGET_ANDROID "Android", @ref CORRADE_TARGET_WINDOWS_RT "Windows RT" or @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten" or if you want to use EGL 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 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. - -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. - */ } diff --git a/doc/coding-style.dox b/doc/coding-style.dox index c2fe906fc..acfb4fb02 100644 --- a/doc/coding-style.dox +++ b/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". -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 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 diff --git a/doc/compilation-speedup.dox b/doc/compilation-speedup.dox index c5a90a8bd..54d4bac57 100644 --- a/doc/compilation-speedup.dox +++ b/doc/compilation-speedup.dox @@ -27,9 +27,12 @@ namespace Magnum { /** @page compilation-speedup Speeding up compilation @brief Techniques for reducing compilation times. +@tableofcontents +@m_footernavigation + @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 policy in all header files, so all types which are not directly used in the 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 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. -@ref Math/Vector3.h. +@ref Magnum/Math/Vector3.h. 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 available, each namespace has its own: - - @ref Math/Math.h - - @ref Magnum.h - - @ref DebugTools/DebugTools.h - - @ref SceneGraph/SceneGraph.h - - @ref Shaders/Shaders.h - - @ref Shapes/Shapes.h - - @ref Text/Text.h - - @ref Trade/Trade.h +- @ref Corrade/Corrade.h +- @ref Corrade/Containers/Containers.h +- @ref Corrade/Interconnect/Interconnect.h +- @ref Corrade/PluginManager/PluginManager.h +- @ref Corrade/TestSuite/TestSuite.h +- @ref Corrade/Utility/Utility.h +- @ref Magnum/Magnum.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 @@ -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 span the whole universe. We include the implementation file in dedicated source file and explicitly instantiate the template: -@code + +@code{.cpp} // Object.cpp #include "SceneGraph/Object.hpp" #include "SceneGraph/MatrixTransformation3D.h" @@ -109,7 +123,7 @@ precious compilation time. @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 it causes conflicting symbol errors when used on whole classes, thus in Magnum 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. Extern template is used for example for @ref debugoperators "debug operators" for common types of matrices and vectors. - */ } diff --git a/doc/debug-tools.dox b/doc/debug-tools.dox index cd9be1a59..18cb17b53 100644 --- a/doc/debug-tools.dox +++ b/doc/debug-tools.dox @@ -27,7 +27,8 @@ namespace Magnum { /** @page debug-tools Debugging helpers @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 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 information about building and usage with CMake. -@tableofcontents - @section debug-tools-renderers Debug renderers 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. Example usage: visualizing object position, rotation and scaling using -@link DebugTools::ObjectRenderer @endlink: -@code +@ref DebugTools::ObjectRenderer : + +@code{.cpp} // Global instance of debug resource manager, drawable group for the renderers DebugTools::ResourceManager manager; SceneGraph::DrawableGroup3D debugDrawables; @@ -77,7 +77,5 @@ new DebugTools::ObjectRenderer2D(*object, "my", debugDrawables); See @ref DebugTools::ObjectRenderer and @ref DebugTools::ShapeRenderer for more information. - -- Previous page: @ref shapes */ } diff --git a/doc/features.dox b/doc/features.dox index cf21f6f20..6c2d9e88c 100644 --- a/doc/features.dox +++ b/doc/features.dox @@ -27,15 +27,15 @@ namespace Magnum { /** @page features Feature overview @brief Fundamental principles and design goals. -- @subpage platform -- @copybrief platform -- @subpage types -- @copybrief types -- @subpage matrix-vector -- @copybrief matrix-vector -- @subpage transformations -- @copybrief transformations -- @subpage plugins -- @copybrief plugins -- @subpage opengl-wrapping -- @copybrief opengl-wrapping -- @subpage shaders -- @copybrief shaders -- @subpage scenegraph -- @copybrief scenegraph -- @subpage shapes -- @copybrief shapes -- @subpage debug-tools -- @copybrief debug-tools +- @subpage platform --- @copybrief platform +- @subpage types --- @copybrief types +- @subpage matrix-vector --- @copybrief matrix-vector +- @subpage transformations --- @copybrief transformations +- @subpage plugins --- @copybrief plugins +- @subpage opengl-wrapping --- @copybrief opengl-wrapping +- @subpage shaders --- @copybrief shaders +- @subpage scenegraph --- @copybrief scenegraph +- @subpage shapes --- @copybrief shapes +- @subpage debug-tools --- @copybrief debug-tools */ } diff --git a/doc/getting-started-blue.png b/doc/getting-started-blue.png index df4aac6ab..1019f1a4b 100644 Binary files a/doc/getting-started-blue.png and b/doc/getting-started-blue.png differ diff --git a/doc/getting-started.dox b/doc/getting-started.dox index 9b3c8992f..c38ddc78c 100644 --- a/doc/getting-started.dox +++ b/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 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 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) -and extract it somewhere. Do it rather than cloning the full repository, as -it's better to init your own repository from scratch with clean 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. +contains only the essential files. Download the branch +[as an archive](https://github.com/mosra/magnum-bootstrap/archive/base.zip) and +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. @section getting-started-download Download, build and install Corrade and Magnum Magnum libraries support both separate compilation/installation and CMake -subprojects. We'll use the subproject approach now, because adding the -dependencies means just cloning them into your project tree: +subprojects. We'll use the subproject approach now --- adding the dependencies +means just cloning them into your project tree: - cd /path/to/the/extracted/bootstrap/project - git clone git://github.com/mosra/corrade.git - git clone git://github.com/mosra/magnum.git +@code{.sh} +cd /path/to/the/extracted/bootstrap/project +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 -these two new subdirectories using `add_subdirectory()` so the file looks like -this: +these two new subdirectories using @cmake add_subdirectory() @ce so the file +looks like this: -@code +@code{.cmake} cmake_minimum_required(VERSION 2.8.12) project(MyApplication) @@ -74,16 +71,22 @@ add_subdirectory(magnum) add_subdirectory(src) @endcode -If you want to install Corrade and Magnum separately instead of cloning them -into your project tree, just follow @ref building "the full installation guide". -Don't forget to enable `WITH_SDL2APPLICATION` (or `WITH_GLUTAPPLICATION`, if -you are using GLUT) when building Magnum so the bootstrap project can use it -later. +@note In the long run it's better to install Corrade and Magnum separately + instead of cloning them into your project tree, as that can vastly improve + your iteration times. Follow @ref building "the full installation guide" if + you want to go that route; don't forget to enable `WITH_SDL2APPLICATION` + 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 -The base project consists of just six files in two subfolders. Magnum uses -CMake build system, see @ref cmake for more information. +The base project consists of just six files in two subfolders. Magnum uses the +CMake build system, you can read more about it in @ref cmake. modules/FindCorrade.cmake modules/FindMagnum.cmake @@ -92,25 +95,27 @@ CMake build system, see @ref cmake for more information. src/CMakeLists.txt CMakeLists.txt -In root there is project-wide `CMakeLists.txt`, which you have seen above. It -just sets up project name, specifies module directory and delegates everything -important to `CMakeLists.txt` in `src/` subdirectory. +In root there is the project-wide `CMakeLists.txt`, which you have seen above. +It just sets up project name, specifies module directory and delegates +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 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 repository. @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 - specific platforms, you may need to copy additional modules. See @ref cmake, - @ref cmake-plugins, @ref cmake-integration and @ref cmake-extras for more - information. - -Directory `src/` contains the actual project. To keep things simple, the -project consists of just one source file with the most minimal code possible: -@code + plan to use additional functionality that isn't part of the core library or + you are targeting specific platforms, you may need to include additional + modules. See @ref cmake, @ref cmake-plugins, @ref cmake-integration and + @ref cmake-extras for more information. + +The `src/` directory contains the actual project. To keep things simple, the +project consists of just a single `MyApplication.cpp` file with the most +minimal code possible: + +@code{.cpp} #include #include @@ -139,11 +144,12 @@ void MyApplication::drawEvent() { MAGNUM_APPLICATION_MAIN(MyApplication) @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 the screen. The `src/CMakeLists.txt` file finds Magnum, creates the executable and links it to all needed libraries: -@code + +@code{.cmake} find_package(Magnum REQUIRED Sdl2Application) 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 +@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 the subprojects using the following three commands: create out-of-source build -directory, run cmake, enable SDL2 application in the Magnum subproject and then -build everything. The compiled application binary will then appear in `src/` -subdirectory of the build dir: - - mkdir -p build && cd build - cmake .. -DWITH_SDL2APPLICATION=ON - cmake --build . - ./src/MyApplication +directory, run `cmake`, enable SDL2 application in the Magnum subproject and +then build everything. The compiled application binary will then appear in +`src/` subdirectory of the build dir: + +@code{.sh} +mkdir -p build && cd build +cmake .. -DWITH_SDL2APPLICATION=ON +cmake --build . +./src/MyApplication +@endcode @note If you installed Corrade and Magnum separately (instead of putting them in the project as subprojects), the `-DWITH_SDL2APPLICATION=ON` is not 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 -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 -Visual Studio the most straightforward way to create the project file is via -the command-line: - - mkdir build && cd build - cmake .. -DWITH_SDL2APPLICATION=ON +@subsection getting-started-windows Windows + +On Windows you can use either MSVC 2015+ or MinGW-w64. Prebuilt SDL2 binaries +can be downloaded at https://libsdl.org/download-2.0.php, dependeding on where +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 +all dependency DLLs copied along it. That can be done by setting +`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 -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 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. -If you have SDL2 in a non-standard location and CMake can't find it, you need -to specify where SDL `include/` and `lib/` directories are through -`CMAKE_PREFIX_PATH`. So, for example, on Windows, the full CMake invocation -might look like this: +@note If you installed Corrade and Magnum separately, the install directory + containing the DLLs needs to be in @cb{.bat} %PATH% @ce in order to + properly run the executable. You can also enable `BUILD_STATIC` to compile + 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. -The solution is either compiling everything as static (enable `BUILD_STATIC` -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`. +If everything went well and the application starts, you will see a blank window +like this: @image html getting-started.png @image latex getting-started.png 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 -else and also print basic information about the GPU the engine is running on. -First include the needed headers: -@code +the concepts of graphics programming, we can change the clear color to +something else and also print basic information about the GPU the engine is +running on. First include the needed headers: + +@code{.cpp} #include #include #include @@ -220,19 +238,24 @@ First include the needed headers: And in the constructor (which is currently empty) change the clear color and 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() - << "using" << Context::current().rendererString(); + Debug() << "Hello! This application is running on" << Context::current().version() + << "using" << Context::current().rendererString(); @endcode After rebuilding and starting the application, the clear color changes to 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 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 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 @ref features "fundamental principles" in the documentation and start experimenting on your own! @section getting-started-more Additional information -- @subpage building -- @subpage building-plugins -- @subpage building-integration -- @subpage building-examples -- @subpage building-extras -- @subpage cmake -- @subpage cmake-plugins -- @subpage cmake-integration -- @subpage cmake-extras +- @subpage building --- @copybrief building +- @subpage building-plugins --- @copybrief building-plugins +- @subpage building-integration --- @copybrief building-integration +- @subpage building-extras --- @copybrief building-extras +- @subpage building-examples --- @copybrief building-examples +- @subpage cmake --- @copybrief cmake +- @subpage cmake-plugins --- @copybrief cmake-plugins +- @subpage cmake-integration --- @copybrief cmake-integration +- @subpage cmake-extras --- @copybrief cmake-extras */ } diff --git a/doc/getting-started.png b/doc/getting-started.png index 85089868a..a0d1ee803 100644 Binary files a/doc/getting-started.png and b/doc/getting-started.png differ diff --git a/doc/mainpage.dox b/doc/mainpage.dox index c7486e94e..a87c8634f 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -26,43 +26,42 @@ namespace Magnum { /** @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 using recent C++11/C++14 features and to abstract away platform-specific issues. @section mainpage-design-goals Design goals -- **2D is not an ugly stepchild** - Many engines out there were created as pure 2D or 3D and the alternative is - usually just an afterthought, if it is present at all. If you want to do - your next project in 2D only, you have to either relearn another engine - from scratch or emulate it in 3D, leaving many things overly complicated. - Magnum treats 2D equivalently to 3D so you can reuse what you already - learned for 3D and even combine 2D and 3D in one project. - -- **Forward compatibility** - If newer technology makes things faster, simpler or more intuitive, it is - the way to go. Magnum by default relies on decent C++11 support and modern - OpenGL features and if some feature isn't available, it tries to emulate it - using older functionality. However, you are not restricted to use the older - functionality directly, if you really want to. - -- **Intuitive, but not restrictive API** - Scripting languages are often preferred to C/C++ because they are designed - to have less complicated APIs and less boilerplate code. Magnum is - designed with intuitivity in mind, but also with speed and static checks - that strongly-typed native code offers. It wraps OpenGL into less verbose - and more type-safe API, which is easier to use. Usually the most common way - is the most simple, but if you need full control, you can have it. - -- **Extensible and replaceable components** - If you want to use different mathematical library for specific purposes, - that new windowing toolkit, your own file formats or another physics - library, you can. Conversion of math structures between different libraries - can be done on top of pre-made skeleton classes, support for file formats - is done using plugins and platform support is done by writing simple - wrapper class. +- **2D is not an ugly stepchild.** Many engines out there were created as + pure 2D or 3D and the alternative is usually just an afterthought, if it is + present at all. If you want to do your next project in 2D only, you have to + either relearn another engine from scratch or emulate it in 3D, leaving + many things overly complicated. Magnum treats 2D equivalently to 3D so you + can reuse what you already learned for 3D and even combine 2D and 3D in one + project. + +- **Forward compatibility.** If newer technology makes things faster, simpler + or more intuitive, it is the way to go. Magnum by default relies on decent + C++11 support and modern OpenGL features and if some feature isn't + available, it tries to emulate it using older functionality. However, you + are not restricted to use the older functionality directly, if you really + want to. + +- **Intuitive, but not restrictive API.** Scripting languages are often + preferred to C/C++ because they are designed to have less complicated APIs + and less boilerplate code. Magnum is designed with intuitivity in mind, but + also with speed and static checks that strongly-typed native code offers. + It wraps OpenGL into less verbose and more type-safe API, which is easier + to use. Usually the most common way is the most simple, but if you need + full control, you can have it. + +- **Extensible and replaceable components.** If you want to use different + mathematical library for specific purposes, that new windowing toolkit, + your own file formats or another physics library, you can. Conversion of + math structures between different libraries can be done on top of pre-made + skeleton classes, support for file formats is done using plugins and + platform support is done by writing simple wrapper class. @section mainpage-platforms Supported platforms @@ -78,10 +77,11 @@ Platforms: - **Linux** and embedded Linux (natively using GLX/EGL and Xlib or through 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) - **iOS** (through SDL2 toolkit) -- **Android** 2.3 (API Level 9) and higher +- **Android** - **Windows RT** (Store/Phone) using ANGLE (through SDL2 toolkit) - **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: -- Website -- http://magnum.graphics -- GitHub -- https://github.com/mosra/magnum -- Gitter -- https://gitter.im/mosra/magnum -- IRC -- join `#magnum-engine` channel on freenode -- Google Groups -- https://groups.google.com/forum/#!forum/magnum-engine -- Twitter -- https://twitter.com/czmosra -- E-mail -- mosra@centrum.cz -- Jabber -- mosra@jabbim.cz +- Website --- http://magnum.graphics +- GitHub --- https://github.com/mosra/magnum +- Gitter --- https://gitter.im/mosra/magnum +- IRC --- join `#magnum-engine` channel on freenode +- Google Groups --- https://groups.google.com/forum/#!forum/magnum-engine +- Twitter --- https://twitter.com/czmosra +- E-mail --- mosra@centrum.cz +- Jabber --- mosra@jabbim.cz @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 diff --git a/doc/matrix-vector.dox b/doc/matrix-vector.dox index e90b22ad2..53d860835 100644 --- a/doc/matrix-vector.dox +++ b/doc/matrix-vector.dox @@ -27,8 +27,8 @@ namespace Magnum { /** @page matrix-vector Operations with matrices and vectors @brief Introduction to essential classes of the graphics pipeline. -- Previous page: @ref types -- Next page: @ref transformations +@tableofcontents +@m_footernavigation 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 @@ -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 information about usage with CMake. -@tableofcontents - @section matrix-vector-hierarchy Matrix and vector classes Magnum has three main matrix and vector classes: @ref Math::RectangularMatrix, (square) @ref Math::Matrix and @ref Math::Vector. To achieve greatest code -reuse, Matrix is internally square RectangularMatrix and RectangularMatrix -is internally array of one or more Vector instances. Both vectors and matrices -can have arbitrary size (known at compile time) and can store any arithmetic -type. +reuse, @ref Math::Matrix is internally square @ref Math::RectangularMatrix and +@ref Math::RectangularMatrix is internally array of one or more @ref Math::Vector +instances. Both vectors and matrices can have arbitrary size (known at compile +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 -@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 direct access to named components. Functions of each class try to return the -most specialized type known to make subsequent operations more convenient -- -columns of RectangularMatrix are returned as Vector, but when accessing -columns of e.g. Matrix3, they are returned as Vector3. +most specialized type known to make subsequent operations more convenient --- +columns of @ref Math::RectangularMatrix are returned as @ref Math::Vector, but +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 @ref Math::Color4 for color handling and conversion. 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". -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 @@ -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::Matrix3, @ref Math::Matrix4) is by default constructed as identity matrix. -@code -Matrix2x3 a; // zero-filled -Vector3i b; // zero-filled -Matrix3 identity; // diagonal set to 1 -Matrix3 zero(Matrix::Zero); // zero-filled +@code{.cpp} +Matrix2x3 a; // zero-filled +Vector3i b; // zero-filled + +Matrix3 identity; // diagonal set to 1 +Matrix3 zero{Math::ZeroInit}; // zero-filled @endcode 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. All constructors check number of passed arguments and the errors are catched at compile time. -@code + +@code{.cpp} Vector3i vec(0, 1, 2); 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 with single value or create diagonal matrix from vector: -@code -Matrix3 diag(Matrix3::Identity, 2.0f); // diagonal set to 2.0f, zeros elsewhere -Vector3i fill(10); // {10, 10, 10} + +@code{.cpp} +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}); @endcode There are also shortcuts to create a vector with all but one component set to 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 -row count; vectors from vector and scalar: -@code -Math::Matrix2x3 a; -Math::Vector3 b, c; -Math::Matrix3 mat(a, b); -Math::Vector<8, Int> vec(1, b, 2, c); +@code{.cpp} +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 -@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 -simple type cast without any copying, so it's possible to conveniently operate -on the array itself: -@code +@code{.cpp} Int[] mat = { 2, 4, 6, 1, 3, 5 }; -Math::Matrix2x3::from(mat) *= 2; // mat == { 4, 8, 12, 2, 6, 10 } +Math::Matrix2x3::from(mat) *= 2; // { 4, 8, 12, 2, 6, 10 } @endcode -Note that, unlike constructors, this function has no way to check whether the -array is long enough to contain all elements, so use with caution. +@attention Note that, unlike constructors, this function has no way to check + 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 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 -@ref Color4ub): -@code +set the alpha to full value (thus @cpp 1.0f @ce for @ref Color4 and @cpp 255 @ce +for @ref Color4ub): + +@code{.cpp} 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} @endcode Similarly to axes in vectors, you can create single color shades too, or create a RGB color from HSV representation: -@code + +@code{.cpp} 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 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""_srgbaf() operator""_srgbaf() @endlink, see their documentation for more information. -@code + +@code{.cpp} Color3ub a = 0x33b27f_rgb; // {0x33, 0xb2, 0x7f} Color4 b = 0x33b27fcc_rgbaf; // {0.2f, 0.7f, 0.5f, 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 brackets: -@code + +@code{.cpp} Matrix3x2 a; a[2] /= 2.0f; // third column (column major indexing, see explanation below) 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 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 @endcode Fixed-size vector subclasses have functions for accessing named components and subparts: -@code + +@code{.cpp} Vector4i a; Int x = a.x(); a.y() += 5; @@ -193,43 +193,48 @@ a.y() += 5; Vector3i xyz = a.xyz(); xyz.xy() *= 5; @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: -@code + +@code{.cpp} Vector4i original(-1, 2, 3, 4); -Vector4i bgra = 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 } +Vector4i bgra = Math::swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 } +Math::Vector<6, Int> w10xyz = Math::swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); // { 4, 1, 0, -1, 2, 3 } @endcode @section matrix-vector-conversion Converting between different underlying types -All vector, matrix and other classes in @ref Math namespace and also -@ref Color3 and @ref Color4 classes are able to be constructed from type with -different underlying type (e.g. convert between integer and floating-point or -betweeen @ref Float and @ref Double). Unlike with plain C++ data types, the -conversion is done via *explicit* constructor. That might sound inconvenient, -but doing the conversion explicitly avoids common issues like precision loss -(or, on the other hand, doing computations in unnecessarily high precision). +All vector, matrix and other classes in @ref Math namespace are able to be +constructed from an instance with different underlying type (e.g. convert +between integer and floating-point or betweeen @ref Float and @ref Double). +Unlike with plain C++ data types, the conversion is done via *explicit* +constructor. That might sound inconvenient, but doing the conversion explicitly +avoids common issues like precision loss (or, on the other hand, doing +computations in unnecessarily high precision). 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}`. -@code +or typo), you are encouraged to use @cpp auto b = Type{a} @ce instead of +@cpp Type b{a} @ce. + +@code{.cpp} Vector3 a{2.2f, 0.25f, -5.1f}; -//Vector3i b = a; // error, implicit conversion not allowed -auto c = Vector3i{a}; // {2, 0, -5} -auto d = Vector3d{a}; // {2.2, 0.25, -5.1} +//Vector3i b = a; // error, implicit conversion not allowed +auto c = Vector3i{a}; // {2, 0, -5} +auto d = Vector3d{a}; // {2.2, 0.25, -5.1} @endcode For packing and unpacking there are @ref Math::pack() and @ref Math::unpack() functions: -@code + +@code{.cpp} Color3 a{0.8f, 1.0f, 0.3f}; -auto b = Math::unpack(a); // {204, 255, 76} +auto b = Math::pack(a); // {204, 255, 76} Color3ub c{64, 127, 89}; -auto d = Math::pack(c); // {0.251, 0.498, 0.349} +auto d = Math::unpack(c); // {0.251f, 0.498f, 0.349} @endcode 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 scalars, as is common in mathematics, Magnum also adds the ability to divide scalar with vector: -@code -Vector3 a(1.0f, 2.0f, 3.0f); -Vector3 b = a*5.0f - Vector3(3.0f, -0.5f, -7.5f); // b == {5.0f, 9.5f, 7.5f} -Vector3 c = 1.0f/a; // c == {1.0f, 0.5f, 0.333f} + +@code{.cpp} +Vector3 a{1.0f, 2.0f, 3.0f}; +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 As in GLSL, vectors can be also multiplied or divided component-wise: -@code -Vector3 a(1.0f, 2.0f, 3.0f); -Vector3 b = a*Vector3(-0.5f, 2.0f, -7.0f); // b == {-0.5f, 4.0f, -21.0f} + +@code{.cpp} +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 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. -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 floating-point type to have floating-point result. -@code -Color3ub color(80, 116, 34); -Color3ub lighter = color*1.5f; // lighter = {120, 174, 51} - -Vector3i a(4, 18, -90); -Vector3 multiplier(2.2f, 0.25f, 0.1f); -Vector3i b = a*multiplier; // b == {8, 4, -9} -Vector3 c = Vector3(a)*multiplier; // c == {8.0f, 4.5f, -9.0f} + +@code{.cpp} +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 b = a*multiplier; // {8, 4, -9} +Vector3 c = Vector3(a)*multiplier; // {8.0f, 4.5f, -9.0f} @endcode -You can use also all bitwise operations on integral vectors: -@code -Vector2i size(256, 256); -Vector2i mipLevel3Size = size >> 3; // == {32, 32} +You can also use all bitwise operations on integral vectors: + +@code{.cpp} +Vector2i size{256, 256}; +Vector2i mipLevel3Size = size >> 3; // {32, 32} @endcode Matrices can be added, subtracted and multiplied with matrix multiplication. -@code + +@code{.cpp} Matrix3x2 a; Matrix3x2 b; Matrix3x2 c = a + (-b); @@ -286,7 +296,8 @@ Matrix3x3 f = b*d; You can also multiply (properly sized) vectors with matrices. These operations are just convenience shortcuts for multiplying with single-column matrices: -@code + +@code{.cpp} Matrix3x4 a; Vector3 b; Vector4 c = a*b; @@ -298,55 +309,62 @@ Matrix4x3 e = b*d; @section matrix-vector-componentwise Component-wise and inter-vector operations As shown above, vectors can be added and multiplied component-wise using the -`+` or `*` operator. You can use @ref Math::Vector::sum() "sum()" and -@ref Math::Vector::product() "product()" for sum or product of components in -one vector: -@code -Float a = Vector3{1.5f, 0.3f, 8.0f}.sum(); // 8.8f -Int b = Vector3i{32, -5, 7}.product() // 1120 +@cpp + @ce or @cpp * @ce operator. You can use @ref Math::Vector::sum() "sum()" +and @ref Math::Vector::product() "product()" for sum or product of components +in one vector: + +@code{.cpp} +Float a = Vector3{1.5f, 0.3f, 8.0f}.sum(); // 8.8f +Int b = Vector3i{32, -5, 7}.product() // 1120 @endcode 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 Vector::min() "min()", @ref Vector::max() "max()" and @ref Vector2::minmax() "minmax()" for components in one vector. -@code + +@code{.cpp} Vector3i a{-5, 7, 24}; Vector3i b{8, -2, 12}; -Vector3i min = Math::min(a, b); // {-5, -2, 12} -Int max = a.max(); // 24 +Vector3i min = Math::min(a, b); // {-5, -2, 12} +Int max = a.max(); // 24 @endcode The vectors can be also compared component-wise, the result is returned in @ref Math::BoolVector class: -@code -BoolVector<3> largerOrEqual = a >= b; // {false, true, true} -bool anySmaller = (a < b).any(); // true -bool allLarger = (a > b).all(); // false + +@code{.cpp} +BoolVector<3> largerOrEqual = a >= b; // {false, true, true} +bool anySmaller = (a < b).any(); // true +bool allLarger = (a > b).all(); // false @endcode There are also function for component-wise rounding, sign operations, square root, various interpolation and (de)normalization functionality: -@code + +@code{.cpp} Vector3 a{5.5f, -0.3f, 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 d = Math::clamp(a, -0.2f, 55.0f); // {5.5f, -0.2f, 55.0f} +Vector3 b = Math::round(a); // {5.0f, 0.0f, 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} @endcode 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 reinterpret the matrix as vector and do the operation on it (and vice versa): -@code + +@code{.cpp} Matrix3x2 mat; Math::Vector<6, Float> vec = mat.toVector(); // ... mat = Matrix3x2::fromVector(vec); @endcode -Note that all component-wise functions in Math namespace work also for scalars: -@code +Note that all component-wise functions in @ref Math namespace work also for +scalars: + +@code{.cpp} std::pair minmax = Math::minmax(24, -5); // -5, 24 Int a = Math::lerp(0, 360, 0.75f); // 270 auto b = Math::denormalize(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 implications and it may differ from what is common in mathematics: -- Order of template arguments in specification of @ref Math::RectangularMatrix - is also column-major: -@code -Math::RectangularMatrix<2, 5, Int> mat; // two columns, five rows -@endcode -- Order of components in matrix constructors is also column-major, further - emphasized by requirement that you have to pass directly column vectors: -@code -Math::Matrix3 mat({0, 1, 2}, - {3, 4, 5}, - {6, 7, 8}); // first column is {0, 1, 2} -@endcode -- Element accessing order is also column-major, thus the bracket operator is - accessing columns. Returned vector has also its own bracket operator, which - is then indexing rows. -@code -mat[0] *= 2; // first column -mat[2][0] = 5; // first element of third column -@endcode -- Various algorithms which commonly operate on matrix rows (such as - @ref Algorithms::gaussJordanInPlace() "Gauss-Jordan elimination") have 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. - -  - -- Previous page: @ref types -- Next page: @ref transformations +
  • + Order of template arguments in specification of @ref Math::RectangularMatrix + is also column-major: + + @code{.cpp} + Math::RectangularMatrix<2, 5, Int> mat; // two columns, five rows + @endcode +
  • + Order of components in matrix constructors is also column-major, further + emphasized by requirement that you have to pass directly column vectors: + + @code{.cpp} + Math::Matrix3 mat({0, 1, 2}, + {3, 4, 5}, + {6, 7, 8}); // first column is {0, 1, 2} + @endcode +
  • + Element accessing order is also column-major, thus the bracket operator is + accessing columns. Returned vector has also its own bracket operator, which + is then indexing rows. + + @code{.cpp} + mat[0] *= 2; // first column + mat[2][0] = 5; // first element of third column + @endcode +
  • + Various algorithms which commonly operate on matrix rows (such as + @ref Algorithms::gaussJordanInPlace() "Gauss-Jordan elimination") have + 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. +
*/ } diff --git a/doc/method-chaining.dox b/doc/method-chaining.dox index 31445982e..8925b4a36 100644 --- a/doc/method-chaining.dox +++ b/doc/method-chaining.dox @@ -25,9 +25,10 @@ namespace Magnum { /** @page method-chaining Method chaining - @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 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 @@ -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 one run, effectively reducing the number of needed bindings. Consider the following example: -@code + +@code{.cpp} Texture2D carDiffuseTexture, carSpecularTexture, carBumpTexture; 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. 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. -@code + +@code{.cpp} carDiffuseTexture.setStorage(5, TextureFormat::SRGB8) .setSubImage(0, {}, diffuse) .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 created object to some variable, for example when adding static object to an scene: -@code + +@code{.cpp} Scene3D scene; -(new MyObject(&scene)) - ->rotateX(90.0_degf) +(*(new MyObject(&scene))) + .rotateX(90.0_degf) .translate({-1.5f, 0.5f, 7.0f}); @endcode */ diff --git a/doc/openal-support.dox b/doc/openal-support.dox index 5b5624a72..206b56c26 100644 --- a/doc/openal-support.dox +++ b/doc/openal-support.dox @@ -24,10 +24,13 @@ DEALINGS IN THE SOFTWARE. */ +namespace Magnum { + /** @page openal-support OpenAL support state @brief List of (un)supported OpenAL features and extensions. @tableofcontents +@m_footernavigation @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 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ @alc_extension{ENUMERATION,EXT} | done @@ -47,10 +52,12 @@ Extension | Status @subsection openal-extension-support-soft OpenAL Soft Extensions +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ @alc_extension{SOFTX,HRTF} | done @alc_extension{SOFT,HRTF} | done - */ +} diff --git a/doc/openal.dox b/doc/openal.dox index 0ed96430e..aeb2f533c 100644 --- a/doc/openal.dox +++ b/doc/openal.dox @@ -42,9 +42,10 @@ but some specific functionality has greater requirements. Following is the list of features requiring specific OpenAL extensions. - @subpage requires-al-extension +*/ -@page requires-al-extension Functionality requiring specific OpenAL extension - +/** @page requires-al-extension Functionality requiring specific OpenAL extension +@m_footernavigation */ } diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index 771cf592c..ac28607cc 100644 --- a/doc/opengl-mapping.dox +++ b/doc/opengl-mapping.dox @@ -29,17 +29,20 @@ namespace Magnum { @brief List of OpenGL commands corresponding to particular Magnum API. @tableofcontents +@m_footernavigation 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 -- *not queryable*, *not supported* -- see @ref opengl-unsupported -- (empty) -- given feature is not yet implemented +- *not queryable*, *not supported* --- see @ref opengl-unsupported +- (empty) --- given feature is not yet implemented @section opengl-mapping-functions Functions @subsection opengl-mapping-functions-a A +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @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 +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @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 +@m_class{m-fullwidth} + 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() @@ -110,6 +117,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-d D +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{DebugMessageCallback} | @ref DebugOutput::setCallback() @@ -131,6 +140,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-e E +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{Enable}, `glDisable()` | @ref Renderer::setFeature() @@ -138,6 +149,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-f F +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{FenceSync}, @fn_gl{DeleteSync} | | @@ -154,6 +167,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-g G +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @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 +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{Hint} | @ref Renderer::setHint() @subsection opengl-mapping-functions-i I +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{InvalidateBufferData} | @ref Buffer::invalidateData() @@ -248,6 +267,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-l L +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{LineWidth} | @ref Renderer::setLineWidth() @@ -256,6 +277,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-m M +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl_extension{MakeImageHandleResident,ARB,bindless_texture} | | @@ -270,12 +293,16 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-o O +@m_class{m-fullwidth} + 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() @subsection opengl-mapping-functions-p P +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{PatchParameter} | | @@ -295,12 +322,16 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-q Q +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{QueryCounter} | @ref TimeQuery::timestamp() @subsection opengl-mapping-functions-r R +@m_class{m-fullwidth} + 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() @@ -311,6 +342,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-s S +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{SampleCoverage} | | @@ -328,6 +361,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-t T +@m_class{m-fullwidth} + 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() @@ -345,6 +380,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-u U +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @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 +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{ValidateProgram} | @ref AbstractShaderProgram::validate() @@ -373,6 +412,8 @@ OpenGL function | Matching API @subsection opengl-mapping-functions-w W +@m_class{m-fullwidth} + OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{WaitSync} | | @@ -381,7 +422,9 @@ OpenGL function | Matching API @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{ALIASED_LINE_WIDTH_RANGE} | | diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox index 4c54b897d..0282eda6f 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -27,6 +27,7 @@ @brief List of (un)supported OpenGL features and extensions. @tableofcontents +@m_footernavigation @section opengl-support-state OpenGL implementation state @@ -47,6 +48,8 @@ following: @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 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 1.30 | done @@ -74,6 +77,8 @@ GLSL 1.30 | done @subsection opengl-support-31 OpenGL 3.1 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 1.40 | done @@ -87,6 +92,8 @@ GLSL 1.40 | done @subsection opengl-support-32 OpenGL 3.2 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 1.50 | done @@ -102,6 +109,8 @@ GLSL 1.50 | done @subsection opengl-support-33 OpenGL 3.3 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 3.30 | done @@ -118,6 +127,8 @@ GLSL 3.30 | done @subsection opengl-support-40 OpenGL 4.0 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 4.00 | done @@ -137,6 +148,8 @@ GLSL 4.00 | done @subsection opengl-support-41 OpenGL 4.1 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 4.10 | done @@ -149,6 +162,8 @@ GLSL 4.10 | done @subsection opengl-support-42 OpenGL 4.2 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 4.20 | done @@ -167,6 +182,8 @@ GLSL 4.20 | done @subsection opengl-support-43 OpenGL 4.3 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 4.30 | done @@ -198,6 +215,8 @@ GLSL 4.30 | done @todo Also fallback to @extension{AMD,query_buffer_object} @todo @extension{AMD,pinned_memory} "fallback" for @extension{ARB,buffer_storage} +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 4.40 | done @@ -213,6 +232,8 @@ GLSL 4.40 | done @subsection opengl-support-45 OpenGL 4.5 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ GLSL 4.50 | done @@ -230,6 +251,8 @@ GLSL 4.50 | done @subsection opengl-support-extensions ARB / Khronos OpenGL extensions +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ @extension{ARB,robustness} | done @@ -256,6 +279,8 @@ Extension | Status @todo @extension{ATI,meminfo}, @extension{NVX,gpu_memory_info}, GPU temperature @todo @extension{AMD,performance_monitor}, @extension{INTEL,performance_query} +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ @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 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ @extension{ANGLE,framebuffer_blit} | done @@ -346,6 +373,8 @@ Extension | Status @todo Support also IMG_multisampled_render_to_texture? It has different enum values (!) +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ @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 +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ @webgl_extension{ANGLE,instanced_arrays} | done @@ -434,6 +465,8 @@ Extension | Status @subsection opengl-support-webgl-extensions WebGL extensions to match desktop functionality +@m_class{m-fullwidth} + Extension | Status ------------------------------------------- | ------ @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 doesn't make any full-screen postprocessing easier, as shaders are excluded. - */ /** @page opengl-deprecated Deprecated OpenGL API list +@m_footernavigation + See also @ref opengl-unsupported and @ref deprecated. */ diff --git a/doc/opengl-wrapping.dox b/doc/opengl-wrapping.dox index 4adb22fb0..c67ed709f 100644 --- a/doc/opengl-wrapping.dox +++ b/doc/opengl-wrapping.dox @@ -27,16 +27,14 @@ namespace Magnum { /** @page opengl-wrapping OpenGL wrapping layer @brief Overview of the base OpenGL wrapper API -- Previous page: @ref plugins -- Next page: @ref shaders +@tableofcontents +@m_footernavigation 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 away extension and platform differences, tracking the state for optimum performance and selecting the best available code path for given system. -@tableofcontents - Magnum provides wrappers for most native OpenGL objects like buffers, textures, meshes, queries, transform feedback objects, shaders etc., but makes it 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 the object before creating context (such as class members) or if you know you would overwrite it later with another object: -@code + +@code{.cpp} Mesh mesh{NoCreate}; Buffer vertices{NoCreate}, indices{NoCreate}; std::tie(mesh, vertices, indices) = importSomeMesh(); @endcode 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 -equivalent to moved-from state and you are responsible for proper deletion -of the returned OpenGL object (note that it is possible to just query ID of the -underlying without releasing it using `id()`). It is also possible to do the -opposite -- wrapping existing OpenGL object ID into Magnum object instance -using `wrap()`. -@code +call @cpp release() @ce. It returns ID of the underlying object, the instance +is then equivalent to moved-from state and you are responsible for proper +deletion of the returned OpenGL object (note that it is possible to just query +ID of the underlying without releasing it using `id()`). It is also possible to +do the opposite --- wrapping existing OpenGL object ID into Magnum object +instance using @cpp wrap() @ce. + +@code{.cpp} // Transferring the instance to external library { Buffer buffer; @@ -89,20 +89,21 @@ using `wrap()`. } @endcode -The `NoInit` constructor, `wrap()` and `release()` functions are available for -all OpenGL classes except @ref Shader and @ref AbstractShaderProgram, where -wrapping external instances makes less sense. +The @cpp NoCreate @ce constructor, @cpp wrap() @ce and @cpp release() @ce +functions are available for all OpenGL classes except @ref Shader and +@ref AbstractShaderProgram, where wrapping external instances makes less sense. @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 -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 improve performance and avoid redundant state changes, Magnum internally tracks OpenGL state such as currently bound objects, activated renderer features etc. When combining Magnum with third-party code, the internal state tracker may get confused and you need to reset it using @ref Context::resetState(): -@code + +@code{.cpp} Buffer buffer; // Raw OpenGL calls @@ -117,14 +118,14 @@ Context::current()->resetState(Context::State::Buffers); auto data = buffer.map(...); @endcode -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 +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 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 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 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 capabilities, large portion of the functionality needs to be realized under the 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. 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 states whether the functionality is available everywhere or whether particular GL version/extension is required. The information is also aggregated on @ref opengl-required-extensions documentation page. Use @ref Context::isVersionSupported() or @ref Context::isExtensionSupported(): -@code + +@code{.cpp} TextureFormat format; if(Context::current()->isExtensionSupported()) format = TextureFormat::DepthComponent32F; @@ -152,11 +154,11 @@ else @endcode @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 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 application prints list of extensions that were used to improve the default 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 platforms that don't support it etc. The goal is to abstract away the (mostly unimportant) differences for easier porting. -@code + +@code{.cpp} Texture2D texture; // - on OpenGL 4.5+/ARB_direct_state_access this calls glTextureStorage2D() @@ -181,8 +184,5 @@ Texture2D texture; texture.setStorage(4, TextureFormat::RGBA8, {256, 256}); @endcode -- Previous page: @ref plugins -- Next page: @ref shaders - */ } diff --git a/doc/opengl.dox b/doc/opengl.dox index 21b58ed85..8bf38a264 100644 --- a/doc/opengl.dox +++ b/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, @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-gl31 Functionality requiring OpenGL 3.1 -@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-gl44 Functionality requiring OpenGL 4.4 + * @m_footernavigation + */ -@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. @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 or desktop OpenGL. @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 +*/ -@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. +*/ -@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. @see @ref MAGNUM_TARGET_WEBGL, @ref requires-gl +*/ -@page requires-webgl20 Functionality requiring WebGL 2.0 - -@page requires-webgl-extension Functionality requiring specific WebGL extension +/** @page requires-webgl20 Functionality requiring WebGL 2.0 + * @m_footernavigation + */ -*/ +/** @page requires-webgl-extension Functionality requiring specific WebGL extension + * @m_footernavigation + */ diff --git a/doc/platform.dox b/doc/platform.dox index 7d44452bb..c62487c96 100644 --- a/doc/platform.dox +++ b/doc/platform.dox @@ -27,7 +27,8 @@ namespace Magnum { /** @page platform Platform support @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 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 information about building and usage with CMake. -@tableofcontents - 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 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 toolkits, you must provide one-argument constructor and implement at least @ref Platform::Sdl2Application::drawEvent() "drawEvent()" function. The class -can be then used directly in `main()`, but for convenience and portability it's -better to use @ref MAGNUM_SDL2APPLICATION_MAIN() macro. +can be then used directly in @cpp main() @ce, but for convenience and +portability it's better to use @ref MAGNUM_SDL2APPLICATION_MAIN() macro. -To simplify the porting, the library provides `Platform::Application` typedef -and `MAGNUM_APPLICATION_MAIN()` macro (but only if only one application header -is included, to avoid ambiguity). Changing the code to use different toolkit is -then matter of replacing only the `#``include` statement (and changing -one line in CMake build script, as you see later). +To simplify the porting, the library provides @cpp Platform::Application @ce +typedef and @cpp MAGNUM_APPLICATION_MAIN() @ce macro (but only if only one +application header is included, to avoid ambiguity). Changing the code to use +different toolkit is then matter of replacing only the @cpp #include @ce +statement (and changing one line in CMake build script, as you see later). Barebone application implementation which will just clear the window to dark 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) repository. -@code +@code{.cpp} #include #include #include @@ -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 @ref Platform::Sdl2Application::viewportEvent() "viewportEvent()" function and pass the new size to the framebuffer: -@code + +@code{.cpp} 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. You need to implement just @ref Platform::WindowlessGlxApplication::exec() "exec()" -function. The class can be then used directly in `main()`, but again, for -convenience and portability it's better to use +function. The class can be then used directly in @cpp main() @ce, but again, +for convenience and portability it's better to use @ref MAGNUM_WINDOWLESSGLXAPPLICATION_MAIN() macro. Similarly as with windowed applications, to simplify the porting, the library -provides `Platform::WindowlessApplication` typedef and `MAGNUM_WINDOWLESSAPPLICATION_MAIN()` -macro, but only if just one windowless application header is included. Changing -the code to use different toolkit is then matter of replacing only the -`#``include` statement. Aliases for windowless applications are -separated from aliases for windowed applications, because projects commonly -contain both graphics application and command-line tools (for data preparation -etc.). +provides @cpp Platform::WindowlessApplication @ce typedef and +@cpp MAGNUM_WINDOWLESSAPPLICATION_MAIN() @ce macro, but only if just one +windowless application header is included. Changing the code to use different +toolkit is then matter of replacing only the @cpp #include @ce statement. +Aliases for windowless applications are separated from aliases for windowed +applications, because projects commonly contain both graphics application and +command-line tools (for data preparation etc.). Barebone application which will just print out current OpenGL version and 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) repository. -@code +@code{.cpp} #include #include @@ -191,9 +191,9 @@ aliases (or `Magnum::WindowlessApplication` for windowless applications), but only if only one application (windowless application) component is requested to avoid ambiguity. Changing the build script to use different toolkit is then 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) 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 application constructor. Using method chaining it can be done conveniently like this: -@code + +@code{.cpp} MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc, argv, Configuration() .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` instead of @ref Platform::Sdl2Application::Configuration "Configuration" 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) { // ... @@ -241,7 +243,8 @@ context using @ref Platform::Sdl2Application::tryCreateContext() "tryCreateConte 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 back to no-AA rendering: -@code + +@code{.cpp} 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 @ref Platform::Context class, which will take care of proper initialization and feature detection. The instance must be alive for whole application lifetime. -Example `main()` function with manual initialization is in the following code -listing. +Example @cpp main() @ce function with manual initialization is in the following +code listing. @note Fully contained application using with manual Magnum initialization on top of Qt toolkit is available in `base-qt` branch of [Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap) repository. -@code +@code{.cpp} int main(int argc, char** argv) { // 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. These platform-specific libraries are available: -- `CglContext` -- CGL context (macOS) -- `EglContext` -- EGL context (everywhere except Emscripten) -- `GlxContext` -- GLX context (X11-based Unix) -- `WglContext` -- WGL context (Windows) +- `CglContext` --- CGL context (macOS) +- `EglContext` --- EGL context (everywhere except Emscripten) +- `GlxContext` --- GLX context (X11-based Unix) +- `WglContext` --- WGL context (Windows) Systems not listed here (such as Emscripten) don't need any `Context` library, 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 `GlxContext` component, and link to `Magnum::GlxContext` target. Similarly to 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: -@code + +@code{.cmake} find_package(Magnum REQUIRED GlxContext) 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. 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. @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. -@code +@code{.cpp} int main(int argc, char** argv) { Platform::WindowlessGLContext glContext{{}}; 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 has to be done on the main thread. -@code +@code{.cpp} int main() { Platform::WindowlessGLContext glContext{{}}; @@ -385,7 +389,5 @@ int main() { worker.join(); } @endcode - -- Next page: @ref types */ } diff --git a/doc/plugins.dox b/doc/plugins.dox index d47d812e6..0a89f9ffd 100644 --- a/doc/plugins.dox +++ b/doc/plugins.dox @@ -27,8 +27,8 @@ namespace Magnum { /** @page plugins Loading and using plugins @brief Extending Magnum with additional functionality -- Previous page: @ref transformations -- Next page: @ref opengl-wrapping +@tableofcontents +@m_footernavigation The base Magnum library contains math support, scene graph implementation and 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 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 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 @@ -54,22 +52,22 @@ might not be available on all platforms. 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 @ref Trade namespace for available importer plugins. These are installed in `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 available image converter plugins. These are installed in `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 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 converter plugins. These are installed in `MAGNUM_PLUGINS_FONTCONVERTER_DIR` 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 plugins. These are installed in `MAGNUM_PLUGINS_AUDIOIMPORTER_DIR` directory. @@ -92,7 +90,8 @@ information. You can provide the variable to your sources using CMake configuration file. Create `configure.h.cmake` file in your source directory with contents similar to these: -@code + +@code{.cpp} #define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DIR}" @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 debug build on multi-configuration build sytems and fall back to autodetection for the rest: -@code + +@code{.cpp} #ifdef CORRADE_IS_DEBUG_BUILD #define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}" #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 replaced with the actual value) is put into build directory, so don't forget to add it to include path: -@code + +@code{.cmake} configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/configure.h) 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 instance of it. Keep in mind that the manager instance must exist for whole lifetime of all plugin instances created from it. -@code + +@code{.cpp} #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 instance of corresponding plugin manager in particular plugin dir so the dependency can be found. Example: -@code + +@code{.cpp} PluginManager::Manager importerManager(MAGNUM_PLUGINS_IMPORTER_DIR); PluginManager::Manager 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 plugin and link it into the executable in your `CMakeLists.txt`. See @ref cmake and @ref cmake-plugins for additional information. -@code + +@code{.cmake} find_package(MagnumPlugins REQUIRED PngImporter) 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 plugin will not be found. See the macro documentation for information about automatic importing and namespace issues. -@code + +@code{.cpp} int main(int argc, char** argv) { 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 to how static plugins are found above. See @ref cmake and @ref cmake-plugins for more information. - -- Previous page: @ref transformations -- Next page: @ref opengl-wrapping - */ } diff --git a/doc/portability.dox b/doc/portability.dox index b8775f9a3..6c0e99f91 100644 --- a/doc/portability.dox +++ b/doc/portability.dox @@ -28,13 +28,14 @@ namespace Magnum { @brief How to support different platforms and different OpenGL capabilities within one codebase. @tableofcontents +@m_footernavigation @section portability-target Target-specific code 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 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 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 Example usage: -@code + +@code{.cpp} #ifndef MAGNUM_TARGET_GLES Renderer::setPolygonMode(Renderer::PolygonMode::Lines); // 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 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 -compiler with good enough support of the new standard. Currently Magnum is -written with GCC 4.8 and Clang 3.1 in mind, but support for some other -compilers is also available and handled by Corrade library. See @ref Corrade.h -for more information. +faster and more secure, but on the other hand it requires a compiler with good +enough support of the standard. Currently Magnum is written with at least GCC +4.8, Clang 3.1 and MSVC 2015 in mind. See @ref Corrade.h for more information. 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 -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 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 -Some functionality is depending on support of particular extension and thus -the decision cannot be made at compile time. Header @ref Extensions.h contains -list of extensions, which you can pass to @ref Context::isExtensionSupported() -and decide based on that: -@code -if(Context::instance()->isExtensionSupported()) { +Some functionality is depending on support of a particular OpenGL extension and +thus the decision cannot be made at compile time. Header @ref Extensions.h +contains list of extensions, which you can pass to +@ref Context::isExtensionSupported() and decide based on that: + +@code{.cpp} +if(Context::current().isExtensionSupported()) { // draw mesh with wireframe on top in one pass using geometry shader... } else { // draw underlying mesh... @@ -96,13 +97,14 @@ if(Context::instance()->isExtensionSupported()) { 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 -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 extensions, you can use macros @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED() or @ref MAGNUM_ASSERT_VERSION_SUPPORTED() to add mandatory requirement of given extension or version: -@code + +@code{.cpp} MAGNUM_ASSERT_EXTENSION_SUPPORTED(GL::ARB::geometry_shader4); // just use geometry shader and don't care about old hardware @endcode @@ -118,20 +120,25 @@ available, but also have proper fallback when it's not, see for example @section portability-shaders Writing portable shaders Shaders are probably the most painful thing to port. There are many issues to -address - different shader syntax (`in`/`out` vs. `attribute` and `varying` -etc.), explicit vs. implicit methods to specify vertex attribute, uniform and -texture uniform locations, required precision qualifiers in OpenGL ES etc. +address --- different shader syntax (@glsl in @ce / @glsl out @ce vs. +@glsl attribute @ce and @glsl varying @ce etc.), explicit vs. implicit methods +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 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: -@code + +@code{.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")); @endcode -@code + +@code{.vert} // MyShader.vert #if __VERSION__ < 130 #define in attribute @@ -149,12 +156,13 @@ void main() { @endcode 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 use @ref Context::isExtensionSupported(Version) const to check that the extension is present in given version: -@code -if(!Context::instance()->isExtensionSupported(version)) { + +@code{.cpp} +if(!Context::current().isExtensionSupported(version)) { bindAttributeLocation(Position::Location, "position"); // ... } @@ -165,21 +173,21 @@ specifying attribute location, uniform location and texture binding unit in various OpenGL versions. 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 -sources to see how portability is handled there. +version 2.1 and also OpenGL ES 2.0 and 3.0 (or WebGL 1.0 / 2.0). Feel free to +look into their sources to see how portability is handled there. @section portability-applications Platform-specific application support 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 -to the application, how to handle input events, how to create window and +browser --- each platform has different requirements how to create an entry +point to the application, how to handle input events, how to create window and OpenGL context etc. Namespace @ref Platform contains application base classes which are abstracting out most of it for your convenience. 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 -change any other code. It has its limitations, though - some toolkits don't -support all keys, mouse movement events etc. +change any other code. It has its limitations, though --- some toolkits don't +support all special keys, mouse movement events etc. 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 @@ -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 functions will work on both without changes, the main difference might (or might not, depending what you use) be in particular event handlers: -@code + +@code{.cpp} #ifndef MAGNUM_TARGET_GLES #include #else @@ -211,10 +220,11 @@ class MyApplication: public Platform::Application { MAGNUM_APPLICATION_MAIN(MyApplication) @endcode -And corresponding CMake code. Note that we need to call `find_package()` twice, -first to get variable `MAGNUM_TARGET_GLES` and then again to find proper -application library based on its value: -@code +And corresponding CMake code. Note that we need to call @cmake find_package() @ce +twice, first to get the @ref MAGNUM_TARGET_GLES variable and then again to find +proper application library based on its value: + +@code{.cmake} find_package(Magnum REQUIRED) if(MAGNUM_TARGET_GLES) @@ -228,6 +238,5 @@ target_link_libraries(myapplication Magnum::Magnum Magnum::Application) @endcode - */ } diff --git a/doc/scenegraph.dox b/doc/scenegraph.dox index 666af5e77..4ad5a95a4 100644 --- a/doc/scenegraph.dox +++ b/doc/scenegraph.dox @@ -27,15 +27,13 @@ namespace Magnum { /** @page scenegraph Using scene graph @brief Overview of scene management capabilities. -- Previous page: @ref shaders -- Next page: @ref shapes - Scene graph provides way to hiearchically manage your objects, their transformation, physics interaction, animation and rendering. The library is contained in @ref SceneGraph namespace, see its documentation for more information about building and usage with CMake. @tableofcontents +@m_footernavigation There are naturally many possible feature combinations (2D vs. 3D, different 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 three main components: - - objects, providing parent/children hierarchy - - transformations, implementing particular transformation type - - features, providing rendering capabilities, collision detection, physics - etc. +- objects, providing parent/children hierarchy +- transformations, implementing particular transformation type +- features, providing rendering capabilities, collision detection, physics + etc. @note Fully contained applications with initial scene graph setup are available 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. 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 transformations, computing their inverse and accounting for floating-point 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 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 floating-point drift reduction -- @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D" -- +- @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D" --- arbitrary 3D transformations but with slow inverse transformations and no floating-point drift reduction -- @ref SceneGraph::BasicRigidMatrixTransformation2D "SceneGraph::RigidMatrixTransformation2D" -- +- @ref SceneGraph::BasicRigidMatrixTransformation2D "SceneGraph::RigidMatrixTransformation2D" --- 2D translation, rotation and reflection (no scaling), with relatively fast 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 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 floating-point drift reduction -- @ref SceneGraph::BasicDualQuaternionTransformation "SceneGraph::DualQuaternionTransformation" -- +- @ref SceneGraph::BasicDualQuaternionTransformation "SceneGraph::DualQuaternionTransformation" --- 3D translation and rotation with fast inverse transformation and 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) Common usage of transformation classes is to typedef Scene and Object with desired transformation type to save unnecessary typing later: -@code + +@code{.cpp} typedef SceneGraph::Scene Scene3D; typedef SceneGraph::Object Object3D; @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 and @ref SceneGraph::MatrixTransformation3D. For convenience you can use method chaining: -@code + +@code{.cpp} Scene3D scene; 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 observed through @ref SceneGraph::Object::parent() and @ref SceneGraph::Object::children(). -@code + +@code{.cpp} Scene3D scene; Object3D* first = new Object3D{&scene}; Object3D* second = new Object3D{first}; @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 @ref scenegraph-object-construction-order "construction and destruction order" below for information about possible issues. To reflect the implicit memory management in the code better, you can use @ref SceneGraph::Object::addChild() instead of the naked `new` call in the code above: -@code + +@code{.cpp} Scene3D scene; Object3D& first = scene.addChild(); @@ -162,21 +164,21 @@ have to add a *feature* to it. Magnum provides the following builtin features. See documentation of each class 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 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 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 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". See @ref shapes for more information. - @ref DebugTools::ObjectRenderer "DebugTools::ObjectRenderer*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 @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 don't even need to keep the pointer to it. List of object features is accessible through @ref SceneGraph::Object::features(). -@code + +@code{.cpp} Object3D& o; new MyFeature{o, ...}; @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 subclass without having to subclass each feature individually (and making the code overly verbose). Simplified example: -@code + +@code{.cpp} class BouncingBall: public Object3D, SceneGraph::Drawable3D, SceneGraph::Animable3D { public: 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 @ref SceneGraph::AbstractObject::addFeature() counterpart to @ref SceneGraph::Object::addChild(): -@code + +@code{.cpp} Object3D& o; o.addFeature(...); @endcode @@ -230,12 +235,12 @@ o.addFeature(...); @subsection scenegraph-features-caching Transformation caching in features 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 objects etc. To avoid computing the transformations from scratch every time, 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(). 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. @@ -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, @ref SceneGraph::Object::setClean() does nothing. -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 +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 inheritance and implement it using @ref SceneGraph::AbstractFeature. In order to have caching, you must enable it first, because by default the caching is disabled. You can enable it using @ref SceneGraph::AbstractFeature::setCachedTransformations() and then implement corresponding cleaning function(s): -@code + +@code{.cpp} class CachingObject: public Object3D, SceneGraph::AbstractFeature3D { public: 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 functions to control the transformation: -- @ref SceneGraph::AbstractTransformation "SceneGraph::AbstractTransformation*D" -- +- @ref SceneGraph::AbstractTransformation "SceneGraph::AbstractTransformation*D" --- base for all transformations -- @ref SceneGraph::AbstractTranslation "SceneGraph::AbstractTranslation*D" -- +- @ref SceneGraph::AbstractTranslation "SceneGraph::AbstractTranslation*D" --- base for all transformations providing translation - @ref SceneGraph::AbstractBasicTranslationRotation2D "SceneGraph::AbstractTranslationRotation2D", - @ref SceneGraph::AbstractBasicTranslationRotation3D "SceneGraph::AbstractTranslationRotation3D" -- + @ref SceneGraph::AbstractBasicTranslationRotation3D "SceneGraph::AbstractTranslationRotation3D" --- base for all transformations providing translation and rotation - @ref SceneGraph::AbstractBasicTranslationRotationScaling2D "SceneGraph::AbstractBasicTranslationRotationScaling2D", - @ref SceneGraph::AbstractBasicTranslationRotationScaling3D "SceneGraph::AbstractBasicTranslationRotationScaling3D" -- + @ref SceneGraph::AbstractBasicTranslationRotationScaling3D "SceneGraph::AbstractBasicTranslationRotationScaling3D" --- base for all transformations providing translation, rotation and scaling 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 @ref SceneGraph::AbstractObject and needed transformation from one constructor parameter using small trick: -@code + +@code{.cpp} class TransformingFeature: public SceneGraph::AbstractFeature3D { public: template TransformingFeature(SceneGraph::Object& object): @@ -319,6 +326,7 @@ class TransformingFeature: public SceneGraph::AbstractFeature3D { SceneGraph::AbstractTranslationRotation3D& transformation; }; @endcode + If we take for example @ref SceneGraph::Object "SceneGraph::Object", it is derived from @ref SceneGraph::AbstractObject "SceneGraph::AbstractObject3D" and @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D", @@ -333,21 +341,24 @@ should be aware of: @subsection scenegraph-object-construction-order Object hierarchy -When objects are created on the heap (the preferred way, using `new`), they -can be constructed in any order and they will be destroyed when their parent -is destroyed. When creating them on the stack, however, they will be destroyed -when they go out of scope. Normally, the natural order of creation is not a -problem: -@code +When objects are created on the heap (the preferred way, using @cpp new @ce), +they can be constructed in any order and they will be destroyed when their +parent is destroyed. When creating them on the stack, however, they will be +destroyed when they go out of scope. Normally, the natural order of creation is +not a problem: + +@code{.cpp} { Scene3D scene; Object3D object(&scene); } @endcode + The object is created last, so it will be destroyed first, removing itself from `scene`'s children list, causing no problems when destroying `scene` object later. However, if their order is swapped, it will cause problems: -@code + +@code{.cpp} { Object3D object; Scene3D scene; @@ -355,6 +366,7 @@ object later. However, if their order is swapped, it will cause problems: object.setParent(&scene); } // crash! @endcode + 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 `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 as member it's no issue, features added using multiple inheritance must be inherited after the Object class: -@code + +@code{.cpp} class MyObject: public Object3D, MyFeature { public: MyObject(Object3D* parent): Object3D(parent), MyFeature(*this) {} }; @endcode -When constructing MyObject, Object3D constructor is called first and then -MyFeature constructor adds itself to Object3D's list of features. When -destroying MyObject, its destructor is called and then the destructors of -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 + +When constructing `MyObject`, `Object3D` constructor is called first and then +`MyFeature` constructor adds itself to `Object3D`'s list of features. When +destroying `MyObject`, its destructor is called and then the destructors of +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{.cpp} class MyObject: MyFeature, public Object3D { public: MyObject(Object3D* parent): MyFeature(*this), Object3D(parent) {} // crash! }; @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 -created, creating empty feature list, making the feature invisible. + +`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 created, creating empty feature list, making the feature +invisible. If we would construct them in swapped order (if it is even possible), it wouldn't help either: -@code + +@code{.cpp} class MyObject: MyFeature, public Object3D { public: MyObject(Object3D* parent): Object3D(parent), MyFeature(*this) {} @@ -397,11 +415,9 @@ class MyObject: MyFeature, public Object3D { // crash on destruction! }; @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 -- Next page: @ref shapes +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). */ } diff --git a/doc/shaders.dox b/doc/shaders.dox index 50d38499b..e2569f0bb 100644 --- a/doc/shaders.dox +++ b/doc/shaders.dox @@ -27,24 +27,22 @@ namespace Magnum { /** @page shaders Builtin shaders @brief Overview and basic usage of builtin shaders. -- Previous page: @ref opengl-wrapping -- Next page: @ref scenegraph - @tableofcontents +@m_footernavigation Magnum contains a set of general-purpose shaders for easy prototyping, UI rendering and data visualization/debugging in both 2D and 3D scenes. The following shaders are available, see documentation of each class for sample output and example setup: -- @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 -- @ref Shaders::Vector "Shaders::Vector*D" -- colored vector graphics +- @ref Shaders::Vector "Shaders::Vector*D" --- colored vector graphics - @ref Shaders::DistanceFieldVector "Shaders::DistanceFieldVector*D" -- colored and outlined vector graphics -- @ref Shaders::VertexColor "Shaders::VertexColor*D" -- vertex-colored meshes -- @ref Shaders::Phong -- Phong shading using colors or textures, 3D only -- @ref Shaders::MeshVisualizer -- wireframe visualization, 3D only +- @ref Shaders::VertexColor "Shaders::VertexColor*D" --- vertex-colored meshes +- @ref Shaders::Phong --- Phong shading using colors or textures, 3D only +- @ref Shaders::MeshVisualizer --- wireframe visualization, 3D only 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 @@ -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 position in the buffer. See @ref Mesh::addVertexBuffer() for details and usage examples. Example mesh configuration for @ref Shaders::Phong shader: -@code + +@code{.cpp} struct Vertex { Vector3 position; 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 compiled shader code. Other configuration is specified through uniforms and various binding points, commonly exposed through various setters. Example -configuration and rendering using @ref Shaders::Phong "Shaders::Phong": -@code +configuration and rendering using @ref Shaders::Phong : + +@code{.cpp} Matrix4 transformationMatrix, projectionMatrix; 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. Configuration of the above mesh using generic attributes could then look like this: -@code + +@code{.cpp} mesh.addVertexBuffer(vertices, 0, Shaders::Generic3D::Position{}, Shaders::Generic3D::Normal{}, Shaders::Generic3D::TextureCoordinates{}); @endcode + Note that in this particular case both configurations are equivalent, because @ref Shaders::Phong also uses generic vertex attribute definitions. Then you can render the mesh using @ref Shaders::Phong shader like above, or use for example @ref Shaders::Flat3D or even @ref Shaders::MeshVisualizer with the same mesh reconfiguration. The unused attributes will be simply ignored. -@code + +@code{.cpp} Shaders::MeshVisualizer visualizerShader{Shaders::MeshVisualizer::Wireframe}; visualizerShader.setColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) .setWireframeColor(Color3{0.95f}) @@ -128,9 +131,5 @@ mesh.draw(visualizerShader); The @ref MeshTools::compile() utility configures meshes using generic vertex attribute definitions to make them usable with any shader. - -- Previous page: @ref opengl-wrapping -- Next page: @ref scenegraph - */ } diff --git a/doc/shapes.dox b/doc/shapes.dox index 185f4f3c1..14454978a 100644 --- a/doc/shapes.dox +++ b/doc/shapes.dox @@ -27,16 +27,14 @@ namespace Magnum { /** @page shapes Collision detection @brief Collection of simple shapes for high performance collision detection. -- Previous page: @ref scenegraph -- Next page: @ref debug-tools +@tableofcontents +@m_footernavigation 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 library is contained in @ref Shapes namespace, see its documentation for more information about building and usage with CMake. -@tableofcontents - These shapes can be either one-, two- or three-dimensional and they can be 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 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 around platformer game level. @subsection shapes-1D One-dimensional shapes -- @ref Shapes::Point "Shapes::Point*D" -- @copybrief Shapes::Point -- @ref Shapes::Line "Shapes::Line*D" -- @copybrief Shapes::Line -- @ref Shapes::LineSegment "Shapes::LineSegment*D" -- @copybrief Shapes::LineSegment +- @ref Shapes::Point "Shapes::Point*D" --- @copybrief Shapes::Point +- @ref Shapes::Line "Shapes::Line*D" --- @copybrief Shapes::Line +- @ref Shapes::LineSegment "Shapes::LineSegment*D" --- @copybrief Shapes::LineSegment 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. @subsection shapes-2D Two-dimensional shapes -- Shapes::Plane -- @copybrief Shapes::Plane +- @ref Shapes::Plane --- @copybrief Shapes::Plane @subsection shapes-3D Three-dimensional shapes -- @ref Shapes::Sphere "Shapes::Sphere*D" -- @copybrief Shapes::Sphere -- @ref Shapes::InvertedSphere "Shapes::InvertedSphere*D" -- @copybrief Shapes::InvertedSphere -- @ref Shapes::Cylinder "Shapes::Cylinder*D" -- @copybrief Shapes::Cylinder -- @ref Shapes::Capsule "Shapes::Capsule*D" -- @copybrief Shapes::Capsule -- @ref Shapes::AxisAlignedBox "Shapes::AxisAlignedBox*D" -- @copybrief Shapes::AxisAlignedBox -- @ref Shapes::Box "Shapes::Box*D" -- @copybrief Shapes::Box +- @ref Shapes::Sphere "Shapes::Sphere*D" --- @copybrief Shapes::Sphere +- @ref Shapes::InvertedSphere "Shapes::InvertedSphere*D" --- @copybrief Shapes::InvertedSphere +- @ref Shapes::Cylinder "Shapes::Cylinder*D" --- @copybrief Shapes::Cylinder +- @ref Shapes::Capsule "Shapes::Capsule*D" --- @copybrief Shapes::Capsule +- @ref Shapes::AxisAlignedBox "Shapes::AxisAlignedBox*D" --- @copybrief Shapes::AxisAlignedBox +- @ref Shapes::Box "Shapes::Box*D" --- @copybrief Shapes::Box The easiest (and most efficient) shape combination for detecting collisions 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 Shapes can be composed together using one of three available logical -operations: AND, OR and NOT. These operations are mapped to `&&`, `||` and `!` -operators, so for example creating negation of logical OR of line segment and -point is simple as this: -@code +operations: AND, OR and NOT. These operations are mapped to @cpp && @ce, @cpp || @ce +and @cpp ! @ce operators, so for example creating negation of logical OR of +line segment and point is simple as this: + +@code{.cpp} Shapes::LineSegment3D segment; Shapes::Point3D point; Shapes::Composition3D composition = !(segment || point); @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 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, 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 -`&&` operator -- the collision is initially detected on first (simplified) -shape and then on the other: -@code +@cpp && @ce operator --- the collision is initially detected on first +(simplified) shape and then on the other: + +@code{.cpp} Shapes::Sphere3D sphere; Shapes::Box3D box; Shapes::AxisAlignedBox3D simplified; @@ -111,9 +111,10 @@ Shapes::Composition3D composition = simplified && (sphere || box); @section shapes-collisions Detecting shape collisions Shape pairs which have collision occurence detection implemented can be tested -for collision using the `%` operator. The operator returns boolean describing -whether the collision happened or not. Example: -@code +for collision using the @cpp % @ce operator. The operator returns boolean +describing whether the collision happened or not. Example: + +@code{.cpp} Shapes::Point3D point; 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 above, this operation is not commutative. See @ref Shapes::Collision class documentation for more information about the returned data. Example: -@code + +@code{.cpp} const Shapes::Collision3D c = point/sphere; if(c) { 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. In conjunction with @ref Shapes::ShapeGroup you can use @ref Shapes::Shape::collides() and @ref Shapes::Shape::collision() similarly to -the `%` and `/` operators above. Please note that the shape group caches the -absolute transformations of all shapes and thus you need to explicitly call -@ref Shapes::ShapeGroup::setClean() before computing the collisions if you did -any modifications to the objects in the scene. +the @cpp % @ce and @cpp / @ce operators above. Please note that the shape group +caches the absolute transformations of all shapes and thus you need to +explicitly call @ref Shapes::ShapeGroup::setClean() before computing the +collisions if you did any modifications to the objects in the scene. Scenegraph-flavored equivalent to the above code: -@code + +@code{.cpp} Shapes::ShapeGroup3D shapes; Object3D& a; auto aShape = new Shapes::Shape(a, {{}, 23.0f}, &shapes); @@ -163,14 +166,10 @@ if(aShape->collides(*bShape)) { @endcode There is also @ref Shapes::ShapeGroup::firstCollision() function which returns -arbitrary first collision for given shape in whole group (or `nullptr`, if -there isn't any collision). +arbitrary first collision for given shape in whole group (or @cpp nullptr @ce, +if there isn't any collision). You can also use @ref DebugTools::ShapeRenderer to visualize the shapes for debugging purposes. See also @ref scenegraph for introduction. - -- Previous page: @ref scenegraph -- Next page: @ref debug-tools - */ } diff --git a/doc/tips.dox b/doc/tips.dox index 3289be8cc..d09b290d5 100644 --- a/doc/tips.dox +++ b/doc/tips.dox @@ -27,11 +27,11 @@ namespace Magnum { /** @page tips Tips and tricks @brief Hints for better productivity and performance. -- @subpage method-chaining -- @copybrief method-chaining -- @subpage portability -- @copybrief portability -- @subpage best-practices -- @copybrief best-practices -- @subpage compilation-speedup -- @copybrief compilation-speedup -- @subpage troubleshooting -- @copybrief troubleshooting +- @subpage method-chaining --- @copybrief method-chaining +- @subpage portability --- @copybrief portability +- @subpage best-practices --- @copybrief best-practices +- @subpage compilation-speedup --- @copybrief compilation-speedup +- @subpage troubleshooting --- @copybrief troubleshooting */ } diff --git a/doc/transformations.dox b/doc/transformations.dox index 9241cdd00..60ff8ad26 100644 --- a/doc/transformations.dox +++ b/doc/transformations.dox @@ -27,16 +27,14 @@ namespace Magnum { /** @page transformations 2D and 3D transformations @brief Introduction to essential operations on vectors and points. -- Previous page: @ref matrix-vector -- Next page: @ref plugins +@tableofcontents +@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 in @ref Math namespace, see its documentation for more information about usage with CMake. -@tableofcontents - 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 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 homogeneous transformation matrix, i.e. @ref Matrix3 for 2D and @ref Matrix4 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 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 transformation properties (such as rotation angle/axis) from them, interpolate 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 scaling, shearing and whatnot. 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 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 @@ -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 and rotation transformation can be created by calling @ref Matrix3::rotation(), @ref Complex::rotation() or @ref DualComplex::rotation(), for example: -@code + +@code{.cpp} auto a = Matrix3::rotation(23.0_degf); auto b = Complex::rotation(Rad(Constants::piHalf())); 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(), @ref Matrix4::rotationY() and @ref Matrix4::rotationZ() which are faster than using the generic function for rotation around primary axes. Examples: -@code + +@code{.cpp} 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 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 Vector2::xAxis() or @ref Vector2::yAxis() to translate only along given axis. Examples: -@code + +@code{.cpp} auto a = Matrix3::translation(Vector2::xAxis(-5.0f)); auto b = DualComplex::translation({-1.0f, 0.5f}); @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 @ref Matrix4::translation() or @ref DualQuaternion::translation(). You can use @ref Vector3::xAxis() and friends also here. Examples: -@code + +@code{.cpp} auto a = Matrix4::translation(vector); auto b = DualQuaternion::translation(Vector3::zAxis(1.3f)); @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 call explicit one-parameter vector constructor to scale uniformly on all axes. Examples: -@code + +@code{.cpp} auto a = Matrix3::scaling(Vector2::xScale(2.0f)); auto b = Matrix4::scaling({2.0f, -2.0f, 1.5f}); 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 @ref Matrix4::reflection(). You can use @ref Vector3::xAxis() and friends also here. Examples: -@code + +@code{.cpp} auto a = Matrix3::reflection(Vector2::yAxis()); auto b = Matrix4::reflection(axis.normalized()); @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, 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: -@code + +@code{.cpp} auto a = Matrix3::projection({4.0f, 3.0f}); auto b = Matrix4::orthographicProjection({4.0f, 3.0f, 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 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 left-hand side is applied second. For example, rotation followed by translation is done like this: -@code + +@code{.cpp} auto a = DualComplex::translation(Vector2::yAxis(2.0f))* DualComplex::rotation(25.0_degf); 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(). For transformation with normalized quaternion you can use faster alternative @ref Quaternion::transformVectorNormalized(). Example: -@code + +@code{.cpp} auto transformation = Matrix3::rotation(-30.0_degf)*Matrix3::scaling(Vector2(3.0f)); Vector2 transformed = transformation.transformVector({1.5f, -7.9f}); @endcode @@ -223,7 +230,8 @@ Point transformation involves also translation, in 2D is done with @ref Matrix3::transformPoint() and @ref DualComplex::transformPoint(), in 3D with @ref Matrix4::transformPoint() and @ref DualQuaternion::transformPoint(). Also here you can use faster alternative @ref DualQuaternion::transformPointNormalized(): -@code + +@code{.cpp} auto transformation = DualQuaternion::rotation(-30.0_degf, Vector3::xAxis())* DualQuaternion::translation(Vector3::yAxis(3.0f)); 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 matrices, particularly translation vector, rotation/scaling part of the matrix (or pure rotation if the matrix has uniform scaling) and also base vectors: -@code + +@code{.cpp} Matrix4 a; auto rotationScaling = transformation.rotationScaling(); Vector3 up = transformation.up(); @@ -244,6 +253,7 @@ Matrix3 b; auto rotation = b.rotation(); Float xTranslation = b.translation().x(); @endcode + Extracting scaling and rotation from arbitrary transformation matrices is 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 @@ -251,7 +261,8 @@ complex number or quaternion, see below. You can also recreate transformation matrix from rotation and translation parts: -@code + +@code{.cpp} Matrix3 c = Matrix3::from(rotation, {1.0f, 3.0f}); @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 @ref DualComplex::rotation() const, @ref DualQuaternion::rotation() const, @ref DualComplex::translation() const and @ref DualQuaternion::translation() const. -@code + +@code{.cpp} DualComplex a; Rad rotationAngle = a.rotation().angle(); 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 to rotation and translation matrix using @ref DualComplex::toMatrix() and @ref DualQuaternion::toMatrix(): -@code + +@code{.cpp} Quaternion a; 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 and translation matrices using @ref DualComplex::fromMatrix() and @ref DualQuaternion::fromMatrix(): -@code + +@code{.cpp} Matrix3 rotation; auto a = Complex::fromMatrix(rotation.rotationScaling()); @@ -301,7 +315,7 @@ auto b = DualQuaternion::fromMatrix(transformation); @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 accumulate rounding errors and behave strangely. For transformation matrices 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 scaling). You can also use @ref Math::Algorithms::svd() to more precisely (but way more slowly) account for the drift. Example: -@code + +@code{.cpp} Matrix4 transformation; Math::Algorithms::gramSchmidtOrthonormalizeInPlace(transformation); @endcode @@ -321,12 +336,10 @@ using @ref Complex::normalized(), @ref Quaternion::normalized(), @ref DualComplex::normalized() and @ref DualQuaternion::normalized(). Transformation quaternions and complex numbers are always of unit length, thus normalizing them reduces the drift. -@code + +@code{.cpp} DualQuaternion transformation; transformation = transformation.normalized(); @endcode - -- Previous page: @ref matrix-vector -- Next page: @ref plugins */ } diff --git a/doc/troubleshooting.dox b/doc/troubleshooting.dox index 3e778e893..e7397633d 100644 --- a/doc/troubleshooting.dox +++ b/doc/troubleshooting.dox @@ -25,9 +25,10 @@ namespace Magnum { /** @page troubleshooting Troubleshooting - @brief Various tricks to overcome common building and rendering issues. +@m_footernavigation + @section troubleshooting-building Building issues 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 primitives were generated. Use @ref SampleQuery to check whether fragments 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", properly set up @ref Mesh::setIndexBuffer() "index buffer" and index count 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", @ref Renderer::Feature::FaceCulling "face culling" and other renderer 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 proper places. - @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 contents, vertex binding and count of generated primitives, rendered fragments and time spent in various calls. - */ } diff --git a/doc/types.dox b/doc/types.dox index 1aff36efb..191488814 100644 --- a/doc/types.dox +++ b/doc/types.dox @@ -27,38 +27,36 @@ namespace Magnum { /** @page types Type system @brief Type aliases, naming and compatibility with OpenGL and GLSL types. -- Previous page: @ref platform -- Next page: @ref matrix-vector +@tableofcontents +@m_footernavigation The root @ref Magnum namespace defines a few aliases for essential types. See its documentation for more information about usage with CMake. -@tableofcontents - @section types-builtin Builtin types Magnum provides typedefs for builtin integral and floating-point arithmetic 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 -refer to the same type). - -| Magnum type | Size | Equivalent GLSL type | -| ------------------ | -------------- | -------------------- | -| @ref UnsignedByte | 8bit unsigned | | -| @ref Byte | 8bit signed | | -| @ref UnsignedShort | 16bit unsigned | | -| @ref Short | 16bit signed | | -| @ref UnsignedInt | 32bit unsigned | `uint` | -| @ref Int | 32bit signed | `int` | -| @ref UnsignedLong | 64bit unsigned | | -| @ref Long | 64bit signed | | -| @ref Half | 16bit | (*none*) | -| @ref Float | 32bit | `float` | -| @ref Double | 64bit | `double` | - -Types not meant to be used in arithmetic (such as `bool` or `std::size_t`) or -types which cannot be directly passed to GLSL shaders (such as `long double`) -have no typedefs. +consistency and reduce confusion (e.g. @ref std::int32_t, @cpp int @ce and +@cpp GLint @ce all refer to the same type). + +| Magnum type | Size | Equivalent GLSL type | +| ------------------ | -------------- | ----------------------- | +| @ref UnsignedByte | 8bit unsigned | | +| @ref Byte | 8bit signed | | +| @ref UnsignedShort | 16bit unsigned | | +| @ref Short | 16bit signed | | +| @ref UnsignedInt | 32bit unsigned | @glsl uint @ce | +| @ref Int | 32bit signed | @glsl int @ce | +| @ref UnsignedLong | 64bit unsigned | | +| @ref Long | 64bit signed | | +| @ref Half | 16bit | (*none*) | +| @ref Float | 32bit | @glsl float @ce | +| @ref Double | 64bit | @glsl double @ce | + +Types not meant to be used in arithmetic (such as @cpp bool @ce or +@cpp std::size_t @ce) or types which cannot be directly passed to GLSL shaders +(such as @cpp long double @ce) have no typedefs. 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 @@ -70,23 +68,23 @@ underlying type. | Magnum vector type | Equivalent GLSL type | | ---------------------------------------------- | ------------------------- | -| @ref Vector2, @ref Vector3, @ref Color3 @ref Vector4, @ref Color4 | `vec2`, `vec3`, `vec4` | -| @ref Vector2ui, @ref Vector3ui, @ref Vector4ui | `uvec2`, `uvec3`, `uvec4` | -| @ref Vector2i, @ref Vector3i, @ref Vector4i | `ivec2`, `ivec3`, `ivec4` | -| @ref Vector2d, @ref Vector3d, @ref Vector4d | `dvec2`, `dvec3`, `dvec4` | +| @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 | @glsl uvec2 @ce, @glsl uvec3 @ce, @glsl uvec4 @ce | +| @ref Vector2i, @ref Vector3i, @ref Vector4i | @glsl ivec2 @ce, @glsl ivec3 @ce, @glsl ivec4 @ce | +| @ref Vector2d, @ref Vector3d, @ref Vector4d | @glsl dvec2 @ce, @glsl dvec3 @ce, @glsl dvec4 @ce | | @ref Color3ub, @ref Color4ub | (*none*) | -| Magnum matrix type | Equivalent GLSL type | -| ---------------------------------------------------------------- | ------------------------------------ | -| @ref Matrix2x2 or @ref Matrix2x2d | `mat2`/`mat2x2` or `dmat2`/`dmat2x2` | -| @ref Matrix3 / @ref Matrix3x3 or @ref Matrix3d / @ref Matrix3x3d | `mat3`/`mat3x3` or `dmat3`/`dmat3x3` | -| @ref Matrix4 / @ref Matrix4x4 or @ref Matrix4d / @ref Matrix4x4d | `mat4`/`mat4x4` or `dmat4`/`dmat4x4` | -| @ref Matrix2x3 or @ref Matrix2x3d | `mat2x3` or `dmat2x3` | -| @ref Matrix3x2 or @ref Matrix3x2d | `mat3x2` or `dmat3x2` | -| @ref Matrix2x4 or @ref Matrix2x4d | `mat2x4` or `dmat2x4` | -| @ref Matrix4x2 or @ref Matrix4x2d | `mat4x2` or `dmat4x2` | -| @ref Matrix3x4 or @ref Matrix3x4d | `mat3x4` or `dmat3x4` | -| @ref Matrix4x3 or @ref Matrix4x3d | `mat4x3` or `dmat4x3` | +| Magnum matrix type | Equivalent GLSL type | +| ---------------------------------------------------------------- | ------------------------------------- | +| @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 | @glsl mat3 @ce / @glsl mat3x3 @ce or @glsl dmat3 @ce / @glsl dmat3x3 @ce | +| @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 | @glsl mat2x3 @ce or @glsl dmat2x3 @ce | +| @ref Matrix3x2 or @ref Matrix3x2d | @glsl mat3x2 @ce or @glsl dmat3x2 @ce | +| @ref Matrix2x4 or @ref Matrix2x4d | @glsl mat2x4 @ce or @glsl dmat2x4 @ce | +| @ref Matrix4x2 or @ref Matrix4x2d | @glsl mat4x2 @ce or @glsl dmat4x2 @ce | +| @ref Matrix3x4 or @ref Matrix3x4d | @glsl mat3x4 @ce or @glsl dmat3x4 @ce | +| @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 equivalently (e.g. @ref Math::Vector "Math::Vector" 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 @ref Math::Literals namespace. See their documentation for more information about the differences. -@code + +@code{.cpp} using namespace Math::Literals; 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 corresponding `GL*` types. Matrix and vector classes have the same binary representation as corresponding array of numeric values without any additional -data or padding (e.g. `sizeof(Vector3i) == sizeof(Int[3])`), all matrices are -stored in column-major order. +data or padding (e.g. @cpp sizeof(Vector3i) == sizeof(Int[3]) @ce), all +matrices are stored in column-major order. 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 @@ -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 bugs (i.e. entering degree value where radians should be) and make the 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 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""_rad() _rad @endlink literals that are provided in the @ref Math::Literals namespace: -@code + +@code{.cpp} using namespace Math::Literals; //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 underlying type is *explicit* to avoid precision loss (or, on the other hand, unnecessarily high precision) during computations: -@code + +@code{.cpp} Rad d = 60.0_degf; // 1.0471976f auto e = Degd{pi}; // 180.0 @@ -167,10 +168,11 @@ auto f = Rad{pi}; // 3.141592654f @endcode 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 any need to care about what input the function expects: -@code + +@code{.cpp} Float a = Math::sin(1.32457_radf); Complex b = Complex::rotation(60.0_degf); @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 use the @link Math::Literals::operator""_h() _h @endlink literal that is provided in the @ref Math::Literals namespace: -@code + +@code{.cpp} using namespace Math::Literals; 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). 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 @@ -225,7 +228,8 @@ explicit: overwrite the contents anyway, works for all types). Example: -@code + +@code{.cpp} // These are equivalent Vector3 a1; Vector3 a1{Math::ZeroInit}; @@ -241,8 +245,5 @@ if(orthographic) else projection = Matrix4::perspectiveProjection(...); @endcode - -- Previous page: @ref platform -- Next page: @ref matrix-vector */ } diff --git a/doc/utilities.dox b/doc/utilities.dox index 885c44de5..94bf89898 100644 --- a/doc/utilities.dox +++ b/doc/utilities.dox @@ -27,11 +27,11 @@ namespace Magnum { /** @page utilities Utilities @brief Command-line utilities for system information and data conversion -- @subpage magnum-info -- @copybrief magnum-info -- @subpage magnum-al-info -- @copybrief magnum-al-info -- @subpage magnum-distancefieldconverter -- @copybrief magnum-distancefieldconverter -- @subpage magnum-fontconverter -- @copybrief magnum-fontconverter -- @subpage magnum-imageconverter -- @copybrief magnum-imageconverter +- @subpage magnum-info --- @copybrief magnum-info +- @subpage magnum-al-info --- @copybrief magnum-al-info +- @subpage magnum-distancefieldconverter --- @copybrief magnum-distancefieldconverter +- @subpage magnum-fontconverter --- @copybrief magnum-fontconverter +- @subpage magnum-imageconverter --- @copybrief magnum-imageconverter */ }