diff --git a/CMakeLists.txt b/CMakeLists.txt index e5f980ff2..a03aa4daa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -23,7 +23,7 @@ # DEALINGS IN THE SOFTWARE. # -cmake_minimum_required(VERSION 2.8.8) +cmake_minimum_required(VERSION 2.8.9) project(Magnum) # Find Corrade first so we can check on the target @@ -36,8 +36,6 @@ option(TARGET_GLES "Build for OpenGL ES instead of desktop OpenGL" OFF) cmake_dependent_option(TARGET_GLES2 "Build for OpenGL ES 2" ON "TARGET_GLES" OFF) cmake_dependent_option(TARGET_DESKTOP_GLES "Build for OpenGL ES on desktop" OFF "TARGET_GLES" OFF) -option(WITH_FIND_MODULE "Install FindMagnum.cmake module into CMake's module dir (might require admin privileges)" OFF) - # Parts of the library option(WITH_AUDIO "Build Audio library" OFF) option(WITH_DEBUGTOOLS "Build DebugTools library" ON) @@ -72,7 +70,7 @@ elseif(CORRADE_TARGET_APPLE) elseif(CORRADE_TARGET_UNIX) option(WITH_GLXAPPLICATION "Build GlxApplication library" OFF) cmake_dependent_option(WITH_WINDOWLESSGLXAPPLICATION "Build WindowlessGlxApplication library" OFF "NOT WITH_MAGNUMINFO;NOT WITH_FONTCONVERTER;NOT WITH_DISTANCEFIELDCONVERTER" ON) - cmake_dependent_option(WITH_XEGLAPPLICATION "Build XEglApplication library" OFF "TARGET_GLES" OFF) + option(WITH_XEGLAPPLICATION "Build XEglApplication library" OFF) option(WITH_GLXCONTEXT "Build GlxContext library" OFF) # Windows-specific application libraries @@ -112,7 +110,8 @@ if(BUILD_DEPRECATED) endif() option(BUILD_STATIC "Build static libraries (default are shared)" OFF) -cmake_dependent_option(BUILD_STATIC_PIC "Build static libraries with position-independent code" OFF "BUILD_STATIC" OFF) +option(BUILD_STATIC_PIC "Build static libraries and plugins with position-independent code" OFF) +option(BUILD_PLUGINS_STATIC "Build static plugins (default are dynamic)" OFF) option(BUILD_TESTS "Build unit tests." OFF) cmake_dependent_option(BUILD_GL_TESTS "Build unit tests for OpenGL code." OFF "BUILD_TESTS" OFF) if(BUILD_TESTS) @@ -135,6 +134,7 @@ endif() # meaningless on Emscripten and too inconvenient on Android if(CORRADE_TARGET_NACL_NEWLIB OR CORRADE_TARGET_EMSCRIPTEN OR CORRADE_TARGET_ANDROID) set(BUILD_STATIC ON) + set(BUILD_PLUGINS_STATIC ON) endif() if(BUILD_STATIC) @@ -182,11 +182,11 @@ else() endif() # Installation paths -include(CorradeLibSuffix) +include(${CORRADE_LIB_SUFFIX_MODULE}) set(MAGNUM_BINARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin) set(MAGNUM_LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) set(MAGNUM_DATA_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/magnum) -set(MAGNUM_CMAKE_FIND_MODULE_INSTALL_DIR ${CMAKE_ROOT}/Modules) +set(MAGNUM_CMAKE_MODULE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/cmake/Magnum) set(MAGNUM_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/Magnum) set(MAGNUM_EXTERNAL_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/MagnumExternal) set(MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/MagnumPlugins) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b1ba1db9..3c1d379f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,7 +44,7 @@ Code contribution /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Copyright © YEAR YOUR_NAME diff --git a/COPYING b/COPYING index 6194ff32a..0d92ab1b3 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright © 2010, 2011, 2012, 2013, 2014 +Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/CREDITS.md b/CREDITS.md index 8697d8ae2..12b137f79 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -1,9 +1,15 @@ Third-party components ---------------------- -* **flextGL** extension loader generator -- https://github.com/ginkgo/flextGL, - Copyright © 2011 Thomas Weber, licensed under - [MIT license](https://raw.githubusercontent.com/ginkgo/flextGL/master/COPYING) +Not mentioning OpenGL API and platform-specific toolkits. + +* Magnum internally uses code generated using **flextGL** extension loader + generator -- https://github.com/ginkgo/flextGL. Copyright © 2011 Thomas + Weber, licensed under [MIT license](https://raw.githubusercontent.com/ginkgo/flextGL/master/COPYING) +* The `Platform::GlutApplication` class uses **freeGLUT** library -- + http://freeglut.sourceforge.net/, licensed under MIT license. +* The `Platform::Sdl2Application` class uses **SDL2** library -- + https://www.libsdl.org/, licensed under [ZLIB license](http://www.gzip.org/zlib/zlib_license.html) Contributors to Magnum library ------------------------------ @@ -21,5 +27,9 @@ Contributors to Magnum library Debian package * Olga Turanksaya ([@olga-python](https://github.com/olga-python)) -- Gentoo ebuild +* [@wivlaro](https://github.com/wivlaro) -- numerous bug reports, Mac OS X + fixes, feature improvements +* Squareys ([@Squareys](https://github.com/Squareys)) -- bug reports, + documentation improvements Big thanks to everyone involved! diff --git a/Doxyfile b/Doxyfile index 0335627a3..a00205d5d 100644 --- a/Doxyfile +++ b/Doxyfile @@ -233,13 +233,13 @@ TAB_SIZE = 8 # newlines. ALIASES = \ - "debugoperator{1}=@relates \1\n@brief Debug output operator @xrefitem debugoperators \"Debug output operator\" \"Debug output operators for custom types\" Allows printing @ref \1 with @ref Corrade::Utility::Debug and friends." \ + "debugoperator{1}=@relatesalso \1\n@brief Debug output operator @xrefitem debugoperators \"Debug output operator\" \"Debug output operators for custom types\" Allows printing @ref \1 with @ref Corrade::Utility::Debug and friends." \ "debugoperatorenum{1}=\n@brief Debug output operator @xrefitem debugoperators \"Debug output operator\" \"Debug output operators for custom types\" Allows printing @ref \1 with @ref Corrade::Utility::Debug and friends." \ - "debugoperatorclassenum{2}=@relates \1\n@brief Debug output operator @xrefitem debugoperators \"Debug output operator\" \"Debug output operators for custom types\" Allows printing @ref \2 with @ref Corrade::Utility::Debug and friends." \ + "debugoperatorclassenum{2}=@relatesalso \1\n@brief Debug output operator @xrefitem debugoperators \"Debug output operator\" \"Debug output operators for custom types\" Allows printing @ref \2 with @ref Corrade::Utility::Debug and friends." \ "configurationvalueref{1}=@see @ref configurationvalues \"Corrade::Utility::ConfigurationValue<\1>\"" \ - "configurationvalue{1}=@brief %Configuration value parser and writer @xrefitem configurationvalues \"Configuration value parser and writer\" \"Configuration value parsers and writers for custom types\" Allows parsing and writing \1 from and to Corrade::Utility::Configuration." \ - "collisionoccurenceoperator{2}=@relates \1\n@brief %Collision occurence of %\1 and %\2\n@see \2::operator%(const \1&) const" \ - "collisionoperator{2}=@relates \1\n@brief %Collision of %\1 and %\2\n@see \2::operator/(const \1&) const" \ + "configurationvalue{1}=@brief Configuration value parser and writer @xrefitem configurationvalues \"Configuration value parser and writer\" \"Configuration value parsers and writers for custom types\" Allows parsing and writing \1 from and to Corrade::Utility::Configuration." \ + "collisionoccurenceoperator{2}=@relatesalso \1\n@brief Collision occurence of \1 and \2\n@see \2::operator%(const \1&) const" \ + "collisionoperator{2}=@relatesalso \1\n@brief Collision of \1 and \2\n@see \2::operator/(const \1&) const" \ "todoc=@xrefitem todoc \"Documentation todo\" \"Documentation-related todo list\"" \ "fn_gl{1}=gl\1()" \ "fn_gl2{2}=gl\1()" \ @@ -342,7 +342,7 @@ MARKDOWN_SUPPORT = YES # or globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. -AUTOLINK_SUPPORT = YES +AUTOLINK_SUPPORT = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this @@ -2000,7 +2000,8 @@ INCLUDE_FILE_PATTERNS = # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. PREDEFINED = DOXYGEN_GENERATING_OUTPUT \ - MAGNUM_BUILD_DEPRECATED CORRADE_DEPRECATED(message)= \ + CORRADE_DEPRECATED(message)= CORRADE_DEPRECATED_ENUM(message)= \ + MAGNUM_BUILD_DEPRECATED \ MAGNUM_EXPORT= \ MAGNUM_AUDIO_EXPORT= \ MAGNUM_DEBUGTOOLS_EXPORT= \ diff --git a/README.md b/README.md index a5f2e32f5..d3c65224c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -Magnum is 2D/3D graphics engine written in C++11 and modern OpenGL. Its goal is -to simplify low-level graphics development and interaction with OpenGL using -recent C++11 features and to abstract away platform-specific issues. +Magnum is 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. DESIGN GOALS ============ @@ -89,7 +90,7 @@ Minimal dependencies >= 3.1. On Windows you can use **MinGW**. GCC 4.5, 4.4 and **MSVC** 2013 support involves some ugly workarounds and thus is available only in `compatibility` branch. -* **CMake** >= 2.8.8 +* **CMake** >= 2.8.9 * **Corrade** - Plugin management and utility library. You can get it at https://github.com/mosra/corrade. @@ -161,6 +162,8 @@ separate repositories. * **libRocket integration** -- integrates Magnum as rendering backend into [libRocket](https://github.com/libRocket/libRocket) GUI library: https://github.com/miguelmartin75/Magnum-libRocket +* **Magnum Inspector** -- Gtk-based inspector window running alongside Magnum + https://github.com/wivlaro/magnum-inspector CONTACT ======= @@ -170,6 +173,7 @@ idea? Feel free to visit my website or contact me at: * Website -- http://mosra.cz/blog/magnum.php * GitHub -- https://github.com/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 diff --git a/doc/best-practices.dox b/doc/best-practices.dox index 3079ebf12..9395b2ed8 100644 --- a/doc/best-practices.dox +++ b/doc/best-practices.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/doc/building.dox b/doc/building.dox index fa1592a2b..d439aeb9f 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,7 +26,7 @@ namespace Magnum { /** @page building Downloading and building -@brief Guide how to download and build %Magnum on different platforms. +@brief Guide how to download and build Magnum on different platforms. @tableofcontents @@ -37,7 +37,7 @@ Minimal set of tools and libraries required for building is: >= 3.1. On Windows you can use **MinGW**. GCC 4.5, 4.4 and **MSVC** 2013 support involves some ugly workarounds and thus is available only in `compatibility` branch. -- **CMake** >= 2.8.8 +- **CMake** >= 2.8.9 - **Corrade** - Plugin management and utility library. See @ref building-corrade "Corrade download and installation guide" for more information. @@ -137,26 +137,24 @@ Installation to given prefix can be done from within QtCreator by adding new The libraries are build as shared by default. If you are developing for platform which doesn't support shared libraries or if you just want to link -them statically, enable `BUILD_STATIC` to build the libraries as static. If you -plan to use them with shared libraries later, enable also position-independent -code with `BUILD_STATIC_PIC`. If you want to build with another compiler (e.g. -Clang), pass `-DCMAKE_CXX_COMPILER=clang++` to CMake. +them statically, enable `BUILD_STATIC` to build the libraries as static. +Building of static plugins is controlled with separate `BUILD_PLUGINS_STATIC` +variable. If you plan to use the static libraries and plugins with shared +libraries later, enable also position-independent code with `BUILD_STATIC_PIC`. +If you want to build with another compiler (e.g. Clang), pass +`-DCMAKE_CXX_COMPILER=clang++` to CMake. Libraries and static plugins built in `Debug` configuration (e.g. with `CMAKE_BUILD_TYPE` set to `Debug`) have `-d` suffix to make it possible to have both debug and release libraries installed alongside each other. *Dynamic* plugins in `Debug` configuration are installed to `magnum-d` subdirectory instead of `magnum`. Headers and other files are the same for both. The library -and plugin distinction is handled semi-automatically when using %Magnum in +and plugin distinction is handled semi-automatically when using Magnum in depending projects, see @ref cmake for more information. -%Magnum by default does not install `FindMagnum.cmake`, as you should bundle -the module with your code instead of depending on it being in system location. -You can install it by enabling `WITH_FIND_MODULE`. - The library is constantly evolving and thus some APIs are deprecated and then later removed in favor of better ones. To preserve backwards compatibility, -%Magnum is by default built with all deprecated APIs. However, to make your +Magnum is by default built with all deprecated APIs. However, to make your code more robust and future-proof, it's recommended to build the library with `BUILD_DEPRECATED` disabled. @@ -182,7 +180,7 @@ 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. Enables also building of - %MeshTools, %Primitives, %SceneGraph, %Shaders and %Shapes libraries. + MeshTools, Primitives, SceneGraph, Shaders and Shapes libraries. - `WITH_MESHTOOLS` - @ref MeshTools library. Enabled automatically if `WITH_DEBUGTOOLS` is enabled. - `WITH_PRIMITIVES` - @ref Primitives library. Enabled automatically if @@ -191,9 +189,9 @@ parameters you can specify which parts will be built and which not: `WITH_DEBUGTOOLS` or `WITH_SHAPES` is enabled. - `WITH_SHADERS` - @ref Shaders library. Enabled automatically if `WITH_DEBUGTOOLS` is enabled. -- `WITH_SHAPES` - @ref Shapes library. Enables also building of %SceneGraph +- `WITH_SHAPES` - @ref Shapes library. Enables also building of SceneGraph library. Enabled automatically if `WITH_DEBUGTOOLS` is enabled. -- `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_TEXT` or `WITH_DISTANCEFIELDCONVERTER` is enabled. @@ -229,12 +227,12 @@ on Linux, Mac OS X and Windows, also disabled by default: information about the engine and OpenGL capabilities. - `WITH_DISTANCEFIELDCONVERTER` - @ref magnum-distancefieldconverter "magnum-distancefieldconverter" executable for converting black&white images to distance field textures. - Enables also building of %TextureTools library. + Enables also building of TextureTools library. - `WITH_FONTCONVERTER` - @ref magnum-fontconverter "magnum-fontconverter" executable for converting fonts to raster ones. Enables also building of - %Text library. + Text library. -%Magnum also contains a set of dependency-less plugins for importing essential +Magnum also contains a set of dependency-less plugins for importing essential 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. @@ -285,9 +283,9 @@ be build by running in root directory (i.e. where `Doxyfile` is). Resulting HTML documentation will be in `build/doc/` directory. You might need to create `build/` directory -if it doesn't exist yet. If %Corrade with generated documentation is placed in +if it doesn't exist yet. If Corrade with generated documentation is placed in `corrade` directory next to `magnum`, the documentation will be crosslinked -with %Corrade's one. If related projects (`magnum-plugins`, `magnum-integration` +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. @@ -310,10 +308,7 @@ 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. You need to build them from -project root: - - makepkg -p package/archlinux/ +which will run all unit tests before packaging. @subsection building-packages-gentoo Gentoo ebuilds @@ -336,7 +331,7 @@ features, for example), modify the last entry in `debian/rules`. @section building-crosscompiling Crosscompiling For crosscompiling you need to have *both* target and native version of -%Corrade installed, because %Corrade needs to run `corrade-rc` utility on the +Corrade installed, because Corrade needs to run `corrade-rc` utility on the host system as part of the build process. If native version of `corrade-rc` is not found on the system, crosscompilation will fail. @@ -364,11 +359,13 @@ You will need MinGW32 versions of the compiler and all dependent libraries Then create build directory and run cmake and build command in it. You may need to modify the `basic-mingw32.cmake` file and `CMAKE_INSTALL_PREFIX` to suit -your distribution filesystem hierarchy. +your distribution filesystem hierarchy and specify path where Corrade is +installed in `CMAKE_PREFIX_PATH`. mkdir build-win && cd build-win cmake .. \ -DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw32.cmake \ + -DCMAKE_PREFIX_PATH=/usr/i486-mingw32 \ -DCMAKE_INSTALL_PREFIX=/usr/i486-mingw32 cmake --build . @@ -392,13 +389,15 @@ Then create build directories for x86-32 and x86-64 and run cmake and build command in them. The toolchains need access to the platform file, so be sure to properly set **absolute** path to `modules/` directory containing `Platform/NaCl.cmake`. Also adapt `CMAKE_INSTALL_PREFIX` to the same value as -in `NACL_PREFIX` in toolchain file. +in `NACL_PREFIX` in toolchain file and specify path where Corrade is installed +in `CMAKE_PREFIX_PATH`. mkdir build-nacl-x86-32 && cd build-nacl-x86-32 cmake .. \ -DCMAKE_MODULE_PATH="/absolute/path/to/toolchains/modules" \ -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/NaCl-newlib-x86-32.cmake" \ -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH=/usr/nacl \ -DCMAKE_INSTALL_PREFIX=/usr/nacl \ -DWITH_NACLAPPLICATION=ON \ -DLIB_SUFFIX=/32 @@ -409,6 +408,7 @@ in `NACL_PREFIX` in toolchain file. -DCMAKE_MODULE_PATH="/absolute/path/to/toolchains/modules" \ -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/NaCl-newlib-x86-64.cmake" \ -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH=/usr/nacl \ -DCMAKE_INSTALL_PREFIX=/usr/nacl \ -DWITH_NACLAPPLICATION=ON cmake --build . @@ -427,9 +427,9 @@ You will need [Emscripten](https://github.com/kripken/emscripten/wiki/Tutorial) installed and configured. Don't forget to adapt `EMSCRIPTEN_PREFIX` variable in `generic/Emscripten.cmake` -to path where Emscripten is installed. Default is `/usr/emscripten`. Emscripten -supports dynamic libraries only to simplify porting and they are generally -slower, thus `BUILD_STATIC` is implicitly enabled. +to path where Emscripten is installed. Default is `/usr/lib/emscripten`. +Emscripten supports dynamic libraries only to simplify porting and they are +generally slower, thus `BUILD_STATIC` is implicitly enabled. Then create build directory and run cmake and build command in it. The toolchain needs access to its platform file, so be sure to properly set @@ -441,7 +441,8 @@ Also set `CMAKE_INSTALL_PREFIX` to path contained in `EMSCRIPTEN_TOOLCHAIN_PATH` -DCMAKE_MODULE_PATH="/absolute/path/to/toolchains/modules" \ -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Emscripten.cmake" \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/usr/emscripten/system \ + -DCMAKE_PREFIX_PATH=/usr/lib/emscripten/system \ + -DCMAKE_INSTALL_PREFIX=/usr/lib/emscripten/system \ -DWITH_SDL2APPLICATION=ON cmake --build . @@ -468,7 +469,8 @@ where NDK is installed. Default is `/opt/android-ndk`. Adapt also Then create build directory and run cmake and build command in it. The toolchain needs access to its platform file, so be sure to properly set **absolute** path to `modules/` directory containing `Platform/Android.cmake`. Also set -`CMAKE_INSTALL_PREFIX` to `/usr` subdirectory of `ANDROID_SYSROOT`. +`CMAKE_INSTALL_PREFIX` to `/usr` subdirectory of `ANDROID_SYSROOT` and specify +path where Corrade is installed in `CMAKE_PREFIX_PATH`. Note that `BUILD_STATIC` is implicitly enabled, because manually loading all depending shared libraries using JNI would be too inconvenient. Decision @@ -480,6 +482,7 @@ between OpenGL ES 2.0 and ES 3.0 is left up to the user (i.e. you need to set -DCMAKE_MODULE_PATH="/absolute/path/to/toolchains/modules" \ -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=ON cmake --build . @@ -489,6 +492,7 @@ between OpenGL ES 2.0 and ES 3.0 is left up to the user (i.e. you need to set -DCMAKE_MODULE_PATH="/absolute/path/to/toolchains/modules" \ -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=ON cmake --build . @@ -504,16 +508,18 @@ named `PKGBUILD-android-arm` and `PKGBUILD-android-x86`, see In `package/ci/` there are `jenkins.xml` and `jenkins-gltests.xml` files containing job configuration, one for build and non-GL tests and the other for -GL tests only. Setup your Jenkins server, enable the **Git** and **Text-finder** -plugin and download the CLI application from here: +GL tests only. Setup your Jenkins server, enable the **Git** and +**Text-finder** plugin and download the CLI application from here (replace +`localhost:8080` with your server name): - http://your-jenkins-server/cli + http://localhost:8080/cli -Then add new jobs or update existing ones (replace `` with `create-job` -or `update-job`). +Then add new jobs or update existing ones (update path to the `*.jar` file, +replace `localhost:8080` with your server name, replace `update-job` with +`create-job` if the job doesn't exist yet). - java -jar jenkins-cli.jar -s http://your-jenkins-server Magnum-Compatibility < jenkins.xml - java -jar jenkins-cli.jar -s http://your-jenkins-server Magnum-Compatibility-GLTests < jenkins-gltests.xml + java -jar ~/jenkins-cli.jar -s http://localhost:8080 update-job Magnum-Compatibility < package/ci/jenkins.xml + java -jar ~/jenkins-cli.jar -s http://localhost:8080 update-job Magnum-Compatibility-GLTests < package/ci/jenkins-gltests.xml Build is done using **Ninja** build system and everything possible is enabled, thus you need also **SDL2**, **GLUT** and **OpenAL** libraries. It expects that @@ -525,15 +531,22 @@ in `axes/hudson.matrix.TextAxis` or via the web interface later. Magnum-Compatibility-GLTests depend on active X11 session, thus they should be run from Jenkins instance running on graphical user session. +Clang Analyzer and *Sanitizer checks are also available. They both require **Clang**, +Analyzer job additionally requires **clang-analyzer** tool. + + java -jar ~/jenkins-cli.jar -s http://localhost:8080 update-job Magnum-ClangAnalyzer < package/ci/jenkins-clang-analyzer.xml + java -jar ~/jenkins-cli.jar -s http://localhost:8080 update-job Magnum-ClangSanitizer < package/ci/jenkins-clang-sanitizer.xml + java -jar ~/jenkins-cli.jar -s http://localhost:8080 update-job Magnum-ClangSanitizer-GLTests < package/ci/jenkins-clang-sanitizer-gltests.xml + There is also MinGW-w64, Emscripten, NaCl and Android configuration, add or update them with the commands below. See @ref building-crosscompiling for more information about setting up the crosscompilers and `toolchains/` submodule. For Emscripten you need also **Node.js** installed to run the tests. - java -jar jenkins-cli.jar -s http://your-jenkins-server Magnum-MinGW-w64 < jenkins-mingw-w64.xml - java -jar jenkins-cli.jar -s http://your-jenkins-server Magnum-Emscripten < jenkins-emscripten.xml - java -jar jenkins-cli.jar -s http://your-jenkins-server Magnum-NaCl < jenkins-nacl.xml - java -jar jenkins-cli.jar -s http://your-jenkins-server Magnum-Android < jenkins-android.xml + java -jar ~/jenkins-cli.jar -s http://localhost:8080 update-job Magnum-MinGW-w64 < package/ci/jenkins-mingw-w64.xml + java -jar ~/jenkins-cli.jar -s http://localhost:8080 update-job Magnum-Emscripten < package/ci/jenkins-emscripten.xml + java -jar ~/jenkins-cli.jar -s http://localhost:8080 update-job Magnum-NaCl < package/ci/jenkins-nacl.xml + java -jar ~/jenkins-cli.jar -s http://localhost:8080 update-job Magnum-Android < package/ci/jenkins-android.xml */ } diff --git a/doc/cmake.dox b/doc/cmake.dox index 9a7199bc4..fb69fff09 100644 --- a/doc/cmake.dox +++ b/doc/cmake.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,14 +25,14 @@ namespace Magnum { /** @page cmake Usage with CMake -@brief Guide how to find and use %Magnum with CMake build system +@brief Guide how to find and use Magnum with CMake build system -%Magnum uses CMake build system for both building and integration into your +Magnum uses CMake build system for both building and integration into your projects. The logic is in module `FindMagnum.cmake` distributed with the engine in `modules/` directory, you are encouraged to copy it along with `FindCorrade.cmake` into your project and add path to the files to `CMAKE_MODULE_PATH`. Otherwise, if CMake won't be able to find this file in -predefined locations, it will error out even if %Magnum might be installed on +predefined locations, it will error out even if Magnum might be installed on the system. If you plan to use Magnum on OpenGL ES, you may also need `FindOpenGLES2.cmake` or `FindOpenGLES3.cmake` and in some cases also `FindEGL.cmake`. @@ -50,17 +50,17 @@ Basic usage is: find_package(Magnum REQUIRED) -This command tries to find base %Magnum library and then defines these +This command tries to find base Magnum library and then defines these variables: - `MAGNUM_FOUND` -- Whether the library was found -- `MAGNUM_LIBRARIES` -- %Magnum library and dependent libraries +- `MAGNUM_LIBRARIES` -- Magnum library and dependent libraries - `MAGNUM_INCLUDE_DIRS` -- Root include dir and include dirs of dependencies - `MAGNUM_PLUGINS_DEBUG_DIR` -- Base directory with dynamic plugins for debug - builds, defaults to `magnum-d/` subdirectory of dir where %Magnum library + builds, defaults to `magnum-d/` subdirectory of dir where Magnum library was found - `MAGNUM_PLUGINS_RELEASE_DIR` -- Base directory with dynamic plugins for - release builds, defaults to `magnum/` subdirectory of dir where %Magnum + release builds, defaults to `magnum/` subdirectory of dir where Magnum library was found - `MAGNUM_PLUGINS_DIR` -- Base directory with dynamic plugins, defaults to `MAGNUM_PLUGINS_RELEASE_DIR` in release builds and multi-configuration @@ -80,32 +80,31 @@ variables: 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 +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 (depends on `%MeshTools`, - `%Primitives`, `%SceneGraph`, `%Shaders` and `%Shapes` components) -- `%MeshTools` -- @ref MeshTools library -- `%Primitives` -- @ref Primitives library -- `%SceneGraph` -- @ref SceneGraph library -- `%Shaders` -- @ref Shaders library -- `%Shapes` -- @ref Shapes library (depends on `%SceneGraph` component) -- `%Text` -- @ref Text library (depends on `%TextureTools` component) -- `%TextureTools` -- @ref TextureTools library +- `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: -- `%GlutApplication` -- @ref Platform::GlutApplication "GlutApplication" -- `%GlxApplication` -- @ref Platform::GlxApplication "GlxApplication" -- `%NaClApplication` -- @ref Platform::NaClApplication "NaClApplication" -- `%Sdl2Application` -- @ref Platform::Sdl2Application "Sdl2Application" -- `%XEglApplication` -- @ref Platform::XEglApplication "XEglApplication" -- `%WindowlessCglApplication` -- @ref Platform::WindowlessCglApplication "WindowlessCglApplication" -- `%WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" -- `%WindowlessNaClApplication` -- @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication" -- `%WindowlessWglApplication` -- @ref Platform::WindowlessWglApplication "WindowlessWglApplication" +- `GlutApplication` -- @ref Platform::GlutApplication "GlutApplication" +- `GlxApplication` -- @ref Platform::GlxApplication "GlxApplication" +- `NaClApplication` -- @ref Platform::NaClApplication "NaClApplication" +- `Sdl2Application` -- @ref Platform::Sdl2Application "Sdl2Application" +- `XEglApplication` -- @ref Platform::XEglApplication "XEglApplication" +- `WindowlessCglApplication` -- @ref Platform::WindowlessCglApplication "WindowlessCglApplication" +- `WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" +- `WindowlessNaClApplication` -- @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication" +- `WindowlessWglApplication` -- @ref Platform::WindowlessWglApplication "WindowlessWglApplication" For manual context creation (without application wrappers) there are also platform-specific context libraries (see @ref platform-custom for more @@ -126,17 +125,14 @@ 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 (depends on - `%Text` component and `TgaImporter` plugin) +- `MagnumFont` -- @ref Text::MagnumFont "MagnumFont" plugin - `MagnumFontConverter` -- @ref Text::MagnumFontConverter "MagnumFontConverter" - plugin (depends on `%Text` component and `%TgaImageConverter` plugin) -- `ObjImporter` -- @ref Trade::ObjImporter "ObjImporter" plugin (depends on - `%MeshTools` component) + plugin +- `ObjImporter` -- @ref Trade::ObjImporter "ObjImporter" plugin - `TgaImageConverter` -- @ref Trade::TgaImageConverter "TgaImageConverter" plugin - `TgaImporter` -- @ref Trade::TgaImporter "TgaImporter" plugin - `WavAudioImporter` -- @ref Audio::WavImporter "WavAudioImporter" plugin - (depends on `%Audio` component) Note that [each namespace](namespaces.html), all @ref Platform libraries and each plugin class contain more detailed information about dependencies, @@ -172,7 +168,7 @@ You can make use of @ref corrade-cmake "CORRADE_IS_DEBUG_BUILD" preprocessor variable along with `MAGNUM_PLUGINS_*_DEBUG_DIR` / `MAGNUM_PLUGINS_*_RELEASE_DIR` variables to decide in preprocessing step. -Features of found %Magnum library are exposed in these CMake variables, they +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": @@ -187,12 +183,7 @@ are also available as preprocessor variables if including emulation on desktop OpenGL - `MAGNUM_TARGET_WEBGL` --- Defined if compiled for WebGL -If `MAGNUM_BUILD_DEPRECATED` is defined, the `MAGNUM_INCLUDE_DIR` variable also -contains path directly to Magnum directory (i.e. for includes without `Magnum/` -prefix) and `MAGNUM_PLUGINS_INCLUDE_DIR` contains include dir for plugins (i.e. -for includes without `MagnumPlugins/` prefix). - -%Corrade library provides also its own set of CMake macros and variables, see +Corrade library provides also its own set of CMake macros and variables, see @ref corrade-cmake "its documentation" for more information. @ref cmake-plugins "Plugins repository" and @ref cmake-integration "Integration library" have also their own CMake modules. diff --git a/doc/coding-style.dox b/doc/coding-style.dox index 23dfb64a7..9f64f4bd6 100644 --- a/doc/coding-style.dox +++ b/doc/coding-style.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -54,11 +54,11 @@ have `*.hpp` extension (hinting that they are something between `*.h` and @subsubsection coding-style-cpp-types Builtin types -Use %Magnum's own type aliases for public API (e.g. @ref UnsignedInt, see +Use Magnum's own type aliases for public API (e.g. @ref UnsignedInt, see @ref types for more information), but use specific types when interacting with third party libraries and OpenGL (e.g. `GLuint`) and rely only on implicit conversions when converting between them. This helps avoiding sign, truncation -and other issues, e.g. `%Math::%Vector2` will implicitly convert to +and other issues, e.g. `Math::Vector2` will implicitly convert to @ref Vector2i if and only if @ref Int is the same type as `GLsizei`. @subsubsection coding-style-cpp-naming Naming @@ -100,7 +100,7 @@ void setPolygonMode(PolygonMode mode); Additionally to @c \@todoc, @c \@debugoperator, @c \@debugoperatorenum, @c \@debugoperatorclassenum, @c \@configurationvalue and -@c \@configurationvalueref (same as in %Corrade), these are defined: +@c \@configurationvalueref (same as in Corrade), these are defined: @subsubsection coding-style-documentation-commands-collisionoperator Shape collision operators @@ -196,7 +196,7 @@ All classes and functions using those commands are cross-referenced in page In detailed documentation the text should be always first, the blocks are then ordered by their importance. Various @c \@note, @c \@attention and @c \@warning blocks to highlight some information are always first, then @c \@see block with -links to related stuff, where related %Magnum functions are first and links to +links to related stuff, where related Magnum functions are first and links to related GL API last, then various support information such as @c \@requires_glXX, @c \@requires_es_extension etc. (first desktop GL, then ES, then WebGL), after that @c \@deprecated_gl and @c \@deprecated information and diff --git a/doc/compilation-speedup.dox b/doc/compilation-speedup.dox index 533235ddc..0b56c2e6f 100644 --- a/doc/compilation-speedup.dox +++ b/doc/compilation-speedup.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,7 +30,7 @@ namespace Magnum { @section compilation-forward-declarations Forward declarations instead of includes Essential thing when speeding up compilation is reducing number of `#``include` -directives in both headers and source files. %Magnum is strictly applying this +directives in both headers and source files. Magnum is strictly applying this policy in all header files, so all types which are not directly used in the header have only forward declarations. @@ -55,19 +55,19 @@ available, each namespace has its own: @section compilation-speedup-templates Templates -Many things in %Magnum are templated to allow handling of various types and +Many things in Magnum are templated to allow handling of various types and sizes of data, for example whole scene graph can operate either with @ref Float or @ref Double data type. However, having templated classes and function usually means that the compiler compiles the whole templated code again in each compilation unit (i.e. source file). In linking stage of the application or library the duplicates are just thrown out, which is a waste of compilation -time. A few techniques are employed in %Magnum to avoid this. +time. A few techniques are employed in Magnum to avoid this. @subsection compilation-speedup-hpp Template headers and implementation files When templated code is too large, it is not stored in header file, but in so-called *template implementation file*. Generally, all header files in -%Magnum have `*.h` extension and all source files have `*.cpp` extension. +Magnum have `*.h` extension and all source files have `*.cpp` extension. Template implementation files have `*.hpp` extension, hinting that they are something between `*.h` and `*.cpp` files. @@ -111,7 +111,7 @@ precious compilation time. Keyword `extern template` 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 causes conflicting symbol errors when used on whole classes, thus in Magnum it's used only for specific functions. This is completely transparent to end user, so no special care is needed. diff --git a/doc/debug-tools.dox b/doc/debug-tools.dox index bd84f1a6a..f079f2b93 100644 --- a/doc/debug-tools.dox +++ b/doc/debug-tools.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,16 +39,16 @@ information about building and usage with CMake. @section debug-tools-renderers Debug renderers -%Debug renderers provide a way to visualize objects and object features in +Debug renderers provide a way to visualize objects and object features in @ref scenegraph "scene graph" without the need to mess around with meshes and shaders. They are implemented as object features, so you can attach any number of them to any object. -Basic usage involves instancing DebugTools::ResourceManager and keeping it for -for the whole lifetime of debug renderers. Next you need some SceneGraph::DrawableGroup -instance. You can use the same group as for the rest of your scene, but -preferrably use dedicated one for debug renderers, so you can easily enable or -disable debug rendering. +Basic usage involves instancing @ref DebugTools::ResourceManager and keeping it +for the whole lifetime of debug renderers. Next you need some +@ref SceneGraph::DrawableGroup instance. You can use the same group as for the +rest of your scene, but preferrably use dedicated one for debug renderers, so +you can easily enable or disable debug rendering. Next step is to create configuration for your debug renderers and create particular debug renderer. The configuration is managed using the resource @@ -58,7 +58,7 @@ 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 -DebugTools::ObjectRenderer: +@link DebugTools::ObjectRenderer @endlink: @code // Global instance of debug resource manager, drawable group for the renderers DebugTools::ResourceManager manager; @@ -75,7 +75,7 @@ Object3D* object; new DebugTools::ObjectRenderer2D(*object, "my", debugDrawables); @endcode -See DebugTools::ObjectRenderer and DebugTools::ShapeRenderer for more +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 adf02fa95..9d0ad696d 100644 --- a/doc/features.dox +++ b/doc/features.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -27,13 +27,14 @@ 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 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 shaders -- @copybrief shaders +- @subpage scenegraph -- @copybrief scenegraph +- @subpage shapes -- @copybrief shapes +- @subpage debug-tools -- @copybrief debug-tools */ } diff --git a/doc/generated/.gitattributes b/doc/generated/.gitattributes new file mode 100644 index 000000000..2117a73f8 --- /dev/null +++ b/doc/generated/.gitattributes @@ -0,0 +1 @@ +vector.svg -diff diff --git a/doc/generated/CMakeLists.txt b/doc/generated/CMakeLists.txt new file mode 100644 index 000000000..1da6f273f --- /dev/null +++ b/doc/generated/CMakeLists.txt @@ -0,0 +1,67 @@ +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 +# Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +cmake_minimum_required(VERSION 2.8.9) +project(MyApplication) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/../../modules/") + +find_package(Magnum REQUIRED + MeshTools + Primitives + Shaders + Sdl2Application) + +if(CORRADE_TARGET_APPLE) + find_package(Magnum REQUIRED WindowlessCglApplication) +elseif(CORRADE_TARGET_UNIX) + find_package(Magnum REQUIRED WindowlessGlxApplication) +elseif(CORRADE_TARGET_WINDOWS) + find_package(Magnum REQUIRED WindowlessWglApplication) +else() + message(FATAL_ERROR "No windowless application available on this platform") +endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CORRADE_CXX_FLAGS}") +include_directories(${MAGNUM_INCLUDE_DIRS} + ${MAGNUM_APPLICATION_INCLUDE_DIRS} + ${MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS}) + +add_executable(hello hello.cpp) +target_link_libraries(hello + ${MAGNUM_LIBRARIES} + ${MAGNUM_APPLICATION_LIBRARIES}) + +add_executable(shaders shaders.cpp) +target_link_libraries(shaders + ${MAGNUM_LIBRARIES} + ${MAGNUM_MESHTOOLS_LIBRARIES} + ${MAGNUM_PRIMITIVES_LIBRARIES} + ${MAGNUM_SHADERS_LIBRARIES} + ${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}) diff --git a/doc/generated/README.md b/doc/generated/README.md new file mode 100644 index 000000000..e3f8bdbdc --- /dev/null +++ b/doc/generated/README.md @@ -0,0 +1,47 @@ +Source files for images in Magnum documentation +----------------------------------------------- + +Compile and install Magnum with `Sdl2Application`, windowless application for +your platform and `magnum-distancefieldconverter` utility and any `PngImporter` +and `PngImageConverter` plugins from Magnum Plugins. + +Create build dir, point CMake to this directory and compile the executables: + + mkdir build-doc + cd build-doc + cmake ../doc/generated + cmake --build . + +### "Getting started" image + +Displayed by the `hello` executable. Run the app and take screenshot using +KSnapshot (including decorations, 880x707). Similarly for the gray version. The +resulting files should be resized to half the size and without alpha channel +using imagemagick: + +```bash +mogrify -flatten -background '#ffffff' -resize 440 getting-started.png +mogrify -flatten -background '#ffffff' -resize 440 getting-started-blue.png +``` + +The output printed by the application can be used to update the example output +in `doc/getting-started.dox`. + +### Shader images + +Generated by the `shaders` executable. Must be run in this directory, the +output is put into `doc/` directory. The executable requires two textures: + +- `vector.png`, generated as full-page PNG output at 90 DPI from `vector.svg`, + converted to pure grayscale using imagemagick: + + ```bash + mogrify -flatten -background '#ffffff' -format grayscale vector.png + ``` + +- `vector-distancefield.png`, generated as full-page PNG output at 360 DPI + (1024x1024) and then processed through `magnum-distancefieldconverter` + + ```bash + magnum-distancefieldconverter --importer PngImporter --converter PngImageConverter --output-size "64 64" --radius 16 vector-src.png vector-distancefield.png + ``` diff --git a/src/Magnum/Shaders/magnumShadersResourceImport.hpp b/doc/generated/configure.h.cmake similarity index 74% rename from src/Magnum/Shaders/magnumShadersResourceImport.hpp rename to doc/generated/configure.h.cmake index af4e3262b..fcf0164d8 100644 --- a/src/Magnum/Shaders/magnumShadersResourceImport.hpp +++ b/doc/generated/configure.h.cmake @@ -1,9 +1,7 @@ -#ifndef Magnum_Shaders_magnumShadersResourceImport_hpp -#define Magnum_Shaders_magnumShadersResourceImport_hpp /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,16 +23,10 @@ DEALINGS IN THE SOFTWARE. */ -#include "Magnum/configure.h" - -#ifdef MAGNUM_BUILD_STATIC -#ifdef MAGNUM_BUILD_DEPRECATED -#include "Magnum/Shaders/resourceImport.hpp" -#else -#error use Magnum/Shaders/resourceImport.hpp instead -#endif +#ifdef CORRADE_IS_DEBUG_BUILD +#define MAGNUM_PLUGINS_IMAGECONVERTER_DIR "${MAGNUM_PLUGINS_IMAGECONVERTER_DEBUG_DIR}" +#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}" #else -#error this header is available only in static build -#endif - +#define MAGNUM_PLUGINS_IMAGECONVERTER_DIR "${MAGNUM_PLUGINS_IMAGECONVERTER_DIR}" +#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DIR}" #endif diff --git a/doc/generated/hello.cpp b/doc/generated/hello.cpp new file mode 100644 index 000000000..c43cdc74d --- /dev/null +++ b/doc/generated/hello.cpp @@ -0,0 +1,54 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include +#include + +using namespace Magnum; + +class Hello: public Platform::Application { +public: + explicit Hello(const Arguments& arguments); + +private: + void drawEvent() override; +}; + +Hello::Hello(const Arguments& arguments): Platform::Application(arguments) { + Renderer::setClearColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)); + Debug() << "Hello! This application is running on" << Context::current()->version() + << "using" << Context::current()->rendererString(); +} + +void Hello::drawEvent() { + defaultFramebuffer.clear(FramebufferClear::Color); + swapBuffers(); +} + +MAGNUM_APPLICATION_MAIN(Hello) diff --git a/doc/generated/shaders.cpp b/doc/generated/shaders.cpp new file mode 100644 index 000000000..743a2a809 --- /dev/null +++ b/doc/generated/shaders.cpp @@ -0,0 +1,301 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include + +#ifdef CORRADE_TARGET_APPLE +#include +#elif defined(CORRADE_TARGET_UNIX) +#include +#elif defined(CORRADE_TARGET_WINDOWS) +#include +#else +#error No windowless application available on this platform +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "configure.h" + +using namespace Magnum; + +struct ShaderVisualizer: Platform::WindowlessApplication { + using Platform::WindowlessApplication::WindowlessApplication; + + int exec() override; + + std::string phong(); + std::string meshVisualizer(); + std::string flat(); + std::string vertexColor(); + + std::string vector(); + std::string distanceFieldVector(); + + std::unique_ptr _importer; +}; + +namespace { + constexpr const Vector2i ImageSize{256}; +} + +int ShaderVisualizer::exec() { + PluginManager::Manager converterManager{MAGNUM_PLUGINS_IMAGECONVERTER_DIR}; + std::unique_ptr converter = converterManager.loadAndInstantiate("PngImageConverter"); + if(!converter) { + Error() << "Cannot load image converter plugin"; + std::exit(1); + } + + PluginManager::Manager importerManager{MAGNUM_PLUGINS_IMPORTER_DIR}; + _importer = importerManager.loadAndInstantiate("PngImporter"); + if(!_importer) { + Error() << "Cannot load image importer plugin"; + std::exit(1); + } + + Renderbuffer multisampleColor, multisampleDepth; + multisampleColor.setStorageMultisample(16, RenderbufferFormat::RGBA8, ImageSize); + multisampleDepth.setStorageMultisample(16, RenderbufferFormat::DepthComponent24, ImageSize); + + Framebuffer multisampleFramebuffer{{{}, ImageSize}}; + multisampleFramebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, multisampleColor) + .attachRenderbuffer(Framebuffer::BufferAttachment::Depth, multisampleDepth) + .bind(); + CORRADE_INTERNAL_ASSERT(multisampleFramebuffer.checkStatus(FramebufferTarget::Draw) == Framebuffer::Status::Complete); + + Renderbuffer color; + color.setStorage(RenderbufferFormat::RGBA8, ImageSize); + Framebuffer framebuffer{{{}, ImageSize}}; + framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, color); + + Renderer::enable(Renderer::Feature::DepthTest); + + for(auto fun: {&ShaderVisualizer::phong, + &ShaderVisualizer::meshVisualizer, + &ShaderVisualizer::flat, + &ShaderVisualizer::vertexColor, + &ShaderVisualizer::vector, + &ShaderVisualizer::distanceFieldVector}) { + multisampleFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); + + std::string filename = (this->*fun)(); + + AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), FramebufferBlit::Color); + Image2D result = framebuffer.read(framebuffer.viewport(), {ColorFormat::RGBA, ColorType::UnsignedByte}); + converter->exportToFile(result, Utility::Directory::join("../", "shaders-" + filename)); + } + + _importer.reset(); + + return 0; +} + +namespace { + const auto Projection = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); + const auto Transformation = Matrix4::translation(Vector3::zAxis(-5.0f)); + const auto BaseColor = Color3::fromHSV(216.0_degf, 0.85f, 1.0f); + const auto OutlineColor = Color3{0.95f}; +} + +std::string ShaderVisualizer::phong() { + std::unique_ptr vertices, indices; + Mesh mesh; + std::tie(mesh, vertices, indices) = MeshTools::compile(Primitives::UVSphere::solid(16, 32), BufferUsage::StaticDraw); + + Shaders::Phong shader; + shader.setAmbientColor(Color3(0.025f)) + .setDiffuseColor(BaseColor) + .setShininess(200.0f) + .setLightPosition({5.0f, 5.0f, 7.0f}) + .setProjectionMatrix(Projection) + .setTransformationMatrix(Transformation) + .setNormalMatrix(Transformation.rotationScaling()); + + mesh.draw(shader); + + return "phong.png"; +} + +std::string ShaderVisualizer::meshVisualizer() { + std::unique_ptr vertices, indices; + Mesh mesh; + std::tie(mesh, vertices, indices) = MeshTools::compile(Primitives::Icosphere::solid(1), BufferUsage::StaticDraw); + + const Matrix4 projection = Projection*Transformation* + Matrix4::rotationZ(13.7_degf)* + Matrix4::rotationX(-12.6_degf); + + Shaders::MeshVisualizer shader{Shaders::MeshVisualizer::Flag::Wireframe}; + shader.setColor(BaseColor) + .setWireframeColor(OutlineColor) + .setViewportSize(Vector2{ImageSize}) + .setTransformationProjectionMatrix(projection); + + mesh.draw(shader); + + return "meshvisualizer.png"; +} + +std::string ShaderVisualizer::flat() { + std::unique_ptr vertices, indices; + Mesh mesh; + std::tie(mesh, vertices, indices) = MeshTools::compile(Primitives::UVSphere::solid(16, 32), BufferUsage::StaticDraw); + + Shaders::Flat3D shader; + shader.setColor(BaseColor) + .setTransformationProjectionMatrix(Projection*Transformation); + + mesh.draw(shader); + + return "flat.png"; +} + +std::string ShaderVisualizer::vertexColor() { + Trade::MeshData3D sphere = Primitives::UVSphere::solid(32, 64); + + /* Color vertices nearest to given position */ + auto target = Vector3{2.0f, 2.0f, 7.0f}.normalized(); + std::vector colors; + colors.reserve(sphere.positions(0).size()); + for(Vector3 position: sphere.positions(0)) + colors.push_back(Color3::fromHSV(Math::lerp(240.0_degf, 420.0_degf, Math::max(1.0f - (position - target).length(), 0.0f)), 0.85f, 0.85f)); + + Buffer vertices, indices; + vertices.setData(MeshTools::interleave(sphere.positions(0), colors), BufferUsage::StaticDraw); + indices.setData(sphere.indices(), BufferUsage::StaticDraw); + + Mesh mesh; + mesh.setPrimitive(MeshPrimitive::Triangles) + .setCount(sphere.indices().size()) + .addVertexBuffer(vertices, 0, Shaders::VertexColor3D::Position{}, Shaders::VertexColor3D::Color{}) + .setIndexBuffer(indices, 0, Mesh::IndexType::UnsignedInt); + + Shaders::VertexColor3D shader; + shader.setTransformationProjectionMatrix(Projection*Transformation); + + mesh.draw(shader); + + return "vertexcolor.png"; +} + +std::string ShaderVisualizer::vector() { + std::optional image; + if(!_importer->openFile("vector.png") || !(image = _importer->image2D(0))) { + Error() << "Cannot open vector.png"; + return "vector.png"; + } + + Texture2D texture; + texture.setMinificationFilter(Sampler::Filter::Linear) + .setMagnificationFilter(Sampler::Filter::Linear) + .setWrapping(Sampler::Wrapping::ClampToEdge) + .setStorage(1, TextureFormat::RGBA8, image->size()) + .setSubImage(0, {}, *image); + + Mesh mesh; + std::unique_ptr vertices; + std::tie(mesh, vertices, std::ignore) = MeshTools::compile(Primitives::Square::solid(Primitives::Square::TextureCoords::Generate), BufferUsage::StaticDraw); + + Shaders::Vector2D shader; + shader.setColor(BaseColor) + .setVectorTexture(texture) + .setTransformationProjectionMatrix({}); + + Renderer::enable(Renderer::Feature::Blending); + Renderer::setBlendFunction(Renderer::BlendFunction::One, Renderer::BlendFunction::OneMinusSourceAlpha); + Renderer::setBlendEquation(Renderer::BlendEquation::Add, Renderer::BlendEquation::Add); + + mesh.draw(shader); + + Renderer::disable(Renderer::Feature::Blending); + + return "vector.png"; +} + +std::string ShaderVisualizer::distanceFieldVector() { + std::optional image; + if(!_importer->openFile("vector-distancefield.png") || !(image = _importer->image2D(0))) { + Error() << "Cannot open vector-distancefield.png"; + return "distancefieldvector.png"; + } + + Texture2D texture; + texture.setMinificationFilter(Sampler::Filter::Linear) + .setMagnificationFilter(Sampler::Filter::Linear) + .setWrapping(Sampler::Wrapping::ClampToEdge) + .setStorage(1, TextureFormat::RGBA8, image->size()) + .setSubImage(0, {}, *image); + + Mesh mesh; + std::unique_ptr vertices; + std::tie(mesh, vertices, std::ignore) = MeshTools::compile(Primitives::Square::solid(Primitives::Square::TextureCoords::Generate), BufferUsage::StaticDraw); + + Shaders::DistanceFieldVector2D shader; + shader.setColor(BaseColor) + .setOutlineColor(OutlineColor) + .setOutlineRange(0.6f, 0.4f) + .setVectorTexture(texture) + .setTransformationProjectionMatrix({}); + + Renderer::enable(Renderer::Feature::Blending); + Renderer::setBlendFunction(Renderer::BlendFunction::One, Renderer::BlendFunction::OneMinusSourceAlpha); + Renderer::setBlendEquation(Renderer::BlendEquation::Add, Renderer::BlendEquation::Add); + + mesh.draw(shader); + + Renderer::disable(Renderer::Feature::Blending); + + return "distancefieldvector.png"; +} + +MAGNUM_WINDOWLESSAPPLICATION_MAIN(ShaderVisualizer) diff --git a/doc/generated/vector-distancefield.png b/doc/generated/vector-distancefield.png new file mode 100644 index 000000000..5a94b2dc4 Binary files /dev/null and b/doc/generated/vector-distancefield.png differ diff --git a/doc/generated/vector.png b/doc/generated/vector.png new file mode 100644 index 000000000..dcd61aeab Binary files /dev/null and b/doc/generated/vector.png differ diff --git a/doc/generated/vector.svg b/doc/generated/vector.svg new file mode 100644 index 000000000..78056b8c6 --- /dev/null +++ b/doc/generated/vector.svg @@ -0,0 +1,79 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/doc/getting-started-blue.png b/doc/getting-started-blue.png index 10e381ddb..df4aac6ab 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 21421ec26..9d4a59817 100644 --- a/doc/getting-started.dox +++ b/doc/getting-started.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,7 +25,7 @@ namespace Magnum { /** @page getting-started Getting started -@brief Get started with %Magnum in matter of minutes. +@brief Get started with Magnum in matter of minutes. @tableofcontents @@ -42,7 +42,7 @@ parameter. @section getting-started-bootstrap Download bootstrap project Setting up a new project can be pretty gruesome and nobody likes repeating the -same process every time. %Magnum provides "bootstrap" project structures for +same process every time. Magnum provides "bootstrap" project structures for many use cases, helping you get up and running in no time. The [bootstrap repository](https://github.com/mosra/magnum-bootstrap) is @@ -67,7 +67,7 @@ so the compatibility mode gets properly detected and used. @section getting-started-review Review project structure -The base project consists of just six files in two subfolders. %Magnum uses +The base project consists of just six files in two subfolders. Magnum uses CMake build system, see @ref cmake for more information. modules/FindCorrade.cmake @@ -83,7 +83,7 @@ project-wide `CMakeLists.txt`. It just sets up project name, specifies module directory and delegates everything important to `CMakeLists.txt` in `src/` subdirectory. @code -cmake_minimum_required(VERSION 2.8.8) +cmake_minimum_required(VERSION 2.8.9) project(MyApplication) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/modules/") @@ -94,7 +94,7 @@ add_subdirectory(src) Directory `modules/` 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 +distributed with the project. These files are just verbatim copied from Magnum repository. Directory `src/` contains the actual project. To keep things simple, the @@ -130,7 +130,7 @@ MAGNUM_APPLICATION_MAIN(MyApplication) The application essentially does nothing, just clears screen framebuffer to default (dark gray) color and then does buffer swap to actually display it on -the screen. `CMakeLists.txt` finds %Magnum, sets up compiler flags, creates the +the screen. `CMakeLists.txt` finds Magnum, sets up compiler flags, creates the executable and links it to all needed libraries: @code find_package(Magnum REQUIRED Sdl2Application) @@ -176,7 +176,7 @@ everything is ready to be built. If CMake isn't able to find the dependencies on Windows, you might want to look at @ref building-windows. If CMake complains about `Sdl2Application` missing, -you forgot to enable `WITH_SDL2APPLICATION` when building %Magnum, +you forgot to enable `WITH_SDL2APPLICATION` when building Magnum, @ref getting-started-download "go back and fix it". @image html getting-started.png @@ -196,7 +196,7 @@ First include the needed headers: And in the constructor (which is currently empty) change the clear color and print something to debug output: @code -Renderer::setClearColor({0.07f, 0.44f, 0.73f}); +Renderer::setClearColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)); Debug() << "Hello! This application is running on" << Context::current()->version() << "using" << Context::current()->rendererString(); @@ -205,7 +205,7 @@ Debug() << "Hello! This application is running on" << Context::current()->versio 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 3.3 using Geforce GT 330M +> Hello! This application is running on OpenGL 4.5 using GeForce GT 740M @image html getting-started-blue.png @image latex getting-started-blue.png @@ -220,12 +220,13 @@ experimenting on your own! @section getting-started-more Additional information -- @subpage building -- @subpage building-plugins -- @subpage building-integration -- @subpage cmake -- @subpage cmake-plugins -- @subpage cmake-integration +- @subpage building +- @subpage building-plugins +- @subpage building-integration +- @subpage building-examples +- @subpage cmake +- @subpage cmake-plugins +- @subpage cmake-integration */ } diff --git a/doc/getting-started.png b/doc/getting-started.png index 2df2b37b3..85089868a 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 47140d8ed..64d28b3a1 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,9 +26,10 @@ namespace Magnum { /** @mainpage -%Magnum is 2D/3D graphics engine written in C++11 and modern OpenGL. Its goal -is to simplify low-level graphics development and interaction with OpenGL using -recent C++11 features and to abstract away platform-specific issues. +Magnum is 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 @@ -37,19 +38,19 @@ recent C++11 features and to abstract away platform-specific issues. 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 + 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 + 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 + 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 @@ -114,6 +115,7 @@ Feel free to get more information or contact the author at: - Website -- http://mosra.cz/blog/magnum.php - GitHub -- https://github.com/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 @@ -121,10 +123,10 @@ Feel free to get more information or contact the author at: @section mainpage-license License -%Magnum is licensed under MIT/Expat license: +Magnum is licensed under MIT/Expat license: > -> Copyright © 2010, 2011, 2012, 2013, 2014 +> Copyright © 2010, 2011, 2012, 2013, 2014, 2015 > Vladimír Vondruš <mosra@centrum.cz> > > Permission is hereby granted, free of charge, to any person obtaining a diff --git a/doc/matrix-vector.dox b/doc/matrix-vector.dox index d57326320..baed48801 100644 --- a/doc/matrix-vector.dox +++ b/doc/matrix-vector.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,7 +31,7 @@ namespace Magnum { - Next page: @ref transformations Matrices and vectors are the most important part of graphics programming and -one of goals of %Magnum is to make their usage as intuitive as possible. They +one of goals of Magnum is to make their usage as intuitive as possible. They 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. @@ -40,10 +40,10 @@ information about usage with CMake. @section matrix-vector-hierarchy Matrix and vector classes -%Magnum has three main matrix and vector classes: @ref Math::RectangularMatrix, +Magnum has three main matrix and vector classes: @ref Math::RectangularMatrix, (square) @ref Math::Matrix and @ref Math::Vector. To achieve greatest code -reuse, %Matrix is internally square %RectangularMatrix and %RectangularMatrix -is internally array of one or more %Vector instances. Both vectors and matrices +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. @@ -53,14 +53,14 @@ vector and matrix sizes there are specialized classes @ref Math::Matrix3 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. +columns of RectangularMatrix are returned as Vector, but when accessing +columns of e.g. Matrix3, they are returned as Vector3. There are also even more specialized subclasses, e.g. @ref Color3 and @ref Color4 for color handling and conversion. Commonly used types have convenience aliases in @ref Magnum namespace, so you -can write e.g. `%Vector3i` instead of `%Math::Vector3`. See @ref types and +can write e.g. `Vector3i` instead of `Math::Vector3`. See @ref types and namespace documentation for more information. @section matrix-vector-construction Constructing matrices and vectors @@ -198,7 +198,7 @@ available component-wise operations. @section matrix-vector-operations Operations with matrices and vectors Vectors can be added, subtracted, negated and multiplied or divided with -scalars, as is common in mathematics, %Magnum also adds the ability to divide +scalars, as is common in mathematics, Magnum also adds the ability to divide scalar with vector: @code Vector3 a(1.0f, 2.0f, 3.0f); @@ -214,7 +214,7 @@ Vector3 b = a*Vector3(-0.5f, 2.0f, -7.0f); // b == {-0.5f, 4.0f, -21.0f} 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 mulitplication/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 @@ -315,7 +315,7 @@ auto b = Math::denormalize(0.89f); // 226 @section matrix-vector-column-major Matrices are column-major and vectors are columns OpenGL matrices are column-major, thus it is reasonable to have matrices in -%Magnum also column major (and vectors as columns). This has naturally some +Magnum also column major (and vectors as columns). This has naturally some implications and it may differ from what is common in mathematics: - Order of template arguments in specification of @ref Math::RectangularMatrix diff --git a/doc/method-chaining.dox b/doc/method-chaining.dox index f79c81aa0..e27750a0d 100644 --- a/doc/method-chaining.dox +++ b/doc/method-chaining.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,12 +33,12 @@ 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 reduce unnecessary repeated names, improving code readability. -%Magnum uses this feature mainly for configuring OpenGL objects (such as +Magnum uses this feature mainly for configuring OpenGL objects (such as various mesh and framebuffer options, shader uniforms etc.). Because OpenGL was designed with "bind-to-modify" approach, most configuration calls internally need to bind the object first and only after that change the parameters (unless @extension{EXT,direct_state_access} extension is available to avoid this). To -reduce unneeded bind calls, %Magnum binds the object only if it is not already +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: @@ -74,13 +74,14 @@ carBumpTexture.setStorage(5, TextureFormat::RGB8) .generateMipmap(); @endcode -Method chaining is not used on non-configuring functions, such as Framebuffer::clear() -or Mesh::draw(), as these won't be commonly used in conjunction with other -functions anyway. +Method chaining is not used on non-configuring functions, such as +@ref Framebuffer::clear() or @ref Mesh::draw(), as these won't be commonly used +in conjunction with other functions anyway. -Method chaining is also used in 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: +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 Scene3D scene; diff --git a/doc/namespaces.dox b/doc/namespaces.dox index 0298aa27b..5cc38addc 100644 --- a/doc/namespaces.dox +++ b/doc/namespaces.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -24,21 +24,21 @@ */ /** @dir magnum/src/Magnum - * @brief Namespace Magnum (part of @ref building "Magnum library") + * @brief Namespace @ref Magnum (part of @ref building "Magnum library") */ /** @namespace Magnum @brief Root namespace Contains classes for interacting with OpenGL. -This library is built as part of %Magnum by default. To use it, you need to -find `%Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link +This library is built as part of Magnum by default. To use it, you need to +find `Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link to `${MAGNUM_LIBRARIES}`. See @ref building and @ref cmake for more information. */ /** @dir Magnum/Platform - * @brief Namespace Magnum::Platform + * @brief Namespace @ref Magnum::Platform */ /** @namespace Magnum::Platform @brief Platform-specific application and context creation @@ -46,9 +46,9 @@ information. Base classes for creating applications with various toolkits. Parts of this namespace are built if `WITH_*APPLICATION` is enabled when -building %Magnum, with each library having specific toolkit dependencies and +building Magnum, with each library having specific toolkit dependencies and platform requirements. To use particular application library, you need to -request given `*Application` component of `%Magnum` package in CMake, add +request given `*Application` component of `Magnum` package in CMake, add `${MAGNUM_*APPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_*APPLICATION_LIBRARIES}`. See particular `*Application` class documentation, @ref building, @ref cmake and @ref platform for more @@ -56,58 +56,58 @@ information. */ /** @dir Magnum/Math - * @brief Namespace Magnum::Math + * @brief Namespace @ref Magnum::Math */ /** @namespace Magnum::Math -@brief %Math library +@brief Math library Template classes for matrix and vector calculations. -This library is built as part of %Magnum by default. To use it, you need to -find `%Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link +This library is built as part of Magnum by default. To use it, you need to +find `Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link to `${MAGNUM_LIBRARIES}`. See @ref building, @ref cmake, @ref matrix-vector and @ref transformations for more information. */ /** @dir Magnum/Math/Algorithms - * @brief Namespace Magnum::Math::Algorithms + * @brief Namespace @ref Magnum::Math::Algorithms */ /** @namespace Magnum::Math::Algorithms -@brief %Algorithms +@brief Algorithms Various matrix and vector algorithms. -This library is built as part of %Magnum by default. To use it, you need to -find `%Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link +This library is built as part of Magnum by default. To use it, you need to +find `Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link to `${MAGNUM_LIBRARIES}`. See @ref building and @ref cmake for more information. */ /** @dir Magnum/Math/Geometry - * @brief Namespace Magnum::Math::Geometry + * @brief Namespace @ref Magnum::Math::Geometry */ /** @namespace Magnum::Math::Geometry -@brief %Geometry library +@brief Geometry library Functions for computing intersections, distances, areas and volumes. -This library is built as part of %Magnum by default. To use it, you need to -find `%Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link +This library is built as part of Magnum by default. To use it, you need to +find `Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link to `${MAGNUM_LIBRARIES}`. See @ref building and @ref cmake for more information. */ /** @dir Magnum/Audio - * @brief Namespace Magnum::Audio + * @brief Namespace @ref Magnum::Audio */ /** @namespace Magnum::Audio -@brief %Audio playback +@brief Audio playback Audio import, playback and integration with @ref SceneGraph. This library depends on **OpenAL** library. It is built if `WITH_AUDIO` is -enabled when building %Magnum. To use this library, you need to request -`%Audio` component of `%Magnum` package in CMake, add `${MAGNUM_AUDIO_INCLUDE_DIRS}` +enabled when building Magnum. To use this library, you need to request +`Audio` component of `Magnum` package in CMake, add `${MAGNUM_AUDIO_INCLUDE_DIRS}` to include path and link to `${MAGNUM_AUDIO_LIBRARIES}`. See @ref building and @ref cmake for more information. Additional plugins are enabled separately, see particular `*Importer` class documentation, @ref building-plugins, @@ -115,100 +115,99 @@ particular `*Importer` class documentation, @ref building-plugins, */ /** @dir Magnum/DebugTools - * @brief Namespace Magnum::DebugTools + * @brief Namespace @ref Magnum::DebugTools */ /** @namespace Magnum::DebugTools -@brief %Debug tools +@brief Debug tools Debugging helpers, renderers and profilers. -This library is built if `WITH_DEBUGTOOLS` is enabled when building %Magnum. To -use this library, you need to request `%DebugTools` component of `%Magnum` +This library is built if `WITH_DEBUGTOOLS` is enabled when building Magnum. To +use this library, you need to request `DebugTools` component of `Magnum` package in CMake and link to `${MAGNUM_DEBUGTOOLS_LIBRARIES}`. See @ref building, @ref cmake and @ref debug-tools for more information. */ /** @dir Magnum/MeshTools - * @brief Namespace Magnum::MeshTools + * @brief Namespace @ref Magnum::MeshTools */ /** @namespace Magnum::MeshTools -@brief %Mesh tools +@brief Mesh tools Tools for generating, optimizing and cleaning meshes. -This library is built if `WITH_MESHTOOLS` is enabled when building %Magnum. To -use this library, you need to request `%MeshTools` component of `%Magnum` +This library is built if `WITH_MESHTOOLS` is enabled when building Magnum. To +use this library, you need to request `MeshTools` component of `Magnum` package in CMake and link to `${MAGNUM_MESHTOOLS_LIBRARIES}`. See @ref building and @ref cmake for more information. */ /** @dir Magnum/Primitives - * @brief Namespace Magnum::Primitives + * @brief Namespace @ref Magnum::Primitives */ /** @namespace Magnum::Primitives @brief Primitive library Basic primitives for testing purposes. -This library is built if `WITH_PRIMITIVES` is enabled when building %Magnum. To -use this library, you need to request `%Primitives` component of `%Magnum` +This library is built if `WITH_PRIMITIVES` is enabled when building Magnum. To +use this library, you need to request `Primitives` component of `Magnum` package in CMake and link to `${MAGNUM_PRIMITIVES_LIBRARIES}`. See @ref building and @ref cmake for more information. */ /** @dir Magnum/SceneGraph - * @brief Namespace Magnum::SceneGraph + * @brief Namespace @ref Magnum::SceneGraph */ -/** -@namespace Magnum::SceneGraph -@brief %Scene graph library +/** @namespace Magnum::SceneGraph +@brief Scene graph library Managing object hierarchy, transformations and interactions. -This library is built if `WITH_SCENEGRAPH` is enabled when building %Magnum. To -use this library, you need to request `%SceneGraph` component of `%Magnum` +This library is built if `WITH_SCENEGRAPH` is enabled when building Magnum. To +use this library, you need to request `SceneGraph` component of `Magnum` package in CMake and link to `${MAGNUM_SCENEGRAPH_LIBRARIES}`. See @ref building, @ref cmake and @ref scenegraph for more information. */ /** @dir Magnum/Shaders - * @brief Namespace Magnum::Shaders + * @brief Namespace @ref Magnum::Shaders */ /** @namespace Magnum::Shaders @brief Builtin shaders Collection of shaders for easy prototyping and basic usage. -This library is built if `WITH_SHADERS` is enabled when building %Magnum. To -use this library, you need to request `%Shaders` component of `%Magnum` package +This library is built if `WITH_SHADERS` is enabled when building Magnum. To +use this library, you need to request `Shaders` component of `Magnum` package in CMake and link to `${MAGNUM_MESHTOOLS_SHADERS}`. See @ref building and -@ref cmake for more information. +@ref cmake and @ref shaders for more information. */ /** @dir Magnum/Shapes - * @brief Namespace Magnum::Shapes + * @brief Namespace @ref Magnum::Shapes */ /** @namespace Magnum::Shapes -@brief %Shape library +@brief Shape library Collision detection system. -This library is built if `WITH_SHAPES` is enabled when building %Magnum. To use -this library, you need to request `%Shapes` component of `%Magnum` package in +This library is built if `WITH_SHAPES` is enabled when building Magnum. To use +this library, you need to request `Shapes` component of `Magnum` package in CMake and link to `${MAGNUM_SHAPES_LIBRARIES}`. See @ref building, @ref cmake and @ref shapes for more information. */ /** @dir Magnum/Text - * @brief Namespace Magnum::Text + * @brief Namespace @ref Magnum::Text */ /** @namespace Magnum::Text -@brief %Text rendering +@brief Text rendering Font texture creation and text layouting. -This library is built if `WITH_TEXT` is enabled when building %Magnum. To use -this library, you need to request `%Text` component of `%Magnum` package in +This library is built if `WITH_TEXT` is enabled when building Magnum. To use +this library, you need to request `Text` component of `Magnum` package in CMake and link to `${MAGNUM_TEXT_LIBRARIES}`. See @ref building and @ref cmake for more information. Additional plugins are enabled separately, see particular `*Font` and `*FontConverter` class documentation, @ref building-plugins, @@ -216,21 +215,21 @@ for more information. Additional plugins are enabled separately, see particular */ /** @dir Magnum/TextureTools - * @brief Namespace Magnum::TextureTools + * @brief Namespace @ref Magnum::TextureTools */ /** @namespace Magnum::TextureTools -@brief %Texture tools +@brief Texture tools Tools for generating, compressing and optimizing textures. -This library is built if `WITH_TEXTURETOOLS` is enabled when building %Magnum. -To use this library, you need to request `%TextureTools` component of `%Magnum` +This library is built if `WITH_TEXTURETOOLS` is enabled when building Magnum. +To use this library, you need to request `TextureTools` component of `Magnum` package in CMake and link to `${MAGNUM_TEXTURETOOLS_LIBRARIES}`. See @ref building and @ref cmake for more information. */ /** @dir Magnum/Trade - * @brief Namespace Magnum::Trade + * @brief Namespace @ref Magnum::Trade */ /** @namespace Magnum::Trade @brief Data format exchange @@ -238,8 +237,8 @@ package in CMake and link to `${MAGNUM_TEXTURETOOLS_LIBRARIES}`. See Contains plugin interfaces for importing data of various formats and classes for direct access to the data. -This library is built as part of %Magnum by default. To use it, you need to -find `%Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link +This library is built as part of Magnum by default. To use it, you need to +find `Magnum` package, add `${MAGNUM_INCLUDE_DIRS}` to include path and link to `${MAGNUM_LIBRARIES}`. See @ref building and @ref cmake for more information. Additional plugins are enabled separately, see particular `*Importer` and `*ImageConverter` class documentation, @ref building-plugins, @@ -247,5 +246,5 @@ information. Additional plugins are enabled separately, see particular */ /** @dir magnum/src/MagnumPlugins - * @brief %Magnum plugins (part of @ref building "Magnum library") + * @brief Magnum plugins (part of @ref building "Magnum library") */ diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index 7d7c55992..8275dd308 100644 --- a/doc/opengl-mapping.dox +++ b/doc/opengl-mapping.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,7 +26,7 @@ namespace Magnum { /** @page opengl-mapping OpenGL command mapping -@brief List of OpenGL commands corresponding to particular %Magnum API. +@brief List of OpenGL commands corresponding to particular Magnum API. @tableofcontents @@ -53,10 +53,10 @@ OpenGL function | Matching API @fn_gl{BeginConditionalRender}, `glEndConditionalRender()` | @ref SampleQuery::beginConditionalRender(), \n @ref SampleQuery::endConditionalRender() @fn_gl{BeginQuery}, `glEndQuery()` | @ref PrimitiveQuery::begin(), \n @ref SampleQuery::begin(), \n @ref TimeQuery::begin(), \n @ref AbstractQuery::end() @fn_gl{BeginQueryIndexed}, `glEndQueryIndexed()` | | -@fn_gl{BeginTransformFeedback}, `glEndTransformFeedback()` | | +@fn_gl{BeginTransformFeedback}, `glEndTransformFeedback()` | @ref TransformFeedback::begin(), @ref TransformFeedback::end() @fn_gl{BindAttribLocation} | @ref AbstractShaderProgram::bindAttributeLocation() @fn_gl{BindBuffer} | not needed, handled internally in @ref Buffer and elsewhere -@fn_gl{BindBufferBase}, \n @fn_gl{BindBuffersBase}, \n @fn_gl{BindBufferRange}, \n @fn_gl{BindBuffersRange} | @ref Buffer::bind(), \n @ref Buffer::unbind() +@fn_gl{BindBufferBase}, \n @fn_gl{BindBuffersBase}, \n @fn_gl{BindBufferRange}, \n @fn_gl{BindBuffersRange} | @ref Buffer::bind(), \n @ref Buffer::unbind(), \n @ref TransformFeedback::attachBuffer(), \n @ref TransformFeedback::attachBuffers() @fn_gl{BindFragDataLocation} | @ref AbstractShaderProgram::bindFragmentDataLocation() @fn_gl{BindFragDataLocationIndexed} | @ref AbstractShaderProgram::bindFragmentDataLocationIndexed() @fn_gl{BindFramebuffer} | @ref Framebuffer::bind() @@ -65,7 +65,7 @@ OpenGL function | Matching API @fn_gl{BindRenderbuffer} | not needed, handled internally in @ref Renderbuffer @fn_gl{BindSampler}, \n @fn_gl{BindSamplers} | | @fn_gl{BindTexture}, \n @fn_gl{BindTextureUnit}, \n @fn_gl{BindTextures}, \n @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} | @ref AbstractTexture::bind() -@fn_gl{BindTransformFeedback} | | +@fn_gl{BindTransformFeedback} | not needed, handled internally in @ref TransformFeedback @fn_gl{BindVertexArray} | not needed, handled internally in @ref Mesh @fn_gl{BindVertexBuffer}, \n `glVertexArrayVertexBuffer()`, \n @fn_gl_extension{VertexArrayBindVertexBuffer,EXT,direct_state_access} \n @fn_gl{BindVertexBuffers}, \n `glVertexArrayVertexBuffers()` | | @fn_gl{BlendColor} | @ref Renderer::setBlendColor() @@ -110,8 +110,8 @@ OpenGL function | Matching API OpenGL function | Matching API --------------------------------------- | ------------ -@fn_gl{DebugMessageCallback} | @ref DebugMessage::setCallback() -@fn_gl{DebugMessageControl} | @ref DebugMessage::setEnabled() +@fn_gl{DebugMessageCallback} | @ref DebugOutput::setCallback() +@fn_gl{DebugMessageControl} | @ref DebugOutput::setEnabled() @fn_gl{DebugMessageInsert}, \n @fn_gl_extension2{InsertEventMarker,EXT,debug_marker}, \n @fn_gl_extension{StringMarker,GREMEDY,string_marker} | @ref DebugMessage::insert() @fn_gl{DepthFunc} | @ref Renderer::setDepthFunction() @fn_gl{DepthMask} | @ref Renderer::setDepthMask() @@ -209,9 +209,9 @@ OpenGL function | Matching API @fn_gl{GetTexImage}, \n `glGetnTexImage()`, \n @fn_gl_extension{GetnTexImage,ARB,robustness}, \n `glGetTextureImage()`, \n @fn_gl_extension{GetTextureImage,EXT,direct_state_access} | @ref Texture::image(), \n @ref TextureArray::image(), \n @ref CubeMapTexture::image(), \n @ref CubeMapTextureArray::image(), \n @ref RectangleTexture::image() @fn_gl{GetTexLevelParameter}, \n `glGetTextureLevelParameter()`, \n @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} | @ref Texture::imageSize(), \n @ref TextureArray::imageSize(), \n @ref CubeMapTexture::imageSize(), \n @ref CubeMapTextureArray::imageSize(), \n @ref RectangleTexture::imageSize() @fn_gl{GetTexParameter}, \n `glGetTextureParameter()`, \n @fn_gl_extension{GetTextureParameter,EXT,direct_state_access} | | -@fn_gl{GetTextureSubImage} | | -@fn_gl{GetTransformFeedback} | | -@fn_gl{GetTransformFeedbackVarying} | | +@fn_gl{GetTextureSubImage} | @ref Texture::subImage(), \n @ref TextureArray::subImage(), \n @ref CubeMapTexture::image(), \n @ref CubeMapTexture::subImage(), \n @ref CubeMapTextureArray::subImage(), \n @ref RectangleTexture::subImage() +@fn_gl{GetTransformFeedback} | not queryable, @ref TransformFeedback::attachBuffer() and @ref TransformFeedback::attachBuffers() setters only +@fn_gl{GetTransformFeedbackVarying} | not queryable, @ref AbstractShaderProgram::setTransformFeedbackOutputs() setter only @fn_gl{GetUniform}, \n `glGetnUniform()`, \n @fn_gl_extension{GetnUniform,ARB,robustness} | not queryable, @ref AbstractShaderProgram::setUniform() setter only @fn_gl{GetUniformBlockIndex} | | @fn_gl{GetUniformIndices} | | @@ -267,7 +267,7 @@ OpenGL function | Matching API OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{PatchParameter} | | -@fn_gl{PauseTransformFeedback}, @fn_gl{ResumeTransformFeedback} | | +@fn_gl{PauseTransformFeedback}, @fn_gl{ResumeTransformFeedback} | @ref TransformFeedback::pause(), @ref TransformFeedback::resume() @fn_gl{PixelStore} | | @fn_gl{PointParameter} | | @fn_gl{PointSize} | @ref Renderer::setPointSize() @@ -277,7 +277,8 @@ OpenGL function | Matching API @fn_gl{ProgramBinary} | | @fn_gl{ProgramParameter} | @ref AbstractShaderProgram::setRetrievableBinary(), \n @ref AbstractShaderProgram::setSeparable() @fn_gl{ProvokingVertex} | @ref Renderer::setProvokingVertex() -@fn_gl{PushDebugGroup}, @fn_gl{PopDebugGroup} | | +@fn_gl{PushDebugGroup}, \n @fn_gl_extension2{PushGroupMarker,EXT,debug_marker} | @ref DebugGroup::push() +@fn_gl{PopDebugGroup}, \n @fn_gl_extension2{PopGroupMarker,EXT,debug_marker} | @ref DebugGroup::pop() @subsection opengl-mapping-functions-q Q @@ -317,7 +318,7 @@ OpenGL function | Matching API OpenGL function | Matching API --------------------------------------- | ------------ @fn_gl{TexBuffer}, \n `glTextureBuffer()`, \n @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, \n @fn_gl{TexBufferRange}, \n `glTextureBufferRange()`, \n @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} | @ref BufferTexture::setBuffer() -@fn_gl{TexImage1D}, \n @fn_gl_extension{TextureImage1D,EXT,direct_state_access} \n @fn_gl{TexImage2D}, \n @fn_gl_extension{TextureImage2D,EXT,direct_state_access}, \n @fn_gl{TexImage3D}, \n @fn_gl_extension{TextureImage3D,EXT,direct_state_access} | @ref Texture::setImage(), \n @ref TextureArray::setImage(), \n @ref CubeMapTexture::setImage(), \n @ref CubeMapTextureArray::setImage(), \n @ref RectangleTexture::setImage() +@fn_gl{TexImage1D}, \n @fn_gl{TexImage2D}, \n @fn_gl{TexImage3D} | @ref Texture::setImage(), \n @ref TextureArray::setImage(), \n @ref CubeMapTexture::setImage(), \n @ref CubeMapTextureArray::setImage(), \n @ref RectangleTexture::setImage() @fn_gl{TexImage2DMultisample}, \n @fn_gl{TexImage3DMultisample} | @ref MultisampleTexture::setStorage() @fn_gl{TexParameter}, \n `glTextureParameter()`, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref Texture::setBaseLevel() "*Texture::setBaseLevel()", \n @ref Texture::setMaxLevel() "*Texture::setMaxLevel()", \n @ref Texture::setMinificationFilter() "*Texture::setMinificationFilter()", \n @ref Texture::setMagnificationFilter() "*Texture::setMagnificationFilter()", \n @ref Texture::setMinLod() "*Texture::setMinLod()", \n @ref Texture::setMaxLod() "*Texture::setMaxLod()", \n @ref Texture::setLodBias() "*Texture::setLodBias()", \n @ref Texture::setWrapping() "*Texture::setWrapping()", \n @ref Texture::setBorderColor() "*Texture::setBorderColor()", \n @ref Texture::setMaxAnisotropy() "*Texture::setMaxAnisotropy()", \n @ref Texture::setSRGBDecode() "*Texture::setSRGBDecode()", \n @ref Texture::setSwizzle() "*Texture::setSwizzle()", \n @ref Texture::setCompareMode() "*Texture::setCompareMode()", \n @ref Texture::setCompareFunction() "*Texture::setCompareFunction()", \n @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()" @fn_gl{TexStorage1D}, \n `glTextureStorage1D()`, \n @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}, \n @fn_gl{TexStorage2D}, \n `glTextureStorage2D()`, \n @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}, \n @fn_gl{TexStorage3D}, \n `glTextureStorage3D()`, \n @fn_gl_extension{TextureStorage3D,EXT,direct_state_access} | @ref Texture::setStorage(), \n @ref TextureArray::setStorage(), \n @ref CubeMapTexture::setStorage(), \n @ref CubeMapTextureArray::setStorage(), \n @ref RectangleTexture::setStorage() @@ -325,8 +326,8 @@ OpenGL function | Matching API @fn_gl{TexSubImage1D}, \n `glTextureSubImage1D()`, \n @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{TexSubImage2D}, \n `glTextureSubImage2D()`, \n @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{TexSubImage3D}, \n `glTextureSubImage3D()`, \n @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} | @ref Texture::setSubImage(), \n @ref TextureArray::setSubImage(), \n @ref CubeMapTexture::setSubImage(), \n @ref CubeMapTextureArray::setSubImage(), \n @ref RectangleTexture::setSubImage() @fn_gl{TextureBarrier} | | @fn_gl{TextureView} | | -@fn_gl{TransformFeedbackBufferBase}, \n @fn_gl{TransformFeedbackBufferRange} | | -@fn_gl{TransformFeedbackVaryings} | | +@fn_gl{TransformFeedbackBufferBase}, \n @fn_gl{TransformFeedbackBufferRange} | @ref TransformFeedback::attachBuffer(), \n @ref TransformFeedback::attachBuffers() +@fn_gl{TransformFeedbackVaryings} | @ref AbstractShaderProgram::setTransformFeedbackOutputs() @subsection opengl-mapping-functions-u U @@ -410,9 +411,9 @@ OpenGL function | Matching API @def_gl{MAX_COMPUTE_WORK_GROUP_COUNT} | | @def_gl{MAX_COMPUTE_WORK_GROUP_INVOCATIONS} | @ref AbstractShaderProgram::maxComputeWorkGroupInvocations() @def_gl{MAX_COMPUTE_WORK_GROUP_SIZE} | | -@def_gl{MAX_DEBUG_LOGGED_MESSAGES} | @ref DebugMessage::maxLoggedMessages() -@def_gl{MAX_DEBUG_MESSAGE_LENGTH} | @ref DebugMessage::maxMessageLength() -@def_gl{MAX_DEBUG_GROUP_STACK_DEPTH} | | +@def_gl{MAX_DEBUG_LOGGED_MESSAGES} | @ref DebugOutput::maxLoggedMessages() +@def_gl{MAX_DEBUG_MESSAGE_LENGTH} | @ref DebugOutput::maxMessageLength() +@def_gl{MAX_DEBUG_GROUP_STACK_DEPTH} | @ref DebugGroup::maxStackDepth() @def_gl{MAX_CLIP_DISTANCES} | | @def_gl{MAX_CULL_DISTANCES} | | @def_gl{MAX_COMBINED_CLIP_AND_CULL_DISTANCES} | | @@ -438,6 +439,10 @@ OpenGL function | Matching API @def_gl{MAX_TEXTURE_BUFFER_SIZE} | @ref BufferTexture::maxSize() @def_gl_extension{MAX_TEXTURE_MAX_ANISOTROPY,EXT,texture_filter_anisotropic} | @ref Sampler::maxMaxAnisotropy() @def_gl{MAX_TEXTURE_LOD_BIAS} | @ref AbstractTexture::maxLodBias() +@def_gl{MAX_TRANSFORM_FEEDBACK_BUFFERS} | @ref TransformFeedback::maxBuffers() +@def_gl{MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS} | @ref TransformFeedback::maxInterleavedComponents() +@def_gl{MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS} | @ref TransformFeedback::maxSeparateAttributes() +@def_gl{MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS} | @ref TransformFeedback::maxSeparateComponents() @def_gl{MAX_UNIFORM_BLOCK_SIZE} | @ref AbstractShaderProgram::maxUniformBlockSize() @def_gl{MAX_UNIFORM_BUFFER_BINDINGS} | @ref Buffer::maxUniformBindings() @def_gl{MAX_UNIFORM_LOCATIONS} | @ref AbstractShaderProgram::maxUniformLocations() diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox index 3b14aaf3d..550d0866d 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -50,7 +50,7 @@ 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 -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 1.30 | done @extension{ARB,map_buffer_range} | done @@ -70,13 +70,13 @@ GLSL 1.30 | done @extension{EXT,texture_shared_exponent} | done @extension{EXT,draw_buffers2} | | @extension{EXT,texture_integer} | done (GL 3.0 subset) -@extension{EXT,transform_feedback} | | +@extension{EXT,transform_feedback} | done @extension{NV,depth_buffer_float} | | @extension{NV,conditional_render} | done @subsection opengl-support-31 OpenGL 3.1 -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 1.40 | done @extension{ARB,texture_rectangle} | done @@ -89,7 +89,7 @@ GLSL 1.40 | done @subsection opengl-support-32 OpenGL 3.2 -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 1.50 | done @extension{ARB,geometry_shader4} | missing layered attachments @@ -104,7 +104,7 @@ GLSL 1.50 | done @subsection opengl-support-33 OpenGL 3.3 -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 3.30 | done @extension{ARB,instanced_arrays} | done @@ -120,7 +120,7 @@ GLSL 3.30 | done @subsection opengl-support-40 OpenGL 4.0 -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 4.00 | done @extension{ARB,draw_buffers_blend} | | @@ -134,12 +134,12 @@ GLSL 4.00 | done @extension{ARB,shader_subroutine} | | @extension{ARB,tessellation_shader} | missing some limit queries and patch parameter specification function @extension{ARB,texture_buffer_object_rgb32} | done -@extension{ARB,transform_feedback2} | | -@extension{ARB,transform_feedback3} | | +@extension{ARB,transform_feedback2} | missing transform feedback draw +@extension{ARB,transform_feedback3} | only advanced interleaving @subsection opengl-support-41 OpenGL 4.1 -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 4.10 | done @extension{ARB,ES2_compatibility} | only float depth clear @@ -151,7 +151,7 @@ GLSL 4.10 | done @subsection opengl-support-42 OpenGL 4.2 -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 4.20 | done @extension{ARB,texture_compression_bptc} | done @@ -169,7 +169,7 @@ GLSL 4.20 | done @subsection opengl-support-43 OpenGL 4.3 -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 4.30 | done @extension{ARB,arrays_of_arrays} | done (shading language only) @@ -177,7 +177,7 @@ GLSL 4.30 | done @extension{ARB,clear_buffer_object} | | @extension{ARB,compute_shader} | | @extension{ARB,copy_image} | | -@extension{KHR,debug} (also in ES) | missing log retrieval, sync, pipeline, transform feedback and sampler label and debug groups +@extension{KHR,debug} (also in ES) | missing log retrieval, sync, pipeline and sampler label @extension{ARB,explicit_uniform_location} | done @extension{ARB,fragment_layer_viewport} | done (shading language only) @extension{ARB,framebuffer_no_attachments} | | @@ -200,7 +200,7 @@ GLSL 4.30 | done @todo Also fallback to @extension{AMD,query_buffer_object} @todo @extension{AMD,pinned_memory} "fallback" for @extension{ARB,buffer_storage} -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 4.40 | done @def_gl{MAX_VERTEX_ATTRIB_STRIDE} | | @@ -215,7 +215,7 @@ GLSL 4.40 | done @subsection opengl-support-45 OpenGL 4.5 -%Extension | Status +Extension | Status ------------------------------------------- | ------ GLSL 4.50 | done @extension{ARB,ES3_1_compatibility} | | @@ -223,8 +223,8 @@ GLSL 4.50 | done @extension{ARB,conditional_render_inverted} | done @extension{ARB,cull_distance} | | @extension{ARB,derivative_control} | done (shading language only) -@extension{ARB,direct_state_access} | object creation subset only -@extension{ARB,get_texture_sub_image} | | +@extension{ARB,direct_state_access} | done for implemented functionality (except VAOs) +@extension{ARB,get_texture_sub_image} | missing compressed texture queries @extension{ARB,shader_texture_image_samples} | done (shading language only) @extension{ARB,texture_barrier} | | @extension{KHR,context_flush_control} (also in ES) | | @@ -232,7 +232,7 @@ GLSL 4.50 | done @subsection opengl-support-extensions ARB / Khronos OpenGL extensions -%Extension | Status +Extension | Status ------------------------------------------- | ------ @extension{ARB,robustness} | done @extension3{KHR,texture_compression_astc_ldr,texture_compression_astc_hdr} (also in ES) | | @@ -255,7 +255,7 @@ GLSL 4.50 | done @todo @extension{ATI,meminfo}, @extension{NVX,gpu_memory_info}, GPU temperature @todo @extension{AMD,performance_monitor}, @extension{INTEL,performance_query} -%Extension | Status +Extension | Status ------------------------------------------- | ------ @extension{AMD,vertex_shader_layer} | done (shading language only) @extension{AMD,shader_trinary_minmax} | done (shading language only) @@ -265,8 +265,8 @@ GLSL 4.50 | done @extension{EXT,direct_state_access} | done for implemented functionality @extension{EXT,texture_sRGB_decode} (also in ES) | done @extension{EXT,shader_integer_mix} (also in ES) | done (shading language only) -@extension2{EXT,debug_label} (also in ES) | missing pipeline, transform feedback and sampler label -@extension2{EXT,debug_marker} (also in ES) | missing marker groups +@extension2{EXT,debug_label} (also in ES) | missing pipeline and sampler label +@extension2{EXT,debug_marker} (also in ES) | done @extension{GREMEDY,string_marker} | done @subsection opengl-support-es20 OpenGL ES 2.0 @@ -286,7 +286,7 @@ supported. ESSL 3.10 is supported. @subsection opengl-support-es30-extensions OpenGL ES 2.0 extensions to match ES 3.0 functionality -%Extension | Status +Extension | Status ------------------------------------------- | ------ @es_extension{ANGLE,framebuffer_blit} | done @es_extension{ANGLE,framebuffer_multisample} | done @@ -323,6 +323,7 @@ supported. ESSL 3.10 is supported. @es_extension{OES,texture_float_linear} | done @es_extension2{OES,texture_half_float,OES_texture_float} | done @es_extension{OES,texture_float} | done +@es_extension{OES,texture_npot} | done (nothing to do) @es_extension{OES,vertex_half_float} | done @es_extension{OES,packed_depth_stencil} | done @es_extension{OES,depth_texture} | done @@ -339,7 +340,7 @@ Only extensions not already listed in above tables are included here. @todo Support also IMG_multisampled_render_to_texture? It has different enum values (!) -%Extension | Status +Extension | Status ------------------------------------------- | ------ @es_extension{APPLE,texture_format_BGRA8888} | done @es_extension{CHROMIUM,map_sub} | only buffer mapping @@ -365,7 +366,7 @@ Only extensions not already listed in above tables are included here. @section opengl-unsupported Unsupported OpenGL features Some functionality, which is either soon-to-be deprecated or isn't proven to -add any performance gains, is not supported in %Magnum. See also +add any performance gains, is not supported in Magnum. See also @ref opengl-deprecated. @subsection opengl-unsupported-features Unsupported features @@ -375,7 +376,7 @@ add any performance gains, is not supported in %Magnum. See also not supported. The only exception are features that are needed for some OpenGL ES 2.0 implementations (such as luminance texture formats). - State queries (various `glIs*()`, `glGet*()` functions) are not supported. - %Magnum API is designed to prevent the need for majority of them, many of + Magnum API is designed to prevent the need for majority of them, many of them are tracked internally to avoid redundant state changes and in many cases it is easier to set the state to some value rather than query it and then decide on the result. For detailed state introspection please use diff --git a/doc/opengl.dox b/doc/opengl.dox index babe2c6c6..c1138d16d 100644 --- a/doc/opengl.dox +++ b/doc/opengl.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,7 +26,7 @@ /** @page opengl OpenGL @brief State of OpenGL support, version and extension requirements. -The following table maps OpenGL function names to %Magnum API, useful for +The following table maps OpenGL function names to Magnum API, useful for developers with existing OpenGL background. Note that, as reverse mapping, each function documentation also contains list of OpenGL functions used. @@ -43,25 +43,25 @@ The engine requires at least OpenGL 2.1 or OpenGL ES 2.0, but some specific functionality has greater requirements. Following are lists of features requiring specific OpenGL version. In most cases it is also specified which extension is required, so if given hardware supports required extension, it -doesn't need to have required OpenGL version too (e.g. `ARB_vertex_array_object` +doesn't need to have required OpenGL version too (e.g. @extension{ARB,vertex_array_object} is supported on older Intel GPUs even if they are capable of OpenGL 2.1 only). -- @subpage requires-gl30 -- @subpage requires-gl31 -- @subpage requires-gl32 -- @subpage requires-gl33 -- @subpage requires-gl40 -- @subpage requires-gl41 -- @subpage requires-gl42 -- @subpage requires-gl43 -- @subpage requires-gl44 -- @subpage requires-gl45 -- @subpage requires-extension -- @subpage requires-gl -- @subpage requires-gles20 -- @subpage requires-gles30 -- @subpage requires-gles31 -- @subpage requires-es-extension +- @subpage requires-gl30 +- @subpage requires-gl31 +- @subpage requires-gl32 +- @subpage requires-gl33 +- @subpage requires-gl40 +- @subpage requires-gl41 +- @subpage requires-gl42 +- @subpage requires-gl43 +- @subpage requires-gl44 +- @subpage requires-gl45 +- @subpage requires-extension +- @subpage requires-gl +- @subpage requires-gles20 +- @subpage requires-gles30 +- @subpage requires-gles31 +- @subpage requires-es-extension @see @ref building, @ref cmake, @ref MAGNUM_TARGET_GLES, @ref MAGNUM_TARGET_GLES2 diff --git a/doc/platform.dox b/doc/platform.dox index b15efcf0b..cfe8de15c 100644 --- a/doc/platform.dox +++ b/doc/platform.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,13 +23,13 @@ DEALINGS IN THE SOFTWARE. */ -namespace Magnum { namespace Platform { +namespace Magnum { /** @page platform Platform support @brief Integration into windowing toolkits and creation of windowless contexts. - Next page: @ref types -@ref Platform namespace contains classes integrating %Magnum engine into +@ref Platform namespace contains classes integrating Magnum engine into various toolkits, both windowed and windowless. Each class has slightly different dependencies and platform requirements, see documentation of @ref Platform namespace and particular `*Application` classes for more @@ -48,14 +48,14 @@ Windowed applications provide a window and keyboard and mouse handling. The 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 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. +@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. 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 +then matter of replacing only the `#``include` statement (and changing one line in CMake build script, as you see later). Barebone application implementation which will just clear the window to dark @@ -103,8 +103,8 @@ MAGNUM_APPLICATION_MAIN(MyApplication) By default the application doesn't respond to window size changes in any way, 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 Sdl2Application::viewportEvent() "viewportEvent()" function and pass the -new size to the framebuffer: +@ref Platform::Sdl2Application::viewportEvent() "viewportEvent()" function and +pass the new size to the framebuffer: @code class MyApplication: public Platform::Application { // ... @@ -125,12 +125,12 @@ void MyApplication::viewportEvent(const Vector2i& size) { Windowless applications provide just a context for ofscreen rendering or performing tasks on GPU. There is not yet any platform-independent toolkit which could handle this in portable way, thus you have to use platform-specific -ones. %Magnum provides windowless applications for X11-based Unix, OS X and +ones. Magnum provides windowless applications for X11-based Unix, OS X and Windows. To make things simple, as an example we will use only @ref Platform::WindowlessGlxApplication, see link for bootstrap application below for fully portable example. -You need to implement just @ref WindowlessGlxApplication::exec() "exec()" +You need to implement just @ref Platform::WindowlessGlxApplication::exec() "exec()" function. The class can be then used directly in `main()`, but again, for convenience and portability it's better to use @ref MAGNUM_WINDOWLESSGLXAPPLICATION_MAIN() macro. @@ -139,7 +139,7 @@ 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 +`#``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.). @@ -182,8 +182,8 @@ MAGNUM_WINDOWLESSAPPLICATION_MAIN(MyApplication) @section platform-compilation Compilation with CMake -Barebone compilation consists just of finding %Magnum library with required -`*Application` component, adding %Magnum's `${MAGNUM_INCLUDE_DIRS}` and +Barebone compilation consists just of finding Magnum library with required +`*Application` component, adding Magnum's `${MAGNUM_INCLUDE_DIRS}` and application-specific `${MAGNUM_SDL2APPLICATION_INCLUDE_DIRS}` to include path, compilation of the executable and linking `${MAGNUM_LIBRARIES}` and `${MAGNUM_SDL2APPLICATION_LIBRARIES}` to it. @@ -194,7 +194,7 @@ and `${MAGNUM_APPLICATION_LIBRARIES}` aliases (or `${MAGNUM_WINDOWLESSAPPLICATIO 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). +`#``include` line in the actual code, as said above). @code find_package(Magnum REQUIRED Sdl2Application) @@ -211,8 +211,9 @@ target_link_libraries(myapplication By default the application is created with some reasonable defaults (e.g. window size 800x600 pixels). If you want something else, you can pass -@ref Sdl2Application::Configuration "Configuration" instance to application -constructor. Using method chaining it can be done conveniently like this: +@ref Platform::Sdl2Application::Configuration "Configuration" instance to +application constructor. Using method chaining it can be done conveniently like +this: @code MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc, argv, Configuration() @@ -225,8 +226,8 @@ MyApplication::MyApplication(int& argc, char** argv): 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 Sdl2Application::Configuration "Configuration" instance and -then specify it later with @ref Sdl2Application::createContext() "createContext()": +instead of @ref Platform::Sdl2Application::Configuration "Configuration" +instance and then specify it later with @ref Platform::Sdl2Application::createContext() "createContext()": @code MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc, argv, nullptr) { // ... @@ -239,9 +240,9 @@ MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc } @endcode -If the context creation in constructor or @ref Sdl2Application::createContext() "createContext()" +If the context creation in constructor or @ref Platform::Sdl2Application::createContext() "createContext()" fails, the application exits. However, it is also possible to negotiate the -context using @ref Sdl2Application::tryCreateContext() "tryCreateContext()". +context using @ref Platform::Sdl2Application::tryCreateContext() "tryCreateContext()". 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: @@ -263,7 +264,7 @@ MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc @section platform-custom Using custom platform toolkits In case you want to use some not-yet-supported toolkit or you don't want to use -the application wrappers in @ref Platform namespace, you can initialize %Magnum +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. @@ -287,6 +288,9 @@ int main(int argc, char** argv) { } @endcode +@attention Currently Magnum is limited to single OpenGL context, which must be + always set as current. + On majority of platforms the @ref Platform::Context class does GL function 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. @@ -319,4 +323,4 @@ target_link_libraries(myapplication - Next page: @ref types */ -}} +} diff --git a/doc/plugins.dox b/doc/plugins.dox index f2c3b0a8e..d2b26cf13 100644 --- a/doc/plugins.dox +++ b/doc/plugins.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,12 +25,12 @@ namespace Magnum { /** @page plugins Loading and using plugins -@brief Extending %Magnum with additional functionality +@brief Extending Magnum with additional functionality - Previous page: @ref transformations -- Next page: @ref scenegraph +- Next page: @ref shaders -The base %Magnum library contains math support, scene graph implementation and +The base Magnum library contains math support, scene graph implementation and is able to interact with graphics and audio hardware. However, the base library doesn't provide any functions for dealing with specific file formats, as there are simply too many formats to have them included directly in the library. @@ -52,7 +52,7 @@ might not be available on all platforms. @section plugins-types Plugin interfaces -%Magnum contains these plugin interfaces: +Magnum contains these plugin interfaces: - @ref Trade::AbstractImporter -- importers for general 2D and 3D scene, mesh, material, texture and image data. See `*Importer` classes in @@ -81,7 +81,7 @@ for given plugin interface, for example @ref Trade::AbstractImporter. You must set particular plugin directory, from which the manager will load and instantiate the plugins. To save you from hardcoding the value into your application source, the plugin directory is provided as `MAGNUM_PLUGINS_DIR` -CMake variable. The default is set to %Magnum install location, but you can +CMake variable. The default is set to Magnum install location, but you can change it through CMake to anything else. The `MAGNUM_PLUGINS_IMPORTER_DIR`, `MAGNUM_PLUGINS_IMAGECONVERTER_DIR`, `MAGNUM_PLUGINS_FONT_DIR`, `MAGNUM_PLUGINS_FONTCONVERTER_DIR`, `MAGNUM_PLUGINS_AUDIOIMPORTER_DIR` @@ -98,10 +98,11 @@ to these: In case you are using multi-configuration build system (such as Visual Studio or XCode), CMake cannot provide separate plugin directory for debug and release -build and you have to do it on your own in preprocessing step using -@ref corrade-cmake "CORRADE_IS_DEBUG_BUILD" 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: +build and you have to select between `MAGNUM_PLUGINS_*_DIR` and +`MAGNUM_PLUGINS_*_DEBUG_DIR` based on @ref corrade-cmake "CORRADE_IS_DEBUG_BUILD" +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 #ifdef CORRADE_IS_DEBUG_BUILD #define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}" @@ -110,6 +111,11 @@ and fall back to autodetection for the rest: #endif @endcode +However, if you want to use only one (debug/release) plugin version for both +debug and release configurations of the application, you need to edit +`MAGNUM_PLUGINS_DIR` or `MAGNUM_PLUGINS_DEBUG_DIR` using CMake and point them +to directory containing desired plugin version. + 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 @@ -129,12 +135,12 @@ lifetime of all plugin instances created from it. // ... { - PluginManager::Manager manager(MAGNUM_PLUGINS_IMPORTER_DIR); - if(!(manager.load("TgaImporter") & PluginManager::LoadState::Loaded)) { - Error() << "Cannot load TgaImporter plugin from" << manager.pluginDirectory(); + PluginManager::Manager manager{MAGNUM_PLUGINS_IMPORTER_DIR}; + std::unique_ptr tgaImporter = manager.loadAndInstantiate("TgaImporter"); + if(!tgaImporter) { + Error() << "Cannot load importer plugin from" << manager.pluginDirectory(); std::exit(1); } - std::unique_ptr tgaImporter = manager.instance("TgaImporter"); // Use the plugin... @@ -202,7 +208,7 @@ int main(int argc, char** argv) { @section plugins-develop Developing your own plugins See class documentation of particular plugin interfaces for more information -about subclassing. The %Corrade's @ref plugin-management "plugin management tutorial" +about subclassing. The Corrade's @ref plugin-management "plugin management tutorial" contains more information about plugin compilation and registering. If you want to develop a plugin which depends on another, you need to find the @@ -211,7 +217,7 @@ to how static plugins are found above. See @ref cmake and @ref cmake-plugins for more information. - Previous page: @ref transformations -- Next page: @ref scenegraph +- Next page: @ref shaders */ } diff --git a/doc/portability.dox b/doc/portability.dox index 578d0fa46..cc8b49d16 100644 --- a/doc/portability.dox +++ b/doc/portability.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,7 +31,7 @@ namespace Magnum { @section portability-target Target-specific code -If %Magnum is compiled with e.g. OpenGL ES 2.0 support, some features present +If Magnum is compiled with e.g. OpenGL ES 2.0 support, some features present in desktop version are not available. It means that some classes, functions 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 @@ -60,10 +60,10 @@ also @ref requires-gl, @ref requires-gles20 and @ref requires-gles30. @section portability-compiler Compiler- and platform-specific code -%Magnum is attempting to be future-proof and as intuitive for users as +Magnum is attempting to be future-proof and as intuitive for users as possible. Many features from C++11 are used to simplify things and make them 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 +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. @@ -108,7 +108,7 @@ MAGNUM_ASSERT_EXTENSION_SUPPORTED(GL::ARB::geometry_shader4); @endcode Each class, function or enum value is marked accordingly if it needs specific -extension or specific OpenGL version. Various classes in %Magnum are taking +extension or specific OpenGL version. Various classes in Magnum are taking advantage of some extensions and enable faster code paths if given extension is available, but also have proper fallback when it's not, see for example @ref AbstractShaderProgram-performance-optimization "AbstractShaderProgram", @@ -117,7 +117,7 @@ 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 +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. diff --git a/doc/scenegraph.dox b/doc/scenegraph.dox index 3a410b60b..aa0a316ea 100644 --- a/doc/scenegraph.dox +++ b/doc/scenegraph.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,14 +23,14 @@ DEALINGS IN THE SOFTWARE. */ -namespace Magnum { namespace SceneGraph { +namespace Magnum { /** @page scenegraph Using scene graph @brief Overview of scene management capabilities. -- Previous page: @ref plugins +- Previous page: @ref shaders - Next page: @ref shapes -%Scene graph provides way to hiearchically manage your objects, their +Scene graph provides way to hiearchically manage your objects, their transformation, physics interaction, animation and rendering. The library is contained in @ref SceneGraph namespace, see its documentation for more information about building and usage with CMake. @@ -41,7 +41,7 @@ There are naturally many possible feature combinations (2D vs. 3D, different transformation representations, animated vs. static, object can have collision shape, participate in physics events, have forward vs. deferred rendering...) and to make everything possible without combinatiorial explosion and allow the -users to provide their own features, scene graph in %Magnum is composed of +users to provide their own features, scene graph in Magnum is composed of three main components: - objects, providing parent/children hierarchy @@ -56,114 +56,154 @@ three main components: @section scenegraph-transformation Transformations Transformation handles object position, rotation etc. and its basic property -is dimension count (2D or 3D) and underlying floating-point type. - -@note All classes in @ref SceneGraph are templated on underlying type. However, - in most cases @ref Magnum::Float "Float" is used and thus nearly all - classes have convenience aliases so you don't have to explicitly specify - it. - -%Scene graph has implementation of transformations in both 2D and 3D, using -either matrices or combination of position and rotation. Each implementation -has its own advantages and disadvantages -- for example when using matrices -you can have nearly arbitrary transformations, but composing transformations -and computing their inverse is costly operation. On the other hand quaternions -won't allow you to scale or shear objects, but are more memory efficient than -matrices. +is dimension count (2D or 3D) and underlying floating-point type. All classes +in @ref SceneGraph are templated on underlying type. However, in most cases +@ref Float "Float" is used and thus nearly all classes have convenience aliases +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 +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 +to scale or shear objects, but have far better performance characteristics. It's also possible to implement your own transformation class for specific -needs, see source of other transformation classes for more information. - -@section scenegraph-hierarchy Scene hierarchy - -%Scene hierarchy is skeleton part of scene graph. In the root there is -@ref Scene and its children are @ref Object instances. The hierarchy has some -transformation type, identical for all objects (because for example having part -of the tree in 2D and part in 3D just wouldn't make sense). Common usage is to -typedef %Scene and %Object with desired transformation type to save unnecessary -typing later: +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" -- + arbitrary 2D transformations but with slow inverse transformations and no + floating-point drift reduction +- @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D" -- + arbitrary 3D transformations but with slow inverse transformations and no + floating-point drift reduction +- @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" -- + 3D translation, rotation and reflection (no scaling), with relatively fast + inverse transformations and floating-point drift reduction +- @ref SceneGraph::BasicDualComplexTransformation "SceneGraph::DualComplexTransformation" -- + 2D translation and rotation with fast inverse transformations and + floating-point drift reduction +- @ref SceneGraph::BasicDualQuaternionTransformation "SceneGraph::DualQuaternionTransformation" -- + 3D translation and rotation with fast inverse transformation and + floating-point drift reduction +- @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 typedef SceneGraph::Scene Scene3D; typedef SceneGraph::Object Object3D; @endcode -Then you can start building the hierarchy by *parenting* one object to another. -Parent object can be either passed in constructor or using @ref Object::setParent(). -%Scene is always root object, so it naturally cannot have parent object. +@attention Note that you have to include both @ref Magnum/SceneGraph/Object.h + and desired transformation class (e.g. @ref Magnum/SceneGraph/MatrixTransformation3D.h) + to be able to use the resulting type. + +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 Scene3D scene; -auto first = new Object3D(&scene); -auto second = new Object3D(first); +Object3D object; +object.setParent(&scene) + .rotateY(15.0_degf) + .translate(Vector3::xAxis(5.0f)); @endcode -%Object children can be accessed using @ref Object::firstChild() and -@ref Object::lastChild(), then you can traverse siblings (objects with the same -parent) with @ref Object::previousSibling() and @ref Object::nextSibling(). For -example all children of an object can be traversed the following way: +@section scenegraph-hierarchy Scene hierarchy + +Scene hierarchy is skeleton part of scene graph. In the root there is +@ref SceneGraph::Scene and its children are @ref SceneGraph::Object instances. +Whole hierarchy has one transformation type, identical for all objects (because +for example having part of the tree in 2D and part in 3D just wouldn't make +sense). + +Then you can start building the hierarchy by *parenting* one object to another. +Parent object can be either passed in constructor or set using +@ref SceneGraph::Object::setParent(). Scene is always root object, so it +naturally cannot have parent object. Parent and children relationships can be +observed through @ref SceneGraph::Object::parent() and +@ref SceneGraph::Object::children(). @code -Object3D* o; -for(Object3D* child = o->firstChild(); child; child = child->nextSibling()) { - // ... -} +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" -for information about possible issues. - -The object is derived from the transformation you specified earlier in the -`typedef`, so you can directly transform the objects using methods of given -transformation implementation. %Scene, as a root object, cannot have any -transformation. For convenience you can use method chaining: +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 -auto next = new Object3D; -next->setParent(another) - .translate(Vector3::yAxis(3.0f)) - .rotateY(35.0_degf); +Scene3D scene; + +Object3D& first = scene.addChild(); +Object3D& second = first.addChild(); @endcode @section scenegraph-features Object features The object itself handles only parent/child relationship and transformation. -To make the object renderable, animatable, add collision shape to it etc., you +To make the object renderable, animable, add collision shape to it etc., you have to add a *feature* to it. -Each feature takes reference to holder object in constructor, so adding a -feature to an object might look just like this, as in some cases you don't even -need to keep the pointer to it: -@code -Object3D* o; -new MyFeature(o); -@endcode - -Features of an object can be accessed using @ref Object::firstFeature() and -@ref Object::lastFeature(), then you can traverse the features using -@ref AbstractFeature::previousFeature() and @ref AbstractFeature::nextFeature(), -similarly to traversing object children: +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 + projection matrix, aspect ratio correction etc.. Used for rendering parts + of the scene. +- @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 + 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 + 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 + object properties, object shape or force vector for debugging purposes. See + @ref debug-tools for more information. + +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 -Object3D* o; -for(Object3D::FeatureType feature = o->firstFeature(); feature; feature = feature->nextFeature()) { - // ... -} +Object3D& o; +new MyFeature{o, ...}; @endcode Some features are passive, some active. Passive features can be just added to -an object like above, without any additional work (for example collision shape). -Active features require the user to implement some virtual function (for -example to draw the object on screen or perform animation step). To make things -convenient, features can be added directly to object itself using multiple -inheritance, so you can conveniently add all the active features you want and -implement needed functions in your own @ref Object subclass without having to -subclass each feature individually (and making the code overly verbose). -Simplified example: +an object, with no additional work except for possible configuration (for +example collision shape). Active features require the user to implement some +virtual function (for example to draw the object on screen or perform animation +step). To make things convenient, features can be added directly to object +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 -class Bomb: public Object3D, SceneGraph::Drawable3D, SceneGraph::Animable3D { +class BouncingBall: public Object3D, SceneGraph::Drawable3D, SceneGraph::Animable3D { public: - Bomb(Object3D* parent): Object3D(parent), SceneGraph::Drawable3D(*this), SceneGraph::Animable3D(*this) {} + explicit BouncingBall(Object3D* parent): Object3D{parent}, SceneGraph::Drawable3D{*this}, SceneGraph::Animable3D{*this} {} - protected: + private: // drawing implementation for Drawable feature void draw(...) override; @@ -179,55 +219,111 @@ feature list. Similarly to object hierarchy, when destroying object, all its features (both member and inherited) are destroyed. See detailed explanation of @ref scenegraph-feature-construction-order "construction and destruction order" -for information about possible issues. +for information about possible issues. Also, there is a +@ref SceneGraph::AbstractObject::addFeature() counterpart to +@ref SceneGraph::Object::addChild(): +@code +Object3D& o; +o.addFeature(...); +@endcode -@section scenegraph-caching Transformation caching +@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 -transformation, changing parent or explicitly calling @ref Object::setDirty(). +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 AbstractFeature::markDirty() is called on every feature. Calling -@ref Object::setClean() cleans the dirty object and all its dirty parents. -The function goes through all object features and calls @ref AbstractFeature::clean() -or @ref AbstractFeature::cleanInverted() depending on which caching is enabled -on given feature. If the object is already clean, @ref Object::setClean() does -nothing. - -Most probably you will need caching in @ref Object itself -- which doesn't -support it on its own -- however you can take advantage of multiple inheritance -and implement it using @ref AbstractFeature. In order to have caching, you must -enable it first, because by default the caching is disabled. You can enable it -using @ref AbstractFeature::setCachedTransformations() and then implement -corresponding cleaning function(s): +@ref SceneGraph::AbstractFeature::markDirty() is called on every feature. +Calling @ref SceneGraph::Object::setClean() cleans the dirty object and all its +dirty parents. The function goes through all object features and calls +@ref SceneGraph::AbstractFeature::clean() or +@ref SceneGraph::AbstractFeature::cleanInverted() depending on which caching is +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 +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 class CachingObject: public Object3D, SceneGraph::AbstractFeature3D { public: - CachingObject(Object3D* parent): SceneGraph::AbstractFeature3D(*this) { + explicit CachingObject(Object3D* parent): Object3D{parent}, SceneGraph::AbstractFeature3D{*this} { setCachedTransformations(SceneGraph::CachedTransformation::Absolute); } protected: void clean(const Matrix4& absoluteTransformation) override { - absolutePosition = absoluteTransformation.translation(); + _absolutePosition = absoluteTransformation.translation(); } private: - Vector3 absolutePosition; + Vector3 _absolutePosition; }; @endcode When you need to use the cached value, you can explicitly request the cleanup -by calling @ref Object::setClean(). @ref Camera3D "Camera", for example, calls -it automatically before it starts rendering, as it needs its own inverse -transformation to properly draw the objects. +by calling @ref SceneGraph::Object::setClean(). @ref SceneGraph::Camera3D "Camera", +for example, calls it automatically before it starts rendering, as it needs its +own inverse transformation to properly draw the objects. + +@subsection scenegraph-features-transformation Polymorphic access to object transformation + +Features by default have access only to @ref SceneGraph::AbstractObject, which +doesn't know about any particular transformation implementation. This has the +advantage that features don't have to be implemented for all possible +transformation implementations. But, as a consequence, it is impossible to +transform the object using only pointer to @ref SceneGraph::AbstractObject. + +To solve this, the transformation classes are subclassed from interfaces +sharing common functionality, so the feature can use that interface instead of +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" -- + base for all transformations +- @ref SceneGraph::AbstractTranslation "SceneGraph::AbstractTranslation*D" -- + base for all transformations providing translation +- @ref SceneGraph::AbstractBasicTranslationRotation2D "SceneGraph::AbstractTranslationRotation2D", + @ref SceneGraph::AbstractBasicTranslationRotation3D "SceneGraph::AbstractTranslationRotation3D" -- + base for all transformations providing translation and rotation +- @ref SceneGraph::AbstractBasicTranslationRotationScaling2D "SceneGraph::AbstractBasicTranslationRotationScaling2D", + @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 +transformations. The virtual calls are used only when calling through the +interface and not when using the concrete implementation directly to avoid +negative performance effects. There are no functions to retrieve object +transformation, you need to use the above transformation caching mechanism for +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 +class TransformingFeature: public SceneGraph::AbstractFeature3D { + public: + template TransformingFeature(SceneGraph::Object& object): + SceneGraph::AbstractFeature3D(object), transformation(object) {} -See @ref SceneGraph-AbstractFeature-subclassing-caching for more information. + private: + 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", +thus the reference to @ref SceneGraph::AbstractBasicTranslationRotation3D "SceneGraph::AbstractTranslationRotation3D", +is automatically extracted from the reference in our constructor. @section scenegraph-construction-order Construction and destruction order @@ -267,7 +363,7 @@ 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: +inherited after the Object class: @code class MyObject: public Object3D, MyFeature { public: @@ -305,7 +401,7 @@ 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 plugins +- Previous page: @ref shaders - Next page: @ref shapes */ -}} +} diff --git a/doc/shaders-distancefieldvector.png b/doc/shaders-distancefieldvector.png new file mode 100644 index 000000000..c54d99240 Binary files /dev/null and b/doc/shaders-distancefieldvector.png differ diff --git a/doc/shaders-flat.png b/doc/shaders-flat.png new file mode 100644 index 000000000..2aa2037ec Binary files /dev/null and b/doc/shaders-flat.png differ diff --git a/doc/shaders-meshvisualizer.png b/doc/shaders-meshvisualizer.png new file mode 100644 index 000000000..896dda575 Binary files /dev/null and b/doc/shaders-meshvisualizer.png differ diff --git a/doc/shaders-phong.png b/doc/shaders-phong.png new file mode 100644 index 000000000..2f1a44a33 Binary files /dev/null and b/doc/shaders-phong.png differ diff --git a/doc/shaders-vector.png b/doc/shaders-vector.png new file mode 100644 index 000000000..9697fdd7a Binary files /dev/null and b/doc/shaders-vector.png differ diff --git a/doc/shaders-vertexcolor.png b/doc/shaders-vertexcolor.png new file mode 100644 index 000000000..a865c87e0 Binary files /dev/null and b/doc/shaders-vertexcolor.png differ diff --git a/doc/shaders.dox b/doc/shaders.dox new file mode 100644 index 000000000..eef8dcc3e --- /dev/null +++ b/doc/shaders.dox @@ -0,0 +1,136 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +namespace Magnum { +/** @page shaders Builtin shaders +@brief Overview and basic usage of builtin shaders. + +- Previous page: @ref plugins +- Next page: @ref scenegraph + +@tableofcontents + +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 + texture +- @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 + +All the builtin shaders can be used on unextended OpenGL 2.1 and OpenGL ES 2.0 +/ WebGL 1.0, but they try to use the most recent technology available to have +them as efficient as possible on every configuration. + +@section shaders-usage Usage + +Shader usage is divided into two parts: configuring vertex attributes in the +mesh and configuring the shader itself. + +Each shader expects some set of vertex attributes, thus when adding vertex +buffer into the mesh, you need to specify which shader attributes are on which +position in the buffer. See @ref Mesh::addVertexBuffer() for details and usage +examples. Example mesh configuration for @ref Shaders::Phong shader: +@code +struct Vertex { + Vector3 position; + Vector3 normal; + Vector2 textureCoordinates; +}; +Vertex data[] = { ... }; + +Buffer vertices; +vertices.setData(data, BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, + Shaders::Phong::Position{}, + Shaders::Phong::Normal{}, + Shaders::Phong::TextureCoordinates{}); +@endcode + +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 +Matrix4 transformationMatrix, projectionMatrix; +Texture2D diffuseTexture, specularTexture; + +Shaders::Phong shader{Shaders::Phong::DiffuseTexture}; +shader.setDiffuseTexture(diffuseTexture) + .setLightPosition({5.0f, 5.0f, 7.0f}) + .setTransformationMatrix(transformationMatrix) + .setNormalMatrix(transformationMatrix.rotation()) + .setProjectionMatrix(projectionMatrix); + +mesh.draw(shader); +@endcode + +@section shaders-generic Generic vertex attributes + +Many shaders share the same vertex attribute definitions, such as positions, +normals, texture coordinates etc. It's thus possible to configure the mesh +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 +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 +Shaders::MeshVisualizer visualizerShader{Shaders::MeshVisualizer::Wireframe}; +visualizerShader.setColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) + .setWireframeColor(Color3{0.95f}) + .setViewportSize(defaultFramebuffer.viewport().size()) + .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix); + +mesh.draw(visualizerShader); +@endcode + +The @ref MeshTools::compile() utility configures meshes using generic vertex +attribute definitions to make them usable with any shader. + +- Previous page: @ref plugins +- Next page: @ref scenegraph + +*/ +} diff --git a/doc/shapes.dox b/doc/shapes.dox index b52c0ed0b..4b9c79bba 100644 --- a/doc/shapes.dox +++ b/doc/shapes.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,7 +23,7 @@ DEALINGS IN THE SOFTWARE. */ -namespace Magnum { namespace Shapes { +namespace Magnum { /** @page shapes Collision detection @brief Collection of simple shapes for high performance collision detection. @@ -42,7 +42,7 @@ grouped together using various operations. @section shapes-collection Available shapes -%Magnum provides a set of simple shapes for collision detection, similarly to +Magnum provides a set of simple shapes for collision detection, similarly to what is found in many other collision detection libraries. Additionally some 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 @@ -55,7 +55,7 @@ around platformer game level. - @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. +line and point. Collision of two lines can be detected only in 2D. @subsection shapes-2D Two-dimensional shapes @@ -76,7 +76,7 @@ is least efficient. @section shapes-composition Creating shape compositions -%Shapes can be composed together using one of three available logical +Shapes can be composed together using one of three available logical operations: AND, OR and NOT. These operations are mapped to `&&`, `||` and `!` operators, so for example creating negation of logical OR of line segment and point is simple as this: @@ -110,7 +110,7 @@ Shapes::Composition3D composition = simplified && (sphere || box); @section shapes-collisions Detecting shape collisions -%Shape pairs which have collision occurence detection implemented can be tested +Shape pairs which have collision occurence detection implemented can be tested for collision using the `%` operator. The operator returns boolean describing whether the collision happened or not. Example: @code @@ -124,9 +124,9 @@ As this is useful for e.g. menu handling and simple particle systems, for serious physics you often need more information like contact point, separation normal and penetration depth. For shape pairs which have implemented this detailed collision detection you can use the `/` operator, which returns -@ref Collision object. Note that unlike with the `%` operator mentioned above, -this operation is not commutative. See @ref Collision class documentation for -more information about the returned data. Example: +@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 const Shapes::Collision3D c = point/sphere; if(c) { @@ -137,7 +137,7 @@ if(c) { @section shapes-scenegraph Integration with scene graph -%Shape can be attached to object in the scene using @ref Shapes::Shape feature. +Shape can be attached to object in the scene using @ref Shapes::Shape feature. In conjunction with @ref Shapes::ShapeGroup you can use @ref Shapes::Shape::collides() and @ref Shapes::Shape::collision() similarly to the `%` and `/` operators above. Please note that the shape group caches the @@ -173,4 +173,4 @@ debugging purposes. See also @ref scenegraph for introduction. - Next page: @ref debug-tools */ -}}} +} diff --git a/doc/tips.dox b/doc/tips.dox index b02c128ac..0620d72f8 100644 --- a/doc/tips.dox +++ b/doc/tips.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/doc/transformations.dox b/doc/transformations.dox index 3eb69cf89..9a20b74c2 100644 --- a/doc/transformations.dox +++ b/doc/transformations.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,7 +23,7 @@ DEALINGS IN THE SOFTWARE. */ -namespace Magnum { namespace Math { +namespace Magnum { /** @page transformations 2D and 3D transformations @brief Introduction to essential operations on vectors and points. @@ -37,7 +37,7 @@ with CMake. @tableofcontents -%Magnum provides classes for transformations in both 2D and 3D. Each class is +Magnum provides classes for transformations in both 2D and 3D. Each class is suited for different purposes, but their usage is nearly the same to make your life simpler. This page will explain the basic operation and differences between various representations. @@ -45,61 +45,63 @@ between various representations. @section transformations-representation Representing transformations The first and most straightforward way to represent transformations is to use -homogeneous transformation matrix, i.e. Matrix3 for 2D and Matrix4 for 3D. The -matrices are able to represent all possible types of 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. - -On the other hand, matrices need 9 or 16 floats to represent the 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 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 Complex in 2D and Quaternion -in 3D, or DualComplex and 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 dual versions), can be -easily inverted and interpolated and have many other awesome properties. However, -they are not magic so they also suffer slightly from floating-point drift, but -not too much and the drift can be accounted for more easily than with matrices. +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 +projective transformation, thus they are used at the very core of graphics +pipeline and are supported natively in OpenGL. + +On the other hand, matrices need 9 or 16 floats to represent the +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 +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 +@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 +dual versions), can be easily inverted and interpolated and have many other +awesome properties. However, they are not magic so they also suffer slightly +from floating-point drift, but not too much and the drift can be accounted for +more easily than with matrices. @section transformations-types Transformation types -Transformation matrices and (dual) complex numbers or quaternions have completely -different internals, but they share the same API to achieve the same things, -greatly simplifying their usage. In many cases it is even possible to hot-swap -the transformation class type without changing any function calls. +Transformation matrices and (dual) complex numbers or quaternions have +completely different internals, but they share the same API to achieve the same +things, greatly simplifying their usage. In many cases it is even possible to +hot-swap the transformation class type without changing any function calls. @subsection transformations-default Default (identity) transformation -Default-constructed Matrix3, Matrix4, Complex, Quaternion, DualComplex and -DualQuaternion represent identity transformation, so you don't need to worry -about them in initialization. +Default-constructed @ref Matrix3, @ref Matrix4, @ref Complex, @ref Quaternion, +@ref DualComplex and @ref DualQuaternion represent identity transformation, so +you don't need to worry about them in initialization. @subsection transformations-rotation Rotation -2D rotation is represented solely by its angle in counterclockwise direction and -rotation transformation can be created by calling Matrix3::rotation(), -Complex::rotation() or DualComplex::rotation(), for example: +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 auto a = Matrix3::rotation(23.0_degf); -auto b = Complex::rotation(Rad(Constants::pi()/2)); +auto b = Complex::rotation(Rad(Constants::piHalf())); auto c = DualComplex::rotation(-1.57_radf); @endcode 3D rotation is represented by angle and (three-dimensional) axis. The rotation -can be created by calling Matrix4::rotation(), Quaternion::rotation() or -DualQuaternion::rotation(). The axis must be always of unit length to avoid -redundant normalization. Shortcuts Vector3::xAxis(), Vector3::yAxis() and -Vector3::zAxis() are provided for convenience. %Matrix representation has also -Matrix4::rotationX(), Matrix4::rotationY() and Matrix4::rotationZ() which are -faster than using the generic function for rotation around primary axes. -Examples: +can be created by calling @ref Matrix4::rotation(), @ref Quaternion::rotation() +or @ref DualQuaternion::rotation(). The axis must be always of unit length to +avoid redundant normalization. Shortcuts @ref Vector3::xAxis(), +@ref Vector3::yAxis() and @ref Vector3::zAxis() are provided for convenience. +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 auto a = Quaternion::rotation(60.0_degf, Vector3::xAxis()); auto b = DualQuaternion::rotation(-1.0_degf, Vector3(1.0f, 0.5f, 3.0f).normalized()); @@ -114,16 +116,17 @@ then translating back. Read below for more information. @subsection transformations-translation Translation 2D translation is defined by two-dimensional vector and can be created with -Matrix3::translation() or DualComplex::translation(). You can use Vector2::xAxis() -or Vector2::yAxis() to translate only along given axis. Examples: +@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 auto a = Matrix3::translation(Vector2::xAxis(-5.0f)); auto b = DualComplex::translation({-1.0f, 0.5f}); @endcode 3D translation is defined by three-dimensional vector and can be created with -Matrix4::translation() or DualQuaternion::translation(). You can use -Vector3::xAxis() and friends also here. Examples: +@ref Matrix4::translation() or @ref DualQuaternion::translation(). You can use +@ref Vector3::xAxis() and friends also here. Examples: @code auto a = Matrix4::translation(vector); auto b = DualQuaternion::translation(Vector3::zAxis(1.3f)); @@ -132,11 +135,11 @@ auto b = DualQuaternion::translation(Vector3::zAxis(1.3f)); @subsection transformations-scaling Scaling and reflection Scaling is defined by two- or three-dimensional vector and is represented by -matrices. You can create it with Matrix3::scaling() or Matrix4::scaling(). You -can use Vector3::xScale(), Vector3::yScale(), 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: +matrices. You can create it with @ref Matrix3::scaling() or @ref Matrix4::scaling(). +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 auto a = Matrix3::scaling(Vector2::xScale(2.0f)); auto b = Matrix4::scaling({2.0f, -2.0f, 1.5f}); @@ -145,8 +148,9 @@ auto c = Matrix4::scaling(Vector3(10.0f)); Reflections are defined by normal along which to reflect (i.e., two- or three-dimensional vector of unit length) and they are also represented by -matrices. Reflection is created with Matrix3::reflection() or Matrix4::reflection(). -You can use Vector3::xAxis() and friends also here. Examples: +matrices. Reflection is created with @ref Matrix3::reflection() or +@ref Matrix4::reflection(). You can use @ref Vector3::xAxis() and friends also +here. Examples: @code auto a = Matrix3::reflection(Vector2::yAxis()); auto b = Matrix4::reflection(axis.normalized()); @@ -161,15 +165,15 @@ operations more expensive, so it's not implemented. @subsection transformations-projective Projective transformations -Projective transformations eploit the full potential of transformation matrices. -In 2D there is only one projection type, which can be created with Matrix3::projection() -and it is defined by area which will be projected into unit rectangle. In 3D -there is orthographic projection, created with Matrix4::orthographicProjection() -and defined by volume to project into unit cube, and perspective projection. -Perspective projection is created with 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: +Projective transformations eploit the full potential of transformation +matrices. In 2D there is only one projection type, which can be created with +@ref Matrix3::projection() and it is defined by area which will be projected +into unit rectangle. In 3D there is orthographic projection, created with +@ref Matrix4::orthographicProjection() and defined by volume to project into +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 auto a = Matrix3::projection({4.0f, 3.0f}); auto b = Matrix4::orthographicProjection({4.0f, 3.0f, 100.0f}); @@ -191,33 +195,34 @@ auto b = Matrix4::translation(Vector3::yAxis(5.0f))* Matrix4::rotationY(25.0_degf); @endcode -Inverse transformation can be computed using Matrix3::inverted(), Matrix4::inverted(), -Complex::inverted(), Quaternion::inverted(), DualComplex::inverted() or -DualQuaternion::inverted(). %Matrix inversion is quite costly, so if your -transformation involves only translation and rotation, you can use faster -alternatives Matrix3::invertedRigid() and Matrix4::invertedRigid(). If you are -sure that the (dual) complex number or (dual) quaternion is of unit length, you -can use Complex::invertedNormalized(), Quaternion::invertedNormalized(), -DualComplex::invertedNormalized() or DualQuaternion::invertedNormalized() which -is a little bit faster, because it doesn't need to renormalize the result. +Inverse transformation can be computed using @ref Matrix3::inverted(), +@ref Matrix4::inverted(), @ref Complex::inverted(), @ref Quaternion::inverted(), +@ref DualComplex::inverted() or @ref DualQuaternion::inverted(). Matrix +inversion is quite costly, so if your transformation involves only translation +and rotation, you can use faster alternatives @ref Matrix3::invertedRigid() and +@ref Matrix4::invertedRigid(). If you are sure that the (dual) complex number +or (dual) quaternion is of unit length, you can use @ref Complex::invertedNormalized(), +@ref Quaternion::invertedNormalized(), @ref DualComplex::invertedNormalized() +or @ref DualQuaternion::invertedNormalized() which is a little bit faster, +because it doesn't need to renormalize the result. @section transformations-transforming Transforming vectors and points -Transformations can be used directly for transforming vectors and points. %Vector -transformation does not involve translation, in 2D can be done using -Matrix3::transformVector() and Complex::transformVector(), in 3D using -Matrix4::transformVector() and Quaternion::transformVector(). For transformation -with normalized quaternion you can use faster alternative Quaternion::transformVectorNormalized(). -Example: +Transformations can be used directly for transforming vectors and points. +Vector transformation does not involve translation, in 2D can be done using +@ref Matrix3::transformVector() and @ref Complex::transformVector(), in 3D +using @ref Matrix4::transformVector() and @ref Quaternion::transformVector(). +For transformation with normalized quaternion you can use faster alternative +@ref Quaternion::transformVectorNormalized(). Example: @code auto transformation = Matrix3::rotation(-30.0_degf)*Matrix3::scaling(Vector2(3.0f)); Vector2 transformed = transformation.transformVector({1.5f, -7.9f}); @endcode Point transformation involves also translation, in 2D is done with -Matrix3::transformPoint() and DualComplex::transformPoint(), in 3D with -Matrix4::transformPoint() and DualQuaternion::transformPoint(). Also here you -can use faster alternative Quaternion::transformPointNormalized(): +@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 auto transformation = DualQuaternion::rotation(-30.0_degf, Vector3::xAxis())* DualQuaternion::translation(Vector3::yAxis(3.0f)); @@ -239,22 +244,23 @@ 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 Algorithms::svd(). Extracting rotation angle (and axis in -3D) from rotation part is possible using by converting it to complex number or -quaternion, see below. +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 +complex number or quaternion, see below. -You can also recreate transformation matrix from rotation and translation parts: +You can also recreate transformation matrix from rotation and translation +parts: @code Matrix3 c = Matrix3::from(rotation, {1.0f, 3.0f}); @endcode -%Complex numbers and quaternions are far better in this regard and they allow -you to extract rotation angle using Complex::angle() or Quaternion::angle() or -rotation axis in 3D using Quaternion::axis(). Their dual versions allow to -extract both rotation and translation part using DualComplex::rotation() const, -DualQuaternion::rotation() const, DualComplex::translation() const and -DualQuaternion::translation() const. +Complex numbers and quaternions are far better in this regard and they allow +you to extract rotation angle using @ref Complex::angle() or +@ref Quaternion::angle() or rotation axis in 3D using @ref Quaternion::axis(). +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 DualComplex a; Rad rotationAngle = a.rotation().angle(); @@ -264,9 +270,10 @@ Quaternion b; Vector3 rotationAxis = b.axis(); @endcode -You can convert Complex and Quaternion to rotation matrix using Complex::toMatrix() -and Quaternion::toMatrix() or their dual version to rotation and translation -matrix using DualComplex::toMatrix() and DualQuaternion::toMatrix(): +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 Quaternion a; auto rotation = Matrix4::from(a.toMatrix(), {}); @@ -276,9 +283,9 @@ Matrix3 transformation = b.toMatrix(); @endcode Conversion the other way around is possible only from rotation matrices using -Complex::fromMatrix() or Quaternion::fromMatrix() and from rotation and -translation matrices using DualComplex::fromMatrix() and -DualQuaternion::fromMatrix(): +@ref Complex::fromMatrix() or @ref Quaternion::fromMatrix() and from rotation +and translation matrices using @ref DualComplex::fromMatrix() and +@ref DualQuaternion::fromMatrix(): @code Matrix3 rotation; auto a = Complex::fromMatrix(rotation.rotationScaling()); @@ -300,19 +307,20 @@ accumulate rounding errors and behave strangely. For transformation matrices this can't always be fixed, because they can represent any transformation (and thus no algorithm can't tell if the transformation is in expected form or not). If you restrict yourselves (e.g. only uniform scaling and no skew), the matrix -can be reorthogonalized using Algorithms::gramSchmidtOrthogonalize() (or -Algorithms::gramSchmidtOrthonormalize(), if you don't have any scaling). You can -also use Algorithms::svd() to more precisely (but way more slowly) account for -the drift. Example: +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 Matrix4 transformation; Math::Algorithms::gramSchmidtOrthonormalizeInPlace(transformation); @endcode For quaternions and complex number this problem can be solved far more easily -using Complex::normalized(), Quaternion::normalized(), DualComplex::normalized() -and DualQuaternion::normalized(). Transformation quaternions and complex numbers -are always of unit length, thus normalizing them reduces the drift. +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 DualQuaternion transformation; transformation = transformation.normalized(); @@ -321,4 +329,4 @@ transformation = transformation.normalized(); - Previous page: @ref matrix-vector - Next page: @ref plugins */ -}} +} diff --git a/doc/troubleshooting.dox b/doc/troubleshooting.dox index 08aaeae5f..6a044c6ee 100644 --- a/doc/troubleshooting.dox +++ b/doc/troubleshooting.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,13 +30,13 @@ namespace Magnum { @section troubleshooting-building Building issues -If your project suddenly stops building after %Magnum upgrade, check these +If your project suddenly stops building after Magnum upgrade, check these things: - If the building fails on CMake step, be sure that you have up-to-date `FindCorrade.cmake`, `FindMagnum.cmake` and other CMake modules in your project (`FindSDL2.cmake`). They are contained in `modules/` directory of - %Magnum sources (and sources of other projects) also are installed into + Magnum sources (and sources of other projects) also are installed into `share/cmake/Magnum`. - In some cases when the changes done to build system are too drastic, recreating the build dir or clearing CMake cache is needed, but this is diff --git a/doc/types.dox b/doc/types.dox index 027c89e66..b4ed06bf0 100644 --- a/doc/types.dox +++ b/doc/types.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -35,12 +35,12 @@ its documentation for more information about usage with CMake. @section types-builtin Builtin types -%Magnum provides typedefs for builtin integral and floating-point arithmetic +Magnum provides typedefs for builtin integral and floating-point arithmetic types to ensure portability (e.g. @ref Int is *always* 32bit), maintain consistency and reduce confusion (e.g. `std::int32_t`, `int` and `GLint` all refer to the same type). -| %Magnum type | Size | Equivalent GLSL type | +| Magnum type | Size | Equivalent GLSL type | | ------------------ | -------------- | -------------------- | | @ref UnsignedByte | 8bit unsigned | | | @ref Byte | 8bit signed | | @@ -65,14 +65,14 @@ underlying type. @section types-matrix Matrix/vector types -| %Magnum vector type | Equivalent GLSL type | +| Magnum vector type | Equivalent GLSL type | | ---------------------------------------------- | ------------------------- | | @ref Vector2, @ref Vector3, @ref Vector4 | `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` | -| %Magnum matrix type | Equivalent GLSL type | +| 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` | @@ -103,7 +103,7 @@ to the internal data array. @section types-special Special types -%Magnum has special type for strongly-typed representation of angles, namely +Magnum has special type for strongly-typed representation of angles, namely 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 diff --git a/doc/utilities.dox b/doc/utilities.dox index dd6cff029..543adcc5a 100644 --- a/doc/utilities.dox +++ b/doc/utilities.dox @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 06b78919d..596a7fcdf 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -23,6 +23,8 @@ # DEALINGS IN THE SOFTWARE. # -if(WITH_FIND_MODULE) - install(FILES FindMagnum.cmake DESTINATION ${MAGNUM_CMAKE_FIND_MODULE_INSTALL_DIR}) -endif() +set(Magnum_MODULES + FindMagnum.cmake + MagnumConfig.cmake) + +install(FILES ${Magnum_MODULES} DESTINATION ${MAGNUM_CMAKE_MODULE_INSTALL_DIR}) diff --git a/modules/FindCorrade.cmake b/modules/FindCorrade.cmake index 3b68afbb0..bb0e058ac 100644 --- a/modules/FindCorrade.cmake +++ b/modules/FindCorrade.cmake @@ -14,6 +14,7 @@ # CORRADE_TESTSUITE_LIBRARIES - TestSuite library and dependent # libraries # CORRADE_RC_EXECUTABLE - Resource compiler executable +# CORRADE_LIB_SUFFIX_MODULE - Path to CorradeLibSuffix.cmake module # The package is found if either debug or release version of each library is # found. If both debug and release libraries are found, proper version is # chosen based on actual build configuration of the project (i.e. Debug build @@ -26,9 +27,9 @@ # single-configuration build systems (such as Makefiles) this information is # not needed and thus the variable is not defined in any case. # -# Corrade configures the compiler to use C++11 standard. Additionally you can -# use CORRADE_CXX_FLAGS to enable additional pedantic set of warnings and -# enable hidden visibility by default. +# Corrade configures the compiler to use C++11 standard (if it is not already +# configured to do so). Additionally you can use CORRADE_CXX_FLAGS to enable +# additional pedantic set of warnings and enable hidden visibility by default. # # Features of found Corrade library are exposed in these variables: # CORRADE_GCC47_COMPATIBILITY - Defined if compiled with compatibility @@ -57,10 +58,6 @@ # CORRADE_TARGET_EMSCRIPTEN - Defined if compiled for Emscripten # CORRADE_TARGET_ANDROID - Defined if compiled for Android # -# If CORRADE_BUILD_DEPRECATED is defined, the CORRADE_INCLUDE_DIR variable also -# contains path directly to Corrade directory (i.e. for includes without -# `Corrade/` prefix). -# # Corrade provides these macros and functions: # # @@ -119,12 +116,14 @@ # CORRADE_*_LIBRARY_DEBUG - Debug version of given library, if found # CORRADE_*_LIBRARY_RELEASE - Release version of given library, if # found +# CORRADE_USE_MODULE - Path to UseCorrade.cmake module (included +# automatically) # # # This file is part of Corrade. # -# Copyright © 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 +# Copyright © 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -174,7 +173,7 @@ endforeach() find_program(CORRADE_RC_EXECUTABLE corrade-rc) # Include dir -find_path(_CORRADE_INCLUDE_DIR +find_path(CORRADE_INCLUDE_DIR NAMES Corrade/PluginManager Corrade/Utility) # CMake module dir @@ -182,19 +181,13 @@ find_path(_CORRADE_MODULE_DIR NAMES UseCorrade.cmake CorradeLibSuffix.cmake PATH_SUFFIXES share/cmake/Corrade) -# If not found, try system module dir -find_path(_CORRADE_MODULE_DIR - NAMES UseCorrade.cmake CorradeLibSuffix.cmake - PATHS ${CMAKE_ROOT}/Modules - NO_CMAKE_FIND_ROOT_PATH) - include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Corrade DEFAULT_MSG CORRADE_UTILITY_LIBRARY CORRADE_INTERCONNECT_LIBRARY CORRADE_PLUGINMANAGER_LIBRARY CORRADE_TESTSUITE_LIBRARY - _CORRADE_INCLUDE_DIR + CORRADE_INCLUDE_DIR CORRADE_RC_EXECUTABLE _CORRADE_MODULE_DIR) @@ -202,75 +195,37 @@ if(NOT CORRADE_FOUND) return() endif() -# Configuration -file(READ ${_CORRADE_INCLUDE_DIR}/Corrade/configure.h _corradeConfigure) - -# Compatibility? -string(FIND "${_corradeConfigure}" "#define CORRADE_GCC47_COMPATIBILITY" _GCC47_COMPATIBILITY) -if(NOT _GCC47_COMPATIBILITY EQUAL -1) - set(CORRADE_GCC47_COMPATIBILITY 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_GCC46_COMPATIBILITY" _GCC46_COMPATIBILITY) -if(NOT _GCC46_COMPATIBILITY EQUAL -1) - set(CORRADE_GCC46_COMPATIBILITY 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_GCC45_COMPATIBILITY" _GCC45_COMPATIBILITY) -if(NOT _GCC45_COMPATIBILITY EQUAL -1) - set(CORRADE_GCC45_COMPATIBILITY 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_GCC44_COMPATIBILITY" _GCC44_COMPATIBILITY) -if(NOT _GCC44_COMPATIBILITY EQUAL -1) - set(CORRADE_GCC44_COMPATIBILITY 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_MSVC2013_COMPATIBILITY" _MSVC2013_COMPATIBILITY) -if(NOT _MSVC2013_COMPATIBILITY EQUAL -1) - set(CORRADE_MSVC2013_COMPATIBILITY 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_BUILD_DEPRECATED" _BUILD_DEPRECATED) -if(NOT _BUILD_DEPRECATED EQUAL -1) - set(CORRADE_BUILD_DEPRECATED 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_BUILD_STATIC" _BUILD_STATIC) -if(NOT _BUILD_STATIC EQUAL -1) - set(CORRADE_BUILD_STATIC 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_UNIX" _TARGET_UNIX) -if(NOT _TARGET_UNIX EQUAL -1) - set(CORRADE_TARGET_UNIX 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_APPLE" _TARGET_APPLE) -if(NOT _TARGET_APPLE EQUAL -1) - set(CORRADE_TARGET_APPLE 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_WINDOWS" _TARGET_WINDOWS) -if(NOT _TARGET_WINDOWS EQUAL -1) - set(CORRADE_TARGET_WINDOWS 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_NACL" _TARGET_NACL) -if(NOT _TARGET_NACL EQUAL -1) - set(CORRADE_TARGET_NACL 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_NACL_NEWLIB" _TARGET_NACL_NEWLIB) -if(NOT _TARGET_NACL_NEWLIB EQUAL -1) - set(CORRADE_TARGET_NACL_NEWLIB 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_NACL_GLIBC" _TARGET_NACL_GLIBC) -if(NOT _TARGET_NACL_GLIBC EQUAL -1) - set(CORRADE_TARGET_NACL_GLIBC 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_EMSCRIPTEN" _TARGET_EMSCRIPTEN) -if(NOT _TARGET_EMSCRIPTEN EQUAL -1) - set(CORRADE_TARGET_EMSCRIPTEN 1) -endif() -string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_ANDROID" _TARGET_ANDROID) -if(NOT _TARGET_ANDROID EQUAL -1) - set(CORRADE_TARGET_ANDROID 1) -endif() +# Read flags from fonfiguration +file(READ ${CORRADE_INCLUDE_DIR}/Corrade/configure.h _corradeConfigure) +set(_corradeFlags + GCC47_COMPATIBILITY + GCC46_COMPATIBILITY + GCC45_COMPATIBILITY + GCC44_COMPATIBILITY + MSVC2013_COMPATIBILITY + BUILD_DEPRECATED + BUILD_STATIC + TARGET_UNIX + TARGET_APPLE + TARGET_WINDOWS + TARGET_NACL + TARGET_NACL_NEWLIB + TARGET_NACL_GLIBC + TARGET_EMSCRIPTEN + TARGET_ANDROID) +foreach(_corradeFlag ${_corradeFlags}) + string(FIND "${_corradeConfigure}" "#define CORRADE_${_corradeFlag}" _corrade_${_corradeFlag}) + if(NOT _corrade_${_corradeFlag} EQUAL -1) + set(CORRADE_${_corradeFlag} 1) + endif() +endforeach() set(CORRADE_UTILITY_LIBRARIES ${CORRADE_UTILITY_LIBRARY}) set(CORRADE_INTERCONNECT_LIBRARIES ${CORRADE_INTERCONNECT_LIBRARY} ${CORRADE_UTILITY_LIBRARIES}) set(CORRADE_PLUGINMANAGER_LIBRARIES ${CORRADE_PLUGINMANAGER_LIBRARY} ${CORRADE_UTILITY_LIBRARIES}) set(CORRADE_TESTSUITE_LIBRARIES ${CORRADE_TESTSUITE_LIBRARY} ${CORRADE_UTILITY_LIBRARIES}) +set(CORRADE_USE_MODULE ${_CORRADE_MODULE_DIR}/UseCorrade.cmake) +set(CORRADE_LIB_SUFFIX_MODULE ${_CORRADE_MODULE_DIR}/CorradeLibSuffix.cmake) # At least static build needs this if(CORRADE_TARGET_UNIX OR CORRADE_TARGET_NACL_GLIBC) @@ -282,20 +237,7 @@ if(CORRADE_TARGET_ANDROID) set(CORRADE_UTILITY_LIBRARIES ${CORRADE_UTILITY_LIBRARIES} log) endif() -mark_as_advanced(_CORRADE_INCLUDE_DIR - _CORRADE_MODULE_DIR) - -# Add Corrade dir to include path if this is deprecated build -if(CORRADE_BUILD_DEPRECATED) - set(CORRADE_INCLUDE_DIR ${_CORRADE_INCLUDE_DIR} ${CORRADE_INCLUDE_DIR}/Corrade) -else() - set(CORRADE_INCLUDE_DIR ${_CORRADE_INCLUDE_DIR}) -endif() - -# Include our module dir, if we have any -if(NOT "${_CORRADE_MODULE_DIR}" STREQUAL "${CMAKE_ROOT}/Modules") - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${_CORRADE_MODULE_DIR}") -endif() +mark_as_advanced(_CORRADE_MODULE_DIR) # Finalize the finding process -include(UseCorrade) +include(${CORRADE_USE_MODULE}) diff --git a/modules/FindEGL.cmake b/modules/FindEGL.cmake index 73df180a7..65f776a48 100644 --- a/modules/FindEGL.cmake +++ b/modules/FindEGL.cmake @@ -10,7 +10,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -37,12 +37,9 @@ find_library(EGL_LIBRARY EGL) # Include dir find_path(EGL_INCLUDE_DIR - NAMES egl.h - PATH_SUFFIXES EGL -) + NAMES EGL/egl.h) include(FindPackageHandleStandardArgs) find_package_handle_standard_args("EGL" DEFAULT_MSG EGL_LIBRARY - EGL_INCLUDE_DIR -) + EGL_INCLUDE_DIR) diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 3af940f32..ba59b13c9 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -34,23 +34,20 @@ # OpenGL ES libraries). Additional dependencies are specified by the # components. The optional components are: # Audio - Audio library -# DebugTools - DebugTools library (depends on MeshTools, Primitives, -# SceneGraph, Shaders and Shapes components) +# DebugTools - DebugTools library # MeshTools - MeshTools library # Primitives - Primitives library # SceneGraph - SceneGraph library # Shaders - Shaders library -# Shapes - Shapes library (depends on SceneGraph component) -# Text - Text library (depends on TextureTools component) +# Shapes - Shapes library +# Text - Text library # TextureTools - TextureTools library -# MagnumFont - Magnum bitmap font plugin (depends on Text component -# and TgaImporter plugin) -# MagnumFontConverter - Magnum bitmap font converter plugin (depends on Text -# component and TgaImageConverter plugin) +# MagnumFont - Magnum bitmap font plugin +# MagnumFontConverter - Magnum bitmap font converter plugin # ObjImporter - OBJ importer plugin # TgaImageConverter - TGA image converter plugin # TgaImporter - TGA importer plugin -# WavAudioImporter - WAV audio importer plugin (depends on Audio component) +# WavAudioImporter - WAV audio importer plugin # GlutApplication - GLUT application # GlxApplication - GLX application # NaClApplication - NaCl application @@ -101,11 +98,6 @@ # emulation on desktop OpenGL # MAGNUM_TARGET_WEBGL - Defined if compiled for WebGL # -# If MAGNUM_BUILD_DEPRECATED is defined, the MAGNUM_INCLUDE_DIR variable also -# contains path directly to Magnum directory (i.e. for includes without -# Magnum/ prefix) and MAGNUM_PLUGINS_INCLUDE_DIR contains include dir for -# plugins (i.e. for includes without MagnumPlugins/ prefix). -# # Additionally these variables are defined for internal usage: # MAGNUM_INCLUDE_DIR - Root include dir (w/o dependencies) # MAGNUM_LIBRARY - Magnum library (w/o dependencies) @@ -116,6 +108,7 @@ # MAGNUM_*_LIBRARY_RELEASE - Release version of given library, if found # MAGNUM_BINARY_INSTALL_DIR - Binary installation directory # MAGNUM_LIBRARY_INSTALL_DIR - Library installation directory +# MAGNUM_DATA_INSTALL_DIR - Data installation directory # MAGNUM_PLUGINS_[DEBUG|RELEASE]_INSTALL_DIR - Plugin installation directory # MAGNUM_PLUGINS_FONT_[DEBUG|RELEASE]_INSTALL_DIR - Font plugin installation # directory @@ -127,8 +120,6 @@ # installation directory # MAGNUM_PLUGINS_AUDIOIMPORTER_[DEBUG|RELEASE]_INSTALL_DIR - Audio importer # plugin installation directory -# MAGNUM_CMAKE_FIND_MODULE_INSTALL_DIR - Installation dir for CMake Find* -# modules # MAGNUM_INCLUDE_INSTALL_DIR - Header installation directory # MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR - Plugin header installation directory # @@ -136,7 +127,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -199,35 +190,20 @@ endif() # Configuration file(READ ${MAGNUM_INCLUDE_DIR}/Magnum/configure.h _magnumConfigure) - -string(FIND "${_magnumConfigure}" "#define MAGNUM_BUILD_DEPRECATED" _BUILD_DEPRECATED) -if(NOT _BUILD_DEPRECATED EQUAL -1) - set(MAGNUM_BUILD_DEPRECATED 1) -endif() -string(FIND "${_magnumConfigure}" "#define MAGNUM_BUILD_STATIC" _BUILD_STATIC) -if(NOT _BUILD_STATIC EQUAL -1) - set(MAGNUM_BUILD_STATIC 1) -endif() -string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_GLES" _TARGET_GLES) -if(NOT _TARGET_GLES EQUAL -1) - set(MAGNUM_TARGET_GLES 1) -endif() -string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_GLES2" _TARGET_GLES2) -if(NOT _TARGET_GLES2 EQUAL -1) - set(MAGNUM_TARGET_GLES2 1) -endif() -string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_GLES3" _TARGET_GLES3) -if(NOT _TARGET_GLES3 EQUAL -1) - set(MAGNUM_TARGET_GLES3 1) -endif() -string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_DESKTOP_GLES" _TARGET_DESKTOP_GLES) -if(NOT _TARGET_DESKTOP_GLES EQUAL -1) - set(MAGNUM_TARGET_DESKTOP_GLES 1) -endif() -string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_WEBGL" _TARGET_WEBGL) -if(NOT _TARGET_WEBGL EQUAL -1) - set(MAGNUM_TARGET_WEBGL 1) -endif() +set(_magnumFlags + BUILD_DEPRECATED + BUILD_STATIC + TARGET_GLES + TARGET_GLES2 + TARGET_GLES3 + TARGET_DESKTOP_GLES + TARGET_WEBGL) +foreach(_magnumFlag ${_magnumFlags}) + string(FIND "${_magnumConfigure}" "#define MAGNUM_${_magnumFlag}" _magnum_${_magnumFlag}) + if(NOT _magnum_${_magnumFlag} EQUAL -1) + set(MAGNUM_${_magnumFlag} 1) + endif() +endforeach() # Dependent libraries and includes set(MAGNUM_INCLUDE_DIRS ${MAGNUM_INCLUDE_DIR} @@ -247,15 +223,44 @@ elseif(MAGNUM_TARGET_GLES3) set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARIES} ${OPENGLES3_LIBRARY}) endif() -# On Windows and in static builds, *Application libraries need to have -# ${MAGNUM_LIBRARIES} listed in dependencies also after all other library names -# to avoid linker errors. Applicaiton libraries are often last thus it is -# +- sufficient to add it there only. -if(CORRADE_TARGET_WINDOWS OR MAGNUM_BUILD_STATIC) - set(_WINDOWCONTEXT_MAGNUM_LIBRARIES_DEPENDENCY ${MAGNUM_LIBRARIES}) +# Ensure that all inter-component dependencies are specified as well +set(_MAGNUM_ADDITIONAL_COMPONENTS ) +foreach(component ${Magnum_FIND_COMPONENTS}) + string(TOUPPER ${component} _COMPONENT) + + # The dependencies need to be sorted by their dependency order as well + if(component STREQUAL Shapes) + set(_MAGNUM_${_COMPONENT}_DEPENDENCIES SceneGraph) + elseif(component STREQUAL Text) + set(_MAGNUM_${_COMPONENT}_DEPENDENCIES TextureTools) + elseif(component STREQUAL DebugTools) + set(_MAGNUM_${_COMPONENT}_DEPENDENCIES MeshTools Primitives SceneGraph Shaders Shapes) + elseif(component STREQUAL MagnumFont) + set(_MAGNUM_${_COMPONENT}_DEPENDENCIES TgaImporter) # and below + elseif(component STREQUAL MagnumFontConverter) + set(_MAGNUM_${_COMPONENT}_DEPENDENCIES TgaImageConverter) # and below + elseif(component STREQUAL ObjImporter) + set(_MAGNUM_${_COMPONENT}_DEPENDENCIES MeshTools) + endif() + + if(component MATCHES ".+AudioImporter") + set(_MAGNUM_${_COMPONENT}_DEPENDENCIES Audio) + elseif(component MATCHES ".+(Font|FontConverter)") + set(_MAGNUM_${_COMPONENT}_DEPENDENCIES TextureTools Text) + endif() + + list(APPEND _MAGNUM_ADDITIONAL_COMPONENTS ${_MAGNUM_${_COMPONENT}_DEPENDENCIES}) +endforeach() + +# Join the lists, remove duplicate components +if(_MAGNUM_ADDITIONAL_COMPONENTS) + list(INSERT Magnum_FIND_COMPONENTS 0 ${_MAGNUM_ADDITIONAL_COMPONENTS}) +endif() +if(Magnum_FIND_COMPONENTS) + list(REMOVE_DUPLICATES Magnum_FIND_COMPONENTS) endif() -# Additional components +# Find all components foreach(component ${Magnum_FIND_COMPONENTS}) string(TOUPPER ${component} _COMPONENT) @@ -352,7 +357,7 @@ foreach(component ${Magnum_FIND_COMPONENTS}) endif() # Applications - if(${component} MATCHES .+Application) + if(${component} MATCHES ".+Application") set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Magnum/Platform) # Android application dependencies @@ -411,13 +416,8 @@ foreach(component ${Magnum_FIND_COMPONENTS}) endif() endif() - # Common application dependencies - set(_MAGNUM_${_COMPONENT}_LIBRARIES - ${_MAGNUM_${_COMPONENT}_LIBRARIES} - ${_WINDOWCONTEXT_MAGNUM_LIBRARIES_DEPENDENCY}) - # Context libraries - elseif(${component} MATCHES .+Context) + elseif(${component} MATCHES ".+Context") set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Magnum/Platform) set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Context.h) @@ -454,6 +454,8 @@ foreach(component ${Magnum_FIND_COMPONENTS}) unset(MAGNUM_${_COMPONENT}_LIBRARY) endif() + # No special setup for DebugTools library + # Mesh tools library elseif(${component} STREQUAL MeshTools) set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES CompressIndices.h) @@ -462,13 +464,17 @@ foreach(component ${Magnum_FIND_COMPONENTS}) elseif(${component} STREQUAL Primitives) set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Cube.h) + # No special setup for SceneGraph library + # No special setup for Shaders library + # No special setup for Shapes library + # No special setup for Text library + # TextureTools library elseif(${component} STREQUAL TextureTools) set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Atlas.h) endif() - # The plugins don't have any dependencies, nothing additional to do for - # them + # No special setup for plugins # Try to find the includes if(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES) @@ -477,10 +483,30 @@ foreach(component ${Magnum_FIND_COMPONENTS}) PATHS ${MAGNUM_INCLUDE_DIR}/${_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX}) endif() + # Add inter-project dependencies, mark the component as not found if + # any dependency is not found + set(_MAGNUM_${_COMPONENT}_DEPENDENCY_LIBRARIES ) + set(_MAGNUM_${_COMPONENT}_DEPENDENCY_INCLUDE_DIRS ) + foreach(dependency ${_MAGNUM_${_COMPONENT}_DEPENDENCIES}) + string(TOUPPER ${dependency} _DEPENDENCY) + if(MAGNUM_${_DEPENDENCY}_LIBRARY) + list(APPEND _MAGNUM_${_COMPONENT}_DEPENDENCY_LIBRARIES ${MAGNUM_${_DEPENDENCY}_LIBRARY} ${_MAGNUM_${_DEPENDENCY}_LIBRARIES}) + list(APPEND _MAGNUM_${_COMPONENT}_DEPENDENCY_INCLUDE_DIRS ${MAGNUM_${_DEPENDENCY}_INCLUDE_DIRS}) + else() + unset(MAGNUM_${_DEPENDENCY}_LIBRARY) + endif() + endforeach() + # Decide if the library was found if(MAGNUM_${_COMPONENT}_LIBRARY AND _MAGNUM_${_COMPONENT}_INCLUDE_DIR) - set(MAGNUM_${_COMPONENT}_LIBRARIES ${MAGNUM_${_COMPONENT}_LIBRARY} ${_MAGNUM_${_COMPONENT}_LIBRARIES}) - set(MAGNUM_${_COMPONENT}_INCLUDE_DIRS ${_MAGNUM_${_COMPONENT}_INCLUDE_DIRS}) + set(MAGNUM_${_COMPONENT}_LIBRARIES + ${MAGNUM_${_COMPONENT}_LIBRARY} + ${_MAGNUM_${_COMPONENT}_LIBRARIES} + ${_MAGNUM_${_COMPONENT}_DEPENDENCY_LIBRARIES} + ${MAGNUM_LIBRARIES}) + set(MAGNUM_${_COMPONENT}_INCLUDE_DIRS + ${_MAGNUM_${_COMPONENT}_INCLUDE_DIRS} + ${_MAGNUM_${_COMPONENT}_DEPENDENCY_INCLUDE_DIRS}) set(Magnum_${component}_FOUND TRUE) @@ -493,7 +519,7 @@ foreach(component ${Magnum_FIND_COMPONENTS}) # Global aliases for Windowless*Application and *Application # components. If already set, unset them to avoid ambiguity. - if(${component} MATCHES Windowless.+Application) + if(${component} MATCHES "Windowless.+Application") if(NOT DEFINED MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES AND NOT DEFINED MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS) set(MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES ${MAGNUM_${_COMPONENT}_LIBRARIES}) set(MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS ${MAGNUM_${_COMPONENT}_INCLUDE_DIRS}) @@ -501,7 +527,7 @@ foreach(component ${Magnum_FIND_COMPONENTS}) unset(MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES) unset(MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS) endif() - elseif(${component} MATCHES .+Application) + elseif(${component} MATCHES ".+Application") if(NOT DEFINED MAGNUM_APPLICATION_LIBRARIES AND NOT DEFINED MAGNUM_APPLICATION_INCLUDE_DIRS) set(MAGNUM_APPLICATION_LIBRARIES ${MAGNUM_${_COMPONENT}_LIBRARIES}) set(MAGNUM_APPLICATION_INCLUDE_DIRS ${MAGNUM_${_COMPONENT}_INCLUDE_DIRS}) @@ -513,7 +539,7 @@ foreach(component ${Magnum_FIND_COMPONENTS}) # Global aliases for *Context components. If already set, unset them to # avoid ambiguity. - if(${component} MATCHES .+Context) + if(${component} MATCHES ".+Context") if(NOT DEFINED MAGNUM_CONTEXT_LIBRARIES AND NOT DEFINED MAGNUM_CONTEXT_INCLUDE_DIRS) set(MAGNUM_CONTEXT_LIBRARIES ${MAGNUM_${_COMPONENT}_LIBRARIES}) set(MAGNUM_CONTEXT_INCLUDE_DIRS ${MAGNUM_${_COMPONENT}_INCLUDE_DIRS}) @@ -533,9 +559,10 @@ find_package_handle_standard_args(Magnum HANDLE_COMPONENTS) # Installation dirs -include(CorradeLibSuffix) +include(${CORRADE_LIB_SUFFIX_MODULE}) set(MAGNUM_BINARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin) set(MAGNUM_LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) +set(MAGNUM_DATA_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/magnum) set(MAGNUM_PLUGINS_DEBUG_INSTALL_DIR ${MAGNUM_LIBRARY_INSTALL_DIR}/magnum-d) set(MAGNUM_PLUGINS_RELEASE_INSTALL_DIR ${MAGNUM_LIBRARY_INSTALL_DIR}/magnum) set(MAGNUM_PLUGINS_FONT_DEBUG_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_INSTALL_DIR}/fonts) @@ -548,7 +575,6 @@ set(MAGNUM_PLUGINS_IMPORTER_DEBUG_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_INSTALL_DIR set(MAGNUM_PLUGINS_IMPORTER_RELEASE_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_INSTALL_DIR}/importers) set(MAGNUM_PLUGINS_AUDIOIMPORTER_DEBUG_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_INSTALL_DIR}/audioimporters) set(MAGNUM_PLUGINS_AUDIOIMPORTER_RELEASE_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_INSTALL_DIR}/audioimporters) -set(MAGNUM_CMAKE_FIND_MODULE_INSTALL_DIR ${CMAKE_ROOT}/Modules) set(MAGNUM_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/Magnum) set(MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/MagnumPlugins) mark_as_advanced(FORCE @@ -574,15 +600,6 @@ mark_as_advanced(FORCE MAGNUM_INCLUDE_INSTALL_DIR MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR) -# Add Magnum dir to include path and create MAGNUM_PLUGINS_INCLUDE_DIR if this -# is deprecated build -if(MAGNUM_BUILD_DEPRECATED) - set(MAGNUM_INCLUDE_DIRS ${MAGNUM_INCLUDE_DIRS} - ${MAGNUM_INCLUDE_DIR}/Magnum - ${MAGNUM_INCLUDE_DIR}/MagnumExternal) - set(MAGNUM_PLUGINS_INCLUDE_DIR ${MAGNUM_INCLUDE_DIR}/MagnumPlugins) -endif() - # Get base plugin directory from main library location set(MAGNUM_PLUGINS_DEBUG_DIR ${_MAGNUM_LIBRARY_PATH}/magnum-d CACHE PATH "Base directory where to look for Magnum plugins for debug builds") diff --git a/modules/FindOpenGLES2.cmake b/modules/FindOpenGLES2.cmake index 68539b59a..103268be9 100644 --- a/modules/FindOpenGLES2.cmake +++ b/modules/FindOpenGLES2.cmake @@ -10,7 +10,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -43,12 +43,9 @@ endif() # Include dir find_path(OPENGLES2_INCLUDE_DIR - NAMES gl2.h - PATH_SUFFIXES GLES2 -) + NAMES GLES2/gl2.h) include(FindPackageHandleStandardArgs) find_package_handle_standard_args("OpenGLES2" DEFAULT_MSG ${OPENGLES2_LIBRARY_NEEDED} - OPENGLES2_INCLUDE_DIR -) + OPENGLES2_INCLUDE_DIR) diff --git a/modules/FindOpenGLES3.cmake b/modules/FindOpenGLES3.cmake index fc9c9e573..ae7cee718 100644 --- a/modules/FindOpenGLES3.cmake +++ b/modules/FindOpenGLES3.cmake @@ -10,7 +10,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -42,12 +42,9 @@ find_library(OPENGLES3_LIBRARY NAMES # Include dir find_path(OPENGLES3_INCLUDE_DIR - NAMES gl3.h - PATH_SUFFIXES GLES3 -) + NAMES GLES3/gl3.h) include(FindPackageHandleStandardArgs) find_package_handle_standard_args("OpenGLES3" DEFAULT_MSG OPENGLES3_LIBRARY - OPENGLES3_INCLUDE_DIR -) + OPENGLES3_INCLUDE_DIR) diff --git a/modules/FindSDL2.cmake b/modules/FindSDL2.cmake index 953159e67..a7557baa2 100644 --- a/modules/FindSDL2.cmake +++ b/modules/FindSDL2.cmake @@ -10,7 +10,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/modules/MagnumConfig.cmake b/modules/MagnumConfig.cmake new file mode 100644 index 000000000..9049be70e --- /dev/null +++ b/modules/MagnumConfig.cmake @@ -0,0 +1,26 @@ +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 +# Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +include(${CMAKE_CURRENT_LIST_DIR}/FindMagnum.cmake) diff --git a/package/archlinux/PKGBUILD b/package/archlinux/PKGBUILD index 5a005ec32..592d3029a 100644 --- a/package/archlinux/PKGBUILD +++ b/package/archlinux/PKGBUILD @@ -2,18 +2,20 @@ pkgname=magnum pkgver=dev pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('corrade' 'openal' 'freeglut' 'sdl2') makedepends=('cmake' 'ninja') -options=('!strip' 'staticlibs') +options=('!strip') provides=('magnum-git') +_rootdir=$startdir/../../ + build() { - mkdir -p "$startdir/build" - cd "$startdir/build" + mkdir -p "$_rootdir/build" + cd "$_rootdir/build" # Disable optimization (saves A LOT of compilation time) newcxxflags=$(echo $CXXFLAGS | sed s/-O.//g | sed s/-D_FORTIFY_SOURCE=.//g) @@ -26,6 +28,7 @@ build() { -DWITH_GLUTAPPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ -DWITH_SDL2APPLICATION=ON \ + -DWITH_XEGLAPPLICATION=ON \ -DWITH_WINDOWLESSGLXAPPLICATION=ON \ -DWITH_EGLCONTEXT=ON \ -DWITH_GLXCONTEXT=ON \ @@ -45,11 +48,11 @@ build() { } check() { - cd "$startdir/build" + cd "$_rootdir/build" ctest --output-on-failure -j5 } package() { - cd "$startdir/build" + cd "$_rootdir/build" DESTDIR="$pkgdir/" ninja install } diff --git a/package/archlinux/PKGBUILD-android-arm b/package/archlinux/PKGBUILD-android-arm index a23ee7512..272043844 100644 --- a/package/archlinux/PKGBUILD-android-arm +++ b/package/archlinux/PKGBUILD-android-arm @@ -2,28 +2,30 @@ pkgname=android-arm-magnum pkgver=dev pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (Android ARM)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (Android ARM)" arch=('any') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('android-arm-corrade') -makedepends=('cmake' 'ninja' 'android-ndk') -options=('!strip' '!buildflags' 'staticlibs') +makedepends=('cmake' 'ninja' 'android-ndk' 'corrade') +options=('!strip' '!buildflags') + +_rootdir=$startdir/../../ build() { - if [ ! -d "$startdir/build-android-arm" ] ; then - mkdir "$startdir/build-android-arm" - cd "$startdir/build-android-arm" + if [ ! -d "$_rootdir/build-android-arm" ] ; then + mkdir "$_rootdir/build-android-arm" + cd "$_rootdir/build-android-arm" cmake .. \ - -DCMAKE_MODULE_PATH="$startdir/toolchains/modules" \ - -DCMAKE_TOOLCHAIN_FILE="$startdir/toolchains/generic/Android-ARM.cmake" \ + -DCMAKE_MODULE_PATH="$_rootdir/toolchains/modules" \ + -DCMAKE_TOOLCHAIN_FILE="$_rootdir/toolchains/generic/Android-ARM.cmake" \ -DTARGET_GLES=ON \ -DTARGET_GLES2=ON \ -G Ninja fi - cd "$startdir/build-android-arm" + cd "$_rootdir/build-android-arm" cmake .. \ -DCMAKE_BUILD_TYPE=Release \ @@ -38,6 +40,6 @@ build() { } package() { - cd "$startdir/build-android-arm" + cd "$_rootdir/build-android-arm" DESTDIR="$pkgdir/" ninja install/strip } diff --git a/package/archlinux/PKGBUILD-android-x86 b/package/archlinux/PKGBUILD-android-x86 index 921d7bbf4..d8225212a 100644 --- a/package/archlinux/PKGBUILD-android-x86 +++ b/package/archlinux/PKGBUILD-android-x86 @@ -2,28 +2,30 @@ pkgname=android-x86-magnum pkgver=dev pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (Android x86)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (Android x86)" arch=('any') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('android-x86-corrade') -makedepends=('cmake' 'ninja' 'android-ndk') -options=('!strip' '!buildflags' 'staticlibs') +makedepends=('cmake' 'ninja' 'android-ndk 'corrade'') +options=('!strip' '!buildflags') + +_rootdir=$startdir/../../ build() { - if [ ! -d "$startdir/build-android-x86" ] ; then - mkdir "$startdir/build-android-x86" - cd "$startdir/build-android-x86" + if [ ! -d "$_rootdir/build-android-x86" ] ; then + mkdir "$_rootdir/build-android-x86" + cd "$_rootdir/build-android-x86" cmake .. \ - -DCMAKE_MODULE_PATH="$startdir/toolchains/modules" \ - -DCMAKE_TOOLCHAIN_FILE="$startdir/toolchains/generic/Android-x86.cmake" \ + -DCMAKE_MODULE_PATH="$_rootdir/toolchains/modules" \ + -DCMAKE_TOOLCHAIN_FILE="$_rootdir/toolchains/generic/Android-x86.cmake" \ -DTARGET_GLES=ON \ -DTARGET_GLES2=ON \ -G Ninja fi - cd "$startdir/build-android-x86" + cd "$_rootdir/build-android-x86" cmake .. \ -DCMAKE_BUILD_TYPE=Release \ @@ -38,6 +40,6 @@ build() { } package() { - cd "$startdir/build-android-x86" + cd "$_rootdir/build-android-x86" DESTDIR="$pkgdir/" ninja install/strip } diff --git a/package/archlinux/PKGBUILD-clang b/package/archlinux/PKGBUILD-clang index 3882d4229..57baa3023 100644 --- a/package/archlinux/PKGBUILD-clang +++ b/package/archlinux/PKGBUILD-clang @@ -2,26 +2,28 @@ pkgname=magnum pkgver=dev.clang pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (built with clang)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (built with clang)" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('corrade' 'openal' 'freeglut' 'sdl2') makedepends=('cmake' 'clang' 'ninja') -options=('!strip' 'staticlibs') +options=('!strip') provides=('magnum-git') +_rootdir=$startdir/../../ + build() { - if [ ! -d "$startdir/build-clang" ] ; then - mkdir "$startdir/build-clang" - cd "$startdir/build-clang" + if [ ! -d "$_rootdir/build-clang" ] ; then + mkdir "$_rootdir/build-clang" + cd "$_rootdir/build-clang" cmake .. \ -DCMAKE_CXX_COMPILER=clang++ \ -G Ninja fi - cd "$startdir/build-clang" + cd "$_rootdir/build-clang" cmake .. \ -DCMAKE_BUILD_TYPE=Debug \ @@ -48,11 +50,11 @@ build() { } check() { - cd "$startdir/build-clang" + cd "$_rootdir/build-clang" ctest --output-on-failure -j5 } package() { - cd "$startdir/build-clang" + cd "$_rootdir/build-clang" DESTDIR="$pkgdir/" ninja install } diff --git a/package/archlinux/PKGBUILD-clang-libc++ b/package/archlinux/PKGBUILD-clang-libc++ index 092789cbb..7e1e1a9db 100644 --- a/package/archlinux/PKGBUILD-clang-libc++ +++ b/package/archlinux/PKGBUILD-clang-libc++ @@ -2,19 +2,21 @@ pkgname=magnum pkgver=dev.clang.libc++ pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (built with clang and libc++)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (built with clang and libc++)" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('corrade' 'openal' 'freeglut' 'sdl2' 'libc++') makedepends=('cmake' 'clang' 'ninja') -options=('!strip' 'staticlibs') +options=('!strip') provides=('magnum-git') +_rootdir=$startdir/../../ + build() { - if [ ! -d "$startdir/build-clang-libc++" ] ; then - mkdir "$startdir/build-clang-libc++" - cd "$startdir/build-clang-libc++" + if [ ! -d "$_rootdir/build-clang-libc++" ] ; then + mkdir "$_rootdir/build-clang-libc++" + cd "$_rootdir/build-clang-libc++" cmake .. \ -DCMAKE_CXX_COMPILER=clang++ \ @@ -23,7 +25,7 @@ build() { -G Ninja fi - cd "$startdir/build-clang-libc++" + cd "$_rootdir/build-clang-libc++" cmake .. \ -DCMAKE_BUILD_TYPE=Debug \ @@ -32,6 +34,7 @@ build() { -DWITH_GLUTAPPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ -DWITH_SDL2APPLICATION=ON \ + -DWITH_XEGLAPPLICATION=ON \ -DWITH_WINDOWLESSGLXAPPLICATION=ON \ -DWITH_EGLCONTEXT=ON \ -DWITH_GLXCONTEXT=ON \ @@ -50,11 +53,11 @@ build() { } check() { - cd "$startdir/build-clang-libc++" + cd "$_rootdir/build-clang-libc++" ctest --output-on-failure -j5 } package() { - cd "$startdir/build-clang-libc++" + cd "$_rootdir/build-clang-libc++" DESTDIR="$pkgdir/" ninja install } diff --git a/package/archlinux/PKGBUILD-emscripten b/package/archlinux/PKGBUILD-emscripten index acfeed663..c1eaf9331 100644 --- a/package/archlinux/PKGBUILD-emscripten +++ b/package/archlinux/PKGBUILD-emscripten @@ -2,26 +2,28 @@ pkgname=emscripten-magnum pkgver=dev pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (Emscripten)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (Emscripten)" arch=('any') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('emscripten-corrade') -makedepends=('cmake' 'ninja' 'emscripten-git') -options=('!strip' '!buildflags' 'staticlibs') +makedepends=('cmake' 'ninja' 'emscripten' 'corrade') +options=('!strip' '!buildflags') + +_rootdir=$startdir/../../ build() { - if [ ! -d "$startdir/build-emscripten" ] ; then - mkdir "$startdir/build-emscripten" - cd "$startdir/build-emscripten" + if [ ! -d "$_rootdir/build-emscripten" ] ; then + mkdir "$_rootdir/build-emscripten" + cd "$_rootdir/build-emscripten" cmake .. \ - -DCMAKE_MODULE_PATH="$startdir/toolchains/modules" \ - -DCMAKE_TOOLCHAIN_FILE="$startdir/toolchains/generic/Emscripten.cmake" \ + -DCMAKE_MODULE_PATH="$_rootdir/toolchains/modules" \ + -DCMAKE_TOOLCHAIN_FILE="$_rootdir/toolchains/generic/Emscripten.cmake" \ -G Ninja fi - cd "$startdir/build-emscripten" + cd "$_rootdir/build-emscripten" cmake .. \ -DCMAKE_BUILD_TYPE=Release \ @@ -36,6 +38,6 @@ build() { } package() { - cd "$startdir/build-emscripten" + cd "$_rootdir/build-emscripten" DESTDIR="$pkgdir/" ninja install } diff --git a/package/archlinux/PKGBUILD-es2 b/package/archlinux/PKGBUILD-es2 index 78fcaa57e..2eea4e0c4 100644 --- a/package/archlinux/PKGBUILD-es2 +++ b/package/archlinux/PKGBUILD-es2 @@ -2,18 +2,20 @@ pkgname=magnum pkgver=dev.es2 pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (OpenGL ES 2.0 version)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (OpenGL ES 2.0 version)" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('corrade' 'openal') makedepends=('cmake' 'ninja') -options=('!strip' 'staticlibs') +options=('!strip') provides=('magnum-git') +_rootdir=$startdir/../../ + build() { - mkdir -p "$startdir/build-es2" - cd "$startdir/build-es2" + mkdir -p "$_rootdir/build-es2" + cd "$_rootdir/build-es2" cmake .. \ -DCMAKE_BUILD_TYPE=Debug \ @@ -34,11 +36,11 @@ build() { } check() { - cd "$startdir/build-es2" + cd "$_rootdir/build-es2" ctest --output-on-failure -j5 } package() { - cd "$startdir/build-es2" + cd "$_rootdir/build-es2" DESTDIR="$pkgdir/" ninja install } diff --git a/package/archlinux/PKGBUILD-es2desktop b/package/archlinux/PKGBUILD-es2desktop index 27d41d901..552984b26 100644 --- a/package/archlinux/PKGBUILD-es2desktop +++ b/package/archlinux/PKGBUILD-es2desktop @@ -2,18 +2,20 @@ pkgname=magnum pkgver=dev.es2desktop pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (desktop OpenGL ES 2.0 version)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (desktop OpenGL ES 2.0 version)" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('corrade' 'openal') makedepends=('cmake' 'ninja') -options=('!strip' 'staticlibs') +options=('!strip') provides=('magnum-git') +_rootdir=$startdir/../../ + build() { - mkdir -p "$startdir/build-es2desktop" - cd "$startdir/build-es2desktop" + mkdir -p "$_rootdir/build-es2desktop" + cd "$_rootdir/build-es2desktop" cmake .. \ -DCMAKE_BUILD_TYPE=Debug \ @@ -22,8 +24,9 @@ build() { -DTARGET_GLES2=ON \ -DTARGET_DESKTOP_GLES=ON \ -DWITH_AUDIO=ON \ - -DWITH_SDL2APPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ + -DWITH_SDL2APPLICATION=ON \ + -DWITH_XEGLAPPLICATION=ON \ -DWITH_WINDOWLESSGLXAPPLICATION=ON \ -DWITH_EGLCONTEXT=ON \ -DWITH_GLXCONTEXT=ON \ @@ -40,11 +43,11 @@ build() { } check() { - cd "$startdir/build-es2desktop" + cd "$_rootdir/build-es2desktop" ctest --output-on-failure -j5 } package() { - cd "$startdir/build-es2desktop" + cd "$_rootdir/build-es2desktop" DESTDIR="$pkgdir/" ninja install } diff --git a/package/archlinux/PKGBUILD-es3 b/package/archlinux/PKGBUILD-es3 index 33348f83a..587a1f9a7 100644 --- a/package/archlinux/PKGBUILD-es3 +++ b/package/archlinux/PKGBUILD-es3 @@ -2,18 +2,20 @@ pkgname=magnum pkgver=dev.es3 pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (OpenGL ES 3.0 version)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (OpenGL ES 3.0 version)" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('corrade' 'openal') makedepends=('cmake' 'ninja') -options=('!strip' 'staticlibs') +options=('!strip') provides=('magnum-git') +_rootdir=$startdir/../../ + build() { - mkdir -p "$startdir/build-es3" - cd "$startdir/build-es3" + mkdir -p "$_rootdir/build-es3" + cd "$_rootdir/build-es3" cmake .. \ -DCMAKE_BUILD_TYPE=Debug \ @@ -34,11 +36,11 @@ build() { } check() { - cd "$startdir/build-es3" + cd "$_rootdir/build-es3" ctest --output-on-failure -j5 } package() { - cd "$startdir/build-es3" + cd "$_rootdir/build-es3" DESTDIR="$pkgdir/" ninja install } diff --git a/package/archlinux/PKGBUILD-es3desktop b/package/archlinux/PKGBUILD-es3desktop index f808cb972..9855e7c3a 100644 --- a/package/archlinux/PKGBUILD-es3desktop +++ b/package/archlinux/PKGBUILD-es3desktop @@ -2,18 +2,20 @@ pkgname=magnum pkgver=dev.es3desktop pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (desktop OpenGL ES 3.0 version)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (desktop OpenGL ES 3.0 version)" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('corrade' 'openal') makedepends=('cmake' 'ninja') -options=('!strip' 'staticlibs') +options=('!strip') provides=('magnum-git') +_rootdir=$startdir/../../ + build() { - mkdir -p "$startdir/build-es3desktop" - cd "$startdir/build-es3desktop" + mkdir -p "$_rootdir/build-es3desktop" + cd "$_rootdir/build-es3desktop" cmake .. \ -DCMAKE_BUILD_TYPE=Debug \ @@ -22,8 +24,9 @@ build() { -DTARGET_GLES2=OFF \ -DTARGET_DESKTOP_GLES=ON \ -DWITH_AUDIO=ON \ - -DWITH_SDL2APPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ + -DWITH_SDL2APPLICATION=ON \ + -DWITH_XEGLAPPLICATION=ON \ -DWITH_WINDOWLESSGLXAPPLICATION=ON \ -DWITH_EGLCONTEXT=ON \ -DWITH_GLXCONTEXT=ON \ @@ -40,11 +43,11 @@ build() { } check() { - cd "$startdir/build-es3desktop" + cd "$_rootdir/build-es3desktop" ctest --output-on-failure -j5 } package() { - cd "$startdir/build-es3desktop" + cd "$_rootdir/build-es3desktop" DESTDIR="$pkgdir/" ninja install } diff --git a/package/archlinux/PKGBUILD-gcc47 b/package/archlinux/PKGBUILD-gcc47 index fefa175e0..2101e11db 100644 --- a/package/archlinux/PKGBUILD-gcc47 +++ b/package/archlinux/PKGBUILD-gcc47 @@ -2,26 +2,28 @@ pkgname=magnum pkgver=dev.gcc47 pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (built with GCC 4.7)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (built with GCC 4.7)" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('corrade' 'openal' 'freeglut' 'sdl2') makedepends=('cmake' 'ninja' 'gcc47') -options=('!strip' 'staticlibs') +options=('!strip') provides=('magnum-git') +_rootdir=$startdir/../../ + build() { - if [ ! -d "$startdir/build-gcc47" ] ; then - mkdir "$startdir/build-gcc47" - cd "$startdir/build-gcc47" + if [ ! -d "$_rootdir/build-gcc47" ] ; then + mkdir "$_rootdir/build-gcc47" + cd "$_rootdir/build-gcc47" cmake .. \ -DCMAKE_CXX_COMPILER=g++-4.7 \ -G Ninja fi - cd "$startdir/build-gcc47" + cd "$_rootdir/build-gcc47" cmake .. \ -DCMAKE_BUILD_TYPE=Debug \ @@ -30,6 +32,7 @@ build() { -DWITH_GLUTAPPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ -DWITH_SDL2APPLICATION=ON \ + -DWITH_XEGLAPPLICATION=ON \ -DWITH_WINDOWLESSGLXAPPLICATION=ON \ -DWITH_EGLCONTEXT=ON \ -DWITH_GLXCONTEXT=ON \ @@ -48,11 +51,11 @@ build() { } check() { - cd "$startdir/build-gcc47" + cd "$_rootdir/build-gcc47" ctest --output-on-failure -j5 } package() { - cd "$startdir/build-gcc47" + cd "$_rootdir/build-gcc47" DESTDIR="$pkgdir/" ninja install } diff --git a/package/archlinux/PKGBUILD-mingw-w64 b/package/archlinux/PKGBUILD-mingw-w64 index 11ca64df8..c70fe9ac0 100644 --- a/package/archlinux/PKGBUILD-mingw-w64 +++ b/package/archlinux/PKGBUILD-mingw-w64 @@ -2,17 +2,19 @@ pkgname=mingw-w64-magnum pkgver=dev pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (mingw-w64)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (mingw-w64)" arch=('any') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('mingw-w64-crt' 'mingw-w64-corrade' 'mingw-w64-freeglut' 'mingw-w64-sdl2' 'mingw-w64-openal') makedepends=('mingw-w64-gcc' 'cmake' 'ninja' 'corrade') -options=('!buildflags' '!strip' 'staticlibs') +options=('!buildflags' '!strip') + +_rootdir=$startdir/../../ build() { - mkdir -p "$startdir/build-mingw-w64-32" - cd "$startdir/build-mingw-w64-32" + mkdir -p "$_rootdir/build-mingw-w64-32" + cd "$_rootdir/build-mingw-w64-32" cmake .. \ -DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw-w64-32.cmake \ @@ -36,8 +38,8 @@ build() { -G Ninja ninja - mkdir -p "$startdir/build-mingw-w64-64" - cd "$startdir/build-mingw-w64-64" + mkdir -p "$_rootdir/build-mingw-w64-64" + cd "$_rootdir/build-mingw-w64-64" cmake .. \ -DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw-w64-64.cmake \ @@ -62,9 +64,9 @@ build() { } package() { - cd "$startdir/build-mingw-w64-32" + cd "$_rootdir/build-mingw-w64-32" DESTDIR="$pkgdir/" ninja install/strip - cd "$startdir/build-mingw-w64-64" + cd "$_rootdir/build-mingw-w64-64" DESTDIR="$pkgdir/" ninja install/strip } diff --git a/package/archlinux/PKGBUILD-nacl-glibc b/package/archlinux/PKGBUILD-nacl-glibc index 25bbc2c01..16f035e9c 100644 --- a/package/archlinux/PKGBUILD-nacl-glibc +++ b/package/archlinux/PKGBUILD-nacl-glibc @@ -2,22 +2,24 @@ pkgname=nacl-magnum pkgver=dev.glibc pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (NaCl glibc version)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (NaCl glibc version)" arch=('any') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('nacl-corrade') makedepends=('nacl-sdk' 'cmake' 'corrade' 'ninja') -options=('!buildflags' '!strip' 'staticlibs') +options=('!strip' '!buildflags') + +_rootdir=$startdir/../../ build() { # Build 32bit - mkdir -p "$startdir/build-nacl-glibc-x86-32" - cd "$startdir/build-nacl-glibc-x86-32" + mkdir -p "$_rootdir/build-nacl-glibc-x86-32" + cd "$_rootdir/build-nacl-glibc-x86-32" cmake .. \ - -DCMAKE_MODULE_PATH="$startdir/toolchains/modules" \ - -DCMAKE_TOOLCHAIN_FILE="$startdir/toolchains/generic/NaCl-glibc-x86-32.cmake" \ + -DCMAKE_MODULE_PATH="$_rootdir/toolchains/modules" \ + -DCMAKE_TOOLCHAIN_FILE="$_rootdir/toolchains/generic/NaCl-glibc-x86-32.cmake" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr/nacl \ -DWITH_MAGNUMINFO=OFF \ @@ -33,12 +35,12 @@ build() { ninja # Build 64bit - mkdir -p "$startdir/build-nacl-glibc-x86-64" - cd "$startdir/build-nacl-glibc-x86-64" + mkdir -p "$_rootdir/build-nacl-glibc-x86-64" + cd "$_rootdir/build-nacl-glibc-x86-64" cmake .. \ - -DCMAKE_MODULE_PATH="$startdir/toolchains/modules" \ - -DCMAKE_TOOLCHAIN_FILE="$startdir/toolchains/generic/NaCl-glibc-x86-64.cmake" \ + -DCMAKE_MODULE_PATH="$_rootdir/toolchains/modules" \ + -DCMAKE_TOOLCHAIN_FILE="$_rootdir/toolchains/generic/NaCl-glibc-x86-64.cmake" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr/nacl \ -DWITH_MAGNUMINFO=OFF \ @@ -55,11 +57,11 @@ build() { package() { # Install 32bit - cd "$startdir/build-nacl-glibc-x86-32" + cd "$_rootdir/build-nacl-glibc-x86-32" DESTDIR="$pkgdir/" ninja install/strip # Install 64bit (the headers will be overwritten, but they are (and should # be) the same for both versions - cd "$startdir/build-nacl-glibc-x86-64" + cd "$_rootdir/build-nacl-glibc-x86-64" DESTDIR="$pkgdir/" ninja install/strip } diff --git a/package/archlinux/PKGBUILD-nacl-newlib b/package/archlinux/PKGBUILD-nacl-newlib index d3dfa6f8e..1821e61f0 100644 --- a/package/archlinux/PKGBUILD-nacl-newlib +++ b/package/archlinux/PKGBUILD-nacl-newlib @@ -2,22 +2,24 @@ pkgname=nacl-magnum pkgver=dev.newlib pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (NaCl newlib version)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (NaCl newlib version)" arch=('any') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('nacl-corrade') makedepends=('nacl-sdk' 'cmake' 'corrade' 'ninja') -options=('!buildflags' '!strip' 'staticlibs') +options=('!strip' '!buildflags') + +_rootdir=$startdir/../../ build() { # Build 32bit - mkdir -p "$startdir/build-nacl-newlib-x86-32" - cd "$startdir/build-nacl-newlib-x86-32" + mkdir -p "$_rootdir/build-nacl-newlib-x86-32" + cd "$_rootdir/build-nacl-newlib-x86-32" cmake .. \ - -DCMAKE_MODULE_PATH="$startdir/toolchains/modules" \ - -DCMAKE_TOOLCHAIN_FILE="$startdir/toolchains/generic/NaCl-newlib-x86-32.cmake" \ + -DCMAKE_MODULE_PATH="$_rootdir/toolchains/modules" \ + -DCMAKE_TOOLCHAIN_FILE="$_rootdir/toolchains/generic/NaCl-newlib-x86-32.cmake" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr/nacl \ -DWITH_MAGNUMINFO=ON \ @@ -34,12 +36,12 @@ build() { ninja # Build 64bit - mkdir -p "$startdir/build-nacl-newlib-x86-64" - cd "$startdir/build-nacl-newlib-x86-64" + mkdir -p "$_rootdir/build-nacl-newlib-x86-64" + cd "$_rootdir/build-nacl-newlib-x86-64" cmake .. \ - -DCMAKE_MODULE_PATH="$startdir/toolchains/modules" \ - -DCMAKE_TOOLCHAIN_FILE="$startdir/toolchains/generic/NaCl-newlib-x86-64.cmake" \ + -DCMAKE_MODULE_PATH="$_rootdir/toolchains/modules" \ + -DCMAKE_TOOLCHAIN_FILE="$_rootdir/toolchains/generic/NaCl-newlib-x86-64.cmake" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr/nacl \ -DWITH_MAGNUMINFO=ON \ @@ -57,11 +59,11 @@ build() { package() { # Install 32bit - cd "$startdir/build-nacl-newlib-x86-32" + cd "$_rootdir/build-nacl-newlib-x86-32" DESTDIR="$pkgdir/" ninja install/strip # Install 64bit (the headers will be overwritten, but they are (and should # be) the same for both versions - cd "$startdir/build-nacl-newlib-x86-64" + cd "$_rootdir/build-nacl-newlib-x86-64" DESTDIR="$pkgdir/" ninja install/strip } diff --git a/package/archlinux/PKGBUILD-release b/package/archlinux/PKGBUILD-release index 09bbdcc5a..c675243a7 100644 --- a/package/archlinux/PKGBUILD-release +++ b/package/archlinux/PKGBUILD-release @@ -2,18 +2,20 @@ pkgname=magnum pkgver=dev.release pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (debug+release libs)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (debug+release libs)" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') depends=('corrade' 'openal' 'sdl2' 'freeglut') makedepends=('cmake' 'ninja') -options=('!strip' 'staticlibs') +options=('!strip') provides=('magnum-git') +_rootdir=$startdir/../../ + build() { - mkdir -p "$startdir/build" - cd "$startdir/build" + mkdir -p "$_rootdir/build" + cd "$_rootdir/build" cmake .. \ -DCMAKE_BUILD_TYPE=Debug \ @@ -22,6 +24,7 @@ build() { -DWITH_GLUTAPPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ -DWITH_SDL2APPLICATION=ON \ + -DWITH_XEGLAPPLICATION=ON \ -DWITH_WINDOWLESSGLXAPPLICATION=ON \ -DWITH_EGLCONTEXT=ON \ -DWITH_GLXCONTEXT=ON \ @@ -39,8 +42,8 @@ build() { -G Ninja ninja - mkdir -p "$startdir/build-release" - cd "$startdir/build-release" + mkdir -p "$_rootdir/build-release" + cd "$_rootdir/build-release" cmake .. \ -DCMAKE_BUILD_TYPE=Release \ @@ -49,6 +52,7 @@ build() { -DWITH_GLUTAPPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ -DWITH_SDL2APPLICATION=ON \ + -DWITH_XEGLAPPLICATION=ON \ -DWITH_WINDOWLESSGLXAPPLICATION=ON \ -DWITH_MAGNUMFONT=ON \ -DWITH_MAGNUMFONTCONVERTER=ON \ @@ -66,17 +70,17 @@ build() { } check() { - cd "$startdir/build" + cd "$_rootdir/build" ctest --output-on-failure -j5 - cd "$startdir/build-release" + cd "$_rootdir/build-release" ctest --output-on-failure -j5 } package() { - cd "$startdir/build" + cd "$_rootdir/build" DESTDIR="$pkgdir/" ninja install - cd "$startdir/build-release" + cd "$_rootdir/build-release" DESTDIR="$pkgdir/" ninja install/strip } diff --git a/package/archlinux/magnum-git/.gitignore b/package/archlinux/magnum-git/.gitignore new file mode 100644 index 000000000..b24f1baee --- /dev/null +++ b/package/archlinux/magnum-git/.gitignore @@ -0,0 +1 @@ +magnum diff --git a/package/archlinux/magnum-git/PKGBUILD b/package/archlinux/magnum-git/PKGBUILD index 66732b605..9d1e0eb84 100644 --- a/package/archlinux/magnum-git/PKGBUILD +++ b/package/archlinux/magnum-git/PKGBUILD @@ -1,8 +1,8 @@ # Author: mosra pkgname=magnum-git -pkgver=20140427 +pkgver=snapshot.2014.06.r380.gd0a85ee pkgrel=1 -pkgdesc="C++11 and OpenGL 2D/3D graphics engine (Git version)" +pkgdesc="C++11/C++14 and OpenGL 2D/3D graphics engine (Git version)" arch=('i686' 'x86_64') url="http://mosra.cz/blog/magnum.php" license=('MIT') @@ -10,33 +10,19 @@ depends=('corrade-git' 'openal' 'sdl2') makedepends=('cmake' 'git') provides=('magnum') conflicts=('magnum') -options=('staticlibs') - -_gitroot="git://github.com/mosra/magnum.git" -_gitname="magnum" +source=("git+git://github.com/mosra/magnum.git") +sha1sums=('SKIP') pkgver() { - date +%Y%m%d + cd "$srcdir/${pkgname%-git}" + git describe --long | sed -r 's/([^-]*-g)/r\1/;s/-/./g' } build() { - cd "$srcdir" - msg "Connecting to Git server..." - - if [ -d $_gitname ] ; then - cd $_gitname && git pull origin - msg "The local files are updated." - else - git clone $_gitroot $_gitname - fi - - msg "Git checkout done." - msg "Starting make..." - mkdir -p "$srcdir/build" cd "$srcdir/build" - cmake ../$_gitname \ + cmake "$srcdir/${pkgname%-git}" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ -DWITH_AUDIO=ON \ diff --git a/package/ci/jenkins-clang-analyzer.xml b/package/ci/jenkins-clang-analyzer.xml new file mode 100644 index 000000000..09587fe85 --- /dev/null +++ b/package/ci/jenkins-clang-analyzer.xml @@ -0,0 +1,158 @@ + + + + + + -1 + 10 + -1 + -1 + + false + + + 2 + + + git://github.com/mosra/magnum.git + + + + + */master + + + false + + + + true + + + + + true + false + false + false + + false + Magnum + + + gl + + desktop + es2 + es2desktop + es3 + es3desktop + + + + compatibility + + + deprecated + + + + + + + + + + + + + scan-build: \d+ bugs found + false + true + true + + + + + true + + + + + UNSTABLE + 1 + YELLOW + true + + + . + diff --git a/package/ci/jenkins-clang-sanitizer-gltests.xml b/package/ci/jenkins-clang-sanitizer-gltests.xml new file mode 100644 index 000000000..5344d0382 --- /dev/null +++ b/package/ci/jenkins-clang-sanitizer-gltests.xml @@ -0,0 +1,103 @@ + + + + + + -1 + 10 + -1 + -1 + + false + + + 2 + + + git://github.com/mosra/magnum.git + + + + + */master + + + false + + + + true + + + + + true + false + false + false + + false + Magnum + + + gl + + desktop + es2desktop + es3desktop + + + + compatibility + + + deprecated + + + + sanitizer + + address + + + + + + + + + + + + + + + Errors while running CTest + false + true + true + + + + + true + + + + + SUCCESS + 0 + BLUE + true + + + . + diff --git a/package/ci/jenkins-clang-sanitizer.xml b/package/ci/jenkins-clang-sanitizer.xml new file mode 100644 index 000000000..a13fe4343 --- /dev/null +++ b/package/ci/jenkins-clang-sanitizer.xml @@ -0,0 +1,176 @@ + + + + + + -1 + 10 + -1 + -1 + + false + + + 2 + + + git://github.com/mosra/magnum.git + + + + + */master + + + false + + + + true + + + + + true + false + false + false + + false + Magnum + + + gl + + desktop + es2 + es2desktop + es3 + es3desktop + + + + compatibility + + + deprecated + + + + sanitizer + + address + + + + + + + + + + + + + + + Magnum-ClangSanitizer-GLTests + + SUCCESS + 0 + BLUE + true + + + + Errors while running CTest + false + true + true + + + + + true + + + + + UNSTABLE + 1 + YELLOW + true + + + . + diff --git a/package/ci/jenkins-mingw-w64.xml b/package/ci/jenkins-mingw-w64.xml index 544e3cd18..e1f9162c1 100644 --- a/package/ci/jenkins-mingw-w64.xml +++ b/package/ci/jenkins-mingw-w64.xml @@ -69,7 +69,7 @@ git submodule init git submodule update if [ ${libraries} = "static" ] ; then - static_build_flag="-DBUILD_STATIC=ON -DBUILD_STATIC_PIC=ON" + static_build_flag="-DBUILD_STATIC=ON -DBUILD_PLUGINS_STATIC=ON -DBUILD_STATIC_PIC=ON" fi if [ "${compatibility}" = "deprecated" ] ; then diff --git a/package/ci/jenkins.xml b/package/ci/jenkins.xml index b7878e11c..fa438a4cd 100644 --- a/package/ci/jenkins.xml +++ b/package/ci/jenkins.xml @@ -88,7 +88,7 @@ else fi if [ ${libraries} = "static" ] ; then - static_build_flag="-DBUILD_STATIC=ON -DBUILD_STATIC_PIC=ON" + static_build_flag="-DBUILD_STATIC=ON -DBUILD_PLUGINS_STATIC=ON -DBUILD_STATIC_PIC=ON" fi if [ "${compatibility}" = "deprecated" ] ; then @@ -142,7 +142,7 @@ cmake .. \ -DWITH_GLUTAPPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ -DWITH_SDL2APPLICATION=ON \ - -DWITH_XEGLAPPLICATION=${es_flag} \ + -DWITH_XEGLAPPLICATION=ON \ -DWITH_EGLCONTEXT=ON \ -DWITH_GLXCONTEXT=ON \ -DWITH_MAGNUMFONT=ON \ diff --git a/package/debian/control b/package/debian/control index c8889b81c..4a79a7ba0 100644 --- a/package/debian/control +++ b/package/debian/control @@ -1,7 +1,7 @@ Source: magnum Priority: optional Maintainer: Vladimír Vondruš -Build-Depends: debhelper (>= 9), cmake (>= 2.8.8) +Build-Depends: debhelper (>= 9), cmake (>= 2.8.9) Standards-Version: 3.9.2 Section: libs Homepage: http://mosra.cz/blog/magnum.php @@ -11,15 +11,15 @@ Vcs-Browser: https://github.com/mosra/magnum Package: magnum-dev Section: libdevel Architecture: any -Depends: magnum (= ${binary:Version}), corrade-dev, libgl-dev, freeglut3-dev, libopenal-dev +Depends: magnum (= ${binary:Version}), corrade-dev, libgl-dev, freeglut3-dev, libopenal-dev, libsdl2-dev Description: Magnum development files Headers and tools needed for developing with Magnum. Package: magnum Section: libs Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, corrade, libgl1, freeglut3, libopenal1 -Description: C++11 and OpenGL 2D/3D graphics engine +Depends: ${shlibs:Depends}, ${misc:Depends}, corrade, libgl1, freeglut3, libopenal1, libsdl2 +Description: C++11/C++14 and OpenGL 2D/3D graphics engine Magnum is 2D/3D graphics engine written in C++11 and modern OpenGL. Its goal is to simplify low-level graphics development and interaction with OpenGL using recent C++11 features and to abstract away platform-specific issues. diff --git a/package/debian/copyright b/package/debian/copyright index a9eaab973..e96081e1a 100644 --- a/package/debian/copyright +++ b/package/debian/copyright @@ -4,7 +4,7 @@ Upstream-Contact: Vladimír Vondruš Source: https://github.com/mosra/magnum Files: * -Copyright: 2010-2014 Vladimír Vondruš +Copyright: 2010-2015 Vladimír Vondruš License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/package/debian/rules b/package/debian/rules index 9752ff134..309a44b15 100755 --- a/package/debian/rules +++ b/package/debian/rules @@ -8,6 +8,7 @@ override_dh_auto_configure: -DWITH_AUDIO=ON \ -DWITH_GLUTAPPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ + -DWITH_SDL2APPLICATION=ON \ -DWITH_WINDOWLESSGLXAPPLICATION=ON \ -DWITH_EGLCONTEXT=ON \ -DWITH_GLXCONTEXT=ON \ diff --git a/package/gentoo/dev-libs/magnum/magnum-9999.ebuild b/package/gentoo/dev-libs/magnum/magnum-9999.ebuild index 1cd38ed5d..22f73e45f 100644 --- a/package/gentoo/dev-libs/magnum/magnum-9999.ebuild +++ b/package/gentoo/dev-libs/magnum/magnum-9999.ebuild @@ -8,7 +8,7 @@ EGIT_REPO_URI="git://github.com/mosra/magnum.git" inherit cmake-utils git-r3 -DESCRIPTION="C++11 and OpenGL 2D/3D graphics engine" +DESCRIPTION="C++11/C++14 and OpenGL 2D/3D graphics engine" HOMEPAGE="http://mosra.cz/blog/magnum.php" LICENSE="MIT" @@ -27,26 +27,25 @@ DEPEND="${RDEPEND}" src_configure() { local mycmakeargs=( -DCMAKE_INSTALL_PREFIX="${EPREFIX}/usr" - -DCMAKE_BUILD_TYPE=Debug \ - -DWITH_AUDIO=ON \ - -DWITH_GLUTAPPLICATION=ON \ - -DWITH_GLXAPPLICATION=ON \ - -DWITH_SDL2APPLICATION=ON \ - -DWITH_WINDOWLESSGLXAPPLICATION=ON \ - -DWITH_EGLCONTEXT=ON \ - -DWITH_GLXCONTEXT=ON \ - -DWITH_MAGNUMFONT=ON \ - -DWITH_MAGNUMFONTCONVERTER=ON \ - -DWITH_OBJIMPORTER=ON \ - -DWITH_TGAIMAGECONVERTER=ON \ - -DWITH_TGAIMPORTER=ON \ - -DWITH_WAVAUDIOIMPORTER=ON \ - -DWITH_DISTANCEFIELDCONVERTER=ON \ - -DWITH_FONTCONVERTER=ON \ - -DWITH_MAGNUMINFO=ON \ - -DBUILD_TESTS=ON \ - -DBUILD_GL_TESTS=ON - ) + -DCMAKE_BUILD_TYPE=Release + -DWITH_AUDIO=ON + -DWITH_GLUTAPPLICATION=ON + -DWITH_GLXAPPLICATION=ON + -DWITH_SDL2APPLICATION=ON + -DWITH_WINDOWLESSGLXAPPLICATION=ON + -DWITH_EGLCONTEXT=ON + -DWITH_GLXCONTEXT=ON + -DWITH_MAGNUMFONT=ON + -DWITH_MAGNUMFONTCONVERTER=ON + -DWITH_OBJIMPORTER=ON + -DWITH_TGAIMAGECONVERTER=ON + -DWITH_TGAIMPORTER=ON + -DWITH_WAVAUDIOIMPORTER=ON + -DWITH_DISTANCEFIELDCONVERTER=ON + -DWITH_FONTCONVERTER=ON + -DWITH_MAGNUMINFO=ON + ) cmake-utils_src_configure } +# kate: replace-tabs off; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5c186438c..b38322828 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/AbstractFramebuffer.cpp b/src/Magnum/AbstractFramebuffer.cpp index 80477b214..a55f34fee 100644 --- a/src/Magnum/AbstractFramebuffer.cpp +++ b/src/Magnum/AbstractFramebuffer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -93,24 +93,45 @@ void AbstractFramebuffer::createIfNotAlready() { CORRADE_INTERNAL_ASSERT(_created); } -void AbstractFramebuffer::bind(FramebufferTarget target) { - bindInternal(target); +void AbstractFramebuffer::bind() { + bindInternal(FramebufferTarget::Draw); setViewportInternal(); } void AbstractFramebuffer::bindInternal(FramebufferTarget target) { - Implementation::FramebufferState* state = Context::current()->state().framebuffer; + #ifndef MAGNUM_TARGET_GLES2 + bindImplementationDefault(target); + #else + (this->*Context::current()->state().framebuffer->bindImplementation)(target); + #endif +} + +#ifdef MAGNUM_TARGET_GLES2 +void AbstractFramebuffer::bindImplementationSingle(FramebufferTarget) { + Implementation::FramebufferState& state = *Context::current()->state().framebuffer; + CORRADE_INTERNAL_ASSERT(state.readBinding == state.drawBinding); + if(state.readBinding == _id) return; + + state.readBinding = state.drawBinding = _id; + + /* Binding the framebuffer finally creates it */ + _created = true; + glBindFramebuffer(GL_FRAMEBUFFER, _id); +} +#endif + +#ifndef MAGNUM_TARGET_GLES2 +inline +#endif +void AbstractFramebuffer::bindImplementationDefault(FramebufferTarget target) { + Implementation::FramebufferState& state = *Context::current()->state().framebuffer; - /* If already bound, done, otherwise update tracked state */ if(target == FramebufferTarget::Read) { - if(state->readBinding == _id) return; - state->readBinding = _id; + if(state.readBinding == _id) return; + state.readBinding = _id; } else if(target == FramebufferTarget::Draw) { - if(state->drawBinding == _id) return; - state->drawBinding = _id; - } else if(target == FramebufferTarget::ReadDraw) { - if(state->readBinding == _id && state->drawBinding == _id) return; - state->readBinding = state->drawBinding = _id; + if(state.drawBinding == _id) return; + state.drawBinding = _id; } else CORRADE_ASSERT_UNREACHABLE(); /* Binding the framebuffer finally creates it */ @@ -119,46 +140,78 @@ void AbstractFramebuffer::bindInternal(FramebufferTarget target) { } FramebufferTarget AbstractFramebuffer::bindInternal() { - Implementation::FramebufferState* state = Context::current()->state().framebuffer; + #ifndef MAGNUM_TARGET_GLES2 + return bindImplementationDefault(); + #else + return (this->*Context::current()->state().framebuffer->bindInternalImplementation)(); + #endif +} + +#ifdef MAGNUM_TARGET_GLES2 +FramebufferTarget AbstractFramebuffer::bindImplementationSingle() { + Implementation::FramebufferState& state = *Context::current()->state().framebuffer; + CORRADE_INTERNAL_ASSERT(state.readBinding == state.drawBinding); + + /* Bind the framebuffer, if not already */ + if(state.readBinding != _id) { + state.readBinding = state.drawBinding = _id; + + /* Binding the framebuffer finally creates it */ + _created = true; + glBindFramebuffer(GL_FRAMEBUFFER, _id); + } + + return FramebufferTarget{}; +} +#endif + +#ifndef MAGNUM_TARGET_GLES2 +inline +#endif +FramebufferTarget AbstractFramebuffer::bindImplementationDefault() { + Implementation::FramebufferState& state = *Context::current()->state().framebuffer; /* Return target to which the framebuffer is already bound */ - if(state->readBinding == _id && state->drawBinding == _id) - return FramebufferTarget::ReadDraw; - if(state->readBinding == _id) + if(state.readBinding == _id) return FramebufferTarget::Read; - if(state->drawBinding == _id) + if(state.drawBinding == _id) return FramebufferTarget::Draw; /* Or bind it, if not already */ - state->readBinding = _id; + state.readBinding = _id; /* Binding the framebuffer finally creates it */ _created = true; - #ifndef MAGNUM_TARGET_GLES2 glBindFramebuffer(GLenum(FramebufferTarget::Read), _id); return FramebufferTarget::Read; - #else - if(state->readTarget == FramebufferTarget::ReadDraw) state->drawBinding = _id; - glBindFramebuffer(GLenum(state->readTarget), _id); - return state->readTarget; - #endif } -void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter) { +void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) { + Context::current()->state().framebuffer->blitImplementation(source, destination, sourceRectangle, destinationRectangle, mask, filter); +} + +#ifndef MAGNUM_TARGET_GLES2 +void AbstractFramebuffer::blitImplementationDefault(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) { source.bindInternal(FramebufferTarget::Read); destination.bindInternal(FramebufferTarget::Draw); - #ifndef MAGNUM_TARGET_GLES2 glBlitFramebuffer(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter)); - #else - Context::current()->state().framebuffer->blitImplementation(sourceRectangle, destinationRectangle, mask, filter); - #endif } -#ifdef MAGNUM_TARGET_GLES2 -void AbstractFramebuffer::blitImplementationANGLE(const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) { +#ifndef MAGNUM_TARGET_GLES +void AbstractFramebuffer::blitImplementationDSA(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) { + glBlitNamedFramebuffer(source._id, destination._id, sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter)); +} +#endif + +#else +void AbstractFramebuffer::blitImplementationANGLE(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) { #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + source.bindInternal(FramebufferTarget::Read); + destination.bindInternal(FramebufferTarget::Draw); glBlitFramebufferANGLE(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter)); #else + static_cast(source); + static_cast(destination); static_cast(sourceRectangle); static_cast(destinationRectangle); static_cast(mask); @@ -167,10 +220,14 @@ void AbstractFramebuffer::blitImplementationANGLE(const Range2Di& sourceRectangl #endif } -void AbstractFramebuffer::blitImplementationNV(const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) { +void AbstractFramebuffer::blitImplementationNV(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) { #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + source.bindInternal(FramebufferTarget::Read); + destination.bindInternal(FramebufferTarget::Draw); glBlitFramebufferNV(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter)); #else + static_cast(source); + static_cast(destination); static_cast(sourceRectangle); static_cast(destinationRectangle); static_cast(mask); @@ -181,6 +238,7 @@ void AbstractFramebuffer::blitImplementationNV(const Range2Di& sourceRectangle, #endif AbstractFramebuffer& AbstractFramebuffer::setViewport(const Range2Di& rectangle) { + CORRADE_INTERNAL_ASSERT(rectangle != Implementation::FramebufferState::DisengagedViewport); _viewport = rectangle; /* Update the viewport if the framebuffer is currently bound */ @@ -191,54 +249,55 @@ AbstractFramebuffer& AbstractFramebuffer::setViewport(const Range2Di& rectangle) } void AbstractFramebuffer::setViewportInternal() { - Implementation::FramebufferState* state = Context::current()->state().framebuffer; + Implementation::FramebufferState& state = *Context::current()->state().framebuffer; - /* We are using empty viewport to indicate disengaged state */ - CORRADE_INTERNAL_ASSERT(_viewport != Range2Di{}); - CORRADE_INTERNAL_ASSERT(state->drawBinding == _id); + CORRADE_INTERNAL_ASSERT(_viewport != Implementation::FramebufferState::DisengagedViewport); + CORRADE_INTERNAL_ASSERT(state.drawBinding == _id); /* Already up-to-date, nothing to do */ - if(state->viewport == _viewport) + if(state.viewport == _viewport) return; /* Update the state and viewport */ - state->viewport = _viewport; + state.viewport = _viewport; glViewport(_viewport.left(), _viewport.bottom(), _viewport.sizeX(), _viewport.sizeY()); } -void AbstractFramebuffer::clear(FramebufferClearMask mask) { - #ifndef MAGNUM_TARGET_GLES2 +AbstractFramebuffer& AbstractFramebuffer::clear(const FramebufferClearMask mask) { bindInternal(FramebufferTarget::Draw); - #else - bindInternal(Context::current()->state().framebuffer->drawTarget); - #endif glClear(GLbitfield(mask)); -} -void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, Image2D& image) { - const Implementation::FramebufferState& state = *Context::current()->state().framebuffer; + return *this; +} - #ifndef MAGNUM_TARGET_GLES2 +void AbstractFramebuffer::read(const Range2Di& rectangle, Image2D& image) { bindInternal(FramebufferTarget::Read); - #else - bindInternal(state.readTarget); - #endif - const std::size_t dataSize = image.dataSize(size); + const std::size_t dataSize = image.dataSize(rectangle.size()); char* const data = new char[dataSize]; - (state.readImplementation)(offset, size, image.format(), image.type(), dataSize, data); - image.setData(image.format(), image.type(), size, data); + (Context::current()->state().framebuffer->readImplementation)(rectangle, image.format(), image.type(), dataSize, data); + image.setData(image.format(), image.type(), rectangle.size(), data); +} + +Image2D AbstractFramebuffer::read(const Range2Di& rectangle, Image2D&& image) { + read(rectangle, image); + return std::move(image); } #ifndef MAGNUM_TARGET_GLES2 -void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, BufferImage2D& image, BufferUsage usage) { +void AbstractFramebuffer::read(const Range2Di& rectangle, BufferImage2D& image, BufferUsage usage) { bindInternal(FramebufferTarget::Read); /* If the buffer doesn't have sufficient size, resize it */ /** @todo Explicitly reset also when buffer usage changes */ - if(image.size() != size) - image.setData(image.format(), image.type(), size, nullptr, usage); + if(image.size() != rectangle.size()) + image.setData(image.format(), image.type(), rectangle.size(), nullptr, usage); image.buffer().bindInternal(Buffer::TargetHint::PixelPack); - (Context::current()->state().framebuffer->readImplementation)(offset, size, image.format(), image.type(), image.dataSize(size), nullptr); + (Context::current()->state().framebuffer->readImplementation)(rectangle, image.format(), image.type(), image.dataSize(rectangle.size()), nullptr); +} + +BufferImage2D AbstractFramebuffer::read(const Range2Di& rectangle, BufferImage2D&& image, BufferUsage usage) { + read(rectangle, image, usage); + return std::move(image); } #endif @@ -256,12 +315,24 @@ void AbstractFramebuffer::invalidateImplementationDefault(const GLsizei count, c #endif } +#ifndef MAGNUM_TARGET_GLES +void AbstractFramebuffer::invalidateImplementationDSA(const GLsizei count, const GLenum* const attachments) { + glInvalidateNamedFramebufferData(_id, count, attachments); +} +#endif + #ifndef MAGNUM_TARGET_GLES2 void AbstractFramebuffer::invalidateImplementationNoOp(GLsizei, const GLenum*, const Range2Di&) {} void AbstractFramebuffer::invalidateImplementationDefault(const GLsizei count, const GLenum* const attachments, const Range2Di& rectangle) { glInvalidateSubFramebuffer(GLenum(bindInternal()), count, attachments, rectangle.left(), rectangle.bottom(), rectangle.sizeX(), rectangle.sizeY()); } + +#ifndef MAGNUM_TARGET_GLES +void AbstractFramebuffer::invalidateImplementationDSA(const GLsizei count, const GLenum* const attachments, const Range2Di& rectangle) { + glInvalidateNamedFramebufferSubData(_id, count, attachments, rectangle.left(), rectangle.bottom(), rectangle.sizeX(), rectangle.sizeY()); +} +#endif #endif GLenum AbstractFramebuffer::checkStatusImplementationDefault(const FramebufferTarget target) { @@ -269,7 +340,18 @@ GLenum AbstractFramebuffer::checkStatusImplementationDefault(const FramebufferTa return glCheckFramebufferStatus(GLenum(target)); } +#ifdef MAGNUM_TARGET_GLES2 +GLenum AbstractFramebuffer::checkStatusImplementationSingle(FramebufferTarget) { + bindInternal(FramebufferTarget{}); + return glCheckFramebufferStatus(GL_FRAMEBUFFER); +} +#endif + #ifndef MAGNUM_TARGET_GLES +GLenum AbstractFramebuffer::checkStatusImplementationDSA(const FramebufferTarget target) { + return glCheckNamedFramebufferStatus(_id, GLenum(target)); +} + GLenum AbstractFramebuffer::checkStatusImplementationDSAEXT(const FramebufferTarget target) { _created = true; return glCheckNamedFramebufferStatusEXT(_id, GLenum(target)); @@ -277,11 +359,7 @@ GLenum AbstractFramebuffer::checkStatusImplementationDSAEXT(const FramebufferTar #endif void AbstractFramebuffer::drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers) { - #ifndef MAGNUM_TARGET_GLES2 bindInternal(FramebufferTarget::Draw); - #else - bindInternal(Context::current()->state().framebuffer->drawTarget); - #endif #ifndef MAGNUM_TARGET_GLES2 glDrawBuffers(count, buffers); @@ -295,6 +373,10 @@ void AbstractFramebuffer::drawBuffersImplementationDefault(GLsizei count, const } #ifndef MAGNUM_TARGET_GLES +void AbstractFramebuffer::drawBuffersImplementationDSA(const GLsizei count, const GLenum* const buffers) { + glNamedFramebufferDrawBuffers(_id, count, buffers); +} + void AbstractFramebuffer::drawBuffersImplementationDSAEXT(GLsizei count, const GLenum* buffers) { _created = true; glFramebufferDrawBuffersEXT(_id, count, buffers); @@ -302,11 +384,7 @@ void AbstractFramebuffer::drawBuffersImplementationDSAEXT(GLsizei count, const G #endif void AbstractFramebuffer::drawBufferImplementationDefault(GLenum buffer) { - #ifndef MAGNUM_TARGET_GLES2 bindInternal(FramebufferTarget::Draw); - #else - bindInternal(Context::current()->state().framebuffer->drawTarget); - #endif #ifndef MAGNUM_TARGET_GLES glDrawBuffer(buffer); @@ -321,6 +399,10 @@ void AbstractFramebuffer::drawBufferImplementationDefault(GLenum buffer) { } #ifndef MAGNUM_TARGET_GLES +void AbstractFramebuffer::drawBufferImplementationDSA(const GLenum buffer) { + glNamedFramebufferDrawBuffer(_id, buffer); +} + void AbstractFramebuffer::drawBufferImplementationDSAEXT(GLenum buffer) { _created = true; glFramebufferDrawBufferEXT(_id, buffer); @@ -328,11 +410,7 @@ void AbstractFramebuffer::drawBufferImplementationDSAEXT(GLenum buffer) { #endif void AbstractFramebuffer::readBufferImplementationDefault(GLenum buffer) { - #ifndef MAGNUM_TARGET_GLES2 bindInternal(FramebufferTarget::Read); - #else - bindInternal(Context::current()->state().framebuffer->readTarget); - #endif #ifndef MAGNUM_TARGET_GLES2 glReadBuffer(buffer); @@ -345,24 +423,27 @@ void AbstractFramebuffer::readBufferImplementationDefault(GLenum buffer) { } #ifndef MAGNUM_TARGET_GLES +void AbstractFramebuffer::readBufferImplementationDSA(const GLenum buffer) { + glFramebufferReadBufferEXT(_id, buffer); +} + void AbstractFramebuffer::readBufferImplementationDSAEXT(GLenum buffer) { _created = true; glFramebufferReadBufferEXT(_id, buffer); } #endif -void AbstractFramebuffer::readImplementationDefault(const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { - glReadPixels(offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); +void AbstractFramebuffer::readImplementationDefault(const Range2Di& rectangle, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { + glReadPixels(rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), GLenum(format), GLenum(type), data); } -void AbstractFramebuffer::readImplementationRobustness(const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { +void AbstractFramebuffer::readImplementationRobustness(const Range2Di& rectangle, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { #ifndef MAGNUM_TARGET_GLES - glReadnPixelsARB(offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), dataSize, data); + glReadnPixelsARB(rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), GLenum(format), GLenum(type), dataSize, data); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glReadnPixelsEXT(offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), dataSize, data); + glReadnPixelsEXT(rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), GLenum(format), GLenum(type), dataSize, data); #else - static_cast(offset); - static_cast(size); + static_cast(rectangle); static_cast(format); static_cast(type); static_cast(dataSize); diff --git a/src/Magnum/AbstractFramebuffer.h b/src/Magnum/AbstractFramebuffer.h index 63da2b409..3db2b374d 100644 --- a/src/Magnum/AbstractFramebuffer.h +++ b/src/Magnum/AbstractFramebuffer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,6 +30,7 @@ */ #include +#include #include "Magnum/Magnum.h" #include "Magnum/OpenGL.h" @@ -58,15 +59,19 @@ enum class FramebufferClear: GLbitfield { @see @ref AbstractFramebuffer::clear() */ +#ifndef DOXYGEN_GENERATING_OUTPUT typedef Containers::EnumSet FramebufferClearMask; +#else +typedef Containers::EnumSet FramebufferClearMask; +#endif /** @brief Mask for framebuffer blitting @see @ref AbstractFramebuffer, @ref FramebufferBlitMask -@requires_gl30 %Extension @extension{ARB,framebuffer_object} -@requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or +@requires_gl30 Extension @extension{ARB,framebuffer_object} +@requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit} in OpenGL ES 2.0 */ enum class FramebufferBlit: GLbitfield { @@ -96,19 +101,23 @@ enum class FramebufferBlit: GLbitfield { @brief Mask for framebuffer blitting @see @ref AbstractFramebuffer::blit() -@requires_gl30 %Extension @extension{ARB,framebuffer_object} -@requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or +@requires_gl30 Extension @extension{ARB,framebuffer_object} +@requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit} in OpenGL ES 2.0 */ +#ifndef DOXYGEN_GENERATING_OUTPUT typedef Containers::EnumSet FramebufferBlitMask; +#else +typedef Containers::EnumSet FramebufferBlitMask; +#endif /** -@brief %Framebuffer blit filtering +@brief Framebuffer blit filtering @see @ref AbstractFramebuffer::blit() -@requires_gl30 %Extension @extension{ARB,framebuffer_object} -@requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or +@requires_gl30 Extension @extension{ARB,framebuffer_object} +@requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit} in OpenGL ES 2.0 */ enum class FramebufferBlitFilter: GLenum { @@ -117,37 +126,38 @@ enum class FramebufferBlitFilter: GLenum { }; /** -@brief Target for binding framebuffer +@brief Framebuffer target -@see @ref DefaultFramebuffer::bind(), @ref Framebuffer::bind() -@requires_gl30 %Extension @extension{ARB,framebuffer_object} +@see @ref DefaultFramebuffer::checkStatus(), @ref Framebuffer::checkStatus() +@requires_gl30 Extension @extension{ARB,framebuffer_object} */ enum class FramebufferTarget: GLenum { - /** - * For reading only. - * @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample}, - * @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit} - * in OpenGL ES 2.0 - */ + /** Frambebuffer reading target */ #ifndef MAGNUM_TARGET_GLES2 Read = GL_READ_FRAMEBUFFER, #else Read = GL_READ_FRAMEBUFFER_APPLE, #endif - /** - * For drawing only. - * @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample}, - * @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit} - * in OpenGL ES 2.0 - */ + /** Framebuffer drawing target */ #ifndef MAGNUM_TARGET_GLES2 Draw = GL_DRAW_FRAMEBUFFER, #else Draw = GL_DRAW_FRAMEBUFFER_APPLE, #endif - ReadDraw = GL_FRAMEBUFFER /**< For both reading and drawing. */ + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * Framebuffer drawing target + * @deprecated Use @ref FramebufferTarget::Draw instead. + */ + ReadDraw CORRADE_DEPRECATED_ENUM("use FramebufferTarget::Draw instead") = + #ifndef MAGNUM_TARGET_GLES2 + GL_DRAW_FRAMEBUFFER + #else + GL_DRAW_FRAMEBUFFER_APPLE + #endif + #endif }; namespace Implementation { struct FramebufferState; } @@ -162,15 +172,19 @@ See @ref DefaultFramebuffer and @ref Framebuffer for more information. The engine tracks currently bound framebuffer and current viewport to avoid unnecessary calls to @fn_gl{BindFramebuffer} and @fn_gl{Viewport} when -switching framebuffers. %Framebuffer limits and implementation-defined values +switching framebuffers. Framebuffer limits and implementation-defined values (such as @ref maxViewportSize()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. +If extension @extension{ARB,direct_state_access} (part of OpenGL 4.5) is +available, @ref blit() function uses DSA to avoid unnecessary call to +@fn_gl{BindFramebuffer}. See its documentation for more information. + If @extension{ARB,robustness} is available, @ref read() operations are protected from buffer overflow. */ class MAGNUM_EXPORT AbstractFramebuffer { - friend struct Implementation::FramebufferState; + friend Implementation::FramebufferState; public: /** @todo `GL_IMPLEMENTATION_COLOR_READ_FORMAT`, `GL_IMPLEMENTATION_COLOR_READ_TYPE`, seems to be depending on currently bound FB (aargh) (@extension{ARB,ES2_compatibility}). */ @@ -219,14 +233,16 @@ class MAGNUM_EXPORT AbstractFramebuffer { * @param mask Which buffers to perform blit operation on * @param filter Interpolation filter * - * Binds @p source framebuffer to @ref FramebufferTarget::Read and - * @p destination framebuffer to @ref FramebufferTarget::Draw and - * performs blitting operation. See @ref DefaultFramebuffer::mapForRead(), - * @ref Framebuffer::mapForRead(), @ref DefaultFramebuffer::mapForDraw() - * and @ref Framebuffer::mapForDraw() for specifying particular buffers - * for blitting operation. - * @see @fn_gl{BlitFramebuffer} - * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or + * See @ref DefaultFramebuffer::mapForRead(), @ref Framebuffer::mapForRead(), + * @ref DefaultFramebuffer::mapForDraw() and @ref Framebuffer::mapForDraw() + * for specifying particular buffers for blitting operation. If + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not + * available, @p source framebuffer is bound to @ref FramebufferTarget::Read + * and @p destination framebuffer to @ref FramebufferTarget::Draw + * before the operation (if not already). + * @see @fn_gl2{BlitNamedFramebuffer,BlitFramebuffer}, eventually + * @fn_gl{BlitFramebuffer} + * @requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or * @es_extension{NV,framebuffer_blit} in OpenGL ES 2.0 * @todo NaCl exports `BlitFramebufferEXT` (although no such extension * exists for ES) @@ -235,35 +251,37 @@ class MAGNUM_EXPORT AbstractFramebuffer { /** * @brief Copy block of pixels - * @param source Source framebuffer - * @param destination Destination framebuffer - * @param rectangle Source and destination rectangle - * @param mask Which buffers to perform blit operation on * - * Convenience alternative to above function when source rectangle is - * the same as destination rectangle. As the image is copied + * Convenience alternative to the above function when source rectangle + * is the same as destination rectangle. As the image is copied * pixel-by-pixel, no interpolation is needed and thus * @ref FramebufferBlitFilter::Nearest filtering is used by default. - * @see @fn_gl{BlitFramebuffer} - * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or - * @es_extension{NV,framebuffer_blit} in OpenGL ES 2.0 */ static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& rectangle, FramebufferBlitMask mask) { blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest); } /** - * @brief Bind framebuffer for rendering + * @brief Bind framebuffer for drawing * - * Binds the framebuffer and updates viewport to saved dimensions. + * Binds the framebuffer for drawing and updates viewport to saved + * dimensions. * @see @ref setViewport(), @ref DefaultFramebuffer::mapForRead(), * @ref Framebuffer::mapForRead(), @ref DefaultFramebuffer::mapForDraw(), * @ref Framebuffer::mapForDraw(), @fn_gl{BindFramebuffer}, * @fn_gl{Viewport} - * @todo Bind internally to ReadDraw if separate binding points are not - * supported */ - void bind(FramebufferTarget target); + void bind(); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief bind() + * @deprecated Use parameter-less @ref bind() instead. + */ + CORRADE_DEPRECATED("use parameter-less bind() instead") void bind(FramebufferTarget) { + bind(); + } + #endif /** @brief Viewport rectangle */ Range2Di viewport() const { return _viewport; } @@ -274,7 +292,9 @@ class MAGNUM_EXPORT AbstractFramebuffer { * * Saves the viewport to be used at later time in @ref bind(). If the * framebuffer is currently bound, updates the viewport to given - * rectangle. + * rectangle. Initial value in @ref DefaultFramebuffer is set to cover + * whole window, in @ref Framebuffer the initial value is specified in + * constructor. * @see @ref maxViewportSize(), @fn_gl{Viewport} */ AbstractFramebuffer& setViewport(const Range2Di& rectangle); @@ -282,6 +302,7 @@ class MAGNUM_EXPORT AbstractFramebuffer { /** * @brief Clear specified buffers in framebuffer * @param mask Which buffers to clear + * @return Reference to self (for method chaining) * * To improve performance you can also use * @ref DefaultFramebuffer::invalidate() / @ref Framebuffer::invalidate() @@ -291,15 +312,14 @@ class MAGNUM_EXPORT AbstractFramebuffer { * @ref Renderer::setClearStencil(), @fn_gl{BindFramebuffer}, * @fn_gl{Clear} */ - void clear(FramebufferClearMask mask); + AbstractFramebuffer& clear(FramebufferClearMask mask); /** * @brief Read block of pixels from framebuffer to image - * @param offset Offset in the framebuffer - * @param size %Image size - * @param image %Image where to put the data + * @param rectangle Framebuffer rectangle to read + * @param image Image where to put the data * - * %Image parameters like format and type of pixel data are taken from + * Image parameters like format and type of pixel data are taken from * given image. * * If @extension{ARB,robustness} is available, the operation is @@ -307,15 +327,33 @@ class MAGNUM_EXPORT AbstractFramebuffer { * @see @fn_gl{BindFramebuffer}, @fn_gl{ReadPixels} or * @fn_gl_extension{ReadnPixels,ARB,robustness} */ - void read(const Vector2i& offset, const Vector2i& size, Image2D& image); + void read(const Range2Di& rectangle, Image2D& image); + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image2D image = framebuffer.read(framebuffer.viewport(), {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image2D read(const Range2Di& rectangle, Image2D&& image); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief read(const Range2Di&, Image2D&) + * @deprecated Use @ref read(const Range2Di&, Image2D&) instead. + */ + CORRADE_DEPRECATED("use read(const Range2Di&, Image2D& instead) instead") void read(const Vector2i& offset, const Vector2i& size, Image2D& image) { + read({offset, size}, image); + } + #endif #ifndef MAGNUM_TARGET_GLES2 /** * @brief Read block of pixels from framebuffer to buffer image - * @param offset Offset in the framebuffer - * @param size %Image size - * @param image %Buffer image where to put the data - * @param usage %Buffer usage + * @param rectangle Framebuffer rectangle to read + * @param image Buffer image where to put the data + * @param usage Buffer usage * * See @ref read(const Vector2i&, const Vector2i&, Image2D&) for more * information. @@ -323,7 +361,27 @@ class MAGNUM_EXPORT AbstractFramebuffer { * @todo Make it more flexible (usable with * @extension{ARB,buffer_storage}, avoiding relocations...) */ - void read(const Vector2i& offset, const Vector2i& size, BufferImage2D& image, BufferUsage usage); + void read(const Range2Di& rectangle, BufferImage2D& image, BufferUsage usage); + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage2D image = framebuffer.read(framebuffer.viewport(), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage2D read(const Range2Di& rectangle, BufferImage2D&& image, BufferUsage usage); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief read(const Range2Di&, BufferImage2D&, BufferUsage) + * @deprecated Use @ref read(const Range2Di&, BufferImage2D&, BufferUsage) + * instead. + */ + CORRADE_DEPRECATED("use read(const Range2Di&, BufferImage2D&, BufferUsage) instead") void read(const Vector2i& offset, const Vector2i& size, BufferImage2D& image, BufferUsage usage) { + read({offset, size}, image, usage); + } + #endif #endif #ifdef DOXYGEN_GENERATING_OUTPUT @@ -345,40 +403,65 @@ class MAGNUM_EXPORT AbstractFramebuffer { Range2Di _viewport; private: + #ifndef MAGNUM_TARGET_GLES2 + static void MAGNUM_LOCAL blitImplementationDefault(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter); + #ifndef MAGNUM_TARGET_GLES + static void MAGNUM_LOCAL blitImplementationDSA(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter); + #endif + #else + static void MAGNUM_LOCAL blitImplementationANGLE(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter); + static void MAGNUM_LOCAL blitImplementationNV(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter); + #endif + + void MAGNUM_LOCAL bindImplementationDefault(FramebufferTarget target); + FramebufferTarget MAGNUM_LOCAL bindImplementationDefault(); #ifdef MAGNUM_TARGET_GLES2 - static void MAGNUM_LOCAL blitImplementationANGLE(const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter); - static void MAGNUM_LOCAL blitImplementationNV(const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter); + void MAGNUM_LOCAL bindImplementationSingle(FramebufferTarget); + FramebufferTarget MAGNUM_LOCAL bindImplementationSingle(); #endif GLenum MAGNUM_LOCAL checkStatusImplementationDefault(FramebufferTarget target); + #ifdef MAGNUM_TARGET_GLES2 + GLenum MAGNUM_LOCAL checkStatusImplementationSingle(FramebufferTarget); + #endif #ifndef MAGNUM_TARGET_GLES + GLenum MAGNUM_LOCAL checkStatusImplementationDSA(FramebufferTarget target); GLenum MAGNUM_LOCAL checkStatusImplementationDSAEXT(FramebufferTarget target); #endif void MAGNUM_LOCAL drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL drawBuffersImplementationDSA(GLsizei count, const GLenum* buffers); void MAGNUM_LOCAL drawBuffersImplementationDSAEXT(GLsizei count, const GLenum* buffers); #endif void MAGNUM_LOCAL drawBufferImplementationDefault(GLenum buffer); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL drawBufferImplementationDSA(GLenum buffer); void MAGNUM_LOCAL drawBufferImplementationDSAEXT(GLenum buffer); #endif void MAGNUM_LOCAL readBufferImplementationDefault(GLenum buffer); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL readBufferImplementationDSA(GLenum buffer); void MAGNUM_LOCAL readBufferImplementationDSAEXT(GLenum buffer); #endif - static void MAGNUM_LOCAL readImplementationDefault(const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); - static void MAGNUM_LOCAL readImplementationRobustness(const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + static void MAGNUM_LOCAL readImplementationDefault(const Range2Di& rectangle, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + static void MAGNUM_LOCAL readImplementationRobustness(const Range2Di& rectangle, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); void MAGNUM_LOCAL invalidateImplementationNoOp(GLsizei, const GLenum*); void MAGNUM_LOCAL invalidateImplementationDefault(GLsizei count, const GLenum* attachments); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL invalidateImplementationDSA(GLsizei count, const GLenum* attachments); + #endif #ifndef MAGNUM_TARGET_GLES2 void MAGNUM_LOCAL invalidateImplementationNoOp(GLsizei, const GLenum*, const Range2Di&); void MAGNUM_LOCAL invalidateImplementationDefault(GLsizei count, const GLenum* attachments, const Range2Di& rectangle); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL invalidateImplementationDSA(GLsizei count, const GLenum* attachments, const Range2Di& rectangle); + #endif #endif }; diff --git a/src/Magnum/AbstractImage.cpp b/src/Magnum/AbstractImage.cpp index 5cb819a6d..c05c3f307 100644 --- a/src/Magnum/AbstractImage.cpp +++ b/src/Magnum/AbstractImage.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/AbstractImage.h b/src/Magnum/AbstractImage.h index 97e0e4492..a5180d8c4 100644 --- a/src/Magnum/AbstractImage.h +++ b/src/Magnum/AbstractImage.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/AbstractObject.cpp b/src/Magnum/AbstractObject.cpp index e59038394..5eed945c3 100644 --- a/src/Magnum/AbstractObject.cpp +++ b/src/Magnum/AbstractObject.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/AbstractObject.h b/src/Magnum/AbstractObject.h index 1c89397d1..74317b57e 100644 --- a/src/Magnum/AbstractObject.h +++ b/src/Magnum/AbstractObject.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -44,7 +44,7 @@ namespace Implementation { struct DebugState; } @brief Base for all OpenGL objects */ class MAGNUM_EXPORT AbstractObject { - friend struct Implementation::DebugState; + friend Implementation::DebugState; public: /** diff --git a/src/Magnum/AbstractQuery.cpp b/src/Magnum/AbstractQuery.cpp index 6221e3fad..b08dced32 100644 --- a/src/Magnum/AbstractQuery.cpp +++ b/src/Magnum/AbstractQuery.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/AbstractQuery.h b/src/Magnum/AbstractQuery.h index b7cff80c8..c00cac466 100644 --- a/src/Magnum/AbstractQuery.h +++ b/src/Magnum/AbstractQuery.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -47,7 +47,7 @@ more information. @todo `QUERY_COUNTER_BITS` (not sure since when this is supported) */ class MAGNUM_EXPORT AbstractQuery: public AbstractObject { - friend class Implementation::QueryState; + friend Implementation::QueryState; public: /** @brief Copying is not allowed */ @@ -66,7 +66,7 @@ class MAGNUM_EXPORT AbstractQuery: public AbstractObject { GLuint id() const { return _id; } /** - * @brief %Query label + * @brief Query label * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. If OpenGL 4.3 is not supported and neither @@ -95,7 +95,7 @@ class MAGNUM_EXPORT AbstractQuery: public AbstractObject { /** @overload */ template AbstractQuery& setLabel(const char(&label)[size]) { - return setLabelInternal(label); + return setLabelInternal({label, size - 1}); } /** @@ -115,10 +115,10 @@ class MAGNUM_EXPORT AbstractQuery: public AbstractObject { * @attention @ref Magnum::UnsignedLong "UnsignedLong" and @ref Magnum::Long "Long" * result type is not available in @ref MAGNUM_TARGET_WEBGL "WebGL". * @see @fn_gl{GetQueryObject} with @def_gl{QUERY_RESULT} - * @requires_gl33 %Extension @extension{ARB,timer_query} for result + * @requires_gl33 Extension @extension{ARB,timer_query} for result * type @ref Magnum::UnsignedInt "UnsignedInt" and @ref Magnum::Long * "Long" - * @requires_es_extension %Extension @es_extension{EXT,disjoint_timer_query} + * @requires_es_extension Extension @es_extension{EXT,disjoint_timer_query} * for result types @ref Magnum::Int "Int", @ref Magnum::UnsignedLong "UnsignedLong" * @ref Magnum::Long "Long". */ @@ -186,8 +186,9 @@ inline AbstractQuery::AbstractQuery(AbstractQuery&& other) noexcept: _id(other._ } inline AbstractQuery& AbstractQuery::operator=(AbstractQuery&& other) noexcept { - std::swap(_id, other._id); - std::swap(_target, other._target); + using std::swap; + swap(_id, other._id); + swap(_target, other._target); return *this; } diff --git a/src/Magnum/AbstractResourceLoader.h b/src/Magnum/AbstractResourceLoader.h index 190b1722b..c32ab37fa 100644 --- a/src/Magnum/AbstractResourceLoader.h +++ b/src/Magnum/AbstractResourceLoader.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -101,7 +101,7 @@ Resource myMesh = manager->get("my-mesh"); buffers), should that be allowed? */ template class AbstractResourceLoader { - friend class Implementation::ResourceManagerData; + friend Implementation::ResourceManagerData; public: explicit AbstractResourceLoader(): manager(nullptr), _requestedCount(0), _loadedCount(0), _notFoundCount(0) {} @@ -132,7 +132,7 @@ template class AbstractResourceLoader { std::size_t loadedCount() const { return _loadedCount; } /** - * @brief %Resource name corresponding to given key + * @brief Resource name corresponding to given key * * If no such resource exists or the resource name is not available, * returns empty string. diff --git a/src/Magnum/AbstractShaderProgram.cpp b/src/Magnum/AbstractShaderProgram.cpp index 9dee5629e..49671e309 100644 --- a/src/Magnum/AbstractShaderProgram.cpp +++ b/src/Magnum/AbstractShaderProgram.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -247,7 +247,8 @@ AbstractShaderProgram::~AbstractShaderProgram() { } AbstractShaderProgram& AbstractShaderProgram::operator=(AbstractShaderProgram&& other) noexcept { - std::swap(_id, other._id); + using std::swap; + swap(_id, other._id); return *this; } @@ -313,6 +314,17 @@ void AbstractShaderProgram::bindFragmentDataLocationIndexedInternal(const Unsign } #endif +#ifndef MAGNUM_TARGET_GLES2 +void AbstractShaderProgram::setTransformFeedbackOutputs(const std::initializer_list outputs, const TransformFeedbackBufferMode bufferMode) { + Containers::Array names{outputs.size()}; + + Int i = 0; + for(const std::string& output: outputs) names[i++] = output.data(); + + glTransformFeedbackVaryings(_id, outputs.size(), names, GLenum(bufferMode)); +} +#endif + bool AbstractShaderProgram::link(std::initializer_list> shaders) { bool allSuccess = true; @@ -1083,305 +1095,4 @@ void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, co } #endif -namespace Implementation { - -UnsignedInt FloatAttribute::size(GLint components, DataType dataType) { - switch(dataType) { - case DataType::UnsignedByte: - case DataType::Byte: - return components; - case DataType::UnsignedShort: - case DataType::Short: - case DataType::HalfFloat: - return 2*components; - case DataType::UnsignedInt: - case DataType::Int: - case DataType::Float: - return 4*components; - #ifndef MAGNUM_TARGET_GLES - case DataType::Double: - return 8*components; - #endif - } - - CORRADE_ASSERT_UNREACHABLE(); -} - -#ifndef MAGNUM_TARGET_GLES2 -UnsignedInt IntAttribute::size(GLint components, DataType dataType) { - switch(dataType) { - case DataType::UnsignedByte: - case DataType::Byte: - return components; - case DataType::UnsignedShort: - case DataType::Short: - return 2*components; - case DataType::UnsignedInt: - case DataType::Int: - return 4*components; - } - - CORRADE_ASSERT_UNREACHABLE(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES -UnsignedInt DoubleAttribute::size(GLint components, DataType dataType) { - switch(dataType) { - case DataType::Double: - return 8*components; - } - - CORRADE_ASSERT_UNREACHABLE(); -} -#endif - -UnsignedInt Attribute>::size(GLint components, DataType dataType) { - switch(dataType) { - case DataType::UnsignedByte: - case DataType::Byte: - return components; - case DataType::UnsignedShort: - case DataType::Short: - case DataType::HalfFloat: - return 2*components; - case DataType::UnsignedInt: - case DataType::Int: - case DataType::Float: - return 4*components; - #ifndef MAGNUM_TARGET_GLES - case DataType::Double: - return 8*components; - case DataType::UnsignedInt10f11f11fRev: - CORRADE_INTERNAL_ASSERT(components == 3); - return 4; - #endif - } - - CORRADE_ASSERT_UNREACHABLE(); -} - -UnsignedInt Attribute>::size(GLint components, DataType dataType) { - #ifndef MAGNUM_TARGET_GLES - if(components == GL_BGRA) components = 4; - #endif - - switch(dataType) { - case DataType::UnsignedByte: - case DataType::Byte: - return components; - case DataType::UnsignedShort: - case DataType::Short: - case DataType::HalfFloat: - return 2*components; - case DataType::UnsignedInt: - case DataType::Int: - case DataType::Float: - return 4*components; - #ifndef MAGNUM_TARGET_GLES - case DataType::Double: - return 8*components; - #endif - - #ifndef MAGNUM_TARGET_GLES2 - case DataType::UnsignedInt2101010Rev: - case DataType::Int2101010Rev: - CORRADE_INTERNAL_ASSERT(components == 4); - return 4; - #endif - } - - CORRADE_ASSERT_UNREACHABLE(); -} - -Debug operator<<(Debug debug, SizedAttribute<1, 1>::Components value) { - switch(value) { - case SizedAttribute<1, 1>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedAttribute<1, 2>::Components value) { - switch(value) { - case SizedAttribute<1, 2>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - case SizedAttribute<1, 2>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedAttribute<1, 3>::Components value) { - switch(value) { - case SizedAttribute<1, 3>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - case SizedAttribute<1, 3>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - case SizedAttribute<1, 3>::Components::Three: - return debug << "AbstractShaderProgram::Attribute::Components::Three"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedAttribute<1, 4>::Components value) { - switch(value) { - case SizedAttribute<1, 4>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - case SizedAttribute<1, 4>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - case SizedAttribute<1, 4>::Components::Three: - return debug << "AbstractShaderProgram::Attribute::Components::Three"; - case SizedAttribute<1, 4>::Components::Four: - return debug << "AbstractShaderProgram::Attribute::Components::Four"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedMatrixAttribute<2>::Components value) { - switch(value) { - case SizedMatrixAttribute<2>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedMatrixAttribute<3>::Components value) { - switch(value) { - case SizedMatrixAttribute<3>::Components::Three: - return debug << "AbstractShaderProgram::Attribute::Components::Three"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedMatrixAttribute<4>::Components value) { - switch(value) { - case SizedMatrixAttribute<4>::Components::Four: - return debug << "AbstractShaderProgram::Attribute::Components::Four"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, Attribute>::Components value) { - switch(value) { - case Attribute>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - case Attribute>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - case Attribute>::Components::Three: - return debug << "AbstractShaderProgram::Attribute::Components::Three"; - case Attribute>::Components::Four: - return debug << "AbstractShaderProgram::Attribute::Components::Four"; - #ifndef MAGNUM_TARGET_GLES - case Attribute>::Components::BGRA: - return debug << "AbstractShaderProgram::Attribute::Components::BGRA"; - #endif - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, FloatAttribute::DataType value) { - switch(value) { - #define _c(value) case FloatAttribute::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(UnsignedByte) - _c(Byte) - _c(UnsignedShort) - _c(Short) - _c(UnsignedInt) - _c(Int) - _c(HalfFloat) - _c(Float) - #ifndef MAGNUM_TARGET_GLES - _c(Double) - #endif - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} - -#ifndef MAGNUM_TARGET_GLES2 -Debug operator<<(Debug debug, IntAttribute::DataType value) { - switch(value) { - #define _c(value) case IntAttribute::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(UnsignedByte) - _c(Byte) - _c(UnsignedShort) - _c(Short) - _c(UnsignedInt) - _c(Int) - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} -#endif - -#ifndef MAGNUM_TARGET_GLES -Debug operator<<(Debug debug, DoubleAttribute::DataType value) { - switch(value) { - #define _c(value) case DoubleAttribute::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(Double) - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} -#endif - -Debug operator<<(Debug debug, Attribute>::DataType value) { - switch(value) { - #define _c(value) case Attribute>::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(UnsignedByte) - _c(Byte) - _c(UnsignedShort) - _c(Short) - _c(UnsignedInt) - _c(Int) - _c(HalfFloat) - _c(Float) - #ifndef MAGNUM_TARGET_GLES - _c(Double) - _c(UnsignedInt10f11f11fRev) - #endif - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} - -Debug operator<<(Debug debug, Attribute>::DataType value) { - switch(value) { - #define _c(value) case Attribute>::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(UnsignedByte) - _c(Byte) - _c(UnsignedShort) - _c(Short) - _c(UnsignedInt) - _c(Int) - _c(HalfFloat) - _c(Float) - #ifndef MAGNUM_TARGET_GLES - _c(Double) - #endif - #ifndef MAGNUM_TARGET_GLES2 - _c(UnsignedInt2101010Rev) - _c(Int2101010Rev) - #endif - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} - -} - } diff --git a/src/Magnum/AbstractShaderProgram.h b/src/Magnum/AbstractShaderProgram.h index 4b9d8f3db..4782e361c 100644 --- a/src/Magnum/AbstractShaderProgram.h +++ b/src/Magnum/AbstractShaderProgram.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,17 +32,13 @@ #include #include #include -#include #include "Magnum/AbstractObject.h" -#include "Magnum/Magnum.h" +#include "Magnum/Attribute.h" namespace Magnum { -namespace Implementation { - template struct Attribute; - struct ShaderProgramState; -} +namespace Implementation { struct ShaderProgramState; } /** @brief Base for shader program implementations @@ -52,7 +48,7 @@ namespace Implementation { This class is designed to be used via subclassing. Subclasses define these functions and properties: -- %Attribute definitions with location and type for +- **Attribute definitions** with location and type for configuring meshes, for example: @code typedef Attribute<0, Vector3> Position; @@ -103,7 +99,7 @@ MyShader& setNormalMatrix(const Matrix3x3& matrix) { return *this; } @endcode -- %Texture setting functions in which you bind the textures +- **Texture setting functions** in which you bind the textures to particular texture units using @ref Texture::bind() "*Texture::bind()" and equivalents, for example: @code @@ -116,6 +112,22 @@ MyShader& setSpecularTexture(Texture2D& texture) { return *this; } @endcode +- **Transform feedback setup function**, if needed, in which you bind buffers + to particular indices using @ref TransformFeedback::attachBuffer() and + similar, possibly with overloads based on desired use cases, e.g.: +@code +MyShader& setTransformFeedback(TransformFeedback& feedback, Buffer& positions, Buffer& data) { + feedback.attachBuffers(0, {positions, data}); + return *this; +} +MyShader& setTransformFeedback(TransformFeedback& feedback, Int totalCount, Buffer& positions, GLintptr positionsOffset, Buffer& data, GLintptr dataOffset) { + feedback.attachBuffers(0, { + std::make_tuple(positions, positionsOffset, totalCount*sizeof(Vector3)), + std::make_tuple(data, dataOffset, totalCount*sizeof(Vector2ui)) + }); + return *this; +} +@endcode @anchor AbstractShaderProgram-attribute-location ### Binding attribute location @@ -167,11 +179,11 @@ bindFragmentDataLocationIndexed(NormalOutput, 1, "normal"); @endcode @see @ref Mesh::maxVertexAttributes(), @ref AbstractFramebuffer::maxDrawBuffers() -@requires_gl30 %Extension @extension{EXT,gpu_shader4} for using +@requires_gl30 Extension @extension{EXT,gpu_shader4} for using @ref Magnum::AbstractShaderProgram::bindFragmentDataLocation() "bindFragmentDataLocation()". -@requires_gl33 %Extension @extension{ARB,blend_func_extended} for using +@requires_gl33 Extension @extension{ARB,blend_func_extended} for using @ref Magnum::AbstractShaderProgram::bindFragmentDataLocationIndexed() "bindFragmentDataLocationIndexed()". -@requires_gl33 %Extension @extension{ARB,explicit_attrib_location} for +@requires_gl33 Extension @extension{ARB,explicit_attrib_location} for explicit attribute location instead of using @ref Magnum::AbstractShaderProgram::bindAttributeLocation() "bindAttributeLocation()", @ref Magnum::AbstractShaderProgram::bindFragmentDataLocation() "bindFragmentDataLocation()" @@ -215,7 +227,7 @@ Int normalMatrixUniform = uniformLocation("normalMatrix"); @endcode @see @ref maxUniformLocations() -@requires_gl43 %Extension @extension{ARB,explicit_uniform_location} for +@requires_gl43 Extension @extension{ARB,explicit_uniform_location} for explicit uniform location instead of using @ref Magnum::AbstractShaderProgram::uniformLocation() "uniformLocation()". @requires_gles31 Explicit uniform location is not supported in OpenGL ES 3.0 @@ -248,17 +260,64 @@ setUniform(uniformLocation("specularTexture"), 1); @endcode @see @ref Shader::maxTextureImageUnits() -@requires_gl42 %Extension @extension{ARB,shading_language_420pack} for explicit +@requires_gl42 Extension @extension{ARB,shading_language_420pack} for explicit texture binding unit instead of using @ref Magnum::AbstractShaderProgram::setUniform(Int, const T&) "setUniform(Int, Int)". @requires_gles31 Explicit texture binding unit is not supported in OpenGL ES 3.0 and older. Use @ref Magnum::AbstractShaderProgram::setUniform(Int, const T&) "setUniform(Int, Int)" instead. +@anchor AbstractShaderProgram-transform-feedback +### Specifying transform feedback binding points + +The preferred workflow is to specify output binding points directly in the +shader code, e.g.: +@code +// GLSL 4.40, or +#extension GL_ARB_enhanced_layouts: enable +layout(xfb_buffer = 0, xfb_stride = 32) out block { + layout(xfb_offset = 0) vec3 position; + layout(xfb_offset = 16) vec3 normal; +}; +layout(xfb_buffer = 1) out vec3 velocity; +@endcode + +If you don't have the required extension, declare the uniforms without the +`xfb_*` qualifier and set the binding points using @ref setTransformFeedbackOutputs(). +Equivalent setup for the previous code would be the following: +@code +out block { + vec3 position; + vec3 normal; +}; +out vec3 velocity; +@endcode +@code +setTransformFeedbackOutputs({ + // Buffer 0 + "position", "gl_SkipComponents1", "normal", "gl_SkipComponents1", + // Buffer 1 + "gl_NextBuffer", "velocity" + }, TransformFeedbackBufferMode::InterleavedAttributes); +@endcode + +@see @ref TransformFeedback::maxInterleavedComponents(), + @ref TransformFeedback::maxSeparateAttributes(), + @ref TransformFeedback::maxSeparateComponents() +@requires_gl40 Extension @extension{ARB,transform_feedback3} for using + `gl_NextBuffer` or `gl_SkipComponents#` names in + @ref Magnum::AbstractShaderProgram::setTransformFeedbackOutputs() "setTransformFeedbackOutputs()" + function +@requires_gl44 Extension @extension{ARB,enhanced_layouts} for explicit + transform feedback output specification instead of using + @ref Magnum::AbstractShaderProgram::setTransformFeedbackOutputs() "setTransformFeedbackOutputs()" +@requires_gl Explicit transform feedback output specification is not available + in OpenGL ES. + @anchor AbstractShaderProgram-rendering-workflow ## Rendering workflow -Basic workflow with %AbstractShaderProgram subclasses is: instance shader +Basic workflow with AbstractShaderProgram subclasses is: instance shader class, configure attribute binding in meshes (see @ref Mesh-configuration "Mesh documentation" for more information) and map shader outputs to framebuffer attachments if needed (see @ref Framebuffer-usage "Framebuffer documentation" for more @@ -274,13 +333,13 @@ mesh.draw(shader); @endcode @anchor AbstractShaderProgram-types -## Mapping between GLSL and %Magnum types +## Mapping between GLSL and Magnum types See @ref types for more information, only types with GLSL equivalent can be used (and their super- or subclasses with the same size and underlying type). See also @ref Attribute::DataType enum for additional type options. -@requires_gl30 %Extension @extension{EXT,gpu_shader4} is required when using +@requires_gl30 Extension @extension{EXT,gpu_shader4} is required when using integer attributes (i.e. @ref Magnum::UnsignedInt "UnsignedInt", @ref Magnum::Int "Int", @ref Magnum::Vector2ui "Vector2ui", @ref Magnum::Vector2i "Vector2i", @ref Magnum::Vector3ui "Vector3ui", @@ -288,7 +347,7 @@ also @ref Attribute::DataType enum for additional type options. @ref Magnum::Vector4i "Vector4i") or unsigned integer uniforms (i.e. @ref Magnum::UnsignedInt "UnsignedInt", @ref Magnum::Vector2ui "Vector2ui", @ref Magnum::Vector3ui "Vector3ui" and @ref Magnum::Vector4ui "Vector4ui"). -@requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} is required when +@requires_gl40 Extension @extension{ARB,gpu_shader_fp64} is required when using double uniforms (i.e. @ref Magnum::Double "Double", @ref Magnum::Vector2d "Vector2d", @ref Magnum::Vector3d "Vector3d", @ref Magnum::Vector4d "Vector4d", @ref Magnum::Matrix2x2d "Matrix2x2d", @@ -296,7 +355,7 @@ also @ref Attribute::DataType enum for additional type options. @ref Magnum::Matrix2x3d "Matrix2x3d", @ref Magnum::Matrix3x2d "Matrix3x2d", @ref Magnum::Matrix2x4d "Matrix2x4d", @ref Magnum::Matrix4x2d "Matrix4x2d", @ref Magnum::Matrix3x4d "Matrix3x4d" and @ref Magnum::Matrix4x3d "Matrix4x3d"). -@requires_gl41 %Extension @extension{ARB,vertex_attrib_64bit} is required when +@requires_gl41 Extension @extension{ARB,vertex_attrib_64bit} is required when using double attributes (i.e. @ref Magnum::Double "Double", @ref Magnum::Vector2d "Vector2d", @ref Magnum::Vector3d "Vector3d", @ref Magnum::Vector4d "Vector4d", @ref Magnum::Matrix2x2d "Matrix2x2d", @@ -315,7 +374,7 @@ also @ref Attribute::DataType enum for additional type options. @anchor AbstractShaderProgram-performance-optimization ## Performance optimizations -%Shader limits (such as @ref maxVertexAttributes()) are cached, so repeated +Shader limits (such as @ref maxVertexAttributes()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. If extension @extension{ARB,separate_shader_objects} (part of OpenGL 4.1), @@ -333,12 +392,29 @@ comes in handy. @todo `GL_NUM_{PROGRAM,SHADER}_BINARY_FORMATS` + `GL_{PROGRAM,SHADER}_BINARY_FORMATS` (vector), (@extension{ARB,ES2_compatibility}) */ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { - friend class Mesh; - friend class MeshView; - friend struct Implementation::ShaderProgramState; + friend Mesh; + friend MeshView; + friend TransformFeedback; + friend Implementation::ShaderProgramState; public: - template class Attribute; + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Buffer mode for transform feedback + * + * @see @ref setTransformFeedbackOutputs() + * @requires_gl30 Extension @extension{EXT,transform_feedback} + * @requires_gles30 Transform feedback is not available in OpenGL ES + * 2.0 + */ + enum class TransformFeedbackBufferMode: GLenum { + /** Attributes will be interleaved at one buffer binding point */ + InterleavedAttributes = GL_INTERLEAVED_ATTRIBS, + + /** Each attribute will be put into separate buffer binding point */ + SeparateAttributes = GL_SEPARATE_ATTRIBS + }; + #endif /** * @brief Max supported vertex attribute count @@ -346,8 +422,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * The result is cached, repeated queries don't result in repeated * OpenGL calls. * @see @ref Mesh::maxVertexAttributes(), - * @ref AbstractShaderProgram::Attribute, @fn_gl{Get} with - * @def_gl{MAX_VERTEX_ATTRIBS} + * @ref Attribute, @fn_gl{Get} with @def_gl{MAX_VERTEX_ATTRIBS} */ static Int maxVertexAttributes(); @@ -466,7 +541,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * OpenGL calls. If extension @extension{EXT,gpu_shader4} (part of * OpenGL 3.0) is not available, returns `0`. * @see @fn_gl{Get} with @def_gl{MIN_PROGRAM_TEXEL_OFFSET} - * @requires_gles30 %Texture lookup with offset is not available in + * @requires_gles30 Texture lookup with offset is not available in * OpenGL ES 2.0 */ static Int minTexelOffset(); @@ -478,7 +553,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * OpenGL calls. If extension @extension{EXT,gpu_shader4} (part of * OpenGL 3.0) is not available, returns `0`. * @see @fn_gl{Get} with @def_gl{MAX_PROGRAM_TEXEL_OFFSET} - * @requires_gles30 %Texture lookup with offset is not available in + * @requires_gles30 Texture lookup with offset is not available in * OpenGL ES 2.0 */ static Int maxTexelOffset(); @@ -516,7 +591,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { GLuint id() const { return _id; } /** - * @brief %Shader program label + * @brief Shader program label * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. If OpenGL 4.3 is not supported and neither @@ -545,7 +620,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { /** @overload */ template AbstractShaderProgram& setLabel(const char (&label)[size]) { - return setLabelInternal(label); + return setLabelInternal({label, size - 1}); } /** @@ -588,7 +663,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * * Initially disabled. * @see @fn_gl{ProgramParameter} with @def_gl{PROGRAM_BINARY_RETRIEVABLE_HINT} - * @requires_gl41 %Extension @extension{ARB,get_program_binary} + * @requires_gl41 Extension @extension{ARB,get_program_binary} * @requires_gles30 Always allowed in OpenGL ES 2.0. */ void setRetrievableBinary(bool enabled) { @@ -601,8 +676,8 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * * Initially disabled. * @see @fn_gl{ProgramParameter} with @def_gl{PROGRAM_SEPARABLE} - * @requires_gl41 %Extension @extension{ARB,separate_shader_objects} - * @requires_es_extension %Extension @es_extension{EXT,separate_shader_objects} + * @requires_gl41 Extension @extension{ARB,separate_shader_objects} + * @requires_es_extension Extension @es_extension{EXT,separate_shader_objects} */ void setSeparable(bool enabled) { /** @todo Remove when extension wrangler is available for ES */ @@ -632,7 +707,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { /** * @brief Bind attribute to given location * @param location Location - * @param name %Attribute name + * @param name Attribute name * * Binds attribute to location which is used later for binding vertex * buffers. @@ -648,7 +723,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { /** @overload */ template void bindAttributeLocation(UnsignedInt location, const char(&name)[size]) { - bindAttributeLocationInternal(location, name); + bindAttributeLocationInternal(location, {name, size - 1}); } #ifndef MAGNUM_TARGET_GLES @@ -666,7 +741,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * explicitly in the shader instead of using this function. See * @ref AbstractShaderProgram-attribute-location "class documentation" * for more information. - * @requires_gl33 %Extension @extension{ARB,blend_func_extended} + * @requires_gl33 Extension @extension{ARB,blend_func_extended} * @requires_gl Multiple blend function inputs are not available in * OpenGL ES. */ @@ -676,7 +751,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { /** @overload */ template void bindFragmentDataLocationIndexed(UnsignedInt location, UnsignedInt index, const char(&name)[size]) { - bindFragmentDataLocationIndexedInternal(location, index, name); + bindFragmentDataLocationIndexedInternal(location, index, {name, size - 1}); } /** @@ -691,7 +766,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * explicitly in the shader instead of using this function. See * @ref AbstractShaderProgram-attribute-location "class documentation" * for more information. - * @requires_gl30 %Extension @extension{EXT,gpu_shader4} + * @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gl Use explicit location specification in OpenGL ES 3.0 * and `gl_FragData[n]` provided by @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} * in OpenGL ES 2.0. @@ -703,10 +778,43 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { /** @overload */ template void bindFragmentDataLocation(UnsignedInt location, const char(&name)[size]) { /* Not using const char* parameter, because this way it avoids most accidents with non-zero-terminated strings */ - bindFragmentDataLocationInternal(location, name); + bindFragmentDataLocationInternal(location, {name, size - 1}); } #endif + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Specify shader outputs to be recorded in transform feedback + * @param outputs Names of output variables + * @param bufferMode Buffer mode + * + * Binds given output variables from vertex, geometry or tessellation + * shader to transform feedback buffer binding points. If + * @ref TransformFeedbackBufferMode::SeparateAttributes is used, each + * output is bound to separate binding point. If + * @ref TransformFeedbackBufferMode::InterleavedAttributes is used, the + * outputs are interleaved into single buffer binding point. In this + * case, special output name `gl_NextBuffer` causes the following + * output to be recorded into next buffer binding point and + * `gl_SkipComponents#` causes the transform feedback to offset the + * following output variable by `#` components. + * @see @fn_gl{TransformFeedbackVaryings} + * @deprecated_gl Preferred usage is to specify transform feedback + * outputs explicitly in the shader instead of using this + * function. See @ref AbstractShaderProgram-transform-feedback "class documentation" + * for more information. + * @requires_gl30 Extension @extension{EXT,transform_feedback} + * @requires_gl40 Extension @extension{ARB,transform_feedback3} for + * using `gl_NextBuffer` or `gl_SkipComponents#` names in + * @p outputs array + * @requires_gles30 Transform feedback is not available in OpenGL ES + * 2.0 + * @requires_gl Special output names `gl_NextBuffer` and + * `gl_SkipComponents#` are not available in OpenGL ES + */ + void setTransformFeedbackOutputs(std::initializer_list outputs, TransformFeedbackBufferMode bufferMode); + #endif + /** * @brief Link the shader * @@ -736,7 +844,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { /** @overload */ template Int uniformLocation(const char(&name)[size]) { - return uniformLocationInternal(name); + return uniformLocationInternal({name, size - 1}); } /** @@ -803,7 +911,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { #ifndef MAGNUM_TARGET_GLES2 /** * @copydoc setUniform(Int, UnsignedInt, const Float*) - * @requires_gl30 %Extension @extension{EXT,gpu_shader4} + * @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ void setUniform(Int location, UnsignedInt count, const UnsignedInt* values); @@ -815,7 +923,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { #ifndef MAGNUM_TARGET_GLES /** * @copydoc setUniform(Int, UnsignedInt, const Float*) - * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ void setUniform(Int location, UnsignedInt count, const Double* values); @@ -845,7 +953,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { #ifndef MAGNUM_TARGET_GLES /** * @copydoc setUniform(Int, UnsignedInt, const Float*) - * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Double>* values); @@ -1022,612 +1130,6 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { GLuint _id; }; -/** -@brief Base struct for attribute location and type - -Template parameter @p location is vertex attribute location, number between `0` -and @ref maxVertexAttributes(). To ensure compatibility, you should always have -vertex attribute with location `0`. - -Template parameter @p T is the type which is used for shader attribute, e.g. -@ref Vector4i for `ivec4`. DataType is type of passed data when adding vertex -buffers to mesh. By default it is the same as type used in shader (e.g. -@ref DataType::Int for @ref Vector4i). It's also possible to pass integer data -to floating-point shader inputs. In this case you may want to normalize the -values (e.g. color components from 0-255 to 0.0f - 1.0f) -- see @ref DataOption::Normalized. - -Only some types are allowed as attribute types, see @ref AbstractShaderProgram-types -for more information. - -See @ref AbstractShaderProgram-subclassing for example usage in shaders and -@ref Mesh-configuration for example usage when adding vertex buffers to mesh. -*/ -template class AbstractShaderProgram::Attribute { - public: - enum: UnsignedInt { - Location = location, /**< Location to which the attribute is bound */ - - /** - * Count of vectors in this type - * - * @see @ref vectorSize() - */ - VectorCount = Implementation::Attribute::VectorCount - }; - - /** - * @brief Type - * - * Type used in shader code. - * @see @ref ScalarType, @ref DataType - */ - typedef T Type; - - /** - * @brief Scalar type - * - * The underlying scalar type of the attribute. - * @see @ref Type, @ref DataType - */ - typedef typename Implementation::Attribute::ScalarType ScalarType; - - /** - * @brief Component count - * - * Count of components passed to the shader. If passing smaller count - * of components than corresponding type has, unspecified components - * are set to default values (second and third to `0`, fourth to `1`). - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - enum class Components: GLint { - /** - * Only first component is specified. Second, third and fourth - * component are set to `0`, `0`, `1`, respectively. Only for - * scalar and vector types, not matrices. - */ - One = 1, - - /** - * First two components are specified. Third and fourth component - * are set to `0`, `1`, respectively. Only for two, three and - * four-component vector types and 2x2, 3x2 and 4x2 matrix types. - */ - Two = 2, - - /** - * First three components are specified. Fourth component is set to - * `1`. Only for three and four-component vector types, 2x3, 3x3 - * and 4x3 matrix types. - */ - Three = 3, - - /** - * All four components are specified. Only for four-component - * vector types and 2x4, 3x4 and 4x4 matrix types. - */ - Four = 4, - - #ifndef MAGNUM_TARGET_GLES - /** - * Four components with BGRA ordering. Only for four-component - * float vector type. Must be used along with @ref DataType::UnsignedByte - * and @ref DataOption::Normalized. - * @requires_gl32 %Extension @extension{ARB,vertex_array_bgra} - * @requires_gl Only RGBA component ordering is supported in OpenGL - * ES. - */ - BGRA = GL_BGRA - #endif - }; - #else - typedef typename Implementation::Attribute::Components Components; - #endif - - /** - * @brief Data type - * - * Type of data passed to shader. - * @see @ref Type, @ref DataOptions, @ref Attribute() - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */ - Byte = GL_BYTE, /**< Byte */ - UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */ - Short = GL_SHORT, /**< Short */ - UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */ - Int = GL_INT, /**< Int */ - - /** - * Half float. Only for float attribute types. - * @requires_gl30 %Extension @extension{ARB,half_float_vertex} - * @requires_gles30 %Extension @es_extension{OES,vertex_half_float} - * in OpenGL ES 2.0 - */ - HalfFloat = GL_HALF_FLOAT, - - /** Float. Only for float attribute types. */ - Float = GL_FLOAT, - - #ifndef MAGNUM_TARGET_GLES - /** - * Double. Only for float and double attribute types. - * @requires_gl Only floats are available in OpenGL ES. - */ - Double = GL_DOUBLE, - - /** - * Unsigned 10.11.11 packed float. Only for three-component float - * vector attribute type. - * @requires_gl44 %Extension @extension{ARB,vertex_type_10f_11f_11f_rev} - * @requires_gl Packed float attributes are not available in OpenGL - * ES. - */ - UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV, - #endif - - /* GL_FIXED not supported */ - - #ifndef MAGNUM_TARGET_GLES2 - /** - * Unsigned 2.10.10.10 packed integer. Only for four-component - * float vector attribute type. - * @todo How about (incompatible) @es_extension{OES,vertex_type_10_10_10_2}? - * @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev} - * @requires_gles30 Packed attributes are not available in OpenGL - * ES 2.0 - */ - UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV, - - /** - * Signed 2.10.10.10 packed integer. Only for four-component float - * vector attribute type. - * @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev} - * @requires_gles30 Packed attributes are not available in OpenGL - * ES 2.0 - */ - Int2101010Rev = GL_INT_2_10_10_10_REV - #endif - }; - #else - typedef typename Implementation::Attribute::DataType DataType; - #endif - - /** - * @brief Data option - * @see @ref DataOptions, @ref Attribute() - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - enum class DataOption: UnsignedByte { - /** - * Normalize integer components. Only for float attribute types. - * Default is to not normalize. - */ - Normalized = 1 << 0 - }; - #else - typedef typename Implementation::Attribute::DataOption DataOption; - #endif - - /** - * @brief Data options - * @see @ref Attribute() - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - typedef typename Containers::EnumSet DataOptions; - #else - typedef typename Implementation::Attribute::DataOptions DataOptions; - #endif - - /** - * @brief Constructor - * @param components Component count - * @param dataType Type of passed data. Default is the same as - * type used in shader (e.g. @ref DataType::Int for @ref Vector4i). - * @param dataOptions Data options. Default is no options. - */ - constexpr Attribute(Components components, DataType dataType = Implementation::Attribute::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(components), _dataType(dataType), _dataOptions(dataOptions) {} - - /** - * @brief Constructor - * @param dataType Type of passed data. Default is the same as - * type used in shader (e.g. @ref DataType::Int for @ref Vector4i). - * @param dataOptions Data options. Default is no options. - * - * Component count is set to the same value as in type used in shader - * (e.g. @ref Components::Three for @ref Vector3). - */ - constexpr Attribute(DataType dataType = Implementation::Attribute::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(Implementation::Attribute::DefaultComponents), _dataType(dataType), _dataOptions(dataOptions) {} - - /** @brief Component count of passed data */ - constexpr Components components() const { return _components; } - - /** @brief Type of passed data */ - constexpr DataType dataType() const { return _dataType; } - - /** - * @brief Size of each vector in passed data - * - * @see @ref VectorCount - */ - UnsignedInt vectorSize() const { - return Implementation::Attribute::size(GLint(_components), _dataType); - } - - /** @brief Data options */ - constexpr DataOptions dataOptions() const { return _dataOptions; } - - private: - Components _components; - DataType _dataType; - DataOptions _dataOptions; -}; - -#ifdef DOXYGEN_GENERATING_OUTPUT -/** @debugoperatorclassenum{Magnum::AbstractShaderProgram::Attribute,Magnum::AbstractShaderProgram::Attribute::Components} */ -template Debug operator<<(Debug debug, AbstractShaderProgram::Attribute::Components); - -/** @debugoperatorclassenum{Magnum::AbstractShaderProgram::Attribute,Magnum::AbstractShaderProgram::Attribute::DataType} */ -template Debug operator<<(Debug debug, AbstractShaderProgram::Attribute::DataType); -#endif - -namespace Implementation { - -/* Base for sized attributes */ -template struct SizedAttribute; - -/* Vector attribute sizes */ -template struct SizedVectorAttribute { - enum: UnsignedInt { VectorCount = UnsignedInt(cols) }; -}; -template<> struct SizedAttribute<1, 1>: SizedVectorAttribute<1> { - enum class Components: GLint { One = 1 }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - Components DefaultComponents = Components::One; -}; -template<> struct SizedAttribute<1, 2>: SizedVectorAttribute<1> { - enum class Components: GLint { One = 1, Two = 2 }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - Components DefaultComponents = Components::Two; -}; -template<> struct SizedAttribute<1, 3>: SizedVectorAttribute<1> { - enum class Components: GLint { One = 1, Two = 2, Three = 3 }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - Components DefaultComponents = Components::Three; -}; -template<> struct SizedAttribute<1, 4>: SizedVectorAttribute<1> { - enum class Components: GLint { One = 1, Two = 2, Three = 3, Four = 4 }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - Components DefaultComponents = Components::Four; -}; -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 1>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 2>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 3>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 4>::Components value); - -/* Matrix attribute sizes */ -template struct SizedMatrixAttribute; -template<> struct SizedMatrixAttribute<2> { - enum class Components: GLint { Two = 2 }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - Components DefaultComponents = Components::Two; -}; -template<> struct SizedMatrixAttribute<3> { - enum class Components: GLint { Three = 3 }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - Components DefaultComponents = Components::Three; -}; -template<> struct SizedMatrixAttribute<4> { - enum class Components: GLint { Four = 4 }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - Components DefaultComponents = Components::Four; -}; -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<2>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<3>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<4>::Components value); -template<> struct SizedAttribute<2, 2>: SizedVectorAttribute<2>, SizedMatrixAttribute<2> {}; -template<> struct SizedAttribute<3, 3>: SizedVectorAttribute<3>, SizedMatrixAttribute<3> {}; -template<> struct SizedAttribute<4, 4>: SizedVectorAttribute<4>, SizedMatrixAttribute<4> {}; -#ifndef MAGNUM_TARGET_GLES2 -template<> struct SizedAttribute<2, 3>: SizedVectorAttribute<2>, SizedMatrixAttribute<3> {}; -template<> struct SizedAttribute<3, 2>: SizedVectorAttribute<3>, SizedMatrixAttribute<2> {}; -template<> struct SizedAttribute<2, 4>: SizedVectorAttribute<2>, SizedMatrixAttribute<4> {}; -template<> struct SizedAttribute<4, 2>: SizedVectorAttribute<4>, SizedMatrixAttribute<2> {}; -template<> struct SizedAttribute<3, 4>: SizedVectorAttribute<3>, SizedMatrixAttribute<4> {}; -template<> struct SizedAttribute<4, 3>: SizedVectorAttribute<4>, SizedMatrixAttribute<3> {}; -#endif - -/* Base for attributes */ -template struct Attribute; - -/* Base for float attributes */ -struct FloatAttribute { - typedef Float ScalarType; - - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, - Byte = GL_BYTE, - UnsignedShort = GL_UNSIGNED_SHORT, - Short = GL_SHORT, - UnsignedInt = GL_UNSIGNED_INT, - Int = GL_INT, - #ifndef MAGNUM_TARGET_GLES2 - HalfFloat = GL_HALF_FLOAT, - #else - HalfFloat = GL_HALF_FLOAT_OES, - #endif - Float = GL_FLOAT - - #ifndef MAGNUM_TARGET_GLES - , - Double = GL_DOUBLE - #endif - }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - DataType DefaultDataType = DataType::Float; - - enum class DataOption: UnsignedByte { - Normalized = 1 << 0 - }; - typedef Containers::EnumSet DataOptions; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -CORRADE_ENUMSET_OPERATORS(FloatAttribute::DataOptions) - -Debug MAGNUM_EXPORT operator<<(Debug debug, FloatAttribute::DataType value); - -#ifndef MAGNUM_TARGET_GLES2 -/* Base for int attributes */ -struct IntAttribute { - typedef Int ScalarType; - - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, - Byte = GL_BYTE, - UnsignedShort = GL_UNSIGNED_SHORT, - Short = GL_SHORT, - UnsignedInt = GL_UNSIGNED_INT, - Int = GL_INT - }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - DataType DefaultDataType = DataType::Int; - - enum class DataOption: UnsignedByte {}; - typedef Containers::EnumSet DataOptions; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -CORRADE_ENUMSET_OPERATORS(IntAttribute::DataOptions) - -Debug MAGNUM_EXPORT operator<<(Debug debug, IntAttribute::DataType value); - -/* Base for unsigned int attributes */ -struct UnsignedIntAttribute { - typedef UnsignedInt ScalarType; - - typedef IntAttribute::DataType DataType; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - DataType DefaultDataType = DataType::UnsignedInt; - - typedef IntAttribute::DataOption DataOption; - typedef IntAttribute::DataOptions DataOptions; - - static UnsignedInt size(GLint components, DataType dataType) { - return IntAttribute::size(components, dataType); - } -}; -#endif - -#ifndef MAGNUM_TARGET_GLES -/* Base for double attributes */ -struct DoubleAttribute { - typedef Double ScalarType; - - enum class DataType: GLenum { - Double = GL_DOUBLE - }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - DataType DefaultDataType = DataType::Double; - - typedef IntAttribute::DataOption DataOption; - typedef IntAttribute::DataOptions DataOptions; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -Debug MAGNUM_EXPORT operator<<(Debug debug, DoubleAttribute::DataType value); -#endif - -/* Floating-point three-component vector has additional data type compared to - classic floats */ -template<> struct Attribute>: SizedAttribute<1, 3> { - typedef Float ScalarType; - - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, - Byte = GL_BYTE, - UnsignedShort = GL_UNSIGNED_SHORT, - Short = GL_SHORT, - UnsignedInt = GL_UNSIGNED_INT, - Int = GL_INT, - #ifndef MAGNUM_TARGET_GLES2 - HalfFloat = GL_HALF_FLOAT, - #else - HalfFloat = GL_HALF_FLOAT_OES, - #endif - Float = GL_FLOAT - - #ifndef MAGNUM_TARGET_GLES - , - Double = GL_DOUBLE, - UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV - #endif - }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - DataType DefaultDataType = DataType::Float; - - typedef FloatAttribute::DataOption DataOption; - typedef FloatAttribute::DataOptions DataOptions; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::DataType value); - -/* Floating-point four-component vector is absolutely special case */ -template<> struct Attribute> { - typedef Float ScalarType; - - enum class Components: GLint { - One = 1, - Two = 2, - Three = 3, - Four = 4 - #ifndef MAGNUM_TARGET_GLES - , - BGRA = GL_BGRA - #endif - }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - Components DefaultComponents = Components::Four; - - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, - Byte = GL_BYTE, - UnsignedShort = GL_UNSIGNED_SHORT, - Short = GL_SHORT, - UnsignedInt = GL_UNSIGNED_INT, - Int = GL_INT, - #ifndef MAGNUM_TARGET_GLES2 - HalfFloat = GL_HALF_FLOAT, - #else - HalfFloat = GL_HALF_FLOAT_OES, - #endif - Float = GL_FLOAT - #ifndef MAGNUM_TARGET_GLES - , - Double = GL_DOUBLE - #endif - #ifndef MAGNUM_TARGET_GLES2 - , - UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV, - Int2101010Rev = GL_INT_2_10_10_10_REV - #endif - }; - #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) - constexpr static - #else - static const - #endif - DataType DefaultDataType = DataType::Float; - - typedef FloatAttribute::DataOption DataOption; - typedef FloatAttribute::DataOptions DataOptions; - - enum: UnsignedInt { VectorCount = 1 }; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::DataType value); - -/* Common float, int, unsigned int and double scalar attributes */ -template<> struct Attribute: FloatAttribute, SizedAttribute<1, 1> {}; -#ifndef MAGNUM_TARGET_GLES2 -template<> struct Attribute: IntAttribute, SizedAttribute<1, 1> {}; -template<> struct Attribute: UnsignedIntAttribute, SizedAttribute<1, 1> {}; -#ifndef MAGNUM_TARGET_GLES -template<> struct Attribute: DoubleAttribute, SizedAttribute<1, 1> {}; -#endif -#endif - -/* Common float, int, unsigned int and double vector attributes */ -template struct Attribute>: FloatAttribute, SizedAttribute<1, size_> {}; -#ifndef MAGNUM_TARGET_GLES2 -template struct Attribute>: IntAttribute, SizedAttribute<1, size_> {}; -template struct Attribute>: UnsignedIntAttribute, SizedAttribute<1, size_> {}; -#ifndef MAGNUM_TARGET_GLES -template struct Attribute>: DoubleAttribute, SizedAttribute<1, size_> {}; -#endif -#endif -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; - -/* Common float and double rectangular matrix attributes */ -template struct Attribute>: FloatAttribute, SizedAttribute {}; -#ifndef MAGNUM_TARGET_GLES -template struct Attribute>: DoubleAttribute, SizedAttribute {}; -#endif - -/* Common float and double square matrix attributes */ -template struct Attribute>: Attribute> {}; -#ifndef MAGNUM_TARGET_GLES -template struct Attribute>: Attribute> {}; -#endif -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; - -} - } #endif diff --git a/src/Magnum/AbstractTexture.cpp b/src/Magnum/AbstractTexture.cpp index 540e2cb1c..50e0671a1 100644 --- a/src/Magnum/AbstractTexture.cpp +++ b/src/Magnum/AbstractTexture.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -35,6 +35,7 @@ #include "Magnum/Extensions.h" #include "Magnum/Image.h" #include "Magnum/TextureFormat.h" +#include "Magnum/Math/Range.h" #ifdef MAGNUM_BUILD_DEPRECATED #include "Magnum/Shader.h" @@ -116,25 +117,25 @@ Int AbstractTexture::maxIntegerSamples() { #endif void AbstractTexture::unbind(const Int textureUnit) { - Implementation::TextureState* const textureState = Context::current()->state().texture; + Implementation::TextureState& textureState = *Context::current()->state().texture; /* If given texture unit is already unbound, nothing to do */ - if(textureState->bindings[textureUnit].second == 0) return; + if(textureState.bindings[textureUnit].second == 0) return; /* Unbind the texture, reset state tracker */ Context::current()->state().texture->unbindImplementation(textureUnit); - textureState->bindings[textureUnit] = {}; + textureState.bindings[textureUnit] = {}; } void AbstractTexture::unbindImplementationDefault(const GLint textureUnit) { - Implementation::TextureState* const textureState = Context::current()->state().texture; + Implementation::TextureState& textureState = *Context::current()->state().texture; /* Activate given texture unit if not already active, update state tracker */ - if(textureState->currentTextureUnit != textureUnit) - glActiveTexture(GL_TEXTURE0 + (textureState->currentTextureUnit = textureUnit)); + if(textureState.currentTextureUnit != textureUnit) + glActiveTexture(GL_TEXTURE0 + (textureState.currentTextureUnit = textureUnit)); - CORRADE_INTERNAL_ASSERT(textureState->bindings[textureUnit].first != 0); - glBindTexture(textureState->bindings[textureUnit].first, 0); + CORRADE_INTERNAL_ASSERT(textureState.bindings[textureUnit].first != 0); + glBindTexture(textureState.bindings[textureUnit].first, 0); } #ifndef MAGNUM_TARGET_GLES @@ -143,11 +144,18 @@ void AbstractTexture::unbindImplementationMulti(const GLint textureUnit) { glBindTextures(textureUnit, 1, &zero); } +void AbstractTexture::unbindImplementationDSA(const GLint textureUnit) { + Implementation::TextureState& textureState = *Context::current()->state().texture; + + CORRADE_INTERNAL_ASSERT(textureState.bindings[textureUnit].first != 0); + glBindTextureUnit(textureUnit, 0); +} + void AbstractTexture::unbindImplementationDSAEXT(const GLint textureUnit) { - Implementation::TextureState* const textureState = Context::current()->state().texture; + Implementation::TextureState& textureState = *Context::current()->state().texture; - CORRADE_INTERNAL_ASSERT(textureState->bindings[textureUnit].first != 0); - glBindMultiTextureEXT(GL_TEXTURE0 + textureUnit, textureState->bindings[textureUnit].first, 0); + CORRADE_INTERNAL_ASSERT(textureState.bindings[textureUnit].first != 0); + glBindMultiTextureEXT(GL_TEXTURE0 + textureUnit, textureState.bindings[textureUnit].first, 0); } #endif @@ -168,8 +176,9 @@ void AbstractTexture::bindImplementationFallback(const GLint firstTextureUnit, c } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, const Containers::ArrayReference textures) { - Implementation::TextureState* const textureState = Context::current()->state().texture; +/** @todoc const Containers::ArrayReference makes Doxygen grumpy */ +void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, Containers::ArrayReference textures) { + Implementation::TextureState& textureState = *Context::current()->state().texture; /* Create array of IDs and also update bindings in state tracker */ Containers::Array ids{textures ? textures.size() : 0}; @@ -182,9 +191,9 @@ void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, cons ids[i] = id; } - if(textureState->bindings[firstTextureUnit + i].second != id) { + if(textureState.bindings[firstTextureUnit + i].second != id) { different = true; - textureState->bindings[firstTextureUnit + i].second = id; + textureState.bindings[firstTextureUnit + i].second = id; } } @@ -246,22 +255,22 @@ AbstractTexture& AbstractTexture::setLabelInternal(const Containers::ArrayRefere } void AbstractTexture::bind(Int textureUnit) { - Implementation::TextureState* const textureState = Context::current()->state().texture; + Implementation::TextureState& textureState = *Context::current()->state().texture; /* If already bound in given texture unit, nothing to do */ - if(textureState->bindings[textureUnit].second == _id) return; + if(textureState.bindings[textureUnit].second == _id) return; /* Update state tracker, bind the texture to the unit */ - textureState->bindings[textureUnit] = {_target, _id}; - (this->*Context::current()->state().texture->bindImplementation)(textureUnit); + textureState.bindings[textureUnit] = {_target, _id}; + (this->*textureState.bindImplementation)(textureUnit); } void AbstractTexture::bindImplementationDefault(GLint textureUnit) { - Implementation::TextureState* const textureState = Context::current()->state().texture; + Implementation::TextureState& textureState = *Context::current()->state().texture; /* Activate given texture unit if not already active, update state tracker */ - if(textureState->currentTextureUnit != textureUnit) - glActiveTexture(GL_TEXTURE0 + (textureState->currentTextureUnit = textureUnit)); + if(textureState.currentTextureUnit != textureUnit) + glActiveTexture(GL_TEXTURE0 + (textureState.currentTextureUnit = textureUnit)); /* Binding the texture finally creates it */ _created = true; @@ -274,6 +283,10 @@ void AbstractTexture::bindImplementationMulti(GLint textureUnit) { glBindTextures(textureUnit, 1, &_id); } +void AbstractTexture::bindImplementationDSA(const GLint textureUnit) { + glBindTextureUnit(textureUnit, _id); +} + void AbstractTexture::bindImplementationDSAEXT(GLint textureUnit) { _created = true; glBindMultiTextureEXT(GL_TEXTURE0 + textureUnit, _target, _id); @@ -401,6 +414,10 @@ void AbstractTexture::mipmapImplementationDefault() { } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::mipmapImplementationDSA() { + glGenerateTextureMipmap(_id); +} + void AbstractTexture::mipmapImplementationDSAEXT() { _created = true; glGenerateTextureMipmapEXT(_id, _target); @@ -412,21 +429,21 @@ void AbstractTexture::bindInternal() { functions need to have the texture bound in *currently active* unit, so we would need to call glActiveTexture() afterwards anyway. */ - Implementation::TextureState* const textureState = Context::current()->state().texture; + Implementation::TextureState& textureState = *Context::current()->state().texture; /* If the texture is already bound in current unit, nothing to do */ - if(textureState->bindings[textureState->currentTextureUnit].second == _id) + if(textureState.bindings[textureState.currentTextureUnit].second == _id) return; /* Set internal unit as active if not already, update state tracker */ - CORRADE_INTERNAL_ASSERT(textureState->maxTextureUnits > 1); - const GLint internalTextureUnit = textureState->maxTextureUnits-1; - if(textureState->currentTextureUnit != internalTextureUnit) - glActiveTexture(GL_TEXTURE0 + (textureState->currentTextureUnit = internalTextureUnit)); + CORRADE_INTERNAL_ASSERT(textureState.maxTextureUnits > 1); + const GLint internalTextureUnit = textureState.maxTextureUnits-1; + if(textureState.currentTextureUnit != internalTextureUnit) + glActiveTexture(GL_TEXTURE0 + (textureState.currentTextureUnit = internalTextureUnit)); /* Bind the texture to internal unit if not already, update state tracker */ - if(textureState->bindings[internalTextureUnit].second == _id) return; - textureState->bindings[internalTextureUnit] = {_target, _id}; + if(textureState.bindings[internalTextureUnit].second == _id) return; + textureState.bindings[internalTextureUnit] = {_target, _id}; /* Binding the texture finally creates it */ _created = true; @@ -810,6 +827,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLint val } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLint value) { + glTextureParameteri(_id, parameter, value); +} + void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLint value) { _created = true; glTextureParameteriEXT(_id, _target, parameter, value); @@ -822,6 +843,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLfloat v } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLfloat value) { + glTextureParameterf(_id, parameter, value); +} + void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLfloat value) { _created = true; glTextureParameterfEXT(_id, _target, parameter, value); @@ -835,6 +860,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLi } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLint* const values) { + glTextureParameteriv(_id, parameter, values); +} + void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLint* values) { _created = true; glTextureParameterivEXT(_id, _target, parameter, values); @@ -848,6 +877,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLf } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLfloat* const values) { + glTextureParameterfv(_id, parameter, values); +} + void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLfloat* values) { _created = true; glTextureParameterfvEXT(_id, _target, parameter, values); @@ -860,6 +893,10 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL glTexParameterIuiv(_target, parameter, values); } +void AbstractTexture::parameterIImplementationDSA(const GLenum parameter, const GLuint* const values) { + glTextureParameterIuiv(_id, parameter, values); +} + void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values) { _created = true; glTextureParameterIuivEXT(_id, _target, parameter, values); @@ -870,6 +907,10 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL glTexParameterIiv(_target, parameter, values); } +void AbstractTexture::parameterIImplementationDSA(const GLenum parameter, const GLint* const values) { + glTextureParameterIiv(_id, parameter, values); +} + void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLint* values) { _created = true; glTextureParameterIivEXT(_id, _target, parameter, values); @@ -883,59 +924,65 @@ void AbstractTexture::setMaxAnisotropyImplementationExt(GLfloat anisotropy) { } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::getLevelParameterImplementationDefault(GLenum target, GLint level, GLenum parameter, GLint* values) { +void AbstractTexture::getLevelParameterImplementationDefault(GLint level, GLenum parameter, GLint* values) { bindInternal(); - glGetTexLevelParameteriv(target, level, parameter, values); + glGetTexLevelParameteriv(_target, level, parameter, values); } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::getLevelParameterImplementationDSAEXT(GLenum target, GLint level, GLenum parameter, GLint* values) { +void AbstractTexture::getLevelParameterImplementationDSA(const GLint level, const GLenum parameter, GLint* const values) { + glGetTextureLevelParameteriv(_id, level, parameter, values); +} + +void AbstractTexture::getLevelParameterImplementationDSAEXT(GLint level, GLenum parameter, GLint* values) { _created = true; - glGetTextureLevelParameterivEXT(_id, target, level, parameter, values); + glGetTextureLevelParameterivEXT(_id, _target, level, parameter, values); } #endif #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageImplementationFallback(const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { - CORRADE_INTERNAL_ASSERT(target == GL_TEXTURE_1D); - +void AbstractTexture::storageImplementationFallback(const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { const ColorFormat format = imageFormatForInternalFormat(internalFormat); const ColorType type = imageTypeForInternalFormat(internalFormat); - for(GLsizei level = 0; level != levels; ++level) { - (this->*Context::current()->state().texture->image1DImplementation)(target, level, internalFormat, Math::max(Math::Vector<1, GLsizei>(1), size >> level), format, type, nullptr); - } + for(GLsizei level = 0; level != levels; ++level) + DataHelper<1>::setImage(*this, level, internalFormat, + ImageReference1D{format, type, Math::max(Math::Vector<1, GLsizei>(1), size >> level)}); } -void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { +void AbstractTexture::storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { bindInternal(); - glTexStorage1D(target, levels, GLenum(internalFormat), size[0]); + glTexStorage1D(_target, levels, GLenum(internalFormat), size[0]); +} + +void AbstractTexture::storageImplementationDSA(const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { + glTextureStorage1D(_id, levels, GLenum(internalFormat), size[0]); } -void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { +void AbstractTexture::storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { _created = true; - glTextureStorage1DEXT(_id, target, levels, GLenum(internalFormat), size[0]); + glTextureStorage1DEXT(_id, _target, levels, GLenum(internalFormat), size[0]); } #endif -void AbstractTexture::storageImplementationFallback(const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { +void AbstractTexture::storageImplementationFallback(const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { const ColorFormat format = imageFormatForInternalFormat(internalFormat); const ColorType type = imageTypeForInternalFormat(internalFormat); /* Common code for classic types */ #ifndef MAGNUM_TARGET_GLES - if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE) + if(_target == GL_TEXTURE_2D || _target == GL_TEXTURE_RECTANGLE) #else - if(target == GL_TEXTURE_2D) + if(_target == GL_TEXTURE_2D) #endif { - for(GLsizei level = 0; level != levels; ++level) { - (this->*Context::current()->state().texture->image2DImplementation)(target, level, internalFormat, Math::max(Vector2i(1), size >> level), format, type, nullptr); - } + for(GLsizei level = 0; level != levels; ++level) + DataHelper<2>::setImage(*this, level, internalFormat, + ImageReference2D{format, type, Math::max(Vector2i(1), size >> level)}); /* Cube map additionally needs to specify all faces */ - } else if(target == GL_TEXTURE_CUBE_MAP) { + } else if(_target == GL_TEXTURE_CUBE_MAP) { for(GLsizei level = 0; level != levels; ++level) { const std::initializer_list faces = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, @@ -946,29 +993,29 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; for(auto it = faces.begin(); it != faces.end(); ++it) - (this->*Context::current()->state().texture->image2DImplementation)(*it, level, internalFormat, Math::max(Vector2i(1), size >> level), format, type, nullptr); + DataHelper<2>::setImage(*this, *it, level, internalFormat, + ImageReference2D{format, type, Math::max(Vector2i(1), size >> level)}); } #ifndef MAGNUM_TARGET_GLES /* Array texture is not scaled in "layer" dimension */ - } else if(target == GL_TEXTURE_1D_ARRAY) { - for(GLsizei level = 0; level != levels; ++level) { - (this->*Context::current()->state().texture->image2DImplementation)(target, level, internalFormat, Math::max(Vector2i(1), size >> level), format, type, nullptr); - } + } else if(_target == GL_TEXTURE_1D_ARRAY) { + for(GLsizei level = 0; level != levels; ++level) + DataHelper<2>::setImage(*this, level, internalFormat, + ImageReference2D{format, type, Vector2i{Math::max(1, size.x() >> level), size.y()}}); #endif /* No other targets are available */ } else CORRADE_ASSERT_UNREACHABLE(); } -void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { +void AbstractTexture::storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { bindInternal(); #ifndef MAGNUM_TARGET_GLES2 - glTexStorage2D(target, levels, GLenum(internalFormat), size.x(), size.y()); + glTexStorage2D(_target, levels, GLenum(internalFormat), size.x(), size.y()); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y()); + glTexStorage2DEXT(_target, levels, GLenum(internalFormat), size.x(), size.y()); #else - static_cast(target); static_cast(levels); static_cast(internalFormat); static_cast(size); @@ -977,53 +1024,53 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { +void AbstractTexture::storageImplementationDSA(const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { + glTextureStorage2D(_id, levels, GLenum(internalFormat), size.x(), size.y()); +} + +void AbstractTexture::storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { _created = true; - glTextureStorage2DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y()); + glTextureStorage2DEXT(_id, _target, levels, GLenum(internalFormat), size.x(), size.y()); } #endif -void AbstractTexture::storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { +void AbstractTexture::storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { const ColorFormat format = imageFormatForInternalFormat(internalFormat); const ColorType type = imageTypeForInternalFormat(internalFormat); /* Common code for classic type */ #ifndef MAGNUM_TARGET_GLES2 - if(target == GL_TEXTURE_3D) + if(_target == GL_TEXTURE_3D) #else - if(target == GL_TEXTURE_3D_OES) + if(_target == GL_TEXTURE_3D_OES) #endif - { - for(GLsizei level = 0; level != levels; ++level) { - (this->*Context::current()->state().texture->image3DImplementation)(target, level, internalFormat, Math::max(Vector3i(1), size >> level), format, type, nullptr); - } + for(GLsizei level = 0; level != levels; ++level) + DataHelper<3>::setImage(*this, level, internalFormat, + ImageReference3D{format, type, Math::max(Vector3i(1), size >> level)}); #ifndef MAGNUM_TARGET_GLES2 /* Array texture is not scaled in "layer" dimension */ - } #ifndef MAGNUM_TARGET_GLES - else if(target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) + else if(_target == GL_TEXTURE_2D_ARRAY || _target == GL_TEXTURE_CUBE_MAP_ARRAY) #else - else if(target == GL_TEXTURE_2D_ARRAY) + else if(_target == GL_TEXTURE_2D_ARRAY) #endif - { - for(GLsizei level = 0; level != levels; ++level) { - (this->*Context::current()->state().texture->image3DImplementation)(target, level, internalFormat, Math::max(Vector3i(1), size >> level), format, type, nullptr); - } + for(GLsizei level = 0; level != levels; ++level) + DataHelper<3>::setImage(*this, level, internalFormat, + ImageReference3D{format, type, Vector3i{Math::max(Vector2i{1}, size.xy() >> level), size.z()}}); #endif /* No other targets are available */ - } else CORRADE_ASSERT_UNREACHABLE(); + else CORRADE_ASSERT_UNREACHABLE(); } -void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { +void AbstractTexture::storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { bindInternal(); #ifndef MAGNUM_TARGET_GLES2 - glTexStorage3D(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); + glTexStorage3D(_target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glTexStorage3DEXT(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); + glTexStorage3DEXT(_target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); #else - static_cast(target); static_cast(levels); static_cast(internalFormat); static_cast(size); @@ -1032,146 +1079,120 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { +void AbstractTexture::storageImplementationDSA(const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) { + glTextureStorage3D(_id, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); +} + +void AbstractTexture::storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { _created = true; - glTextureStorage3DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); + glTextureStorage3DEXT(_id, _target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageMultisampleImplementationFallback(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { +void AbstractTexture::storageMultisampleImplementationFallback(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { bindInternal(); - glTexImage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); + glTexImage2DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::storageMultisampleImplementationDefault(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { +void AbstractTexture::storageMultisampleImplementationDefault(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { bindInternal(); - glTexStorage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); + glTexStorage2DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { - _created = true; - glTextureStorage2DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); +void AbstractTexture::storageMultisampleImplementationDSA(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { + glTextureStorage2DMultisample(_id, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); } -void AbstractTexture::storageMultisampleImplementationFallback(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { - bindInternal(); - glTexImage3DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); +void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { + _created = true; + glTextureStorage2DMultisampleEXT(_id, _target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); } -void AbstractTexture::storageMultisampleImplementationDefault(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { +void AbstractTexture::storageMultisampleImplementationFallback(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { bindInternal(); - glTexStorage3DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); + glTexImage3DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); } -void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { - _created = true; - glTextureStorage3DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); -} -#endif - -#ifndef MAGNUM_TARGET_GLES -void AbstractTexture::getImageImplementationDefault(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { +void AbstractTexture::storageMultisampleImplementationDefault(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { bindInternal(); - glGetTexImage(target, level, GLenum(format), GLenum(type), data); + glTexStorage3DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); } -void AbstractTexture::getImageImplementationDSAEXT(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { - _created = true; - glGetTextureImageEXT(_id, target, level, GLenum(format), GLenum(type), data); +void AbstractTexture::storageMultisampleImplementationDSA(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { + glTextureStorage3DMultisample(_id, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); } -void AbstractTexture::getImageImplementationRobustness(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { - bindInternal(); - glGetnTexImageARB(target, level, GLenum(format), GLenum(type), dataSize, data); +void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { + _created = true; + glTextureStorage3DMultisampleEXT(_id, _target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::getImageImplementationDefault(const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { bindInternal(); - glTexImage1D(target, level, GLint(internalFormat), size[0], 0, GLenum(format), GLenum(type), data); -} - -void AbstractTexture::imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { - _created = true; - glTextureImage1DEXT(_id, target, level, GLint(internalFormat), size[0], 0, GLenum(format), GLenum(type), data); + glGetTexImage(_target, level, GLenum(format), GLenum(type), data); } -#endif -void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { - bindInternal(); - glTexImage2D(target, level, GLint(internalFormat), size.x(), size.y(), 0, GLenum(format), GLenum(type), data); +void AbstractTexture::getImageImplementationDSA(const GLint level, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { + glGetTextureImage(_id, level, GLenum(format), GLenum(type), dataSize, data); } -#ifndef MAGNUM_TARGET_GLES -void AbstractTexture::imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::getImageImplementationDSAEXT(const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { _created = true; - glTextureImage2DEXT(_id, target, level, GLint(internalFormat), size.x(), size.y(), 0, GLenum(format), GLenum(type), data); + glGetTextureImageEXT(_id, _target, level, GLenum(format), GLenum(type), data); } -#endif -void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::getImageImplementationRobustness(const GLint level, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { bindInternal(); - #ifndef MAGNUM_TARGET_GLES2 - glTexImage3D(target, level, GLint(internalFormat), size.x(), size.y(), size.z(), 0, GLenum(format), GLenum(type), data); - #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glTexImage3DOES(target, level, GLint(internalFormat), size.x(), size.y(), size.z(), 0, GLenum(format), GLenum(type), data); - #else - static_cast(target); - static_cast(level); - static_cast(internalFormat); - static_cast(size); - static_cast(format); - static_cast(type); - static_cast(data); - CORRADE_ASSERT_UNREACHABLE(); - #endif -} - -#ifndef MAGNUM_TARGET_GLES -void AbstractTexture::imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { - _created = true; - glTextureImage3DEXT(_id, target, level, GLint(internalFormat), size.x(), size.y(), size.z(), 0, GLenum(format), GLenum(type), data); + glGetnTexImageARB(_target, level, GLenum(format), GLenum(type), dataSize, data); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDefault(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { bindInternal(); - glTexSubImage1D(target, level, offset[0], size[0], GLenum(format), GLenum(type), data); + glTexSubImage1D(_target, level, offset[0], size[0], GLenum(format), GLenum(type), data); } -void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDSA(const GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + glTextureSubImage1D(_id, level, offset[0], size[0], GLenum(format), GLenum(type), data); +} + +void AbstractTexture::subImageImplementationDSAEXT(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { _created = true; - glTextureSubImage1DEXT(_id, target, level, offset[0], size[0], GLenum(format), GLenum(type), data); + glTextureSubImage1DEXT(_id, _target, level, offset[0], size[0], GLenum(format), GLenum(type), data); } #endif -void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDefault(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { bindInternal(); - glTexSubImage2D(target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); + glTexSubImage2D(_target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDSA(const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + glTextureSubImage2D(_id, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); +} + +void AbstractTexture::subImageImplementationDSAEXT(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { _created = true; - glTextureSubImage2DEXT(_id, target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); + glTextureSubImage2DEXT(_id, _target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); } #endif -void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDefault(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { bindInternal(); #ifndef MAGNUM_TARGET_GLES2 - glTexSubImage3D(target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); + glTexSubImage3D(_target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glTexSubImage3DOES(target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); + glTexSubImage3DOES(_target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); #else - static_cast(target); static_cast(level); static_cast(offset); static_cast(size); @@ -1183,9 +1204,13 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDSA(const GLint level, const Vector3i& offset, const Vector3i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + glTextureSubImage3D(_id, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); +} + +void AbstractTexture::subImageImplementationDSAEXT(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { _created = true; - glTextureSubImage3DEXT(_id, target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); + glTextureSubImage3DEXT(_id, _target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); } #endif @@ -1209,109 +1234,148 @@ void AbstractTexture::invalidateSubImageImplementationARB(GLint level, const Vec #ifndef DOXYGEN_GENERATING_OUTPUT #ifndef MAGNUM_TARGET_GLES -template void AbstractTexture::image(GLenum target, GLint level, Image& image) { - const Math::Vector size = DataHelper::imageSize(*this, target, level); +template void AbstractTexture::image(GLint level, Image& image) { + const Math::Vector size = DataHelper::imageSize(*this, level); const std::size_t dataSize = image.dataSize(size); char* data = new char[dataSize]; - (this->*Context::current()->state().texture->getImageImplementation)(target, level, image.format(), image.type(), dataSize, data); + Buffer::unbindInternal(Buffer::TargetHint::PixelPack); + (this->*Context::current()->state().texture->getImageImplementation)(level, image.format(), image.type(), dataSize, data); image.setData(image.format(), image.type(), size, data); } -template void MAGNUM_EXPORT AbstractTexture::image<1>(GLenum, GLint, Image<1>&); -template void MAGNUM_EXPORT AbstractTexture::image<2>(GLenum, GLint, Image<2>&); -template void MAGNUM_EXPORT AbstractTexture::image<3>(GLenum, GLint, Image<3>&); +template void MAGNUM_EXPORT AbstractTexture::image<1>(GLint, Image<1>&); +template void MAGNUM_EXPORT AbstractTexture::image<2>(GLint, Image<2>&); +template void MAGNUM_EXPORT AbstractTexture::image<3>(GLint, Image<3>&); -template void AbstractTexture::image(GLenum target, GLint level, BufferImage& image, BufferUsage usage) { - const Math::Vector size = DataHelper::imageSize(*this, target, level); +template void AbstractTexture::image(GLint level, BufferImage& image, BufferUsage usage) { + const Math::Vector size = DataHelper::imageSize(*this, level); const std::size_t dataSize = image.dataSize(size); if(image.size() != size) image.setData(image.format(), image.type(), size, nullptr, usage); image.buffer().bindInternal(Buffer::TargetHint::PixelPack); - (this->*Context::current()->state().texture->getImageImplementation)(target, level, image.format(), image.type(), dataSize, nullptr); + (this->*Context::current()->state().texture->getImageImplementation)(level, image.format(), image.type(), dataSize, nullptr); } -template void MAGNUM_EXPORT AbstractTexture::image<1>(GLenum, GLint, BufferImage<1>&, BufferUsage); -template void MAGNUM_EXPORT AbstractTexture::image<2>(GLenum, GLint, BufferImage<2>&, BufferUsage); -template void MAGNUM_EXPORT AbstractTexture::image<3>(GLenum, GLint, BufferImage<3>&, BufferUsage); +template void MAGNUM_EXPORT AbstractTexture::image<1>(GLint, BufferImage<1>&, BufferUsage); +template void MAGNUM_EXPORT AbstractTexture::image<2>(GLint, BufferImage<2>&, BufferUsage); +template void MAGNUM_EXPORT AbstractTexture::image<3>(GLint, BufferImage<3>&, BufferUsage); + +template void AbstractTexture::subImage(const GLint level, const RangeTypeFor& range, Image& image) { + createIfNotAlready(); + + const Math::Vector size = range.size(); + const Vector3i paddedOffset = Vector3i::pad(range.min()); + const Vector3i paddedSize = Vector3i::pad(size, 1); + const std::size_t dataSize = image.dataSize(size); + char* data = new char[dataSize]; + + Buffer::unbindInternal(Buffer::TargetHint::PixelPack); + glGetTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), GLenum(image.format()), GLenum(image.type()), dataSize, data); + image.setData(image.format(), image.type(), size, data); +} + +template void MAGNUM_EXPORT AbstractTexture::subImage<1>(GLint, const Range1Di&, Image<1>&); +template void MAGNUM_EXPORT AbstractTexture::subImage<2>(GLint, const Range2Di&, Image<2>&); +template void MAGNUM_EXPORT AbstractTexture::subImage<3>(GLint, const Range3Di&, Image<3>&); + +template void AbstractTexture::subImage(const GLint level, const RangeTypeFor& range, BufferImage& image, const BufferUsage usage) { + createIfNotAlready(); + + const Math::Vector size = range.size(); + const std::size_t dataSize = image.dataSize(size); + const Vector3i paddedOffset = Vector3i::pad(range.min()); + const Vector3i paddedSize = Vector3i::pad(size, 1); + if(image.size() != size) + image.setData(image.format(), image.type(), size, nullptr, usage); + + image.buffer().bindInternal(Buffer::TargetHint::PixelPack); + glGetTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), GLenum(image.format()), GLenum(image.type()), dataSize, nullptr); +} + +template void MAGNUM_EXPORT AbstractTexture::subImage<1>(GLint, const Range1Di&, BufferImage<1>&, BufferUsage); +template void MAGNUM_EXPORT AbstractTexture::subImage<2>(GLint, const Range2Di&, BufferImage<2>&, BufferUsage); +template void MAGNUM_EXPORT AbstractTexture::subImage<3>(GLint, const Range3Di&, BufferImage<3>&, BufferUsage); #endif #endif #ifndef DOXYGEN_GENERATING_OUTPUT #ifndef MAGNUM_TARGET_GLES -Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture& texture, const GLenum target, const GLint level) { +Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture& texture, const GLint level) { Math::Vector<1, GLint> value; - (texture.*Context::current()->state().texture->getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]); + (texture.*Context::current()->state().texture->getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]); return value; } #endif #ifndef MAGNUM_TARGET_GLES2 -Vector2i AbstractTexture::DataHelper<2>::imageSize(AbstractTexture& texture, const GLenum target, const GLint level) { +Vector2i AbstractTexture::DataHelper<2>::imageSize(AbstractTexture& texture, const GLint level) { const Implementation::TextureState& state = *Context::current()->state().texture; Vector2i value; - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]); - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_HEIGHT, &value[1]); return value; } -Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture& texture, const GLenum target, const GLint level) { +Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture& texture, const GLint level) { const Implementation::TextureState& state = *Context::current()->state().texture; Vector3i value; - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]); - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]); - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_DEPTH, &value[2]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_HEIGHT, &value[1]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_DEPTH, &value[2]); return value; } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::DataHelper<1>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector< 1, GLsizei >& size) { - (texture.*Context::current()->state().texture->storage1DImplementation)(target, levels, internalFormat, size); +void AbstractTexture::DataHelper<1>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector< 1, GLsizei >& size) { + (texture.*Context::current()->state().texture->storage1DImplementation)(levels, internalFormat, size); } #endif -void AbstractTexture::DataHelper<2>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { - (texture.*Context::current()->state().texture->storage2DImplementation)(target, levels, internalFormat, size); +void AbstractTexture::DataHelper<2>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { + (texture.*Context::current()->state().texture->storage2DImplementation)(levels, internalFormat, size); } -void AbstractTexture::DataHelper<3>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) { - (texture.*Context::current()->state().texture->storage3DImplementation)(target, levels, internalFormat, size); +void AbstractTexture::DataHelper<3>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) { + (texture.*Context::current()->state().texture->storage3DImplementation)(levels, internalFormat, size); } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::DataHelper<2>::setStorageMultisample(AbstractTexture& texture, const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { - (texture.*Context::current()->state().texture->storage2DMultisampleImplementation)(target, samples, internalFormat, size, fixedSampleLocations); +void AbstractTexture::DataHelper<2>::setStorageMultisample(AbstractTexture& texture, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { + (texture.*Context::current()->state().texture->storage2DMultisampleImplementation)(samples, internalFormat, size, fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::DataHelper<3>::setStorageMultisample(AbstractTexture& texture, const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { - (texture.*Context::current()->state().texture->storage3DMultisampleImplementation)(target, samples, internalFormat, size, fixedSampleLocations); +void AbstractTexture::DataHelper<3>::setStorageMultisample(AbstractTexture& texture, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { + (texture.*Context::current()->state().texture->storage3DMultisampleImplementation)(samples, internalFormat, size, fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference1D& image) { +void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, const ImageReference1D& image) { Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->image1DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data()); + texture.bindInternal(); + glTexImage1D(texture._target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), image.data()); } -void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage1D& image) { +void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, BufferImage1D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->image1DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr); + texture.bindInternal(); + glTexImage1D(texture._target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), nullptr); } -void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image) { +void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image) { Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data()); + (texture.*Context::current()->state().texture->subImage1DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data()); } -void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image) { +void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr); + (texture.*Context::current()->state().texture->subImage1DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr); } #endif @@ -1319,55 +1383,68 @@ void AbstractTexture::DataHelper<2>::setImage(AbstractTexture& texture, const GL #ifndef MAGNUM_TARGET_GLES2 Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); #endif - (texture.*Context::current()->state().texture->image2DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data()); + texture.bindInternal(); + glTexImage2D(target, level, GLint(internalFormat), image.size().x(), image.size().y(), 0, GLenum(image.format()), GLenum(image.type()), image.data()); } #ifndef MAGNUM_TARGET_GLES2 void AbstractTexture::DataHelper<2>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage2D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->image2DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr); + texture.bindInternal(); + glTexImage2D(target, level, GLint(internalFormat), image.size().x(), image.size().y(), 0, GLenum(image.format()), GLenum(image.type()), nullptr); } #endif -void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector2i& offset, const ImageReference2D& image) { +void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLint level, const Vector2i& offset, const ImageReference2D& image) { #ifndef MAGNUM_TARGET_GLES2 Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); #endif - (texture.*Context::current()->state().texture->subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data()); + (texture.*Context::current()->state().texture->subImage2DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data()); } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector2i& offset, BufferImage2D& image) { +void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLint level, const Vector2i& offset, BufferImage2D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr); + (texture.*Context::current()->state().texture->subImage2DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr); } #endif -void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference3D& image) { +void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, const ImageReference3D& image) { #ifndef MAGNUM_TARGET_GLES2 Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); #endif - (texture.*Context::current()->state().texture->image3DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data()); + texture.bindInternal(); + #ifndef MAGNUM_TARGET_GLES2 + glTexImage3D(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data()); + #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + glTexImage3DOES(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data()); + #else + static_cast(level); + static_cast(internalFormat); + static_cast(image); + CORRADE_ASSERT_UNREACHABLE(); + #endif } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage3D& image) { +void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, BufferImage3D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->image3DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr); + texture.bindInternal(); + glTexImage3D(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), nullptr); } #endif -void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector3i& offset, const ImageReference3D& image) { +void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLint level, const Vector3i& offset, const ImageReference3D& image) { #ifndef MAGNUM_TARGET_GLES2 Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); #endif - (texture.*Context::current()->state().texture->subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data()); + (texture.*Context::current()->state().texture->subImage3DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data()); } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector3i& offset, BufferImage3D& image) { +void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLint level, const Vector3i& offset, BufferImage3D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr); + (texture.*Context::current()->state().texture->subImage3DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr); } #endif diff --git a/src/Magnum/AbstractTexture.h b/src/Magnum/AbstractTexture.h index b8a2fab28..b7fbc3d03 100644 --- a/src/Magnum/AbstractTexture.h +++ b/src/Magnum/AbstractTexture.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,8 +31,13 @@ #include -#include "Magnum/Sampler.h" #include "Magnum/AbstractObject.h" +#include "Magnum/DimensionTraits.h" +#include "Magnum/Sampler.h" + +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif #ifdef CORRADE_GCC45_COMPATIBILITY #include "Buffer.h" @@ -75,27 +80,36 @@ documentation for details. The engine tracks currently bound textures in all available texture units to avoid unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. -%Texture configuration functions use dedicated highest available texture unit -to not affect active bindings in user units. %Texture limits and +Texture configuration functions use dedicated highest available texture unit +to not affect active bindings in user units. Texture limits and implementation-defined values (such as @ref maxColorSamples()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. -If extension @extension{ARB,multi_bind} is available, @ref bind() uses -@fn_gl{BindTextures} to avoid unnecessary calls to @fn_gl{ActiveTexture}. -Otherwise, if extension @extension{EXT,direct_state_access} is available, -@ref bind() uses @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} -function. - -In addition, if extension @extension{EXT,direct_state_access} is available, -also all texture configuration and data updating functions use DSA functions -to avoid unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. -See respective function documentation for more information. +If on desktop GL and @extension{ARB,direct_state_access} (part of OpenGL 4.5) +is available, @ref bind(Int) and @ref unbind(Int) use @fn_gl{BindTextureUnit}. +Otherwise, if @extension{ARB,multi_bind} (part of OpenGL 4.4) is available, +@ref bind(Int) and @ref unbind() uses @fn_gl{BindTextures}. Lastly, if +@extension{EXT,direct_state_access} is available, @fn_gl_extension{BindNamedTexture,EXT,direct_state_access} +function is used to avoid unnecessary calls to @fn_gl{ActiveTexture}. + +In addition, if either @extension{ARB,direct_state_access} (part of OpenGL 4.5) +or @extension{EXT,direct_state_access} is available, also all texture +configuration and data updating functions use DSA functions to avoid +unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. See +respective function documentation for more information. + +If @extension{ARB,multi_bind} (part of OpenGL 4.5) is available, +@ref bind(Int, std::initializer_list) and @ref unbind(Int, std::size_t) +use @fn_gl{BindTextures} to avoid unnecessary calls to @fn_gl{ActiveTexture}. +Otherwise the feature is emulated with sequence of @ref bind(Int)/@ref unbind(Int) +calls. -If extension @extension{ARB,robustness} is available, image reading operations -(such as @ref Texture::image()) are protected from buffer overflow. However, if -both @extension{EXT,direct_state_access} and @extension{ARB,robustness} are -available, the DSA version is used, because it is better for performance and -there isn't any function combining both features. +If either @extension{ARB,direct_state_access} or @extension{ARB,robustness} is +available, image reading operations (such as @ref Texture::image()) are +protected from buffer overflow. However, if @extension{ARB,direct_state_access} +is not available and both @extension{EXT,direct_state_access} and +@extension{ARB,robustness} are available, the robust version is preferred over +DSA. To achieve least state changes, fully configure each texture in one run -- method chaining comes in handy -- and try to have often used textures in @@ -128,13 +142,10 @@ functions do nothing. @todo `GL_NUM_COMPRESSED_TEXTURE_FORMATS` when compressed textures are implemented @todo `GL_MAX_SAMPLE_MASK_WORDS` when @extension{ARB,texture_multisample} is done @todo Query for immutable levels (@extension{ARB,ES3_compatibility}) -@bug If using @extension{ARB,multi_bind} and the texture is bound right after - construction, the @fn_gl{BindTextures} call will fail with - Renderer::Error::InvalidOperation, because the texture doesn't yet have - associated target */ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { - friend struct Implementation::TextureState; + friend Implementation::TextureState; + friend CubeMapTexture; public: #ifdef MAGNUM_BUILD_DEPRECATED @@ -153,7 +164,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { * The result is cached, repeated queries don't result in repeated * OpenGL calls. * @see @fn_gl{Get} with @def_gl{MAX_TEXTURE_LOD_BIAS} - * @requires_gles30 %Texture LOD bias doesn't have + * @requires_gles30 Texture LOD bias doesn't have * implementation-defined range in OpenGL ES 2.0. */ static Float maxLodBias(); @@ -197,15 +208,17 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { /** * @brief Unbind any texture from given texture unit * - * If @extension{ARB,multi_bind} (part of OpenGL 4.4) or - * @extension{EXT,direct_state_access} is not available, the texture - * unit is made active before binding the texture. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5), @extension{ARB,multi_bind} (part of OpenGL 4.4) nor + * @extension{EXT,direct_state_access} is available, the texture unit + * is made active before unbinding the texture. * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. * @see @ref bind(), @ref Shader::maxCombinedTextureImageUnits(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture}, @fn_gl{BindTextures} - * or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} + * @fn_gl{BindTextureUnit}, @fn_gl{BindTextures}, + * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture} and @fn_gl{BindTexture} */ static void unbind(Int textureUnit); @@ -218,9 +231,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. - * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}, - * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or - * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} + * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures} */ static void unbind(Int firstTextureUnit, std::size_t count); @@ -235,9 +246,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. - * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}, - * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or - * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} + * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures} */ static void bind(Int firstTextureUnit, std::initializer_list textures); @@ -262,7 +271,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { AbstractTexture& operator=(AbstractTexture&& other) noexcept; /** - * @brief %Texture label + * @brief Texture label * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. If OpenGL 4.3 is not supported and neither @@ -291,7 +300,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { /** @overload */ template AbstractTexture& setLabel(const char(&label)[size]) { - return setLabelInternal(label); + return setLabelInternal({label, size - 1}); } /** @brief OpenGL texture ID */ @@ -300,16 +309,18 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { /** * @brief Bind texture to given texture unit * - * If @extension{ARB,multi_bind} (part of OpenGL 4.4) or - * @extension{EXT,direct_state_access} is not available, the texture - * unit is made active before binding the texture. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5), @extension{ARB,multi_bind} (part of OpenGL 4.4) nor + * @extension{EXT,direct_state_access} is available, the texture unit + * is made active before binding the texture. * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. * @see @ref bind(Int, std::initializer_list), * @ref unbind(), @ref Shader::maxCombinedTextureImageUnits(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture}, @fn_gl{BindTextures} - * or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} + * @fn_gl{BindTextureUnit}, @fn_gl{BindTextures}, + * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture} and @fn_gl{BindTexture} */ void bind(Int textureUnit); @@ -367,8 +378,10 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void generateMipmap(); #ifndef MAGNUM_TARGET_GLES - template void image(GLenum target, GLint level, Image& image); - template void image(GLenum target, GLint level, BufferImage& image, BufferUsage usage); + template void image(GLint level, Image& image); + template void image(GLint level, BufferImage& image, BufferUsage usage); + template void subImage(GLint level, const RangeTypeFor& range, Image& image); + template void subImage(GLint level, const RangeTypeFor& range, BufferImage& image, BufferUsage usage); #endif GLenum _target; @@ -377,6 +390,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { static void MAGNUM_LOCAL unbindImplementationDefault(GLint textureUnit); #ifndef MAGNUM_TARGET_GLES static void MAGNUM_LOCAL unbindImplementationMulti(GLint textureUnit); + static void MAGNUM_LOCAL unbindImplementationDSA(GLint textureUnit); static void MAGNUM_LOCAL unbindImplementationDSAEXT(GLint textureUnit); #endif @@ -395,6 +409,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit); #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit); + void MAGNUM_LOCAL bindImplementationDSA(GLint textureUnit); void MAGNUM_LOCAL bindImplementationDSAEXT(GLint textureUnit); #endif @@ -409,11 +424,17 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void MAGNUM_LOCAL parameterIImplementationDefault(GLenum parameter, const GLint* values); #endif #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLint value); void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, GLint value); + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLfloat value); void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, GLfloat value); + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLint* values); void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, const GLint* values); + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLfloat* values); void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, const GLfloat* values); + void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLuint* values); void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values); + void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLint* values); void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLint* values); #endif @@ -421,85 +442,81 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void MAGNUM_LOCAL setMaxAnisotropyImplementationExt(GLfloat anisotropy); #ifndef MAGNUM_TARGET_GLES2 - void MAGNUM_LOCAL getLevelParameterImplementationDefault(GLenum target, GLint level, GLenum parameter, GLint* values); + void MAGNUM_LOCAL getLevelParameterImplementationDefault(GLint level, GLenum parameter, GLint* values); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL getLevelParameterImplementationDSAEXT(GLenum target, GLint level, GLenum parameter, GLint* values); + void MAGNUM_LOCAL getLevelParameterImplementationDSA(GLint level, GLenum parameter, GLint* values); + void MAGNUM_LOCAL getLevelParameterImplementationDSAEXT(GLint level, GLenum parameter, GLint* values); #endif #endif void MAGNUM_LOCAL mipmapImplementationDefault(); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL mipmapImplementationDSA(); void MAGNUM_LOCAL mipmapImplementationDSAEXT(); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); - void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); - void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + void MAGNUM_LOCAL storageImplementationDSA(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + void MAGNUM_LOCAL storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); #endif - void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); - void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector2i& size); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL storageImplementationDSA(GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector2i& size); #endif - void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); - void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector3i& size); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + void MAGNUM_LOCAL storageImplementationDSA(GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + void MAGNUM_LOCAL storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector3i& size); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); #endif #ifndef MAGNUM_TARGET_GLES2 - void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); - #endif - #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); #endif - - #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); - void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); - void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); - #endif - - #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL getImageImplementationDefault(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); - void MAGNUM_LOCAL getImageImplementationDSAEXT(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); - void MAGNUM_LOCAL getImageImplementationRobustness(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); - #endif - #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); - void MAGNUM_LOCAL imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); #endif - void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); #endif - void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDefault(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDSA(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDSAEXT(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationRobustness(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); - void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDefault(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSA(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSAEXT(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); #endif - void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDefault(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSA(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSAEXT(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); #endif - void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDefault(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSA(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSAEXT(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); #endif void MAGNUM_LOCAL invalidateImageImplementationNoOp(GLint level); @@ -528,17 +545,17 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> { }; #endif - static Math::Vector<1, GLint> imageSize(AbstractTexture& texture, GLenum target, GLint level); + static Math::Vector<1, GLint> imageSize(AbstractTexture& texture, GLint level); static void setWrapping(AbstractTexture& texture, const Array1D& wrapping); - static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + static void setStorage(AbstractTexture& texture, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); - static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference1D& image); - static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage1D& image); + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, const ImageReference1D& image); + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, BufferImage1D& image); - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image); - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image); static void invalidateSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size); }; @@ -556,25 +573,31 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { #endif #ifndef MAGNUM_TARGET_GLES2 - static Vector2i imageSize(AbstractTexture& texture, GLenum target, GLint level); + static Vector2i imageSize(AbstractTexture& texture, GLint level); #endif static void setWrapping(AbstractTexture& texture, const Array2D& wrapping); - static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + static void setStorage(AbstractTexture& texture, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); #ifndef MAGNUM_TARGET_GLES2 - static void setStorageMultisample(AbstractTexture& texture, GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedSampleLocations); + static void setStorageMultisample(AbstractTexture& texture, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedSampleLocations); #endif + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, const ImageReference2D& image) { + setImage(texture, texture._target, level, internalFormat, image); + } static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference2D& image); #ifndef MAGNUM_TARGET_GLES2 + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, BufferImage2D& image) { + setImage(texture, texture._target, level, internalFormat, image); + } static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage2D& image); #endif - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector2i& offset, const ImageReference2D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, const ImageReference2D& image); #ifndef MAGNUM_TARGET_GLES2 - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector2i& offset, BufferImage2D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, BufferImage2D& image); #endif static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, const Vector2i& size); @@ -595,25 +618,25 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> { #endif #ifndef MAGNUM_TARGET_GLES2 - static Vector3i imageSize(AbstractTexture& texture, GLenum target, GLint level); + static Vector3i imageSize(AbstractTexture& texture, GLint level); #endif static void setWrapping(AbstractTexture& texture, const Array3D& wrapping); - static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + static void setStorage(AbstractTexture& texture, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); #ifndef MAGNUM_TARGET_GLES - static void setStorageMultisample(AbstractTexture& texture, GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedSampleLocations); + static void setStorageMultisample(AbstractTexture& texture, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedSampleLocations); #endif - static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference3D& image); + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, const ImageReference3D& image); #ifndef MAGNUM_TARGET_GLES2 - static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage3D& image); + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, BufferImage3D& image); #endif - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector3i& offset, const ImageReference3D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, const ImageReference3D& image); #ifndef MAGNUM_TARGET_GLES2 - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector3i& offset, BufferImage3D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, BufferImage3D& image); #endif static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, const Vector3i& size); @@ -625,9 +648,10 @@ inline AbstractTexture::AbstractTexture(AbstractTexture&& other) noexcept: _targ } inline AbstractTexture& AbstractTexture::operator=(AbstractTexture&& other) noexcept { - std::swap(_target, other._target); - std::swap(_id, other._id); - std::swap(_created, other._created); + using std::swap; + swap(_target, other._target); + swap(_id, other._id); + swap(_created, other._created); return *this; } diff --git a/src/Magnum/Array.h b/src/Magnum/Array.h index 1658a038c..5df9862f7 100644 --- a/src/Magnum/Array.h +++ b/src/Magnum/Array.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -41,7 +41,7 @@ namespace Magnum { /** -@brief %Array +@brief Array @tparam dimensions Dimension count @tparam T Data type @@ -169,7 +169,7 @@ template class Array2D: public Array<2, T> { */ constexpr /*implicit*/ Array2D(T x, T y): Array<2, T>(x, y) {} - /** @copydoc Array::Array(U) */ + /** @brief Initializer-list constructor */ constexpr /*implicit*/ Array2D(T value): Array<2, T>(value, value) {} /** @brief Copy constructor */ @@ -198,7 +198,7 @@ template class Array3D: public Array<3, T> { */ constexpr /*implicit*/ Array3D(T x, T y, T z): Array<3, T>(x, y, z) {} - /** @copydoc Array::Array(U) */ + /** @brief Initializer-list constructor */ constexpr /*implicit*/ Array3D(T value): Array<3, T>(value, value, value) {} /** @brief Copy constructor */ diff --git a/src/Magnum/Attribute.cpp b/src/Magnum/Attribute.cpp new file mode 100644 index 000000000..57406c1a0 --- /dev/null +++ b/src/Magnum/Attribute.cpp @@ -0,0 +1,329 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Attribute.h" + +#include + +namespace Magnum { namespace Implementation { + +UnsignedInt FloatAttribute::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + case DataType::HalfFloat: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + case DataType::Float: + return 4*components; + #ifndef MAGNUM_TARGET_GLES + case DataType::Double: + return 8*components; + #endif + } + + CORRADE_ASSERT_UNREACHABLE(); +} + +#ifndef MAGNUM_TARGET_GLES2 +UnsignedInt IntAttribute::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + return 4*components; + } + + CORRADE_ASSERT_UNREACHABLE(); +} +#endif + +#ifndef MAGNUM_TARGET_GLES +UnsignedInt DoubleAttribute::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::Double: + return 8*components; + } + + CORRADE_ASSERT_UNREACHABLE(); +} +#endif + +UnsignedInt Attribute>::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + case DataType::HalfFloat: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + case DataType::Float: + return 4*components; + #ifndef MAGNUM_TARGET_GLES + case DataType::Double: + return 8*components; + case DataType::UnsignedInt10f11f11fRev: + CORRADE_INTERNAL_ASSERT(components == 3); + return 4; + #endif + } + + CORRADE_ASSERT_UNREACHABLE(); +} + +UnsignedInt Attribute>::size(GLint components, DataType dataType) { + #ifndef MAGNUM_TARGET_GLES + if(components == GL_BGRA) components = 4; + #endif + + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + case DataType::HalfFloat: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + case DataType::Float: + return 4*components; + #ifndef MAGNUM_TARGET_GLES + case DataType::Double: + return 8*components; + #endif + + #ifndef MAGNUM_TARGET_GLES2 + case DataType::UnsignedInt2101010Rev: + case DataType::Int2101010Rev: + CORRADE_INTERNAL_ASSERT(components == 4); + return 4; + #endif + } + + CORRADE_ASSERT_UNREACHABLE(); +} + +Debug operator<<(Debug debug, SizedAttribute<1, 1>::Components value) { + switch(value) { + case SizedAttribute<1, 1>::Components::One: + return debug << "Attribute::Components::One"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedAttribute<1, 2>::Components value) { + switch(value) { + case SizedAttribute<1, 2>::Components::One: + return debug << "Attribute::Components::One"; + case SizedAttribute<1, 2>::Components::Two: + return debug << "Attribute::Components::Two"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedAttribute<1, 3>::Components value) { + switch(value) { + case SizedAttribute<1, 3>::Components::One: + return debug << "Attribute::Components::One"; + case SizedAttribute<1, 3>::Components::Two: + return debug << "Attribute::Components::Two"; + case SizedAttribute<1, 3>::Components::Three: + return debug << "Attribute::Components::Three"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedAttribute<1, 4>::Components value) { + switch(value) { + case SizedAttribute<1, 4>::Components::One: + return debug << "Attribute::Components::One"; + case SizedAttribute<1, 4>::Components::Two: + return debug << "Attribute::Components::Two"; + case SizedAttribute<1, 4>::Components::Three: + return debug << "Attribute::Components::Three"; + case SizedAttribute<1, 4>::Components::Four: + return debug << "Attribute::Components::Four"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedMatrixAttribute<2>::Components value) { + switch(value) { + case SizedMatrixAttribute<2>::Components::Two: + return debug << "Attribute::Components::Two"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedMatrixAttribute<3>::Components value) { + switch(value) { + case SizedMatrixAttribute<3>::Components::Three: + return debug << "Attribute::Components::Three"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedMatrixAttribute<4>::Components value) { + switch(value) { + case SizedMatrixAttribute<4>::Components::Four: + return debug << "Attribute::Components::Four"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, Attribute>::Components value) { + switch(value) { + case Attribute>::Components::One: + return debug << "Attribute::Components::One"; + case Attribute>::Components::Two: + return debug << "Attribute::Components::Two"; + case Attribute>::Components::Three: + return debug << "Attribute::Components::Three"; + case Attribute>::Components::Four: + return debug << "Attribute::Components::Four"; + #ifndef MAGNUM_TARGET_GLES + case Attribute>::Components::BGRA: + return debug << "Attribute::Components::BGRA"; + #endif + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, FloatAttribute::DataType value) { + switch(value) { + #define _c(value) case FloatAttribute::DataType::value: return debug << "Attribute::DataType::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + _c(HalfFloat) + _c(Float) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + #endif + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} + +#ifndef MAGNUM_TARGET_GLES2 +Debug operator<<(Debug debug, IntAttribute::DataType value) { + switch(value) { + #define _c(value) case IntAttribute::DataType::value: return debug << "Attribute::DataType::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} +#endif + +#ifndef MAGNUM_TARGET_GLES +Debug operator<<(Debug debug, DoubleAttribute::DataType value) { + switch(value) { + #define _c(value) case DoubleAttribute::DataType::value: return debug << "Attribute::DataType::" #value; + _c(Double) + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} +#endif + +Debug operator<<(Debug debug, Attribute>::DataType value) { + switch(value) { + #define _c(value) case Attribute>::DataType::value: return debug << "Attribute::DataType::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + _c(HalfFloat) + _c(Float) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + _c(UnsignedInt10f11f11fRev) + #endif + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} + +Debug operator<<(Debug debug, Attribute>::DataType value) { + switch(value) { + #define _c(value) case Attribute>::DataType::value: return debug << "Attribute::DataType::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + _c(HalfFloat) + _c(Float) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(UnsignedInt2101010Rev) + _c(Int2101010Rev) + #endif + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} + +}} diff --git a/src/Magnum/Attribute.h b/src/Magnum/Attribute.h new file mode 100644 index 000000000..448e4d1c0 --- /dev/null +++ b/src/Magnum/Attribute.h @@ -0,0 +1,657 @@ +#ifndef Magnum_Attribute_h +#define Magnum_Attribute_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Attribute + */ + +#include + +#include "Magnum/Magnum.h" +#include "Magnum/OpenGL.h" +#include "Magnum/visibility.h" + +namespace Magnum { + +namespace Implementation { template struct Attribute; } + +/** +@brief Base class for attribute location and type + +For use in @ref AbstractShaderProgram subclasses. Template parameter @p location +is vertex attribute location, number between `0` and +@ref AbstractShaderProgram::maxVertexAttributes(). To ensure compatibility, you +should always have vertex attribute with location `0`. + +Template parameter @p T is the type which is used for shader attribute, e.g. +@ref Vector4i for `ivec4`. DataType is type of passed data when adding vertex +buffers to mesh. By default it is the same as type used in shader (e.g. +@ref DataType::Int for @ref Vector4i). It's also possible to pass integer data +to floating-point shader inputs. In this case you may want to normalize the +values (e.g. color components from 0-255 to 0.0f - 1.0f) -- see +@ref DataOption::Normalized. + +Only some types are allowed as attribute types, see @ref AbstractShaderProgram-types +for more information. + +See @ref AbstractShaderProgram-subclassing for example usage in shaders and +@ref Mesh-configuration for example usage when adding vertex buffers to mesh. +*/ +template class Attribute { + public: + enum: UnsignedInt { + /** + * Location to which the attribute is bound + * + * @see @ref AbstractShaderProgram::maxVertexAttributes() + */ + Location = location, + + /** + * Count of vectors in this type + * + * @see @ref vectorSize() + */ + VectorCount = Implementation::Attribute::VectorCount + }; + + /** + * @brief Type + * + * Type used in shader code. + * @see @ref ScalarType, @ref DataType + */ + typedef T Type; + + /** + * @brief Scalar type + * + * The underlying scalar type of the attribute. + * @see @ref Type, @ref DataType + */ + typedef typename Implementation::Attribute::ScalarType ScalarType; + + /** + * @brief Component count + * + * Count of components passed to the shader. If passing smaller count + * of components than corresponding type has, unspecified components + * are set to default values (second and third to `0`, fourth to `1`). + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + enum class Components: GLint { + /** + * Only first component is specified. Second, third and fourth + * component are set to `0`, `0`, `1`, respectively. Only for + * scalar and vector types, not matrices. + */ + One = 1, + + /** + * First two components are specified. Third and fourth component + * are set to `0`, `1`, respectively. Only for two, three and + * four-component vector types and 2x2, 3x2 and 4x2 matrix types. + */ + Two = 2, + + /** + * First three components are specified. Fourth component is set to + * `1`. Only for three and four-component vector types, 2x3, 3x3 + * and 4x3 matrix types. + */ + Three = 3, + + /** + * All four components are specified. Only for four-component + * vector types and 2x4, 3x4 and 4x4 matrix types. + */ + Four = 4, + + #ifndef MAGNUM_TARGET_GLES + /** + * Four components with BGRA ordering. Only for four-component + * float vector type. Must be used along with @ref DataType::UnsignedByte + * and @ref DataOption::Normalized. + * @requires_gl32 Extension @extension{ARB,vertex_array_bgra} + * @requires_gl Only RGBA component ordering is supported in OpenGL + * ES. + */ + BGRA = GL_BGRA + #endif + }; + #else + typedef typename Implementation::Attribute::Components Components; + #endif + + /** + * @brief Data type + * + * Type of data passed to shader. + * @see @ref Type, @ref DataOptions, @ref Attribute() + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */ + Byte = GL_BYTE, /**< Byte */ + UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */ + Short = GL_SHORT, /**< Short */ + UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */ + Int = GL_INT, /**< Int */ + + /** + * Half float. Only for float attribute types. + * @requires_gl30 Extension @extension{ARB,half_float_vertex} + * @requires_gles30 Extension @es_extension{OES,vertex_half_float} + * in OpenGL ES 2.0 + */ + HalfFloat = GL_HALF_FLOAT, + + /** Float. Only for float attribute types. */ + Float = GL_FLOAT, + + #ifndef MAGNUM_TARGET_GLES + /** + * Double. Only for float and double attribute types. + * @requires_gl Only floats are available in OpenGL ES. + */ + Double = GL_DOUBLE, + + /** + * Unsigned 10.11.11 packed float. Only for three-component float + * vector attribute type. + * @requires_gl44 Extension @extension{ARB,vertex_type_10f_11f_11f_rev} + * @requires_gl Packed float attributes are not available in OpenGL + * ES. + */ + UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV, + #endif + + /* GL_FIXED not supported */ + + #ifndef MAGNUM_TARGET_GLES2 + /** + * Unsigned 2.10.10.10 packed integer. Only for four-component + * float vector attribute type. + * @todo How about (incompatible) @es_extension{OES,vertex_type_10_10_10_2}? + * @requires_gl33 Extension @extension{ARB,vertex_type_2_10_10_10_rev} + * @requires_gles30 Packed attributes are not available in OpenGL + * ES 2.0 + */ + UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV, + + /** + * Signed 2.10.10.10 packed integer. Only for four-component float + * vector attribute type. + * @requires_gl33 Extension @extension{ARB,vertex_type_2_10_10_10_rev} + * @requires_gles30 Packed attributes are not available in OpenGL + * ES 2.0 + */ + Int2101010Rev = GL_INT_2_10_10_10_REV + #endif + }; + #else + typedef typename Implementation::Attribute::DataType DataType; + #endif + + /** + * @brief Data option + * @see @ref DataOptions, @ref Attribute() + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + enum class DataOption: UnsignedByte { + /** + * Normalize integer components. Only for float attribute types. + * Default is to not normalize. + */ + Normalized = 1 << 0 + }; + #else + typedef typename Implementation::Attribute::DataOption DataOption; + #endif + + /** + * @brief Data options + * @see @ref Attribute() + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + typedef typename Containers::EnumSet DataOptions; + #else + typedef typename Implementation::Attribute::DataOptions DataOptions; + #endif + + /** + * @brief Constructor + * @param components Component count + * @param dataType Type of passed data. Default is the same as + * type used in shader (e.g. @ref DataType::Int for @ref Vector4i). + * @param dataOptions Data options. Default is no options. + */ + constexpr Attribute(Components components, DataType dataType = Implementation::Attribute::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(components), _dataType(dataType), _dataOptions(dataOptions) {} + + /** + * @brief Constructor + * @param dataType Type of passed data. Default is the same as + * type used in shader (e.g. @ref DataType::Int for @ref Vector4i). + * @param dataOptions Data options. Default is no options. + * + * Component count is set to the same value as in type used in shader + * (e.g. @ref Components::Three for @ref Vector3). + */ + constexpr Attribute(DataType dataType = Implementation::Attribute::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(Implementation::Attribute::DefaultComponents), _dataType(dataType), _dataOptions(dataOptions) {} + + /** @brief Component count of passed data */ + constexpr Components components() const { return _components; } + + /** @brief Type of passed data */ + constexpr DataType dataType() const { return _dataType; } + + /** + * @brief Size of each vector in passed data + * + * @see @ref VectorCount + */ + UnsignedInt vectorSize() const { + return Implementation::Attribute::size(GLint(_components), _dataType); + } + + /** @brief Data options */ + constexpr DataOptions dataOptions() const { return _dataOptions; } + + private: + Components _components; + DataType _dataType; + DataOptions _dataOptions; +}; + +#ifdef DOXYGEN_GENERATING_OUTPUT +/** @debugoperatorclassenum{Magnum::Attribute,Magnum::Attribute::Components} */ +template Debug operator<<(Debug debug, Attribute::Components); + +/** @debugoperatorclassenum{Magnum::Attribute,Magnum::Attribute::DataType} */ +template Debug operator<<(Debug debug, Attribute::DataType); +#endif + +namespace Implementation { + +/* Base for sized attributes */ +template struct SizedAttribute; + +/* Vector attribute sizes */ +template struct SizedVectorAttribute { + enum: UnsignedInt { VectorCount = UnsignedInt(cols) }; +}; +template<> struct SizedAttribute<1, 1>: SizedVectorAttribute<1> { + enum class Components: GLint { One = 1 }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + Components DefaultComponents = Components::One; +}; +template<> struct SizedAttribute<1, 2>: SizedVectorAttribute<1> { + enum class Components: GLint { One = 1, Two = 2 }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + Components DefaultComponents = Components::Two; +}; +template<> struct SizedAttribute<1, 3>: SizedVectorAttribute<1> { + enum class Components: GLint { One = 1, Two = 2, Three = 3 }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + Components DefaultComponents = Components::Three; +}; +template<> struct SizedAttribute<1, 4>: SizedVectorAttribute<1> { + enum class Components: GLint { One = 1, Two = 2, Three = 3, Four = 4 }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + Components DefaultComponents = Components::Four; +}; +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 1>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 2>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 3>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 4>::Components value); + +/* Matrix attribute sizes */ +template struct SizedMatrixAttribute; +template<> struct SizedMatrixAttribute<2> { + enum class Components: GLint { Two = 2 }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + Components DefaultComponents = Components::Two; +}; +template<> struct SizedMatrixAttribute<3> { + enum class Components: GLint { Three = 3 }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + Components DefaultComponents = Components::Three; +}; +template<> struct SizedMatrixAttribute<4> { + enum class Components: GLint { Four = 4 }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + Components DefaultComponents = Components::Four; +}; +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<2>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<3>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<4>::Components value); +template<> struct SizedAttribute<2, 2>: SizedVectorAttribute<2>, SizedMatrixAttribute<2> {}; +template<> struct SizedAttribute<3, 3>: SizedVectorAttribute<3>, SizedMatrixAttribute<3> {}; +template<> struct SizedAttribute<4, 4>: SizedVectorAttribute<4>, SizedMatrixAttribute<4> {}; +#ifndef MAGNUM_TARGET_GLES2 +template<> struct SizedAttribute<2, 3>: SizedVectorAttribute<2>, SizedMatrixAttribute<3> {}; +template<> struct SizedAttribute<3, 2>: SizedVectorAttribute<3>, SizedMatrixAttribute<2> {}; +template<> struct SizedAttribute<2, 4>: SizedVectorAttribute<2>, SizedMatrixAttribute<4> {}; +template<> struct SizedAttribute<4, 2>: SizedVectorAttribute<4>, SizedMatrixAttribute<2> {}; +template<> struct SizedAttribute<3, 4>: SizedVectorAttribute<3>, SizedMatrixAttribute<4> {}; +template<> struct SizedAttribute<4, 3>: SizedVectorAttribute<4>, SizedMatrixAttribute<3> {}; +#endif + +/* Base for attributes */ +template struct Attribute; + +/* Base for float attributes */ +struct FloatAttribute { + typedef Float ScalarType; + + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT, + #ifndef MAGNUM_TARGET_GLES2 + HalfFloat = GL_HALF_FLOAT, + #else + HalfFloat = GL_HALF_FLOAT_OES, + #endif + Float = GL_FLOAT + + #ifndef MAGNUM_TARGET_GLES + , + Double = GL_DOUBLE + #endif + }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + DataType DefaultDataType = DataType::Float; + + enum class DataOption: UnsignedByte { + Normalized = 1 << 0 + }; + typedef Containers::EnumSet DataOptions; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +CORRADE_ENUMSET_OPERATORS(FloatAttribute::DataOptions) + +Debug MAGNUM_EXPORT operator<<(Debug debug, FloatAttribute::DataType value); + +#ifndef MAGNUM_TARGET_GLES2 +/* Base for int attributes */ +struct IntAttribute { + typedef Int ScalarType; + + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT + }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + DataType DefaultDataType = DataType::Int; + + enum class DataOption: UnsignedByte {}; + typedef Containers::EnumSet DataOptions; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +CORRADE_ENUMSET_OPERATORS(IntAttribute::DataOptions) + +Debug MAGNUM_EXPORT operator<<(Debug debug, IntAttribute::DataType value); + +/* Base for unsigned int attributes */ +struct UnsignedIntAttribute { + typedef UnsignedInt ScalarType; + + typedef IntAttribute::DataType DataType; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + DataType DefaultDataType = DataType::UnsignedInt; + + typedef IntAttribute::DataOption DataOption; + typedef IntAttribute::DataOptions DataOptions; + + static UnsignedInt size(GLint components, DataType dataType) { + return IntAttribute::size(components, dataType); + } +}; +#endif + +#ifndef MAGNUM_TARGET_GLES +/* Base for double attributes */ +struct DoubleAttribute { + typedef Double ScalarType; + + enum class DataType: GLenum { + Double = GL_DOUBLE + }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + DataType DefaultDataType = DataType::Double; + + typedef IntAttribute::DataOption DataOption; + typedef IntAttribute::DataOptions DataOptions; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +Debug MAGNUM_EXPORT operator<<(Debug debug, DoubleAttribute::DataType value); +#endif + +/* Floating-point three-component vector has additional data type compared to + classic floats */ +template<> struct Attribute>: SizedAttribute<1, 3> { + typedef Float ScalarType; + + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT, + #ifndef MAGNUM_TARGET_GLES2 + HalfFloat = GL_HALF_FLOAT, + #else + HalfFloat = GL_HALF_FLOAT_OES, + #endif + Float = GL_FLOAT + + #ifndef MAGNUM_TARGET_GLES + , + Double = GL_DOUBLE, + UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV + #endif + }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + DataType DefaultDataType = DataType::Float; + + typedef FloatAttribute::DataOption DataOption; + typedef FloatAttribute::DataOptions DataOptions; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::DataType value); + +/* Floating-point four-component vector is absolutely special case */ +template<> struct Attribute> { + typedef Float ScalarType; + + enum class Components: GLint { + One = 1, + Two = 2, + Three = 3, + Four = 4 + #ifndef MAGNUM_TARGET_GLES + , + BGRA = GL_BGRA + #endif + }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + Components DefaultComponents = Components::Four; + + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT, + #ifndef MAGNUM_TARGET_GLES2 + HalfFloat = GL_HALF_FLOAT, + #else + HalfFloat = GL_HALF_FLOAT_OES, + #endif + Float = GL_FLOAT + #ifndef MAGNUM_TARGET_GLES + , + Double = GL_DOUBLE + #endif + #ifndef MAGNUM_TARGET_GLES2 + , + UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV, + Int2101010Rev = GL_INT_2_10_10_10_REV + #endif + }; + #if !defined(CORRADE_GCC45_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) + constexpr static + #else + static const + #endif + DataType DefaultDataType = DataType::Float; + + typedef FloatAttribute::DataOption DataOption; + typedef FloatAttribute::DataOptions DataOptions; + + enum: UnsignedInt { VectorCount = 1 }; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::DataType value); + +/* Common float, int, unsigned int and double scalar attributes */ +template<> struct Attribute: FloatAttribute, SizedAttribute<1, 1> {}; +#ifndef MAGNUM_TARGET_GLES2 +template<> struct Attribute: IntAttribute, SizedAttribute<1, 1> {}; +template<> struct Attribute: UnsignedIntAttribute, SizedAttribute<1, 1> {}; +#ifndef MAGNUM_TARGET_GLES +template<> struct Attribute: DoubleAttribute, SizedAttribute<1, 1> {}; +#endif +#endif + +/* Common float, int, unsigned int and double vector attributes */ +template struct Attribute>: FloatAttribute, SizedAttribute<1, size_> {}; +#ifndef MAGNUM_TARGET_GLES2 +template struct Attribute>: IntAttribute, SizedAttribute<1, size_> {}; +template struct Attribute>: UnsignedIntAttribute, SizedAttribute<1, size_> {}; +#ifndef MAGNUM_TARGET_GLES +template struct Attribute>: DoubleAttribute, SizedAttribute<1, size_> {}; +#endif +#endif +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; + +/* Common float and double rectangular matrix attributes */ +template struct Attribute>: FloatAttribute, SizedAttribute {}; +#ifndef MAGNUM_TARGET_GLES +template struct Attribute>: DoubleAttribute, SizedAttribute {}; +#endif + +/* Common float and double square matrix attributes */ +template struct Attribute>: Attribute> {}; +#ifndef MAGNUM_TARGET_GLES +template struct Attribute>: Attribute> {}; +#endif +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; + +} + +} + +#endif diff --git a/src/Magnum/Audio/AbstractImporter.cpp b/src/Magnum/Audio/AbstractImporter.cpp index a16c29d9d..c955b0595 100644 --- a/src/Magnum/Audio/AbstractImporter.cpp +++ b/src/Magnum/Audio/AbstractImporter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -35,7 +35,7 @@ AbstractImporter::AbstractImporter() = default; AbstractImporter::AbstractImporter(PluginManager::AbstractManager& manager, std::string plugin): PluginManager::AbstractPlugin(manager, std::move(plugin)) {} -bool AbstractImporter::openData(Containers::ArrayReference data) { +bool AbstractImporter::openData(Containers::ArrayReference data) { CORRADE_ASSERT(features() & Feature::OpenData, "Audio::AbstractImporter::openData(): feature not supported", nullptr); @@ -44,7 +44,7 @@ bool AbstractImporter::openData(Containers::ArrayReference return isOpened(); } -void AbstractImporter::doOpenData(Containers::ArrayReference) { +void AbstractImporter::doOpenData(Containers::ArrayReference) { CORRADE_ASSERT(false, "Audio::AbstractImporter::openData(): feature advertised but not implemented", ); } @@ -83,7 +83,7 @@ UnsignedInt AbstractImporter::frequency() const { return doFrequency(); } -Containers::Array AbstractImporter::data() { +Containers::Array AbstractImporter::data() { #ifndef CORRADE_GCC45_COMPATIBILITY CORRADE_ASSERT(isOpened(), "Audio::AbstractImporter::data(): no file opened", nullptr); #else diff --git a/src/Magnum/Audio/AbstractImporter.h b/src/Magnum/Audio/AbstractImporter.h index 303acf0ff..dce5d9ce9 100644 --- a/src/Magnum/Audio/AbstractImporter.h +++ b/src/Magnum/Audio/AbstractImporter.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -103,7 +103,7 @@ class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin * `true` on success, `false` otherwise. * @see @ref features(), @ref openFile() */ - bool openData(Containers::ArrayReference data); + bool openData(Containers::ArrayReference data); /** * @brief Open file @@ -126,7 +126,7 @@ class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin UnsignedInt frequency() const; /** @brief Sample data */ - Containers::Array data(); + Containers::Array data(); /*@}*/ @@ -142,7 +142,7 @@ class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin virtual bool doIsOpened() const = 0; /** @brief Implementation for @ref openData() */ - virtual void doOpenData(Containers::ArrayReference data); + virtual void doOpenData(Containers::ArrayReference data); /** * @brief Implementation for @ref openFile() @@ -162,7 +162,7 @@ class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin virtual UnsignedInt doFrequency() const = 0; /** @brief Implementation for @ref data() */ - virtual Containers::Array doData() = 0; + virtual Containers::Array doData() = 0; }; }} diff --git a/src/Magnum/Audio/Audio.cpp b/src/Magnum/Audio/Audio.cpp index 940d215c0..c901ba5a9 100644 --- a/src/Magnum/Audio/Audio.cpp +++ b/src/Magnum/Audio/Audio.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Audio/Audio.h b/src/Magnum/Audio/Audio.h index 46865200d..13488dae8 100644 --- a/src/Magnum/Audio/Audio.h +++ b/src/Magnum/Audio/Audio.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,11 +31,13 @@ namespace Magnum { namespace Audio { +#ifndef DOXYGEN_GENERATING_OUTPUT class AbstractImporter; class Buffer; class Context; class Source; /* Renderer used only statically */ +#endif }} diff --git a/src/Magnum/Audio/Buffer.cpp b/src/Magnum/Audio/Buffer.cpp index 5cb5bf167..433f44d59 100644 --- a/src/Magnum/Audio/Buffer.cpp +++ b/src/Magnum/Audio/Buffer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Audio/Buffer.h b/src/Magnum/Audio/Buffer.h index de7147355..5d33e90ca 100644 --- a/src/Magnum/Audio/Buffer.h +++ b/src/Magnum/Audio/Buffer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -112,7 +112,8 @@ inline Buffer::Buffer(Buffer&& other): _id(other._id) { } inline Buffer& Buffer::operator=(Buffer&& other) { - std::swap(_id, other._id); + using std::swap; + swap(_id, other._id); return *this; } diff --git a/src/Magnum/Audio/CMakeLists.txt b/src/Magnum/Audio/CMakeLists.txt index 2dc837505..68f69f923 100644 --- a/src/Magnum/Audio/CMakeLists.txt +++ b/src/Magnum/Audio/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -45,10 +45,15 @@ set(MagnumAudio_HEADERS visibility.h) +# Audio library add_library(MagnumAudio ${SHARED_OR_STATIC} ${MagnumAudio_SRCS} ${MagnumAudio_HEADERS}) set_target_properties(MagnumAudio PROPERTIES DEBUG_POSTFIX "-d") +if(BUILD_STATIC_PIC) + set_target_properties(MagnumAudio PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() + target_link_libraries(MagnumAudio ${CORRADE_PLUGINMANAGER_LIBRARIES} ${OPENAL_LIBRARY}) install(TARGETS MagnumAudio diff --git a/src/Magnum/Audio/Context.cpp b/src/Magnum/Audio/Context.cpp index 6194c561e..480d8ffd0 100644 --- a/src/Magnum/Audio/Context.cpp +++ b/src/Magnum/Audio/Context.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Audio/Context.h b/src/Magnum/Audio/Context.h index 2ef9c37d5..ca79c3639 100644 --- a/src/Magnum/Audio/Context.h +++ b/src/Magnum/Audio/Context.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -71,7 +71,7 @@ class MAGNUM_AUDIO_EXPORT Context { std::string vendorString() const { return alGetString(AL_VENDOR); } /** - * @brief %Renderer string + * @brief Renderer string * * @see @ref vendorString(), @fn_al{GetString} with @def_al{RENDERER} */ diff --git a/src/Magnum/Audio/Renderer.cpp b/src/Magnum/Audio/Renderer.cpp index 9aba583dd..4b75444ab 100644 --- a/src/Magnum/Audio/Renderer.cpp +++ b/src/Magnum/Audio/Renderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Audio/Renderer.h b/src/Magnum/Audio/Renderer.h index c70969c8e..d6842e79e 100644 --- a/src/Magnum/Audio/Renderer.h +++ b/src/Magnum/Audio/Renderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Audio/Source.cpp b/src/Magnum/Audio/Source.cpp index 229b65dc6..838722941 100644 --- a/src/Magnum/Audio/Source.cpp +++ b/src/Magnum/Audio/Source.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Audio/Source.h b/src/Magnum/Audio/Source.h index b3deb0ddf..7ccdf6b4a 100644 --- a/src/Magnum/Audio/Source.h +++ b/src/Magnum/Audio/Source.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -42,7 +42,7 @@ namespace Magnum { namespace Audio { /** -@brief %Source +@brief Source Manages positional audio source. @todo Expose convenient API for buffer queuing @@ -327,7 +327,7 @@ class MAGNUM_AUDIO_EXPORT Source { /** @{ @name Buffer management */ /** - * @brief %Source type + * @brief Source type * * @see @ref type() */ @@ -338,7 +338,7 @@ class MAGNUM_AUDIO_EXPORT Source { }; /** - * @brief %Source type + * @brief Source type * * @see @ref setBuffer(), @fn_al{GetSourcei} with @def_al{SOURCE_TYPE} */ @@ -346,7 +346,7 @@ class MAGNUM_AUDIO_EXPORT Source { /** * @brief Attach buffer - * @param buffer %Buffer to attach or `nullptr` + * @param buffer Buffer to attach or `nullptr` * @return Reference to self (for method chaining) * * If an buffer is attached, changes source type to @ref Type::Static, @@ -361,7 +361,7 @@ class MAGNUM_AUDIO_EXPORT Source { /** @{ @name State management */ /** - * @brief %Source state + * @brief Source state * * @see @ref state(), @ref play(), @ref pause(), @ref stop(), * @ref rewind() @@ -594,7 +594,8 @@ inline Source::Source(Source&& other): _id(other._id) { } inline Source& Source::operator=(Source&& other) { - std::swap(_id, other._id); + using std::swap; + swap(_id, other._id); return *this; } diff --git a/src/Magnum/Audio/Test/AbstractImporterTest.cpp b/src/Magnum/Audio/Test/AbstractImporterTest.cpp index 86bcf0d6e..df26475f5 100644 --- a/src/Magnum/Audio/Test/AbstractImporterTest.cpp +++ b/src/Magnum/Audio/Test/AbstractImporterTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,11 +33,10 @@ namespace Magnum { namespace Audio { namespace Test { -class AbstractImporterTest: public TestSuite::Tester { - public: - explicit AbstractImporterTest(); +struct AbstractImporterTest: TestSuite::Tester { + explicit AbstractImporterTest(); - void openFile(); + void openFile(); }; AbstractImporterTest::AbstractImporterTest() { @@ -54,13 +53,13 @@ void AbstractImporterTest::openFile() { bool doIsOpened() const override { return opened; } void doClose() override {} - void doOpenData(Containers::ArrayReference data) override { - opened = (data.size() == 1 && data[0] == 0xa5); + void doOpenData(Containers::ArrayReference data) override { + opened = (data.size() == 1 && data[0] == '\xa5'); } Buffer::Format doFormat() const override { return Buffer::Format(); } UnsignedInt doFrequency() const override { return {}; } - Corrade::Containers::Array doData() override { + Corrade::Containers::Array doData() override { #ifndef CORRADE_GCC45_COMPATIBILITY return nullptr; #else diff --git a/src/Magnum/Audio/Test/BufferTest.cpp b/src/Magnum/Audio/Test/BufferTest.cpp index d21a08abf..187fa3d32 100644 --- a/src/Magnum/Audio/Test/BufferTest.cpp +++ b/src/Magnum/Audio/Test/BufferTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Audio { namespace Test { -class BufferTest: public TestSuite::Tester { - public: - explicit BufferTest(); +struct BufferTest: TestSuite::Tester { + explicit BufferTest(); - void debugFormat(); + void debugFormat(); }; BufferTest::BufferTest() { diff --git a/src/Magnum/Audio/Test/CMakeLists.txt b/src/Magnum/Audio/Test/CMakeLists.txt index aa0e53f5b..a7dfefa5d 100644 --- a/src/Magnum/Audio/Test/CMakeLists.txt +++ b/src/Magnum/Audio/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Audio/Test/RendererTest.cpp b/src/Magnum/Audio/Test/RendererTest.cpp index c580acc07..5d3ae3829 100644 --- a/src/Magnum/Audio/Test/RendererTest.cpp +++ b/src/Magnum/Audio/Test/RendererTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Audio { namespace Test { -class RendererTest: public TestSuite::Tester { - public: - explicit RendererTest(); +struct RendererTest: TestSuite::Tester { + explicit RendererTest(); - void debugError(); + void debugError(); }; RendererTest::RendererTest() { diff --git a/src/Magnum/Audio/Test/SourceTest.cpp b/src/Magnum/Audio/Test/SourceTest.cpp index bac17f07d..d11361fa5 100644 --- a/src/Magnum/Audio/Test/SourceTest.cpp +++ b/src/Magnum/Audio/Test/SourceTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Audio { namespace Test { -class SourceTest: public TestSuite::Tester { - public: - explicit SourceTest(); +struct SourceTest: TestSuite::Tester { + explicit SourceTest(); - void debugState(); + void debugState(); }; SourceTest::SourceTest() { diff --git a/src/Magnum/Audio/Test/configure.h.cmake b/src/Magnum/Audio/Test/configure.h.cmake index a931fa1f8..0cafe472d 100644 --- a/src/Magnum/Audio/Test/configure.h.cmake +++ b/src/Magnum/Audio/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Audio/visibility.h b/src/Magnum/Audio/visibility.h index c903ab19d..38944f927 100644 --- a/src/Magnum/Audio/visibility.h +++ b/src/Magnum/Audio/visibility.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Buffer.cpp b/src/Magnum/Buffer.cpp index 275bff5cc..e77f22851 100644 --- a/src/Magnum/Buffer.cpp +++ b/src/Magnum/Buffer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -144,7 +144,7 @@ void Buffer::unbind(const Target target, const UnsignedInt firstIndex, const std /** @todoc const std::initializer_list makes Doxygen grumpy */ void Buffer::bind(const Target target, const UnsignedInt firstIndex, std::initializer_list> buffers) { #ifdef MAGNUM_BUILD_DEPRECATED - CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform); + CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform || GLenum(target) == GL_TRANSFORM_FEEDBACK_BUFFER); #endif Context::current()->state().buffer->bindRangesImplementation(target, firstIndex, {buffers.begin(), buffers.size()}); } @@ -152,7 +152,7 @@ void Buffer::bind(const Target target, const UnsignedInt firstIndex, std::initia /** @todoc const std::initializer_list makes Doxygen grumpy */ void Buffer::bind(const Target target, const UnsignedInt firstIndex, std::initializer_list buffers) { #ifdef MAGNUM_BUILD_DEPRECATED - CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform); + CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform || GLenum(target) == GL_TRANSFORM_FEEDBACK_BUFFER); #endif Context::current()->state().buffer->bindBasesImplementation(target, firstIndex, {buffers.begin(), buffers.size()}); } @@ -247,7 +247,7 @@ void Buffer::bindInternal(const TargetHint target, Buffer* const buffer) { /* Bind the buffer otherwise, which will also finally create it */ bound = id; - buffer->_created = true; + if(buffer) buffer->_created = true; glBindBuffer(GLenum(target), id); } @@ -273,7 +273,7 @@ auto Buffer::bindSomewhereInternal(const TargetHint hint) -> TargetHint { #ifndef MAGNUM_TARGET_GLES2 Buffer& Buffer::bind(const Target target, const UnsignedInt index, const GLintptr offset, const GLsizeiptr size) { #ifdef MAGNUM_BUILD_DEPRECATED - CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform); + CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform || GLenum(target) == GL_TRANSFORM_FEEDBACK_BUFFER); #endif glBindBufferRange(GLenum(target), index, _id, offset, size); return *this; @@ -281,7 +281,7 @@ Buffer& Buffer::bind(const Target target, const UnsignedInt index, const GLintpt Buffer& Buffer::bind(const Target target, const UnsignedInt index) { #ifdef MAGNUM_BUILD_DEPRECATED - CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform); + CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform || GLenum(target) == GL_TRANSFORM_FEEDBACK_BUFFER); #endif glBindBufferBase(GLenum(target), index, _id); return *this; @@ -389,7 +389,8 @@ void Buffer::bindImplementationMulti(const Target target, const GLuint firstInde } #endif -void Buffer::bindImplementationFallback(const Target target, const GLuint firstIndex, const Containers::ArrayReference> buffers) { +/** @todoc const Containers::ArrayReference makes Doxygen grumpy */ +void Buffer::bindImplementationFallback(const Target target, const GLuint firstIndex, Containers::ArrayReference> buffers) { for(std::size_t i = 0; i != buffers.size(); ++i) { if(buffers && std::get<0>(buffers[i])) std::get<0>(buffers[i])->bind(target, firstIndex + i, std::get<1>(buffers[i]), std::get<2>(buffers[i])); @@ -398,7 +399,8 @@ void Buffer::bindImplementationFallback(const Target target, const GLuint firstI } #ifndef MAGNUM_TARGET_GLES -void Buffer::bindImplementationMulti(const Target target, const GLuint firstIndex, const Containers::ArrayReference> buffers) { +/** @todoc const Containers::ArrayReference makes Doxygen grumpy */ +void Buffer::bindImplementationMulti(const Target target, const GLuint firstIndex, Containers::ArrayReference> buffers) { /** @todo use ArrayTuple */ Containers::Array ids{buffers ? buffers.size() : 0}; Containers::Array offsetsSizes{buffers ? buffers.size()*2 : 0}; @@ -425,6 +427,10 @@ void Buffer::copyImplementationDefault(Buffer& read, Buffer& write, GLintptr rea } #ifndef MAGNUM_TARGET_GLES +void Buffer::copyImplementationDSA(Buffer& read, Buffer& write, const GLintptr readOffset, const GLintptr writeOffset, const GLsizeiptr size) { + glCopyNamedBufferSubData(read._id, write._id, readOffset, writeOffset, size); +} + void Buffer::copyImplementationDSAEXT(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { read._created = write._created = true; glNamedCopyBufferSubDataEXT(read._id, write._id, readOffset, writeOffset, size); @@ -437,6 +443,10 @@ void Buffer::getParameterImplementationDefault(const GLenum value, GLint* const } #ifndef MAGNUM_TARGET_GLES +void Buffer::getParameterImplementationDSA(const GLenum value, GLint* const data) { + glGetNamedBufferParameteriv(_id, value, data); +} + void Buffer::getParameterImplementationDSAEXT(const GLenum value, GLint* const data) { _created = true; glGetNamedBufferParameterivEXT(_id, value, data); @@ -448,6 +458,10 @@ void Buffer::getSubDataImplementationDefault(const GLintptr offset, const GLsize glGetBufferSubData(GLenum(bindSomewhereInternal(_targetHint)), offset, size, data); } +void Buffer::getSubDataImplementationDSA(const GLintptr offset, const GLsizeiptr size, GLvoid* const data) { + glGetNamedBufferSubData(_id, offset, size, data); +} + void Buffer::getSubDataImplementationDSAEXT(const GLintptr offset, const GLsizeiptr size, GLvoid* const data) { _created = true; glGetNamedBufferSubDataEXT(_id, offset, size, data); @@ -459,6 +473,10 @@ void Buffer::dataImplementationDefault(GLsizeiptr size, const GLvoid* data, Buff } #ifndef MAGNUM_TARGET_GLES +void Buffer::dataImplementationDSA(const GLsizeiptr size, const GLvoid* const data, const BufferUsage usage) { + glNamedBufferData(_id, size, data, GLenum(usage)); +} + void Buffer::dataImplementationDSAEXT(GLsizeiptr size, const GLvoid* data, BufferUsage usage) { _created = true; glNamedBufferDataEXT(_id, size, data, GLenum(usage)); @@ -470,6 +488,10 @@ void Buffer::subDataImplementationDefault(GLintptr offset, GLsizeiptr size, cons } #ifndef MAGNUM_TARGET_GLES +void Buffer::subDataImplementationDSA(const GLintptr offset, const GLsizeiptr size, const GLvoid* const data) { + glNamedBufferSubData(_id, offset, size, data); +} + void Buffer::subDataImplementationDSAEXT(GLintptr offset, GLsizeiptr size, const GLvoid* data) { _created = true; glNamedBufferSubDataEXT(_id, offset, size, data); @@ -506,6 +528,10 @@ void* Buffer::mapImplementationDefault(MapAccess access) { } #ifndef MAGNUM_TARGET_GLES +void* Buffer::mapImplementationDSA(const MapAccess access) { + return glMapNamedBuffer(_id, GLenum(access)); +} + void* Buffer::mapImplementationDSAEXT(MapAccess access) { _created = true; return glMapNamedBufferEXT(_id, GLenum(access)); @@ -526,6 +552,10 @@ void* Buffer::mapRangeImplementationDefault(GLintptr offset, GLsizeiptr length, } #ifndef MAGNUM_TARGET_GLES +void* Buffer::mapRangeImplementationDSA(const GLintptr offset, const GLsizeiptr length, const MapFlags access) { + return glMapNamedBufferRange(_id, offset, length, GLenum(access)); +} + void* Buffer::mapRangeImplementationDSAEXT(GLintptr offset, GLsizeiptr length, MapFlags access) { _created = true; return glMapNamedBufferRangeEXT(_id, offset, length, GLenum(access)); @@ -545,6 +575,10 @@ void Buffer::flushMappedRangeImplementationDefault(GLintptr offset, GLsizeiptr l } #ifndef MAGNUM_TARGET_GLES +void Buffer::flushMappedRangeImplementationDSA(const GLintptr offset, const GLsizeiptr length) { + glFlushMappedNamedBufferRange(_id, offset, length); +} + void Buffer::flushMappedRangeImplementationDSAEXT(GLintptr offset, GLsizeiptr length) { _created = true; glFlushMappedNamedBufferRangeEXT(_id, offset, length); @@ -562,6 +596,10 @@ bool Buffer::unmapImplementationDefault() { } #ifndef MAGNUM_TARGET_GLES +bool Buffer::unmapImplementationDSA() { + return glUnmapNamedBuffer(_id); +} + bool Buffer::unmapImplementationDSAEXT() { _created = true; return glUnmapNamedBufferEXT(_id); diff --git a/src/Magnum/Buffer.h b/src/Magnum/Buffer.h index 482d9f0a8..fc0afa13f 100644 --- a/src/Magnum/Buffer.h +++ b/src/Magnum/Buffer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,10 +40,14 @@ #include "Magnum/AbstractObject.h" #include "Magnum/Magnum.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif + namespace Magnum { /** -@brief %Buffer usage +@brief Buffer usage @see @ref Buffer, @ref Buffer::setData(Containers::ArrayReference, BufferUsage) */ @@ -118,7 +122,7 @@ enum class BufferUsage: GLenum { namespace Implementation { struct BufferState; } /** -@brief %Buffer +@brief Buffer Encapsulates one OpenGL buffer object and provides functions for convenient data updates. @@ -142,7 +146,7 @@ buffer.setData(data, BufferUsage::StaticDraw); @anchor Buffer-data-mapping ## Memory mapping -%Buffer data can be also updated asynchronously. First you need to allocate +Buffer data can be also updated asynchronously. First you need to allocate the buffer to desired size by passing `nullptr` to @ref setData(), e.g.: @code buffer.setData({nullptr, 200*sizeof(Vector3)}, BufferUsage::StaticDraw); @@ -173,7 +177,7 @@ CORRADE_INTERNAL_ASSERT_OUTPUT(buffer.unmap()); Buffers in @ref MAGNUM_TARGET_WEBGL "WebGL" and @ref CORRADE_TARGET_NACL "NaCl" need to be bound only to one unique target, i.e., @ref Buffer bound to @ref Buffer::Target::Array cannot be later rebound to -@ref Buffer::Target::ElementArray. However, %Magnum by default uses any +@ref Buffer::Target::ElementArray. However, Magnum by default uses any sufficient target when binding the buffer internally (e.g. for setting data). To avoid GL errors, set target hint to desired target, either in constructor or using @ref Buffer::setTargetHint(): @@ -192,14 +196,16 @@ The engine tracks currently bound buffers to avoid unnecessary calls to @ref copy(), @ref setData(), @ref setSubData(), @ref map(), @ref flushMappedRange() and @ref unmap() use that target instead of binding the buffer to some specific target. You can also use @ref setTargetHint() to possibly reduce unnecessary -rebinding. %Buffer limits and implementation-defined values (such as +rebinding. Buffer limits and implementation-defined values (such as @ref maxUniformBindings()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. -If extension @extension{EXT,direct_state_access} is available, functions -@ref copy(), @ref setData(), @ref setSubData(), @ref map(), @ref flushMappedRange() -and @ref unmap() use DSA functions to avoid unnecessary calls to -@fn_gl{BindBuffer}. See their respective documentation for more information. +If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL +4.5) or @extension{EXT,direct_state_access} is available, functions +@ref copy(), @ref size(), @ref data(), @ref subData(), @ref setData(), +@ref setSubData(), @ref map(), @ref flushMappedRange() and @ref unmap() use DSA +functions to avoid unnecessary calls to @fn_gl{BindBuffer}. See their +respective documentation for more information. You can use functions @ref invalidateData() and @ref invalidateSubData() if you don't need buffer data anymore to avoid unnecessary memory operations performed @@ -208,11 +214,11 @@ by OpenGL in order to preserve the data. If running on OpenGL ES or extension functions do nothing. */ class MAGNUM_EXPORT Buffer: public AbstractObject { - friend struct Implementation::BufferState; + friend Implementation::BufferState; public: /** - * @brief %Buffer target + * @brief Buffer target * * @see @ref Buffer(), @ref setTargetHint() */ @@ -223,7 +229,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { #ifndef MAGNUM_TARGET_GLES2 /** * Used for storing atomic counters. - * @requires_gl42 %Extension @extension{ARB,shader_atomic_counters} + * @requires_gl42 Extension @extension{ARB,shader_atomic_counters} * @requires_gles31 Atomic counters are not available in OpenGL ES * 3.0 and older. */ @@ -231,7 +237,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * Source for copies. See @ref copy(). - * @requires_gl31 %Extension @extension{ARB,copy_buffer} + * @requires_gl31 Extension @extension{ARB,copy_buffer} * @requires_gles30 Buffer copying is not available in OpenGL ES * 2.0. */ @@ -239,7 +245,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * Target for copies. See @ref copy(). - * @requires_gl31 %Extension @extension{ARB,copy_buffer} + * @requires_gl31 Extension @extension{ARB,copy_buffer} * @requires_gles30 Buffer copying is not available in OpenGL ES * 2.0. */ @@ -247,7 +253,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * Indirect compute dispatch commands. - * @requires_gl43 %Extension @extension{ARB,compute_shader} + * @requires_gl43 Extension @extension{ARB,compute_shader} * @requires_gles31 Compute shaders are not available in OpenGL ES * 3.0 and older. */ @@ -255,7 +261,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * Used for supplying arguments for indirect drawing. - * @requires_gl40 %Extension @extension{ARB,draw_indirect} + * @requires_gl40 Extension @extension{ARB,draw_indirect} * @requires_gles31 Indirect drawing not available in OpenGL ES 3.0 * and older. */ @@ -282,7 +288,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * Used for shader storage. - * @requires_gl43 %Extension @extension{ARB,shader_storage_buffer_object} + * @requires_gl43 Extension @extension{ARB,shader_storage_buffer_object} * @requires_gles31 Shader storage is not available in OpenGL ES * 3.0 and older. */ @@ -292,7 +298,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { #ifndef MAGNUM_TARGET_GLES /** * Source for texel fetches. See @ref BufferTexture. - * @requires_gl31 %Extension @extension{ARB,texture_buffer_object} + * @requires_gl31 Extension @extension{ARB,texture_buffer_object} * @requires_gl Texture buffers are not available in OpenGL ES. */ Texture = GL_TEXTURE_BUFFER, @@ -301,7 +307,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { #ifndef MAGNUM_TARGET_GLES2 /** * Target for transform feedback. - * @requires_gl30 %Extension @extension{EXT,transform_feedback} + * @requires_gl30 Extension @extension{EXT,transform_feedback} * @requires_gles30 Transform feedback is not available in OpenGL * ES 2.0. */ @@ -309,7 +315,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * Used for storing uniforms. - * @requires_gl31 %Extension @extension{ARB,uniform_buffer_object} + * @requires_gl31 Extension @extension{ARB,uniform_buffer_object} * @requires_gles30 Uniform buffers are not available in OpenGL ES * 2.0. */ @@ -319,7 +325,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { #if !defined(MAGNUM_TARGET_GLES2) || defined(MAGNUM_BUILD_DEPRECATED) /** - * @brief %Buffer binding target + * @brief Buffer binding target * * @see @ref bind(), @ref unbind() */ @@ -337,7 +343,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { #ifndef MAGNUM_TARGET_GLES2 /** * Atomic counter binding - * @requires_gl42 %Extension @extension{ARB,shader_atomic_counters} + * @requires_gl42 Extension @extension{ARB,shader_atomic_counters} * @requires_gles31 Atomic counters are not available in OpenGL ES * 3.0 and older */ @@ -411,7 +417,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { #ifndef MAGNUM_TARGET_GLES2 /** * Shader storage binding - * @requires_gl43 %Extension @extension{ARB,shader_storage_buffer_object} + * @requires_gl43 Extension @extension{ARB,shader_storage_buffer_object} * @requires_gles31 Shader storage is not available in OpenGL ES * 3.0 and older */ @@ -441,7 +447,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { #ifndef MAGNUM_TARGET_GLES2 /** * Uniform binding - * @requires_gl31 %Extension @extension{ARB,uniform_buffer_object} + * @requires_gl31 Extension @extension{ARB,uniform_buffer_object} * @requires_gles30 Uniform buffers are not available in OpenGL ES * 2.0 */ @@ -462,7 +468,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @brief Memory mapping access * * @see @ref map(MapAccess), @ref mapSub() - * @requires_es_extension %Extension @es_extension{OES,mapbuffer} or + * @requires_es_extension Extension @es_extension{OES,mapbuffer} or * @es_extension{CHROMIUM,map_sub} * @deprecated_gl Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * instead, as it has more complete set of features. @@ -496,8 +502,8 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @brief Memory mapping flag * * @see @ref MapFlags, @ref map(GLintptr, GLsizeiptr, MapFlags) - * @requires_gl30 %Extension @extension{ARB,map_buffer_range} - * @requires_gles30 %Extension @es_extension{EXT,map_buffer_range} in + * @requires_gl30 Extension @extension{ARB,map_buffer_range} + * @requires_gles30 Extension @es_extension{EXT,map_buffer_range} in * OpenGL ES 2.0 */ enum class MapFlag: GLbitfield { @@ -563,8 +569,8 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @brief Memory mapping flags * * @see @ref map(GLintptr, GLsizeiptr, MapFlags) - * @requires_gl30 %Extension @extension{ARB,map_buffer_range} - * @requires_gles30 %Extension @es_extension{EXT,map_buffer_range} in + * @requires_gl30 Extension @extension{ARB,map_buffer_range} + * @requires_gles30 Extension @es_extension{EXT,map_buffer_range} in * OpenGL ES 2.0 */ typedef Containers::EnumSet MapFlags; @@ -653,7 +659,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @fn_gl{BindBufferBase} * @requires_gl30 No form of indexed buffer binding is available in * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target" - * values for version requirements. + * values for version/extension requirements. * @requires_gles30 No form of indexed buffer binding is available in * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target" * values for version requirements. @@ -676,7 +682,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @fn_gl{BindBuffersBase} or @fn_gl{BindBufferBase} * @requires_gl30 No form of indexed buffer binding is available in * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target" - * values for version requirements. + * values for version/extension requirements. * @requires_gles30 No form of indexed buffer binding is available in * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target" * values for version requirements. @@ -691,9 +697,10 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * any buffer is `nullptr`, given indexed target is unbound. The range * of indices must respect limits for given @p target. The offsets must * respect alignment, which is 4 bytes for @ref Target::AtomicCounter - * and implementation-defined for other targets. If @extension{ARB,multi_bind} - * (part of OpenGL 4.4) is not available, the feature is emulated with - * sequence of @ref bind(Target, UnsignedInt, GLintptr, GLsizeiptr) / + * and implementation-defined for other targets. All the buffers must + * have allocated data store. If @extension{ARB,multi_bind} (part of + * OpenGL 4.4) is not available, the feature is emulated with sequence + * of @ref bind(Target, UnsignedInt, GLintptr, GLsizeiptr) / * @ref unbind(Target, UnsignedInt) calls. * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation @@ -701,11 +708,11 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @see @ref bind(Target, UnsignedInt, GLintptr, GLsizeiptr), * @ref maxAtomicCounterBindings(), @ref maxShaderStorageBindings(), * @ref maxUniformBindings(), @ref shaderStorageOffsetAlignment(), - * @ref uniformOffsetAlignment(), @fn_gl{BindBuffersRange} or - * @fn_gl{BindBufferRange} + * @ref uniformOffsetAlignment(), @ref TransformFeedback::attachBuffers(), + * @fn_gl{BindBuffersRange} or @fn_gl{BindBufferRange} * @requires_gl30 No form of indexed buffer binding is available in * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target" - * values for version requirements. + * values for version/extension requirements. * @requires_gles30 No form of indexed buffer binding is available in * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target" * values for version requirements. @@ -718,19 +725,20 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * Binds first buffer in the list to @p firstIndex, second to * `firstIndex + 1` etc. If any buffer is `nullptr`, given indexed * target is unbound. The range of indices must respect limits for - * given @p target. If @extension{ARB,multi_bind} (part of OpenGL 4.4) - * is not available, the feature is emulated with sequence of - * @ref bind(Target, UnsignedInt) / @ref unbind(Target, UnsignedInt) - * calls. + * given @p target. All the buffers must have allocated data store. If + * @extension{ARB,multi_bind} (part of OpenGL 4.4) is not available, + * the feature is emulated with sequence of @ref bind(Target, UnsignedInt) + * / @ref unbind(Target, UnsignedInt) calls. * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. * @see @ref bind(Target, UnsignedInt), @ref maxAtomicCounterBindings(), * @ref maxShaderStorageBindings(), @ref maxUniformBindings(), - * @fn_gl{BindBuffersBase} or @fn_gl{BindBufferBase} + * @ref TransformFeedback::attachBuffers(), @fn_gl{BindBuffersBase} + * or @fn_gl{BindBufferBase} * @requires_gl30 No form of indexed buffer binding is available in * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target" - * values for version requirements. + * values for version/extension requirements. * @requires_gles30 No form of indexed buffer binding is available in * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target" * values for version requirements. @@ -739,20 +747,21 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * @brief Copy one buffer to another - * @param read %Buffer from which to read - * @param write %Buffer to which to copy + * @param read Buffer from which to read + * @param write Buffer to which to copy * @param readOffset Offset in the read buffer * @param writeOffset Offset in the write buffer * @param size Data size * - * If @extension{EXT,direct_state_access} is not available and the - * buffers aren't already bound somewhere, they are bound to - * @ref Target::CopyRead and @ref Target::CopyWrite before the copy is - * performed. - * @see @fn_gl{BindBuffer} and @fn_gl{CopyBufferSubData} or - * @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access} - * @requires_gl31 %Extension @extension{ARB,copy_buffer} - * @requires_gles30 %Buffer copying is not available in OpenGL ES 2.0. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * @p read buffer is bound for reading and @p write buffer is bound for + * writing before the copy is performed (if not already). + * @see @fn_gl2{CopyNamedBufferSubData,CopyBufferSubData}, + * @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{CopyBufferSubData} + * @requires_gl31 Extension @extension{ARB,copy_buffer} + * @requires_gles30 Buffer copying is not available in OpenGL ES 2.0. */ static void copy(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); #endif @@ -802,7 +811,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { GLuint id() const { return _id; } /** - * @brief %Buffer label + * @brief Buffer label * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. If OpenGL 4.3 is not supported and neither @@ -831,7 +840,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** @overload */ template Buffer& setLabel(const char(&label)[size]) { - return setLabelInternal(label); + return setLabelInternal({label, size - 1}); } /** @brief Target hint */ @@ -841,12 +850,12 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @brief Set target hint * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, the buffer - * must be internally bound to some target before any operation. You - * can specify target which will always be used when binding the buffer - * internally, possibly saving some calls to @fn_gl{BindBuffer}. - * - * Default target hint is @ref Target::Array. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the buffer needs to be internally bound to some target before any + * operation. You can specify target which will always be used when + * binding the buffer internally, possibly saving some calls to + * @fn_gl{BindBuffer}. Default target hint is @ref Target::Array. * @see @ref setData(), @ref setSubData() * @todo Target::ElementArray cannot be used when no VAO is bound - * http://www.opengl.org/wiki/Vertex_Specification#Index_buffers @@ -875,17 +884,18 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * The @p index parameter must respect limits for given @p target. The * @p offset parameter must respect alignment, which is 4 bytes for * @ref Target::AtomicCounter and implementation-defined for other - * targets. + * targets. The buffer must have allocated data store. * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. * @see @ref bind(Target, UnsignedInt, std::initializer_list>), * @ref maxAtomicCounterBindings(), @ref maxShaderStorageBindings(), * @ref maxUniformBindings(), @ref shaderStorageOffsetAlignment(), - * @ref uniformOffsetAlignment(), @fn_gl{BindBufferRange} + * @ref uniformOffsetAlignment(), @ref TransformFeedback::attachBuffer(), + * @fn_gl{BindBufferRange} * @requires_gl30 No form of indexed buffer binding is available in * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target" - * values for version requirements. + * values for version/extension requirements. * @requires_gles30 No form of indexed buffer binding is available in * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target" * values for version requirements. @@ -896,16 +906,18 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * @brief Bind buffer to given binding index * - * The @p index parameter must respect limits for given @p target. + * The @p index parameter must respect limits for given @p target. The + * buffer must have allocated data store. * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. * @see @ref bind(Target, UnsignedInt, std::initializer_list), * @ref maxAtomicCounterBindings(), @ref maxShaderStorageBindings(), - * @ref maxUniformBindings(), @fn_gl{BindBufferBase} + * @ref maxUniformBindings(), @ref TransformFeedback::attachBuffer(), + * @fn_gl{BindBufferBase} * @requires_gl30 No form of indexed buffer binding is available in * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target" - * values for version requirements. + * values for version/extension requirements. * @requires_gles30 No form of indexed buffer binding is available in * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target" * values for version requirements. @@ -914,62 +926,70 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { #endif /** - * @brief %Buffer size + * @brief Buffer size * - * If @extension{EXT,direct_state_access} is not available and the - * buffer is not already bound somewhere, it is bound to hinted target - * before the operation. - * @see @fn_gl{BindBuffer} and @fn_gl{GetBufferParameter} or - * @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access} - * with @def_gl{BUFFER_SIZE} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the buffer is bound to hinted target before the operation (if not + * already). + * @see @ref setTargetHint(), @fn_gl2{GetNamedBufferParameter,GetBufferParameter}, + * @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{GetBufferParameter} */ Int size(); #ifndef MAGNUM_TARGET_GLES /** - * @brief %Buffer data + * @brief Buffer data * - * Returns data of whole buffer. If @extension{EXT,direct_state_access} - * is not available and the buffer is not already bound somewhere, it - * is bound to hinted target before the operation. - * @see @ref size(), @ref subData(), @ref setData(), @fn_gl{BindBuffer} - * and @fn_gl{GetBufferParameter} or - * @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access} - * with @def_gl{BUFFER_SIZE}, @fn_gl{GetBufferSubData} or - * @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access} - * @requires_gl %Buffer data queries are not available in OpenGL ES. + * Returns data of whole buffer. If neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the buffer is bound to hinted target before the operation + * (if not already). + * @see @ref size(), @ref subData(), @ref setData(), @ref setTargetHint(), + * @fn_gl2{GetNamedBufferParameter,GetBufferParameter}, + * @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{GetBufferParameter} + * with @def_gl{BUFFER_SIZE}, then @fn_gl2{GetNamedBufferSubData,GetBufferSubData}, + * @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access}, + * eventually @fn_gl{GetBufferSubData} + * @requires_gl Buffer data queries are not available in OpenGL ES. * Use @ref Magnum::Buffer::map() "map()" instead. */ - template Containers::Array data(); + template Containers::Array data(); /** - * @brief %Buffer subdata + * @brief Buffer subdata * @param offset Byte offset in the buffer * @param size Data size (count of @p T values) * - * Returns data of given buffer portion. If @extension{EXT,direct_state_access} - * is not available and the buffer is not already bound somewhere, it - * is bound to hinted target before the operation. - * @see @ref size(), @ref data(), @ref setSubData(), @fn_gl{BindBuffer} - * and @fn_gl{GetBufferSubData} or - * @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access} - * @requires_gl %Buffer data queries are not available in OpenGL ES. + * Returns data of given buffer portion. If neither + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the buffer is + * bound to hinted target before the operation (if not already). + * @see @ref size(), @ref data(), @ref setSubData(), @ref setTargetHint(), + * @fn_gl2{GetNamedBufferSubData,GetBufferSubData}, + * @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{GetBufferSubData} + * @requires_gl Buffer data queries are not available in OpenGL ES. * Use @ref Magnum::Buffer::map() "map()" instead. */ - template Containers::Array subData(GLintptr offset, GLsizeiptr size); + template Containers::Array subData(GLintptr offset, GLsizeiptr size); #endif /** * @brief Set buffer data * @param data Data - * @param usage %Buffer usage + * @param usage Buffer usage * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available and the - * buffer is not already bound somewhere, it is bound to hinted target - * before the operation. - * @see @ref setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferData} - * or @fn_gl_extension{NamedBufferData,EXT,direct_state_access} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the buffer is bound to hinted target before the operation (if not + * already). + * @see @ref setTargetHint(), @fn_gl2{NamedBufferData,BufferData}, + * @fn_gl_extension{NamedBufferData,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{BufferData} */ Buffer& setData(Containers::ArrayReference data, BufferUsage usage); @@ -991,11 +1011,13 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @param data Data * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available and the - * buffer is not already bound somewhere, it is bound to hinted target - * before the operation. - * @see @ref setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferSubData} - * or @fn_gl_extension{NamedBufferSubData,EXT,direct_state_access} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the buffer is bound to hinted target before the operation (if not + * already). + * @see @ref setTargetHint(), @fn_gl2{NamedBufferSubData,BufferSubData}, + * @fn_gl_extension{NamedBufferSubData,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{BufferSubData} */ Buffer& setSubData(GLintptr offset, Containers::ArrayReference data); @@ -1038,13 +1060,15 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @param access Access * @return Pointer to buffer data * - * If @extension{EXT,direct_state_access} is not available and the - * buffer is not already bound somewhere, it is bound to hinted target - * before the operation. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the buffer is bound to hinted target before the operation (if not + * already). * @see @ref minMapAlignment(), @ref unmap(), @ref setTargetHint(), - * @fn_gl{BindBuffer} and @fn_gl{MapBuffer} or - * @fn_gl_extension{MapNamedBuffer,EXT,direct_state_access} - * @requires_es_extension %Extension @es_extension{OES,mapbuffer} in + * @fn_gl2{MapNamedBuffer,MapBuffer}, + * @fn_gl_extension{MapNamedBuffer,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{MapBuffer} + * @requires_es_extension Extension @es_extension{OES,mapbuffer} in * OpenGL ES 2.0, use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * in OpenGL ES 3.0 instead. * @deprecated_gl Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" @@ -1060,14 +1084,14 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @param access Access * @return Pointer to buffer data * - * If the buffer is not already bound somewhere, it is bound to hinted - * target before the operation. + * The buffer is bound to hinted target before the operation (if not + * already). * @see @ref unmapSub(), @ref setTargetHint(), * @fn_gl_extension{MapBufferSubData,CHROMIUM,map_sub} * @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use * @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * instead. - * @requires_es_extension %Extension @es_extension{CHROMIUM,map_sub} + * @requires_es_extension Extension @es_extension{CHROMIUM,map_sub} * @deprecated_gl Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * instead, as it has more complete set of features. */ @@ -1082,14 +1106,17 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @ref MapFlag::Write must be specified. * @return Pointer to buffer data * - * If @extension{EXT,direct_state_access} is not available and the - * buffer is not already bound somewhere, it is bound to hinted target - * before the operation. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the buffer is bound to hinted target before the operation (if not + * already). * @see @ref minMapAlignment(), @ref flushMappedRange(), @ref unmap(), - * @ref map(MapAccess), @ref setTargetHint(), @fn_gl{BindBuffer} - * and @fn_gl{MapBufferRange} or @fn_gl_extension{MapNamedBufferRange,EXT,direct_state_access} - * @requires_gl30 %Extension @extension{ARB,map_buffer_range} - * @requires_gles30 %Extension @es_extension{EXT,map_buffer_range} in + * @ref map(MapAccess), @ref setTargetHint(), + * @fn_gl2{MapNamedBufferRange,MapBufferRange}, + * @fn_gl_extension{MapNamedBufferRange,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{MapBufferRange} + * @requires_gl30 Extension @extension{ARB,map_buffer_range} + * @requires_gles30 Extension @es_extension{EXT,map_buffer_range} in * OpenGL ES 2.0 */ void* map(GLintptr offset, GLsizeiptr length, MapFlags flags); @@ -1104,13 +1131,15 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @ref map() with @ref MapFlag::FlushExplicit flag. See * @ref Buffer-data-mapping "class documentation" for usage example. * - * If @extension{EXT,direct_state_access} is not available and the - * buffer is not already bound somewhere, it is bound to hinted target - * before the operation. - * @see @ref setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{FlushMappedBufferRange} - * or @fn_gl_extension{FlushMappedNamedBufferRange,EXT,direct_state_access} - * @requires_gl30 %Extension @extension{ARB,map_buffer_range} - * @requires_gles30 %Extension @es_extension{EXT,map_buffer_range} in + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the buffer is bound to hinted target before the operation (if not + * already). + * @see @ref setTargetHint(), @fn_gl2{FlushMappedNamedBufferRange,FlushMappedBufferRange}, + * @fn_gl_extension{FlushMappedNamedBufferRange,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{FlushMappedBufferRange} + * @requires_gl30 Extension @extension{ARB,map_buffer_range} + * @requires_gles30 Extension @es_extension{EXT,map_buffer_range} in * OpenGL ES 2.0 */ Buffer& flushMappedRange(GLintptr offset, GLsizeiptr length); @@ -1122,12 +1151,14 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * otherwise. * * Unmaps buffer previously mapped with @ref map(), invalidating the - * pointer returned by these functions. If @extension{EXT,direct_state_access} - * is not available and the buffer is not already bound somewhere, it - * is bound to hinted target before the operation. - * @see setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{UnmapBuffer} or - * @fn_gl_extension{UnmapNamedBuffer,EXT,direct_state_access} - * @requires_gles30 %Extension @es_extension{OES,mapbuffer} in OpenGL + * pointer returned by these functions. If on OpenGL ES or neither + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the buffer is + * bound to hinted target before the operation (if not already). + * @see @ref setTargetHint(), @fn_gl2{UnmapNamedBuffer,UnmapBuffer}, + * @fn_gl_extension{UnmapNamedBuffer,EXT,direct_state_access}, + * eventually @fn_gl{BindBuffer} and @fn_gl{UnmapBuffer} + * @requires_gles30 Extension @es_extension{OES,mapbuffer} in OpenGL * ES 2.0 */ bool unmap(); @@ -1142,7 +1173,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { * @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use * @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * instead. - * @requires_es_extension %Extension @es_extension{CHROMIUM,map_sub} + * @requires_es_extension Extension @es_extension{CHROMIUM,map_sub} */ void unmapSub(); #endif @@ -1162,18 +1193,19 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { TargetHint MAGNUM_LOCAL bindSomewhereInternal(TargetHint hint); #ifndef MAGNUM_TARGET_GLES2 - static void MAGNUM_LOCAL bindImplementationFallback(Target target, GLuint first, Containers::ArrayReference buffers); + static void MAGNUM_LOCAL bindImplementationFallback(Target target, GLuint firstIndex, Containers::ArrayReference buffers); #ifndef MAGNUM_TARGET_GLES - static void MAGNUM_LOCAL bindImplementationMulti(Target target, GLuint first, Containers::ArrayReference buffers); + static void MAGNUM_LOCAL bindImplementationMulti(Target target, GLuint firstIndex, Containers::ArrayReference buffers); #endif - static void MAGNUM_LOCAL bindImplementationFallback(Target target, GLuint first, Containers::ArrayReference> buffers); + static void MAGNUM_LOCAL bindImplementationFallback(Target target, GLuint firstIndex, Containers::ArrayReference> buffers); #ifndef MAGNUM_TARGET_GLES - static void MAGNUM_LOCAL bindImplementationMulti(Target target, GLuint first, Containers::ArrayReference> buffers); + static void MAGNUM_LOCAL bindImplementationMulti(Target target, GLuint firstIndex, Containers::ArrayReference> buffers); #endif static void MAGNUM_LOCAL copyImplementationDefault(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); #ifndef MAGNUM_TARGET_GLES + static void MAGNUM_LOCAL copyImplementationDSA(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); static void MAGNUM_LOCAL copyImplementationDSAEXT(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); #endif #endif @@ -1193,21 +1225,25 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { void MAGNUM_LOCAL getParameterImplementationDefault(GLenum value, GLint* data); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL getParameterImplementationDSA(GLenum value, GLint* data); void MAGNUM_LOCAL getParameterImplementationDSAEXT(GLenum value, GLint* data); #endif #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL getSubDataImplementationDefault(GLintptr offset, GLsizeiptr size, GLvoid* data); + void MAGNUM_LOCAL getSubDataImplementationDSA(GLintptr offset, GLsizeiptr size, GLvoid* data); void MAGNUM_LOCAL getSubDataImplementationDSAEXT(GLintptr offset, GLsizeiptr size, GLvoid* data); #endif void MAGNUM_LOCAL dataImplementationDefault(GLsizeiptr size, const GLvoid* data, BufferUsage usage); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL dataImplementationDSA(GLsizeiptr size, const GLvoid* data, BufferUsage usage); void MAGNUM_LOCAL dataImplementationDSAEXT(GLsizeiptr size, const GLvoid* data, BufferUsage usage); #endif void MAGNUM_LOCAL subDataImplementationDefault(GLintptr offset, GLsizeiptr size, const GLvoid* data); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL subDataImplementationDSA(GLintptr offset, GLsizeiptr size, const GLvoid* data); void MAGNUM_LOCAL subDataImplementationDSAEXT(GLintptr offset, GLsizeiptr size, const GLvoid* data); #endif @@ -1223,21 +1259,25 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { void MAGNUM_LOCAL * mapImplementationDefault(MapAccess access); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL * mapImplementationDSA(MapAccess access); void MAGNUM_LOCAL * mapImplementationDSAEXT(MapAccess access); #endif void MAGNUM_LOCAL * mapRangeImplementationDefault(GLintptr offset, GLsizeiptr length, MapFlags access); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL * mapRangeImplementationDSA(GLintptr offset, GLsizeiptr length, MapFlags access); void MAGNUM_LOCAL * mapRangeImplementationDSAEXT(GLintptr offset, GLsizeiptr length, MapFlags access); #endif void MAGNUM_LOCAL flushMappedRangeImplementationDefault(GLintptr offset, GLsizeiptr length); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL flushMappedRangeImplementationDSA(GLintptr offset, GLsizeiptr length); void MAGNUM_LOCAL flushMappedRangeImplementationDSAEXT(GLintptr offset, GLsizeiptr length); #endif bool MAGNUM_LOCAL unmapImplementationDefault(); #ifndef MAGNUM_TARGET_GLES + bool MAGNUM_LOCAL unmapImplementationDSA(); bool MAGNUM_LOCAL unmapImplementationDSAEXT(); #endif @@ -1272,12 +1312,13 @@ inline Buffer::Buffer(Buffer&& other) noexcept: _id{other._id}, _targetHint{othe } inline Buffer& Buffer::operator=(Buffer&& other) noexcept { - std::swap(_id, other._id); - std::swap(_targetHint, other._targetHint); + using std::swap; + swap(_id, other._id); + swap(_targetHint, other._targetHint); #ifdef CORRADE_TARGET_NACL - std::swap(_mappedBuffer, other._mappedBuffer); + swap(_mappedBuffer, other._mappedBuffer); #endif - std::swap(_created, other._created); + swap(_created, other._created); return *this; } @@ -1295,7 +1336,7 @@ template Containers::Array inline Buffer::data() { template Containers::Array inline Buffer::subData(const GLintptr offset, const GLsizeiptr size) { Containers::Array data(size); if(size) subDataInternal(offset, size*sizeof(T), data); - return std::move(data); + return data; } #endif diff --git a/src/Magnum/BufferImage.cpp b/src/Magnum/BufferImage.cpp index 440a69ce9..1571f534b 100644 --- a/src/Magnum/BufferImage.cpp +++ b/src/Magnum/BufferImage.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/BufferImage.h b/src/Magnum/BufferImage.h index 6715d579f..ad2cbd99e 100644 --- a/src/Magnum/BufferImage.h +++ b/src/Magnum/BufferImage.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,7 +40,7 @@ namespace Magnum { #ifndef MAGNUM_TARGET_GLES2 /** -@brief %Buffer image +@brief Buffer image Stores image data in GPU memory. Interchangeable with @ref Image, @ref ImageReference or @ref Trade::ImageData. @@ -49,15 +49,15 @@ Stores image data in GPU memory. Interchangeable with @ref Image, */ template class BufferImage: public AbstractImage { public: - const static UnsignedInt Dimensions = dimensions; /**< @brief %Image dimension count */ + const static UnsignedInt Dimensions = dimensions; /**< @brief Image dimension count */ /** * @brief Constructor * @param format Format of pixel data * @param type Data type of pixel data - * @param size %Image size - * @param data %Image data - * @param usage %Image buffer usage + * @param size Image size + * @param data Image data + * @param usage Image buffer usage * * Note that the image data are not copied on construction, but they * are deleted on class destruction. @@ -74,7 +74,7 @@ template class BufferImage: public AbstractImage { * Size is zero and buffer are empty, call @ref setData() to fill the * image with data. */ - explicit BufferImage(ColorFormat format, ColorType type); + /*implicit*/ BufferImage(ColorFormat format, ColorType type); /** @brief Copying is not allowed */ BufferImage(const BufferImage&) = delete; @@ -88,7 +88,7 @@ template class BufferImage: public AbstractImage { /** @brief Move assignment */ BufferImage& operator=(BufferImage&& other) noexcept; - /** @brief %Image size */ + /** @brief Image size */ typename DimensionTraits::VectorType size() const { return _size; } /** @copydoc Image::dataSize() */ @@ -96,16 +96,16 @@ template class BufferImage: public AbstractImage { return AbstractImage::dataSize(size); } - /** @brief %Image buffer */ + /** @brief Image buffer */ Buffer& buffer() { return _buffer; } /** * @brief Set image data * @param format Format of pixel data * @param type Data type of pixel data - * @param size %Image size - * @param data %Image data - * @param usage %Image buffer usage + * @param size Image size + * @param data Image data + * @param usage Image buffer usage * * Updates the image buffer with given data. The data are not deleted * after filling the buffer. @@ -115,16 +115,6 @@ template class BufferImage: public AbstractImage { */ void setData(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, const void* data, BufferUsage usage); - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @copybrief setData(ColorFormat, ColorType, const typename DimensionTraits::VectorType&, const void*, BufferUsage) - * @deprecated Use @ref Magnum::BufferImage::setData(ColorFormat, ColorType, const typename DimensionTraits::VectorType&, const void*, BufferUsage) "setData(ColorFormat, ColorType, const typename DimensionTraits::VectorType&, const void*, BufferUsage)" instead. - */ - CORRADE_DEPRECATED("use setData(ColorFormat, ColorType, VectorNi, const void*, BufferUsage) instead") void setData(const typename DimensionTraits::VectorType& size, ColorFormat format, ColorType type, const void* data, BufferUsage usage) { - setData(format, type, size, data, usage); - } - #endif - private: Math::Vector _size; Buffer _buffer; @@ -145,8 +135,9 @@ template inline BufferImage::BufferImage(Buf template inline BufferImage& BufferImage::operator=(BufferImage&& other) noexcept { AbstractImage::operator=(std::move(other)); - std::swap(_size, other._size); - std::swap(_buffer, other._buffer); + using std::swap; + swap(_size, other._size); + swap(_buffer, other._buffer); return *this; } #else diff --git a/src/Magnum/BufferTexture.cpp b/src/Magnum/BufferTexture.cpp index 0c45eb264..a9fe6b9cb 100644 --- a/src/Magnum/BufferTexture.cpp +++ b/src/Magnum/BufferTexture.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -75,6 +75,10 @@ void BufferTexture::setBufferImplementationDefault(BufferTextureFormat internalF glTexBuffer(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id()); } +void BufferTexture::setBufferImplementationDSA(const BufferTextureFormat internalFormat, Buffer& buffer) { + glTextureBuffer(id(), GLenum(internalFormat), buffer.id()); +} + void BufferTexture::setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer) { glTextureBufferEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id()); } @@ -84,6 +88,10 @@ void BufferTexture::setBufferRangeImplementationDefault(BufferTextureFormat inte glTexBufferRange(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size); } +void BufferTexture::setBufferRangeImplementationDSA(const BufferTextureFormat internalFormat, Buffer& buffer, const GLintptr offset, const GLsizeiptr size) { + glTextureBufferRange(id(), GLenum(internalFormat), buffer.id(), offset, size); +} + void BufferTexture::setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size) { glTextureBufferRangeEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size); } diff --git a/src/Magnum/BufferTexture.h b/src/Magnum/BufferTexture.h index 8aa468974..e8ea149c3 100644 --- a/src/Magnum/BufferTexture.h +++ b/src/Magnum/BufferTexture.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -104,7 +104,7 @@ enum class BufferTextureFormat: GLenum { /** * RGB, each component non-normalized unsigned int. - * @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32} + * @requires_gl40 Extension @extension{ARB,texture_buffer_object_rgb32} */ RGB32UI = GL_RGB32UI, @@ -119,7 +119,7 @@ enum class BufferTextureFormat: GLenum { /** * RGB, each component non-normalized signed int. - * @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32} + * @requires_gl40 Extension @extension{ARB,texture_buffer_object_rgb32} */ RGB32I = GL_RGB32I, @@ -143,7 +143,7 @@ enum class BufferTextureFormat: GLenum { /** * RGB, each component float. - * @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32} + * @requires_gl40 Extension @extension{ARB,texture_buffer_object_rgb32} */ RGB32F = GL_RGB32F, @@ -152,14 +152,14 @@ enum class BufferTextureFormat: GLenum { }; /** -@brief %Buffer texture +@brief Buffer texture -This texture is, unlike classic textures such as @ref Texture used as simple +This texture is, unlike classic textures such as @ref Texture, used as simple data source, without any unnecessary interpolation and wrapping methods. ## Usage -%Texture data are stored in buffer and after binding the buffer to the texture +Texture data are stored in buffer and after binding the buffer to the texture using @ref setBuffer(), you can fill the buffer at any time using data setting functions in Buffer itself. @@ -187,7 +187,8 @@ documentation for more information about usage in shaders. ## Performance optimizations -If extension @extension{EXT,direct_state_access} is available, @ref setBuffer() +If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL +4.5) or @extension{EXT,direct_state_access} is available, @ref setBuffer() functions use DSA to avoid unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. See @ref AbstractTexture-performance-optimization "relevant section in AbstractTexture documentation" @@ -195,11 +196,11 @@ and respective function documentation for more information. @see @ref Texture, @ref TextureArray, @ref CubeMapTexture, @ref CubeMapTextureArray, @ref RectangleTexture, @ref MultisampleTexture -@requires_gl31 %Extension @extension{ARB,texture_buffer_object} +@requires_gl31 Extension @extension{ARB,texture_buffer_object} @requires_gl Texture buffers are not available in OpenGL ES. */ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { - friend struct Implementation::TextureState; + friend Implementation::TextureState; public: /** @@ -246,33 +247,41 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { /** * @brief Set texture buffer * @param internalFormat Internal format - * @param buffer %Buffer with data + * @param buffer Buffer with data * @return Reference to self (for method chaining) * * Binds given buffer to this texture. The buffer itself can be then * filled with data of proper format at any time using @ref Buffer "Buffer"'s - * own data setting functions. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexBuffer} or - * @fn_gl_extension{TextureBuffer,EXT,direct_state_access} + * own data setting functions. If neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). + * @see @ref maxSize(), @fn_gl2{TextureBuffer,TexBuffer}, + * @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexBuffer} */ BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer); /** * @brief Set texture buffer * @param internalFormat Internal format - * @param buffer %Buffer + * @param buffer Buffer * @param offset Offset * @param size Data size * @return Reference to self (for method chaining) * * Binds range of given buffer to this texture. The buffer itself can * be then filled with data of proper format at any time using @ref Buffer "Buffer"'s - * own data setting functions. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexBufferRange} or - * @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} - * @requires_gl43 %Extension @extension{ARB,texture_buffer_range} + * own data setting functions. If neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). + * @see @ref maxSize(), @fn_gl2{TextureBufferRange,TexBufferRange}, + * @fn_gl_extension{TextureBufferRange,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexBufferRange} + * @requires_gl43 Extension @extension{ARB,texture_buffer_range} */ BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); @@ -290,9 +299,11 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { private: void MAGNUM_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer); + void MAGNUM_LOCAL setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer); void MAGNUM_LOCAL setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer); void MAGNUM_LOCAL setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); + void MAGNUM_LOCAL setBufferRangeImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); void MAGNUM_LOCAL setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); }; diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt index 588bc6d3e..f3fa54aaf 100644 --- a/src/Magnum/CMakeLists.txt +++ b/src/Magnum/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -34,11 +34,12 @@ set(Magnum_SRCS AbstractQuery.cpp AbstractTexture.cpp AbstractShaderProgram.cpp + Attribute.cpp Buffer.cpp ColorFormat.cpp CubeMapTexture.cpp Context.cpp - DebugMessage.cpp + DebugOutput.cpp DefaultFramebuffer.cpp Framebuffer.cpp Image.cpp @@ -89,12 +90,13 @@ set(Magnum_HEADERS AbstractShaderProgram.h AbstractTexture.h Array.h + Attribute.h Buffer.h Color.h ColorFormat.h Context.h CubeMapTexture.h - DebugMessage.h + DebugOutput.h DefaultFramebuffer.h DimensionTraits.h Extensions.h @@ -110,6 +112,7 @@ set(Magnum_HEADERS Renderer.h Resource.h ResourceManager.h + ResourceManager.hpp SampleQuery.h Sampler.h Shader.h @@ -140,6 +143,7 @@ set(Magnum_PRIVATE_HEADERS if(BUILD_DEPRECATED) set(Magnum_HEADERS ${Magnum_HEADERS} DebugMarker.h + DebugMessage.h Query.h) endif() @@ -161,11 +165,19 @@ if(NOT TARGET_GLES2) BufferImage.h MultisampleTexture.h PrimitiveQuery.h - TextureArray.h) + TextureArray.h + TransformFeedback.h) + + list(APPEND Magnum_PRIVATE_HEADES + Implementation/TransformFeedbackState.h) + set(Magnum_SRCS ${Magnum_SRCS} BufferImage.cpp MultisampleTexture.cpp - TextureArray.cpp) + TextureArray.cpp + TransformFeedback.cpp + + Implementation/TransformFeedbackState.cpp) endif() # Link in GL function pointer variables on platforms that support it @@ -178,24 +190,26 @@ set(MagnumMath_SRCS Math/Functions.cpp Math/instantiation.cpp) -# Main library +# Objects shared between main and test library add_library(MagnumMathObjects OBJECT ${MagnumMath_SRCS}) +if(NOT BUILD_STATIC) + set_target_properties(MagnumMathObjects PROPERTIES COMPILE_FLAGS "-DMagnumMathObjects_EXPORTS") +endif() +if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) + set_target_properties(MagnumMathObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() + +# Main library add_library(Magnum ${SHARED_OR_STATIC} ${Magnum_SRCS} ${Magnum_HEADERS} ${Magnum_PRIVATE_HEADERS} $) set_target_properties(Magnum PROPERTIES DEBUG_POSTFIX "-d") - -# TODO: fix when CMake sets target_EXPORTS for OBJECT targets as well -if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) - # Set shared library flags for the objects, as they will be part of shared lib - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumMathObjects PROPERTIES COMPILE_FLAGS "-DMagnumMathObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") - set_target_properties(Magnum PROPERTIES COMPILE_FLAGS "-DFlextGL_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") -else() - set_target_properties(MagnumMathObjects PROPERTIES COMPILE_FLAGS "-DMagnumMathObjects_EXPORTS") +if(NOT BUILD_STATIC) set_target_properties(Magnum PROPERTIES COMPILE_FLAGS "-DFlextGL_EXPORTS") +elseif(BUILD_STATIC_PIC) + set_target_properties(Magnum PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() set(Magnum_LIBS @@ -258,7 +272,7 @@ if(WITH_TEXTURETOOLS) endif() if(BUILD_TESTS) - # Libraries with graceful assert for testing + # Library with graceful assert for testing add_library(MagnumMathTestLib ${SHARED_OR_STATIC} $) set_target_properties(MagnumMathTestLib PROPERTIES @@ -268,7 +282,7 @@ if(BUILD_TESTS) # On Windows we need to install first and then run the tests to avoid "DLL # not found" hell, thus we need to install this too - if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING) + if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING AND NOT BUILD_STATIC) install(TARGETS MagnumMathTestLib RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} diff --git a/src/Magnum/Color.h b/src/Magnum/Color.h index 0c00f28f4..946c45311 100644 --- a/src/Magnum/Color.h +++ b/src/Magnum/Color.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -125,10 +125,10 @@ template inline typename BasicColor3::HSV toHSV(typename std::enable } /* Value for full channel (1.0f for floats, 255 for unsigned byte) */ -template inline constexpr typename std::enable_if::value, T>::type fullChannel() { +template constexpr typename std::enable_if::value, T>::type fullChannel() { return T(1); } -template inline constexpr typename std::enable_if::value, T>::type fullChannel() { +template constexpr typename std::enable_if::value, T>::type fullChannel() { return std::numeric_limits::max(); } @@ -161,7 +161,7 @@ template class BasicColor3: public Math::Vector3 { /** * @brief Red color * - * Convenience alternative to e.g. `%Color3(red, 0.0f, 0.0f)`. With + * Convenience alternative to e.g. `Color3(red, 0.0f, 0.0f)`. With * floating-point underlying type equivalent to @ref Vector3::xAxis(). * @see @ref green(), @ref blue(), @ref cyan() */ @@ -177,7 +177,7 @@ template class BasicColor3: public Math::Vector3 { /** * @brief Green color * - * Convenience alternative to e.g. `%Color3(0.0f, green, 0.0f)`. With + * Convenience alternative to e.g. `Color3(0.0f, green, 0.0f)`. With * floating-point underlying type equivalent to @ref Vector3::yAxis(). * @see @ref red(), @ref blue(), @ref magenta() */ @@ -193,7 +193,7 @@ template class BasicColor3: public Math::Vector3 { /** * @brief Blue color * - * Convenience alternative to e.g. `%Color3(0.0f, 0.0f, blue)`. With + * Convenience alternative to e.g. `Color3(0.0f, 0.0f, blue)`. With * floating-point underlying type equivalent to @ref Vector3::zAxis(). * @see @ref red(), @ref green(), @ref yellow() */ @@ -209,7 +209,7 @@ template class BasicColor3: public Math::Vector3 { /** * @brief Cyan color * - * Convenience alternative to e.g. `%Color3(red, 1.0f, 1.0f)`. With + * Convenience alternative to e.g. `Color3(red, 1.0f, 1.0f)`. With * floating-point underlying type equivalent to @ref Vector3::xScale(). * @see @ref magenta(), @ref yellow(), @ref red() */ @@ -220,7 +220,7 @@ template class BasicColor3: public Math::Vector3 { /** * @brief Magenta color * - * Convenience alternative to e.g. `%Color3(0.0f, green, 0.0f)`. With + * Convenience alternative to e.g. `Color3(0.0f, green, 0.0f)`. With * floating-point underlying type equivalent to @ref Vector3::yScale(). * @see @ref cyan(), @ref yellow(), @ref green() */ @@ -231,7 +231,7 @@ template class BasicColor3: public Math::Vector3 { /** * @brief Yellow color * - * Convenience alternative to `%Color3(0.0f, 0.0f, yellow)`. With + * Convenience alternative to `Color3(0.0f, 0.0f, yellow)`. With * floating-point underlying type equivalent to @ref Vector3::zScale(). * @see @ref cyan(), @ref magenta(), @ref red() */ @@ -385,7 +385,7 @@ class BasicColor4: public Math::Vector4 { /** * @brief Red color * - * Convenience alternative to e.g. `%Color4(red, 0.0f, 0.0f, alpha)`. + * Convenience alternative to e.g. `Color4(red, 0.0f, 0.0f, alpha)`. * @see @ref green(), @ref blue(), @ref cyan() */ #ifndef CORRADE_MSVC2013_COMPATIBILITY @@ -400,7 +400,7 @@ class BasicColor4: public Math::Vector4 { /** * @brief Green color * - * Convenience alternative to e.g. `%Color4(0.0f, green, 0.0f, alpha)`. + * Convenience alternative to e.g. `Color4(0.0f, green, 0.0f, alpha)`. * @see @ref red(), @ref blue(), @ref magenta() */ #ifndef CORRADE_MSVC2013_COMPATIBILITY @@ -415,7 +415,7 @@ class BasicColor4: public Math::Vector4 { /** * @brief Blue color * - * Convenience alternative to e.g. `%Color4(0.0f, 0.0f, blue, alpha)`. + * Convenience alternative to e.g. `Color4(0.0f, 0.0f, blue, alpha)`. * @see @ref red(), @ref green(), @ref yellow() */ #ifndef CORRADE_MSVC2013_COMPATIBILITY @@ -430,7 +430,7 @@ class BasicColor4: public Math::Vector4 { /** * @brief Cyan color * - * Convenience alternative to e.g. `%Color4(red, 1.0f, 1.0f, alpha)`. + * Convenience alternative to e.g. `Color4(red, 1.0f, 1.0f, alpha)`. * @see @ref magenta(), @ref yellow(), @ref red() */ #ifndef CORRADE_MSVC2013_COMPATIBILITY @@ -445,7 +445,7 @@ class BasicColor4: public Math::Vector4 { /** * @brief Magenta color * - * Convenience alternative to e.g. `%Color4(1.0f, green, 1.0f, alpha)`. + * Convenience alternative to e.g. `Color4(1.0f, green, 1.0f, alpha)`. * @see @ref cyan(), @ref yellow(), @ref green() */ #ifndef CORRADE_MSVC2013_COMPATIBILITY @@ -460,7 +460,7 @@ class BasicColor4: public Math::Vector4 { /** * @brief Yellow color * - * Convenience alternative to e.g. `%Color4(1.0f, 1.0f, blue, alpha)`. + * Convenience alternative to e.g. `Color4(1.0f, 1.0f, blue, alpha)`. * @see @ref cyan(), @ref magenta(), @ref red() */ #ifndef CORRADE_MSVC2013_COMPATIBILITY diff --git a/src/Magnum/ColorFormat.cpp b/src/Magnum/ColorFormat.cpp index ad7a5bf09..eb6bec697 100644 --- a/src/Magnum/ColorFormat.cpp +++ b/src/Magnum/ColorFormat.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/ColorFormat.h b/src/Magnum/ColorFormat.h index f7d2f52a4..9d0a9db3c 100644 --- a/src/Magnum/ColorFormat.h +++ b/src/Magnum/ColorFormat.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,7 +40,7 @@ namespace Magnum { Note that some formats can be used only for framebuffer reading (using @ref AbstractFramebuffer::read()) and some only for texture data (using -@ref Texture::setImage() and others), the limitations are mentioned in +@ref Texture::setSubImage() and others), the limitations are mentioned in documentation of each particular value. In most cases you may want to use @ref ColorFormat::Red (for grayscale images), @@ -95,7 +95,7 @@ enum class ColorFormat: GLenum { /** * Floating-point red and green channel. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 For texture data only, extension @es_extension{EXT,texture_rg} * in OpenGL ES 2.0 * @requires_es_extension For framebuffer reading, extension @es_extension{EXT,texture_rg}. @@ -137,7 +137,7 @@ enum class ColorFormat: GLenum { /** * Floating-point BGRA. - * @requires_es_extension %Extension @es_extension{EXT,read_format_bgra} + * @requires_es_extension Extension @es_extension{EXT,read_format_bgra} * for framebuffer reading, extension @es_extension{APPLE,texture_format_BGRA8888} * or @es_extension{EXT,texture_format_BGRA8888} for texture data. */ @@ -150,7 +150,7 @@ enum class ColorFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * Integer red channel. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only floating-point image data are available in OpenGL * ES 2.0. */ @@ -159,7 +159,7 @@ enum class ColorFormat: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Integer green channel. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gl Only @ref Magnum::ColorFormat::RedInteger "ColorFormat::RedInteger" * is available in OpenGL ES 3.0, only floating-point image data are * available in OpenGL ES 2.0. @@ -168,7 +168,7 @@ enum class ColorFormat: GLenum { /** * Integer blue channel. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gl Only @ref Magnum::ColorFormat::RedInteger "ColorFormat::RedInteger" * is available in OpenGL ES 3.0, only floating-point image data are * available in OpenGL ES 2.0. @@ -178,7 +178,7 @@ enum class ColorFormat: GLenum { /** * Integer red and green channel. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gl Can't be used for framebuffer reading in OpenGL ES. * @requires_gles30 For texture data only, only floating-point image data * are available in OpenGL ES 2.0. @@ -187,7 +187,7 @@ enum class ColorFormat: GLenum { /** * Integer RGB. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gl Can't be used for framebuffer reading in OpenGL ES. * @requires_gles30 For texture data only, only floating-point image data * are available in OpenGL ES 2.0. @@ -196,7 +196,7 @@ enum class ColorFormat: GLenum { /** * Integer RGBA. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only floating-point image data are available in OpenGL * ES 2.0. */ @@ -205,7 +205,7 @@ enum class ColorFormat: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Integer BGR. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gl Only @ref Magnum::ColorFormat::RGBInteger "ColorFormat::RGBInteger" * is available in OpenGL ES 3.0, only floating-point image data are * available in OpenGL ES 2.0. @@ -214,7 +214,7 @@ enum class ColorFormat: GLenum { /** * Integer BGRA. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gl Only @ref Magnum::ColorFormat::RGBAInteger "ColorFormat::RGBAInteger" * is available in OpenGL ES 3.0, only floating-point image data are * available in OpenGL ES 2.0. @@ -234,9 +234,9 @@ enum class ColorFormat: GLenum { /** * Stencil index. - * @requires_gl44 %Extension @extension{ARB,texture_stencil8} for texture + * @requires_gl44 Extension @extension{ARB,texture_stencil8} for texture * data, otherwise for framebuffer reading only. - * @requires_es_extension %Extension @es_extension2{NV,read_stencil,GL_NV_read_depth_stencil}, + * @requires_es_extension Extension @es_extension2{NV,read_stencil,GL_NV_read_depth_stencil}, * for framebuffer reading only. * @todo Where to get GL_STENCIL_INDEX in ES? */ @@ -248,7 +248,7 @@ enum class ColorFormat: GLenum { /** * Depth and stencil. - * @requires_gl30 %Extension @extension{ARB,framebuffer_object} + * @requires_gl30 Extension @extension{ARB,framebuffer_object} * @requires_gles30 For texture data only, extension @es_extension{OES,packed_depth_stencil} * in OpenGL ES 2.0 * @requires_es_extension For framebuffer reading only, extension @@ -266,7 +266,7 @@ enum class ColorFormat: GLenum { Note that some formats can be used only for framebuffer reading (using @ref AbstractFramebuffer::read()) and some only for texture data (using -@ref Texture::setImage() and others), the limitations are mentioned in +@ref Texture::setSubImage() and others), the limitations are mentioned in documentation of each particular value. In most cases you may want to use @ref ColorType::UnsignedByte along with @@ -331,7 +331,7 @@ enum class ColorType: GLenum { /** * Each component half float. - * @requires_gl30 %Extension @extension{ARB,half_float_pixel} + * @requires_gl30 Extension @extension{ARB,half_float_pixel} * @requires_gles30 For texture data only, extension * @es_extension2{OES,texture_half_float,OES_texture_float} in OpenGL * ES 2.0 @@ -451,7 +451,7 @@ enum class ColorType: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * BGR, unsigned int, red and green 11bit float, blue 10bit float. - * @requires_gl30 %Extension @extension{EXT,packed_float} + * @requires_gl30 Extension @extension{EXT,packed_float} * @requires_gles30 Floating-point types are not available in OpenGL ES * 2.0. */ @@ -459,7 +459,7 @@ enum class ColorType: GLenum { /** * BGR, unsigned int, each component 9bit + 5bit exponent. - * @requires_gl30 %Extension @extension{EXT,texture_shared_exponent} + * @requires_gl30 Extension @extension{EXT,texture_shared_exponent} * @requires_gles30 Only 8bit and 16bit types are available in OpenGL ES * 2.0. */ @@ -468,7 +468,7 @@ enum class ColorType: GLenum { /** * Unsigned int, depth component 24bit, stencil index 8bit. - * @requires_gl30 %Extension @extension{ARB,framebuffer_object} + * @requires_gl30 Extension @extension{ARB,framebuffer_object} * @requires_gles30 For texture data only, extension @es_extension{OES,packed_depth_stencil} * in OpenGL ES 2.0 */ @@ -482,7 +482,7 @@ enum class ColorType: GLenum { /** * Float + unsigned int, depth component 32bit float, 24bit gap, stencil * index 8bit. - * @requires_gl30 %Extension @extension{ARB,depth_buffer_float} + * @requires_gl30 Extension @extension{ARB,depth_buffer_float} * @requires_gles30 For texture data only, only * @ref Magnum::ColorType::UnsignedInt248 "ColorType::UnsignedInt248" * is available in OpenGL ES 2.0. diff --git a/src/Magnum/Context.cpp b/src/Magnum/Context.cpp index f2906b984..07d736ad0 100644 --- a/src/Magnum/Context.cpp +++ b/src/Magnum/Context.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -50,6 +50,7 @@ #include "Implementation/MeshState.h" #include "Implementation/ShaderProgramState.h" #include "Implementation/TextureState.h" +#include "Implementation/TransformFeedbackState.h" namespace Magnum { @@ -177,7 +178,6 @@ const std::vector& Extension::extensions(Version version) { _extension(GL,ARB,clear_buffer_object), _extension(GL,ARB,compute_shader), _extension(GL,ARB,copy_image), - _extension(GL,KHR,debug), _extension(GL,ARB,explicit_uniform_location), _extension(GL,ARB,fragment_layer_viewport), _extension(GL,ARB,framebuffer_no_attachments), @@ -193,7 +193,8 @@ const std::vector& Extension::extensions(Version version) { _extension(GL,ARB,texture_query_levels), _extension(GL,ARB,texture_storage_multisample), _extension(GL,ARB,texture_view), - _extension(GL,ARB,vertex_attrib_binding)}; + _extension(GL,ARB,vertex_attrib_binding), + _extension(GL,KHR,debug)}; static const std::vector extensions440{ _extension(GL,ARB,buffer_storage), _extension(GL,ARB,clear_texture), @@ -284,6 +285,7 @@ const std::vector& Extension::extensions(Version version) { _extension(GL,OES,texture_float_linear), _extension(GL,OES,texture_half_float), _extension(GL,OES,texture_float), + _extension(GL,OES,texture_npot), _extension(GL,OES,vertex_half_float), _extension(GL,OES,packed_depth_stencil), _extension(GL,OES,depth_texture), @@ -518,7 +520,7 @@ std::vector Context::shadingLanguageVersionStrings() const { versions.reserve(versionCount); for(GLint i = 0; i != versionCount; ++i) versions.push_back(reinterpret_cast(glGetStringi(GL_SHADING_LANGUAGE_VERSION, i))); - return std::move(versions); + return versions; #else return {shadingLanguageVersionString()}; #endif @@ -584,6 +586,10 @@ void Context::resetState(const States states) { if(states & State::Textures) _state->texture->reset(); + #ifndef MAGNUM_TARGET_GLES2 + if(states & State::TransformFeedback) + _state->transformFeedback->reset(); + #endif } #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Magnum/Context.h b/src/Magnum/Context.h index d99bc4c12..31cb9fb1b 100644 --- a/src/Magnum/Context.h +++ b/src/Magnum/Context.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -60,7 +60,7 @@ See also @ref Extensions namespace, which contain compile-time information about OpenGL extensions. */ class MAGNUM_EXPORT Extension { - friend class Context; + friend Context; public: /** @brief All extensions for given OpenGL version */ @@ -72,7 +72,7 @@ class MAGNUM_EXPORT Extension { /** @brief Version in which this extension was adopted to core */ constexpr Version coreVersion() const { return _coreVersion; } - /** @brief %Extension string */ + /** @brief Extension string */ constexpr const char* string() const { return _string; } private: @@ -87,7 +87,7 @@ class MAGNUM_EXPORT Extension { }; /** -@brief %Magnum context +@brief Magnum context Provides access to version and extension information. Instance available through @ref Context::current() is automatically created during construction of @@ -98,19 +98,19 @@ using @ref Platform::Context subclass, see @ref platform documentation for more information. */ class MAGNUM_EXPORT Context { - friend class Platform::Context; + friend Platform::Context; public: /** - * @brief %Context flag + * @brief Context flag * * @see @ref Flags, @ref flags(), @ref Platform::Sdl2Application::Configuration::setFlags() "Platform::*Application::Configuration::setFlags()" */ enum class Flag: GLint { /** * Debug context - * @requires_gl43 %Extension @es_extension{KHR,debug} - * @requires_es_extension %Extension @es_extension{KHR,debug} + * @requires_gl43 Extension @es_extension{KHR,debug} + * @requires_es_extension Extension @es_extension{KHR,debug} */ #ifndef MAGNUM_TARGET_GLES Debug = GL_CONTEXT_FLAG_DEBUG_BIT, @@ -121,8 +121,8 @@ class MAGNUM_EXPORT Context { #ifndef MAGNUM_TARGET_GLES /** * Context with robust access - * @requires_extension %Extension @extension{ARB,robustness} - * @requires_es_extension %Extension @es_extension{EXT,robustness} + * @requires_extension Extension @extension{ARB,robustness} + * @requires_es_extension Extension @es_extension{EXT,robustness} * @todo In ES available under glGetIntegerv(CONTEXT_ROBUST_ACCESS_EXT), * how to make it compatible? */ @@ -139,7 +139,7 @@ class MAGNUM_EXPORT Context { }; /** - * @brief %Context flags + * @brief Context flags * * @see @ref flags() */ @@ -167,7 +167,12 @@ class MAGNUM_EXPORT Context { Shaders = 1 << 4, /** Reset tracked texture-related bindings and state */ - Textures = 1 << 5 + Textures = 1 << 5, + + #ifndef MAGNUM_TARGET_GLES2 + /** Reset tracked transform feedback-related bindings */ + TransformFeedback = 1 << 6 + #endif }; /** @@ -186,6 +191,9 @@ class MAGNUM_EXPORT Context { #ifndef MAGNUM_TARGET_GLES /** Binary AMD desktop drivers on Windows and Linux */ AMD = 1 << 0, + + /** Intel desktop drivers on Windows */ + IntelWindows = 1 << 1, #endif #ifdef MAGNUM_TARGET_GLES2 @@ -195,7 +203,7 @@ class MAGNUM_EXPORT Context { * specification explicitly disallows exposing driver information * to the application, this check cannot be done reliably. */ - ProbablyAngle = 1 << 1 + ProbablyAngle = 1 << 2 #endif }; @@ -259,7 +267,7 @@ class MAGNUM_EXPORT Context { } /** - * @brief %Renderer string + * @brief Renderer string * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. @@ -305,11 +313,11 @@ class MAGNUM_EXPORT Context { std::vector shadingLanguageVersionStrings() const; /** - * @brief %Extension strings + * @brief Extension strings * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. Note that this function returns list of all extensions - * reported by the driver (even those not supported by %Magnum), see + * reported by the driver (even those not supported by Magnum), see * @ref supportedExtensions(), @ref Extension::extensions() or * @ref isExtensionSupported() for alternatives. * @see @fn_gl{Get} with @def_gl{NUM_EXTENSIONS}, @fn_gl{GetString} @@ -317,7 +325,7 @@ class MAGNUM_EXPORT Context { */ std::vector extensionStrings() const; - /** @brief %Context flags */ + /** @brief Context flags */ Flags flags() const { return _flags; } /** @@ -353,15 +361,14 @@ class MAGNUM_EXPORT Context { * If no version from the list is supported, returns lowest available * OpenGL version (@ref Version::GL210 for desktop OpenGL, * @ref Version::GLES200 for OpenGL ES). - * @see isExtensionSupported(Version) const - * @todoc Explicit reference when Doxygen can handle const + * @see @ref isExtensionSupported(Version) const */ Version supportedVersion(std::initializer_list versions) const; /** * @brief Whether given extension is supported * - * %Extensions usable with this function are listed in @ref Extensions + * Extensions usable with this function are listed in @ref Extensions * namespace in header @ref Extensions.h. Example usage: * @code * if(Context::current()->isExtensionSupported()) { @@ -371,10 +378,9 @@ class MAGNUM_EXPORT Context { * } * @endcode * - * @see isExtensionSupported(const Extension&) const, + * @see @ref isExtensionSupported(const Extension&) const, * @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED(), * @ref isExtensionDisabled() - * @todoc Explicit reference when Doxygen can handle const */ template bool isExtensionSupported() const { return isExtensionSupported(version()); @@ -403,18 +409,17 @@ class MAGNUM_EXPORT Context { * @brief Whether given extension is supported * * Can be used e.g. for listing extensions available on current - * hardware, but for general usage prefer isExtensionSupported() const, + * hardware, but for general usage prefer @ref isExtensionSupported() const, * as it does most operations in compile time. * @see @ref supportedExtensions(), @ref Extension::extensions(), * @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED() - * @todoc Explicit reference when Doxygen can handle const */ bool isExtensionSupported(const Extension& extension) const { return isVersionSupported(_extensionRequiredVersion[extension._index]) && extensionStatus[extension._index]; } /** - * @brief Whether given extension is supported by the driver but disabled + * @brief Whether given extension is disabled * * Can be used for detecting driver bug workarounds. Disabled * extensions return `false` in @ref isExtensionSupported() even if @@ -425,26 +430,25 @@ class MAGNUM_EXPORT Context { } /** - * @brief Whether given extension is supported by the driver but disabled for given version + * @brief Whether given extension is disabled for given version * * Similar to above, but can also check for extensions which are * disabled only for particular versions. */ template bool isExtensionDisabled(Version version) const { /* The extension is advertised, but the minimal version has been increased */ - return T::requiredVersion() <= version && extensionStatus[T::Index] && _extensionRequiredVersion[T::Index] > version; + return T::requiredVersion() <= version && _extensionRequiredVersion[T::Index] > version; } /** - * @brief Whether given extension is supported by the driver but disabled + * @brief Whether given extension is disabled * * Can be used e.g. for listing extensions available on current - * hardware, but for general usage prefer isExtensionDisabled() const, + * hardware, but for general usage prefer @ref isExtensionDisabled() const, * as it does most operations in compile time. - * @todoc Explicit reference when Doxygen can handle const */ bool isExtensionDisabled(const Extension& extension) const { - return isVersionSupported(extension._requiredVersion) && extensionStatus[extension._index] && !isVersionSupported(_extensionRequiredVersion[extension._index]); + return isVersionSupported(extension._requiredVersion) && !isVersionSupported(_extensionRequiredVersion[extension._index]); } /** diff --git a/src/Magnum/CubeMapTexture.cpp b/src/Magnum/CubeMapTexture.cpp index f53d297d4..ba3f119e3 100644 --- a/src/Magnum/CubeMapTexture.cpp +++ b/src/Magnum/CubeMapTexture.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,12 +25,196 @@ #include "CubeMapTexture.h" +#ifndef MAGNUM_TARGET_GLES2 +#include "Magnum/BufferImage.h" +#endif +#include "Magnum/Context.h" +#include "Magnum/Image.h" + #include "Implementation/maxTextureSize.h" +#include "Implementation/State.h" +#include "Implementation/TextureState.h" namespace Magnum { +static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 0 && + GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1 && + GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2 && + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3 && + GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4 && + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, + "Unexpected GL enum values for cube faces"); + Vector2i CubeMapTexture::maxSize() { return Vector2i{Implementation::maxCubeMapTextureSideSize()}; } +#ifndef MAGNUM_TARGET_GLES2 +Vector2i CubeMapTexture::imageSize(const Int level) { + return (this->*Context::current()->state().texture->getCubeImageSizeImplementation)(level); +} +#endif + +#ifndef MAGNUM_TARGET_GLES +void CubeMapTexture::image(const Int level, Image3D& image) { + const Vector3i size{imageSize(level), 6}; + const std::size_t dataSize = image.dataSize(size); + char* data = new char[dataSize]; + Buffer::unbindInternal(Buffer::TargetHint::PixelPack); + glGetTextureImage(_id, level, GLenum(image.format()), GLenum(image.type()), dataSize, data); + image.setData(image.format(), image.type(), size, data); +} + +Image3D CubeMapTexture::image(const Int level, Image3D&& image) { + this->image(level, image); + return std::move(image); +} + +void CubeMapTexture::image(const Int level, BufferImage3D& image, const BufferUsage usage) { + const Vector3i size{imageSize(level), 6}; + const std::size_t dataSize = image.dataSize(size); + if(image.size() != size) + image.setData(image.format(), image.type(), size, nullptr, usage); + + image.buffer().bindInternal(Buffer::TargetHint::PixelPack); + glGetTextureImage(_id, level, GLenum(image.format()), GLenum(image.type()), dataSize, nullptr); +} + +BufferImage3D CubeMapTexture::image(const Int level, BufferImage3D&& image, const BufferUsage usage) { + this->image(level, image, usage); + return std::move(image); +} + +void CubeMapTexture::image(const Coordinate coordinate, const Int level, Image2D& image) { + const Vector2i size = imageSize(level); + const std::size_t dataSize = image.dataSize(size); + char* data = new char[dataSize]; + Buffer::unbindInternal(Buffer::TargetHint::PixelPack); + (this->*Context::current()->state().texture->getCubeImageImplementation)(coordinate, level, size, image.format(), image.type(), dataSize, data); + image.setData(image.format(), image.type(), size, data); +} + +Image2D CubeMapTexture::image(const Coordinate coordinate, const Int level, Image2D&& image) { + this->image(coordinate, level, image); + return std::move(image); +} + +void CubeMapTexture::image(const Coordinate coordinate, const Int level, BufferImage2D& image, const BufferUsage usage) { + const Vector2i size = imageSize(level); + const std::size_t dataSize = image.dataSize(size); + if(image.size() != size) + image.setData(image.format(), image.type(), size, nullptr, usage); + + image.buffer().bindInternal(Buffer::TargetHint::PixelPack); + (this->*Context::current()->state().texture->getCubeImageImplementation)(coordinate, level, size, image.format(), image.type(), dataSize, nullptr); +} + +BufferImage2D CubeMapTexture::image(const Coordinate coordinate, const Int level, BufferImage2D&& image, const BufferUsage usage) { + this->image(coordinate, level, image, usage); + return std::move(image); +} + +Image3D CubeMapTexture::subImage(const Int level, const Range3Di& range, Image3D&& image) { + this->subImage(level, range, image); + return std::move(image); +} + +BufferImage3D CubeMapTexture::subImage(const Int level, const Range3Di& range, BufferImage3D&& image, const BufferUsage usage) { + this->subImage(level, range, image, usage); + return std::move(image); +} + +CubeMapTexture& CubeMapTexture::setSubImage(const Int level, const Vector3i& offset, const ImageReference3D& image) { + Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); + glTextureSubImage3D(_id, level, offset.x(), offset.y(), offset.z(), image.size().x(), image.size().y(), image.size().z(), GLenum(image.format()), GLenum(image.type()), image.data()); + return *this; +} + +CubeMapTexture& CubeMapTexture::setSubImage(const Int level, const Vector3i& offset, BufferImage3D& image) { + image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); + glTextureSubImage3D(_id, level, offset.x(), offset.y(), offset.z(), image.size().x(), image.size().y(), image.size().z(), GLenum(image.format()), GLenum(image.type()), nullptr); + return *this; +} +#endif + +CubeMapTexture& CubeMapTexture::setSubImage(const Coordinate coordinate, const Int level, const Vector2i& offset, const ImageReference2D& image) { + #ifndef MAGNUM_TARGET_GLES2 + Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); + #endif + (this->*Context::current()->state().texture->cubeSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), image.type(), image.data()); + return *this; +} + +#ifndef MAGNUM_TARGET_GLES2 +CubeMapTexture& CubeMapTexture::setSubImage(const Coordinate coordinate, const Int level, const Vector2i& offset, BufferImage2D& image) { + image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); + (this->*Context::current()->state().texture->cubeSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), image.type(), nullptr); + return *this; +} +#endif + +#ifndef MAGNUM_TARGET_GLES2 +Vector2i CubeMapTexture::getImageSizeImplementationDefault(const Int level) { + Vector2i size; + bindInternal(); + glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_WIDTH, &size.x()); + glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_HEIGHT, &size.y()); + return size; +} + +#ifndef MAGNUM_TARGET_GLES +Vector2i CubeMapTexture::getImageSizeImplementationDSA(const Int level) { + Vector2i size; + glGetTextureLevelParameteriv(_id, level, GL_TEXTURE_WIDTH, &size.x()); + glGetTextureLevelParameteriv(_id, level, GL_TEXTURE_HEIGHT, &size.y()); + return size; +} + +Vector2i CubeMapTexture::getImageSizeImplementationDSAEXT(const Int level) { + _created = true; + Vector2i size; + glGetTextureLevelParameterivEXT(_id, GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_WIDTH, &size.x()); + glGetTextureLevelParameterivEXT(_id, GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_HEIGHT, &size.y()); + return size; +} +#endif +#endif + +#ifndef MAGNUM_TARGET_GLES +void CubeMapTexture::getImageImplementationDefault(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, std::size_t, GLvoid* const data) { + bindInternal(); + glGetTexImage(GLenum(coordinate), level, GLenum(format), GLenum(type), data); +} + +void CubeMapTexture::getImageImplementationDSA(const Coordinate coordinate, const GLint level, const Vector2i& size, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { + glGetTextureSubImage(_id, level, 0, 0, GLenum(coordinate) - GL_TEXTURE_CUBE_MAP_POSITIVE_X, size.x(), size.y(), 1, GLenum(format), GLenum(type), dataSize, data); +} + +void CubeMapTexture::getImageImplementationDSAEXT(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, std::size_t, GLvoid* const data) { + _created = true; + glGetTextureImageEXT(_id, GLenum(coordinate), level, GLenum(format), GLenum(type), data); +} + +void CubeMapTexture::getImageImplementationRobustness(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { + bindInternal(); + glGetnTexImageARB(GLenum(coordinate), level, GLenum(format), GLenum(type), dataSize, data); +} +#endif + +void CubeMapTexture::subImageImplementationDefault(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + bindInternal(); + glTexSubImage2D(GLenum(coordinate), level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); +} + +#ifndef MAGNUM_TARGET_GLES +void CubeMapTexture::subImageImplementationDSA(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + glTextureSubImage3D(_id, level, offset.x(), offset.y(), GLenum(coordinate) - GL_TEXTURE_CUBE_MAP_POSITIVE_X, size.x(), size.y(), 1, GLenum(format), GLenum(type), data); +} + +void CubeMapTexture::subImageImplementationDSAEXT(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + _created = true; + glTextureSubImage2DEXT(_id, GLenum(coordinate), level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); +} +#endif + } diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h index 5dc73c20b..3f6104936 100644 --- a/src/Magnum/CubeMapTexture.h +++ b/src/Magnum/CubeMapTexture.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,7 +38,7 @@ namespace Magnum { /** @brief Cube map texture -%Texture used mainly for environment maps. It consists of 6 square textures +Texture used mainly for environment maps. It consists of 6 square textures generating 6 faces of the cube as following. Note that all images must be turned upside down (+Y is top): @@ -80,6 +80,8 @@ which intersects one of the six sides of the cube map. See @ref MultisampleTexture */ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { + friend Implementation::TextureState; + public: /** @brief Cube map coordinate */ enum class Coordinate: GLenum { @@ -122,39 +124,77 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { #endif #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setBaseLevel() */ + /** + * @copybrief Texture::setBaseLevel() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBaseLevel() for more information. + * @requires_gles30 Base level is always `0` in OpenGL ES 2.0. + */ CubeMapTexture& setBaseLevel(Int level) { AbstractTexture::setBaseLevel(level); return *this; } #endif - /** @copydoc Texture::setMaxLevel() */ + /** + * @copybrief Texture::setMaxLevel() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxLevel() for more information. + * @requires_gles30 Extension @es_extension{APPLE,texture_max_level}, + * otherwise the max level is always set to largest possible value + * in OpenGL ES 2.0. + */ CubeMapTexture& setMaxLevel(Int level) { AbstractTexture::setMaxLevel(level); return *this; } - /** @copydoc Texture::setMinificationFilter() */ + /** + * @copybrief Texture::setMinificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinificationFilter() for more information. + */ CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { AbstractTexture::setMinificationFilter(filter, mipmap); return *this; } - /** @copydoc Texture::setMagnificationFilter() */ + /** + * @copybrief Texture::setMagnificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMagnificationFilter() for more information. + */ CubeMapTexture& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); return *this; } #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setMinLod() */ + /** + * @copybrief Texture::setMinLod() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinLod() for more information. + * @requires_gles30 Texture LOD parameters are not available in OpenGL + * ES 2.0. + */ CubeMapTexture& setMinLod(Float lod) { AbstractTexture::setMinLod(lod); return *this; } - /** @copydoc Texture::setMaxLod() */ + /** + * @copybrief Texture::setMaxLod() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxLod() for more information. + * @requires_gles30 Texture LOD parameters are not available in OpenGL + * ES 2.0. + */ CubeMapTexture& setMaxLod(Float lod) { AbstractTexture::setMaxLod(lod); return *this; @@ -162,53 +202,106 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { #endif #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::setLodBias() */ + /** + * @copybrief Texture::setLodBias() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setLodBias() for more information. + * @requires_gl Texture LOD bias can be specified only directly in + * fragment shader in OpenGL ES. + */ CubeMapTexture& setLodBias(Float bias) { AbstractTexture::setLodBias(bias); return *this; } #endif - /** @copydoc Texture::setWrapping() */ + /** + * @copybrief Texture::setWrapping() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setWrapping() for more information. + */ CubeMapTexture& setWrapping(const Array3D& wrapping) { DataHelper<3>::setWrapping(*this, wrapping); return *this; } - /** @copydoc Texture::setBorderColor(const Color4&) */ + /** + * @copybrief Texture::setBorderColor(const Color4&) + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBorderColor(const Color4&) for more + * information. + * @requires_es_extension Extension @es_extension{NV,texture_border_clamp} + */ CubeMapTexture& setBorderColor(const Color4& color) { AbstractTexture::setBorderColor(color); return *this; } #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::setBorderColor(const Vector4ui&) */ + /** + * @copybrief Texture::setBorderColor(const Vector4ui&) + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBorderColor(const Vector4ui&) for more + * information. + * @requires_gl30 Extension @extension{EXT,texture_integer} + * @requires_gl Border is available only for float textures in OpenGL + * ES. + */ CubeMapTexture& setBorderColor(const Vector4ui& color) { AbstractTexture::setBorderColor(color); return *this; } - /** @copydoc Texture::setBorderColor(const Vector4i&) */ + /** @overload + * @requires_gl30 Extension @extension{EXT,texture_integer} + * @requires_gl Border is available only for float textures in OpenGL + * ES. + */ CubeMapTexture& setBorderColor(const Vector4i& color) { AbstractTexture::setBorderColor(color); return *this; } #endif - /** @copydoc Texture::setMaxAnisotropy() */ + /** + * @copybrief Texture::setMaxAnisotropy() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxAnisotropy() for more information. + */ CubeMapTexture& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return *this; } - /** @copydoc Texture::setSRGBDecode() */ + /** + * @copybrief Texture::setSRGBDecode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSRGBDecode() for more information. + * @requires_extension Extension @extension{EXT,texture_sRGB_decode} + * @requires_es_extension OpenGL ES 3.0 or extension + * @es_extension{EXT,sRGB} and + * @es_extension2{EXT,texture_sRGB_decode,texture_sRGB_decode} + */ CubeMapTexture& setSRGBDecode(bool decode) { AbstractTexture::setSRGBDecode(decode); return *this; } #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setSwizzle() */ + /** + * @copybrief Texture::setSwizzle() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSwizzle() for more information. + * @requires_gl33 Extension @extension{ARB,texture_swizzle} + * @requires_gles30 Texture swizzle is not available in OpenGL ES 2.0. + */ template CubeMapTexture& setSwizzle() { AbstractTexture::setSwizzle(); return *this; @@ -220,7 +313,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setCompareMode() for more information. - * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} and + * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} and * @es_extension{NV,shadow_samplers_cube} */ CubeMapTexture& setCompareMode(Sampler::CompareMode mode) { @@ -233,7 +326,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setCompareFunction() for more information. - * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} and + * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} and * @es_extension{NV,shadow_samplers_cube} */ CubeMapTexture& setCompareFunction(Sampler::CompareFunction function) { @@ -242,80 +335,212 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { } #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setDepthStencilMode() */ + /** + * @copybrief Texture::setDepthStencilMode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setDepthStencilMode() for more information. + * @requires_gl43 Extension @extension{ARB,stencil_texturing} + * @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0 + * and older. + */ CubeMapTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) { AbstractTexture::setDepthStencilMode(mode); return *this; } #endif - #ifndef MAGNUM_TARGET_GLES2 /** - * @brief %Image size in given mip level - * @param coordinate Coordinate - * @param level Mip level + * @copybrief Texture::setStorage() + * @return Reference to self (for method chaining) * - * See @ref Texture::imageSize() for more information. - * @requires_gles31 %Texture image size queries are not available in - * OpenGL ES 3.0 and older. + * See @ref Texture::setStorage() for more information. + * @see @ref maxSize() */ - Vector2i imageSize(Coordinate coordinate, Int level) { - return DataHelper<2>::imageSize(*this, GLenum(coordinate), level); + CubeMapTexture& setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) { + DataHelper<2>::setStorage(*this, levels, internalFormat, size); + return *this; } - #endif + #ifndef MAGNUM_TARGET_GLES2 /** - * @brief Set storage + * @copybrief Texture::imageSize() * - * See @ref Texture::setStorage() for more information. - * @see @ref maxSize() + * If on OpenGL ES or @extension{ARB,direct_state_access} (part of + * OpenGL 4.5) is not available, it is assumed that faces have the same + * size and just the size of @ref Coordinate::PositiveX face is + * queried. See @ref Texture::imageSize() for more information. + * @requires_gles31 Texture image size queries are not available in + * OpenGL ES 3.0 and older. */ - CubeMapTexture& setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) { - DataHelper<2>::setStorage(*this, _target, levels, internalFormat, size); - return *this; + Vector2i imageSize(Int level); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief imageSize() + * @deprecated Use @ref Magnum::CubeMapTexture::imageSize(Int) "imageSize(Int)" + * instead. + */ + CORRADE_DEPRECATED("use imageSize(Int) instead") Vector2i imageSize(Coordinate, Int level) { + return imageSize(level); } + #endif + #endif #ifndef MAGNUM_TARGET_GLES /** * @brief Read given mip level of texture to image - * @param coordinate Coordinate - * @param level Mip level - * @param image %Image where to put the data * - * See @ref Texture::image(Int, Image&) for more information. - * @requires_gl %Texture image queries are not available in OpenGL ES. + * Image parameters like format and type of pixel data are taken from + * given image, image size is taken from the texture using + * @ref imageSize(). + * @see @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter} with + * @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT}, then + * @fn_gl{GetTextureImage} + * @requires_gl45 Extension @extension{ARB,direct_state_access} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. */ - void image(Coordinate coordinate, Int level, Image2D& image) { - AbstractTexture::image<2>(GLenum(coordinate), level, image); - } + void image(Int level, Image3D& image); + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image3D image(Int level, Image3D&& image); /** * @brief Read given mip level of texture to buffer image - * @param coordinate Coordinate - * @param level Mip level - * @param image %Buffer image where to put the data - * @param usage %Buffer usage * - * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more - * information. - * @requires_gl %Texture image queries are not available in OpenGL ES. + * See @ref image(Int, Image3D&) for more information. + * @requires_gl45 Extension @extension{ARB,direct_state_access} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ + void image(Int level, BufferImage3D& image, BufferUsage usage); + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage3D image(Int level, BufferImage3D&& image, BufferUsage usage); + + /** + * @brief Read given mip level and coordinate of texture to image + * + * Image parameters like format and type of pixel data are taken from + * given image, image size is taken from the texture using + * @ref imageSize(). + * + * If neither @extension{ARB,get_texture_sub_image} (part of OpenGL + * 4.5) nor @extension{EXT,direct_state_access} is available, the + * texture is bound before the operation (if not already). If either + * @extension{ARB,get_texture_sub_image} or @extension{ARB,robustness} + * is available, the operation is protected from buffer overflow. + * However, if @extension{ARB,get_texture_sub_image} is not available + * and both @extension{EXT,direct_state_access} and + * @extension{ARB,robustness} are available, the robust operation is + * preferred over DSA. + * @see @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter}, + * @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{GetTexLevelParameter} with @def_gl{TEXTURE_WIDTH}, + * @def_gl{TEXTURE_HEIGHT}, then @fn_gl{GetTextureSubImage}, + * @fn_gl_extension{GetnTexImage,ARB,robustness}, + * @fn_gl_extension{GetTextureImage,EXT,direct_state_access}, + * eventually @fn_gl{GetTexImage} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ + void image(Coordinate coordinate, Int level, Image2D& image); + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image2D image = texture.image(CubeMapTexture::Coordinate::PositiveX, 0, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image2D image(Coordinate coordinate, Int level, Image2D&& image); + + /** + * @brief Read given mip level and coordinate of texture to buffer image + * + * See @ref image(Coordinate, Int, Image2D&) for more information. + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ + void image(Coordinate coordinate, Int level, BufferImage2D& image, BufferUsage usage); + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage2D image = texture.image(CubeMapTexture::Coordinate::PositiveX, 0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage2D image(Coordinate coordinate, Int level, BufferImage2D&& image, BufferUsage usage); + + /** + * @copybrief Texture::subImage(Int, const RangeTypeFor&, Image&) + * + * See @ref Texture::subImage(Int, const RangeTypeFor&, Image&) + * for more information. + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ + void subImage(Int level, const Range3Di& range, Image3D& image) { + AbstractTexture::subImage<3>(level, range, image); + } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image3D subImage(Int level, const Range3Di& range, Image3D&& image); + + /** + * @copybrief Texture::subImage(Int, const RangeTypeFor&, BufferImage&, BufferUsage) + * + * See @ref Texture::subImage(Int, const RangeTypeFor&, BufferImage&, BufferUsage) + * for more information. + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. */ - void image(Coordinate coordinate, Int level, BufferImage2D& image, BufferUsage usage) { - AbstractTexture::image<2>(GLenum(coordinate), level, image, usage); + void subImage(Int level, const Range3Di& range, BufferImage3D& image, BufferUsage usage) { + AbstractTexture::subImage<3>(level, range, image, usage); } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage); #endif /** - * @brief Set image data - * @param coordinate Coordinate - * @param level Mip level - * @param internalFormat Internal format - * @param image @ref Image2D, @ref ImageReference2D or - * @ref Trade::ImageData2D + * @copybrief Texture::setImage() * @return Reference to self (for method chaining) * * See @ref Texture::setImage() for more information. * @see @ref maxSize() + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTexture::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTexture::setSubImage() "setSubImage()" + * instead. */ CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, const ImageReference2D& image) { DataHelper<2>::setImage(*this, GLenum(coordinate), level, internalFormat, image); @@ -323,62 +548,108 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { } #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTexture::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTexture::setSubImage() "setSubImage()" + * instead. + */ CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D& image) { DataHelper<2>::setImage(*this, GLenum(coordinate), level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTexture::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTexture::setSubImage() "setSubImage()" + * instead. + */ CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D&& image) { return setImage(coordinate, level, internalFormat, image); } #endif + #ifndef MAGNUM_TARGET_GLES /** * @brief Set image subdata - * @param coordinate Coordinate * @param level Mip level * @param offset Offset where to put data in the texture - * @param image @ref Image2D, @ref ImageReference2D or - * @ref Trade::ImageData2D + * @param image @ref Image, @ref ImageReference or + * @ref Trade::ImageData of the same dimension count * @return Reference to self (for method chaining) * - * See @ref Texture::setSubImage() for more information. + * @see @ref setStorage(), @fn_gl2{TextureSubImage3D,TexSubImage3D} + * @requires_gl45 Extension @extension{ARB,direct_state_access} + * @requires_gl In OpenGL ES you need to set image for each face + * separately. */ - CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image) { - DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image); - return *this; + CubeMapTexture& setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image); + + /** @overload + * @requires_gl45 Extension @extension{ARB,direct_state_access} + * @requires_gl In OpenGL ES you need to set image for each face + * separately. + */ + CubeMapTexture& setSubImage(Int level, const Vector3i& offset, BufferImage3D& image); + + /** @overload + * @requires_gl45 Extension @extension{ARB,direct_state_access} + * @requires_gl In OpenGL ES you need to set image for each face + * separately. + */ + CubeMapTexture& setSubImage(Int level, const Vector3i& offset, BufferImage3D&& image) { + return setSubImage(level, offset, image); } + #endif + + /** + * @copybrief Texture::setSubImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSubImage() for more information. + */ + CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image); #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ - CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image) { - DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image); - return *this; - } + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + */ + CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image); - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + */ CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D&& image) { - DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image); - return *this; + return setSubImage(coordinate, level, offset, image); } #endif - /** @copydoc Texture::generateMipmap() */ + /** + * @copybrief Texture::generateMipmap() + * @return Reference to self (for method chaining) + * + * See @ref Texture::generateMipmap() for more information. + * @requires_gl30 Extension @extension{ARB,framebuffer_object} + */ CubeMapTexture& generateMipmap() { AbstractTexture::generateMipmap(); return *this; } - /** @copydoc Texture::invalidateImage() */ + /** + * @copybrief Texture::invalidateImage() + * + * See @ref Texture::invalidateImage() for more information. + */ void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } /** - * @brief Invalidate texture subimage - * @param level Mip level - * @param offset Offset into the texture - * @param size Size of invalidated data + * @copybrief Texture::invalidateSubImage() * * Z coordinate is equivalent to number of texture face, i.e. * @ref Coordinate::PositiveX is `0` and so on, in the same order as in @@ -401,6 +672,26 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { return *this; } #endif + + private: + Vector2i MAGNUM_LOCAL getImageSizeImplementationDefault(Int level); + #ifndef MAGNUM_TARGET_GLES + Vector2i MAGNUM_LOCAL getImageSizeImplementationDSA(Int level); + Vector2i MAGNUM_LOCAL getImageSizeImplementationDSAEXT(Int level); + #endif + + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL getImageImplementationDefault(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDSA(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDSAEXT(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationRobustness(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + #endif + + void MAGNUM_LOCAL subImageImplementationDefault(Coordinate coordinate, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL subImageImplementationDSA(Coordinate coordinate, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSAEXT(Coordinate coordinate, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + #endif }; } diff --git a/src/Magnum/CubeMapTextureArray.cpp b/src/Magnum/CubeMapTextureArray.cpp index 6a0866716..22b5024cb 100644 --- a/src/Magnum/CubeMapTextureArray.cpp +++ b/src/Magnum/CubeMapTextureArray.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,8 +26,10 @@ #include "CubeMapTextureArray.h" #ifndef MAGNUM_TARGET_GLES +#include "Magnum/BufferImage.h" #include "Magnum/Context.h" #include "Magnum/Extensions.h" +#include "Magnum/Image.h" #include "Implementation/maxTextureSize.h" @@ -41,5 +43,25 @@ Vector3i CubeMapTextureArray::maxSize() { Implementation::maxTextureArrayLayers()}; } +Image3D CubeMapTextureArray::image(const Int level, Image3D&& image) { + this->image(level, image); + return std::move(image); +} + +BufferImage3D CubeMapTextureArray::image(const Int level, BufferImage3D&& image, const BufferUsage usage) { + this->image(level, image, usage); + return std::move(image); +} + +Image3D CubeMapTextureArray::subImage(const Int level, const Range3Di& range, Image3D&& image) { + this->subImage(level, range, image); + return std::move(image); +} + +BufferImage3D CubeMapTextureArray::subImage(const Int level, const Range3Di& range, BufferImage3D&& image, const BufferUsage usage) { + this->subImage(level, range, image, usage); + return std::move(image); +} + } #endif diff --git a/src/Magnum/CubeMapTextureArray.h b/src/Magnum/CubeMapTextureArray.h index 486a03928..d69542474 100644 --- a/src/Magnum/CubeMapTextureArray.h +++ b/src/Magnum/CubeMapTextureArray.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -79,10 +79,10 @@ the six sides of the cube map, fourth part is layer in the array. See @see @ref Renderer::Feature::SeamlessCubeMapTexture, @ref CubeMapTexture, @ref Texture, @ref TextureArray, @ref RectangleTexture, @ref BufferTexture, @ref MultisampleTexture -@requires_gl40 %Extension @extension{ARB,texture_cube_map_array} +@requires_gl40 Extension @extension{ARB,texture_cube_map_array} @requires_gl Cube map texture arrays are not available in OpenGL ES. */ -class CubeMapTextureArray: public AbstractTexture { +class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture { public: /** * @brief Constructor @@ -138,13 +138,23 @@ class CubeMapTextureArray: public AbstractTexture { return *this; } - /** @copydoc Texture::setMinificationFilter() */ + /** + * @copybrief Texture::setMinificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinificationFilter() for more information. + */ CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { AbstractTexture::setMinificationFilter(filter, mipmap); return *this; } - /** @copydoc Texture::setMagnificationFilter() */ + /** + * @copybrief Texture::setMagnificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMagnificationFilter() for more information. + */ CubeMapTextureArray& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); return *this; @@ -183,7 +193,12 @@ class CubeMapTextureArray: public AbstractTexture { return *this; } - /** @copydoc Texture::setWrapping() */ + /** + * @copybrief Texture::setWrapping() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setWrapping() for more information. + */ CubeMapTextureArray& setWrapping(const Array3D& wrapping) { DataHelper<3>::setWrapping(*this, wrapping); return *this; @@ -207,31 +222,39 @@ class CubeMapTextureArray: public AbstractTexture { * * See @ref Texture::setBorderColor(const Vector4ui&) for more * information. + * @requires_gl30 Extension @extension{EXT,texture_integer} */ CubeMapTextureArray& setBorderColor(const Vector4ui& color) { AbstractTexture::setBorderColor(color); return *this; } - /** - * @copybrief Texture::setBorderColor(const Vector4ui&) - * @return Reference to self (for method chaining) - * - * See @ref Texture::setBorderColor(const Vector4i&) for more - * information. + /** @overload + * @requires_gl30 Extension @extension{EXT,texture_integer} */ CubeMapTextureArray& setBorderColor(const Vector4i& color) { AbstractTexture::setBorderColor(color); return *this; } - /** @copydoc Texture::setMaxAnisotropy() */ + /** + * @copybrief Texture::setMaxAnisotropy() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxAnisotropy() for more information. + */ CubeMapTextureArray& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return *this; } - /** @copydoc RectangleTexture::setSRGBDecode() */ + /** + * @copybrief Texture::setSRGBDecode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSRGBDecode() for more information. + * @requires_extension Extension @extension{EXT,texture_sRGB_decode} + */ CubeMapTextureArray& setSRGBDecode(bool decode) { AbstractTexture::setSRGBDecode(decode); return *this; @@ -242,6 +265,7 @@ class CubeMapTextureArray: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setSwizzle() for more information. + * @requires_gl33 Extension @extension{ARB,texture_swizzle} */ template CubeMapTextureArray& setSwizzle() { AbstractTexture::setSwizzle(); @@ -275,6 +299,7 @@ class CubeMapTextureArray: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setDepthStencilMode() for more information. + * @requires_gl43 Extension @extension{ARB,stencil_texturing} */ CubeMapTextureArray& setDepthStencilMode(Sampler::DepthStencilMode mode) { AbstractTexture::setDepthStencilMode(mode); @@ -282,57 +307,107 @@ class CubeMapTextureArray: public AbstractTexture { } /** - * @brief %Image size in given mip level - * @param level Mip level + * @copybrief Texture::setStorage() + * @return Reference to self (for method chaining) * - * See @ref Texture::imageSize() for more information. + * Z coordinate of @p size must be multiple of 6. + * + * See @ref Texture::setStorage() for more information. + * @see @ref maxSize() */ - Vector3i imageSize(Int level) { - return DataHelper<3>::imageSize(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level); + CubeMapTextureArray& setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) { + DataHelper<3>::setStorage(*this, levels, internalFormat, size); + return *this; } /** - * @brief Set storage + * @copybrief Texture::imageSize() * - * Z coordinate of @p size must be multiple of 6. See - * @ref Texture::setStorage() for more information. - * @see @ref maxSize() + * See @ref Texture::imageSize() for more information. */ - CubeMapTextureArray& setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) { - DataHelper<3>::setStorage(*this, _target, levels, internalFormat, size); - return *this; + Vector3i imageSize(Int level) { + return DataHelper<3>::imageSize(*this, level); } /** - * @brief Read given mip level of texture to image - * @param level Mip level - * @param image %Image where to put the data + * @copybrief Texture::image(Int, Image&) * * See @ref Texture::image(Int, Image&) for more information. */ void image(Int level, Image3D& image) { - AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_ARRAY, level, image); + AbstractTexture::image<3>(level, image); } + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image3D image(Int level, Image3D&& image); + /** - * @brief Read given mip level of texture to buffer image - * @param level Mip level - * @param image %Buffer image where to put the data - * @param usage %Buffer usage + * @copybrief Texture::image(Int, BufferImage&, BufferUsage) * * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more * information. */ void image(Int level, BufferImage3D& image, BufferUsage usage) { - AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_ARRAY, level, image, usage); + AbstractTexture::image<3>(level, image, usage); + } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage3D image(Int level, BufferImage3D&& image, BufferUsage usage); + + /** + * @copybrief Texture::subImage(Int, const RangeTypeFor&, Image&) + * + * See @ref Texture::subImage(Int, const RangeTypeFor&, Image&) + * for more information. + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + */ + void subImage(Int level, const Range3Di& range, Image3D& image) { + AbstractTexture::subImage<3>(level, range, image); } + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image3D subImage(Int level, const Range3Di& range, Image3D&& image); + /** - * @brief Set image data - * @param level Mip level - * @param internalFormat Internal format - * @param image @ref Image3D, @ref ImageReference3D or - * @ref Trade::ImageData3D + * @copybrief Texture::subImage(Int, const RangeTypeFor&, BufferImage&, BufferUsage) + * + * See @ref Texture::subImage(Int, const RangeTypeFor&, BufferImage&, BufferUsage) + * for more information. + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + */ + void subImage(Int level, const Range3Di& range, BufferImage3D& image, BufferUsage usage) { + AbstractTexture::subImage<3>(level, range, image, usage); + } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage); + + /** + * @copybrief Texture::setImage() * @return Reference to self (for method chaining) * * Sets texture image data from three-dimensional image for all cube @@ -342,29 +417,36 @@ class CubeMapTextureArray: public AbstractTexture { * * See @ref Texture::setImage() for more information. * @see @ref maxSize() + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTextureArray::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTextureArray::setSubImage() "setSubImage()" + * instead. */ CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, const ImageReference3D& image) { - DataHelper<3>::setImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image); + DataHelper<3>::setImage(*this, level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTextureArray::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTextureArray::setSubImage() "setSubImage()" + * instead. + */ CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage3D& image) { - DataHelper<3>::setImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image); + DataHelper<3>::setImage(*this, level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTextureArray::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTextureArray::setSubImage() "setSubImage()" + * instead. + */ CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage3D&& image) { return setImage(level, internalFormat, image); } /** - * @brief Set texture image 3D subdata - * @param level Mip level - * @param offset Offset where to put data in the texture - * @param image @ref Image3D, @ref ImageReference3D or - * @ref Trade::ImageData3D + * @copybrief Texture::setSubImage() * @return Reference to self (for method chaining) * * Z coordinate is equivalent to layer * 6 + number of texture face, @@ -373,13 +455,13 @@ class CubeMapTextureArray: public AbstractTexture { * See @ref Texture::setSubImage() for more information. */ CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image) { - DataHelper<3>::setSubImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image); + DataHelper<3>::setSubImage(*this, level, offset, image); return *this; } /** @overload */ CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, BufferImage3D& image) { - DataHelper<3>::setSubImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image); + DataHelper<3>::setSubImage(*this, level, offset, image); return *this; } @@ -388,20 +470,27 @@ class CubeMapTextureArray: public AbstractTexture { return setSubImage(level, offset, image); } - /** @copydoc Texture::generateMipmap() */ + /** + * @copybrief Texture::generateMipmap() + * @return Reference to self (for method chaining) + * + * See @ref Texture::generateMipmap() for more information. + * @requires_gl30 Extension @extension{ARB,framebuffer_object} + */ CubeMapTextureArray& generateMipmap() { AbstractTexture::generateMipmap(); return *this; } - /** @copydoc Texture::invalidateImage() */ + /** + * @copybrief Texture::invalidateImage() + * + * See @ref Texture::invalidateImage() for more information. + */ void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } /** - * @brief Invalidate texture subimage - * @param level Mip level - * @param offset Offset into the texture - * @param size Size of invalidated data + * @copybrief Texture::invalidateSubImage() * * Z coordinate is equivalent to layer * 6 + number of texture face, * i.e. +X is `0` and so on, in order of (+X, -X, +Y, -Y, +Z, -Z). diff --git a/src/Magnum/DebugMarker.h b/src/Magnum/DebugMarker.h index 1a3f9e8d0..ef47d0fc1 100644 --- a/src/Magnum/DebugMarker.h +++ b/src/Magnum/DebugMarker.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,11 +26,11 @@ */ /** @file - * @brief Typedef @ref Magnum::DebugMarker - * @deprecated Use @ref DebugMessage.h instead. + * @brief Class @ref Magnum::DebugMarker + * @deprecated Use @ref DebugOutput.h instead. */ -#include "Magnum/DebugMessage.h" +#include "Magnum/DebugOutput.h" #ifdef MAGNUM_BUILD_DEPRECATED namespace Magnum { @@ -46,7 +46,7 @@ class CORRADE_DEPRECATED("use DebugMessage instead") MAGNUM_EXPORT DebugMarker: * @deprecated Use @ref Magnum::DebugMessage::insert() "insert()" instead. */ static CORRADE_DEPRECATED("use DebugMessage::insert() instead") void mark(const std::string& string) { - insert(Source::Application, Type::Marker, 0, Severity::Notification, string); + insert(Source::Application, Type::Marker, 0, DebugOutput::Severity::Notification, string); } }; diff --git a/src/Magnum/DebugMessage.cpp b/src/Magnum/DebugMessage.cpp deleted file mode 100644 index a444ee618..000000000 --- a/src/Magnum/DebugMessage.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013, 2014 - Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "DebugMessage.h" - -#include - -#include "Magnum/Context.h" -#include "Magnum/Extensions.h" -#include "Magnum/Implementation/State.h" -#include "Magnum/Implementation/DebugState.h" - -namespace Magnum { - -namespace { - -#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) -void -#ifdef CORRADE_TARGET_WINDOWS -APIENTRY -#endif -callbackWrapper(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) { - Context::current()->state().debug->messageCallback(DebugMessage::Source(source), DebugMessage::Type(type), id, DebugMessage::Severity(severity), std::string(message, length), userParam); -} -#endif - -void defaultCallback(const DebugMessage::Source source, const DebugMessage::Type type, const UnsignedInt id, const DebugMessage::Severity severity, const std::string& string, const void*) { - switch(severity) { - case DebugMessage::Severity::High: - Error() << source << type << id << severity << "\n " << string; - break; - - case DebugMessage::Severity::Medium: - case DebugMessage::Severity::Low: - Warning() << source << type << id << severity << "\n " << string; - break; - - default: Debug() << source << type << id << severity << "\n " << string; - } -} - -} - -Int DebugMessage::maxLoggedMessages() { - if(!Context::current()->isExtensionSupported()) - return 0; - - GLint& value = Context::current()->state().debug->maxLoggedMessages; - - if(value == 0) { - #ifndef MAGNUM_TARGET_GLES - glGetIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES, &value); - #else - glGetIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES_KHR, &value); - #endif - } - - return value; -} - -Int DebugMessage::maxMessageLength() { - if(!Context::current()->isExtensionSupported()) - return 0; - - GLint& value = Context::current()->state().debug->maxMessageLength; - - if(value == 0) { - #ifndef MAGNUM_TARGET_GLES - glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &value); - #else - glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH_KHR, &value); - #endif - } - - return value; -} - -void DebugMessage::setCallback(const Callback callback, const void* userParam) { - Context::current()->state().debug->messageCallbackImplementation(callback, userParam); -} - -void DebugMessage::setDefaultCallback() { - setCallback(defaultCallback, nullptr); -} - -void DebugMessage::insertInternal(const Source source, const Type type, const UnsignedInt id, const Severity severity, const Containers::ArrayReference string) { - Context::current()->state().debug->messageInsertImplementation(source, type, id, severity, string); -} - -void DebugMessage::insertImplementationNoOp(Source, Type, UnsignedInt, Severity, const Containers::ArrayReference) {} - -void DebugMessage::insertImplementationKhr(const Source source, const Type type, const UnsignedInt id, const Severity severity, const Containers::ArrayReference string) { - #ifndef MAGNUM_TARGET_GLES - glDebugMessageInsert(GLenum(source), GLenum(type), id, GLenum(severity), string.size(), string.data()); - #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glDebugMessageInsertKHR(GLenum(source), GLenum(type), id, GLenum(severity), string.size(), string.data()); - #else - static_cast(source); - static_cast(type); - static_cast(id); - static_cast(severity); - static_cast(string); - CORRADE_ASSERT_UNREACHABLE(); - #endif -} - -void DebugMessage::insertImplementationExt(Source, Type, UnsignedInt, Severity, const Containers::ArrayReference string) { - #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glInsertEventMarkerEXT(string.size(), string.data()); - #else - static_cast(string); - CORRADE_ASSERT_UNREACHABLE(); - #endif -} - -#ifndef MAGNUM_TARGET_GLES -void DebugMessage::insertImplementationGremedy(Source, Type, UnsignedInt, Severity, const Containers::ArrayReference string) { - glStringMarkerGREMEDY(string.size(), string.data()); -} -#endif - -void DebugMessage::setEnabledInternal(const GLenum source, const GLenum type, const GLenum severity, const std::initializer_list ids, const bool enabled) { - Context::current()->state().debug->messageControlImplementation(source, type, severity, ids, enabled); -} - -void DebugMessage::controlImplementationNoOp(GLenum, GLenum, GLenum, std::initializer_list, bool) {} - -void DebugMessage::controlImplementationKhr(const GLenum source, const GLenum type, const GLenum severity, const std::initializer_list ids, const bool enabled) { - #ifndef MAGNUM_TARGET_GLES - glDebugMessageControl(source, type, severity, ids.size(), ids.begin(), enabled); - #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glDebugMessageControlKHR(source, type, severity, ids.size(), ids.begin(), enabled); - #else - static_cast(source); - static_cast(type); - static_cast(severity); - static_cast(ids); - static_cast(enabled); - CORRADE_ASSERT_UNREACHABLE(); - #endif -} - -void DebugMessage::callbackImplementationNoOp(Callback, const void*) {} - -void DebugMessage::callbackImplementationKhr(const Callback callback, const void* userParam) { - /* Replace the callback */ - const Callback original = Context::current()->state().debug->messageCallback; - Context::current()->state().debug->messageCallback = callback; - - /* Adding callback */ - if(!original && callback) { - #ifndef MAGNUM_TARGET_GLES - glDebugMessageCallback(callbackWrapper, userParam); - #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glDebugMessageCallbackKHR(callbackWrapper, userParam); - #else - static_cast(userParam); - CORRADE_ASSERT_UNREACHABLE(); - #endif - - /* Deleting callback */ - } else if(original && !callback) { - #ifndef MAGNUM_TARGET_GLES - glDebugMessageCallback(nullptr, nullptr); - #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glDebugMessageCallbackKHR(nullptr, nullptr); - #else - CORRADE_ASSERT_UNREACHABLE(); - #endif - } -} - -#ifndef DOXYGEN_GENERATING_OUTPUT -Debug operator<<(Debug debug, const DebugMessage::Source value) { - switch(value) { - #define _c(value) case DebugMessage::Source::value: return debug << "DebugMessage::Source::" #value; - _c(Api) - _c(WindowSystem) - _c(ShaderCompiler) - _c(ThirdParty) - _c(Application) - _c(Other) - #undef _c - } - - return debug << "DebugMessage::Source::(invalid)"; -} - -Debug operator<<(Debug debug, const DebugMessage::Type value) { - switch(value) { - #define _c(value) case DebugMessage::Type::value: return debug << "DebugMessage::Type::" #value; - _c(Error) - _c(DeprecatedBehavior) - _c(UndefinedBehavior) - _c(Portability) - _c(Performance) - _c(Other) - _c(Marker) - #undef _c - } - - return debug << "DebugMessage::Type::(invalid)"; -} - -Debug operator<<(Debug debug, const DebugMessage::Severity value) { - switch(value) { - #define _c(value) case DebugMessage::Severity::value: return debug << "DebugMessage::Severity::" #value; - _c(High) - _c(Medium) - _c(Low) - _c(Notification) - #undef _c - } - - return debug << "DebugMessage::Severity::(invalid)"; -} -#endif - -} diff --git a/src/Magnum/DebugMessage.h b/src/Magnum/DebugMessage.h index 041a2cb07..d844afd3a 100644 --- a/src/Magnum/DebugMessage.h +++ b/src/Magnum/DebugMessage.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,368 +26,9 @@ */ /** @file - * @brief Class @ref Magnum::DebugMessage + * @deprecated Use @ref DebugOutput.h instead. */ -#include -#include - -#include "Magnum/Magnum.h" -#include "Magnum/OpenGL.h" -#include "Magnum/visibility.h" - -namespace Magnum { - -namespace Implementation { struct DebugState; } - -/** -@brief Debug message - -Allows retrieving and inserting debug messages from and to OpenGL command -stream, for example with conjunction with various debuggers, such as Apitrace -or gDEBugger. - -## Basic usage - -To retrieve debug messages from either the GL or your application you need to -have OpenGL 4.3 or @extension{KHR,debug} desktop/ES extension. You need to -enable @ref Renderer::Feature::DebugOutput and possibly also -@ref Renderer::Feature::DebugOutputSynchronous. Then set up message callback -using @ref setCallback() or use the default one provided in -@ref setDefaultCallback(): - -@code -Renderer::enable(Renderer::Feature::DebugOutput); -Renderer::enable(Renderer::Feature::DebugOutputSynchronous); - -DebugMessage::setDefaultCallback(); -DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, - 1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!"); -@endcode - -With default callback the messages will be printed on standard output: - - DebugMessage::Source::Application DebugMessage::Type::Marker -1 DebugMessage::Severity::Notification - Hello from OpenGL command stream! -*/ -class MAGNUM_EXPORT DebugMessage { - friend struct Implementation::DebugState; - - public: - /** - * @brief Message source - * - * @see @ref insert(), @ref setCallback() - */ - enum class Source: GLenum { - /** OpenGL */ - #ifndef MAGNUM_TARGET_GLES - Api = GL_DEBUG_SOURCE_API, - #else - Api = GL_DEBUG_SOURCE_API_KHR, - #endif - - /** Window system (GLX, WGL) */ - #ifndef MAGNUM_TARGET_GLES - WindowSystem = GL_DEBUG_SOURCE_WINDOW_SYSTEM, - #else - WindowSystem = GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR, - #endif - - /** %Shader compiler */ - #ifndef MAGNUM_TARGET_GLES - ShaderCompiler = GL_DEBUG_SOURCE_SHADER_COMPILER, - #else - ShaderCompiler = GL_DEBUG_SOURCE_SHADER_COMPILER_KHR, - #endif - - /** External debugger or third-party middleware */ - #ifndef MAGNUM_TARGET_GLES - ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY, - #else - ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY_KHR, - #endif - - /** The application */ - #ifndef MAGNUM_TARGET_GLES - Application = GL_DEBUG_SOURCE_APPLICATION, - #else - Application = GL_DEBUG_SOURCE_APPLICATION_KHR, - #endif - - /** Any other source */ - #ifndef MAGNUM_TARGET_GLES - Other = GL_DEBUG_SOURCE_OTHER - #else - Other = GL_DEBUG_SOURCE_OTHER_KHR - #endif - }; - - /** - * @brief Message type - * - * @see @ref insert(), @ref setCallback() - */ - enum class Type: GLenum { - /** OpenGL error */ - #ifndef MAGNUM_TARGET_GLES - Error = GL_DEBUG_TYPE_ERROR, - #else - Error = GL_DEBUG_TYPE_ERROR_KHR, - #endif - - /** Behavior that has been marked for deprecation */ - #ifndef MAGNUM_TARGET_GLES - DeprecatedBehavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, - #else - DeprecatedBehavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR, - #endif - - /** Behavior that is undefined according to the specification */ - #ifndef MAGNUM_TARGET_GLES - UndefinedBehavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, - #else - UndefinedBehavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR, - #endif - - /** Non-portable usage of extensions or shaders */ - #ifndef MAGNUM_TARGET_GLES - Portability = GL_DEBUG_TYPE_PORTABILITY, - #else - Portability = GL_DEBUG_TYPE_PORTABILITY_KHR, - #endif - - /** Implementation-dependent performance warning */ - #ifndef MAGNUM_TARGET_GLES - Performance = GL_DEBUG_TYPE_PERFORMANCE, - #else - Performance = GL_DEBUG_TYPE_PERFORMANCE_KHR, - #endif - - /** Any other type */ - #ifndef MAGNUM_TARGET_GLES - Other = GL_DEBUG_TYPE_OTHER, - #else - Other = GL_DEBUG_TYPE_OTHER_KHR, - #endif - - /** Annotation of the command stream */ - #ifndef MAGNUM_TARGET_GLES - Marker = GL_DEBUG_TYPE_MARKER - #else - Marker = GL_DEBUG_TYPE_MARKER_KHR - #endif - }; - - /** - * @brief Message severity - * - * @see @ref insert(), @ref setCallback() - */ - enum class Severity: GLenum { - /** - * Any OpenGL error, dangerous undefined behavior, shader - * compilation errors. - */ - #ifndef MAGNUM_TARGET_GLES - High = GL_DEBUG_SEVERITY_HIGH, - #else - High = GL_DEBUG_SEVERITY_HIGH_KHR, - #endif - - /** - * Severe performance warnings, shader compilation warnings, use of - * deprecated behavior. - */ - #ifndef MAGNUM_TARGET_GLES - Medium = GL_DEBUG_SEVERITY_MEDIUM, - #else - Medium = GL_DEBUG_SEVERITY_MEDIUM_KHR, - #endif - - /** Minor performance warnings, trivial undefined behavior. */ - #ifndef MAGNUM_TARGET_GLES - Low = GL_DEBUG_SEVERITY_LOW, - #else - Low = GL_DEBUG_SEVERITY_LOW_KHR, - #endif - - /** Any message other than error or performance warning. */ - #ifndef MAGNUM_TARGET_GLES - Notification = GL_DEBUG_SEVERITY_NOTIFICATION - #else - Notification = GL_DEBUG_SEVERITY_NOTIFICATION_KHR - #endif - }; - - /** - * @brief Debug callback - * - * @see @ref setCallback() - */ - typedef void(*Callback)(Source, Type, UnsignedInt, Severity, const std::string&, const void*); - - /** - * @brief Max count of debug messages in log - * - * The result is cached, repeated queries don't result in repeated - * OpenGL calls. If OpenGL 4.3 is not supported and @extension{KHR,debug} - * desktop or ES extension is not available, returns `0`. - * @see @fn_gl{Get} with @def_gl{MAX_DEBUG_LOGGED_MESSAGES} - */ - static Int maxLoggedMessages(); - - /** - * @brief Max debug message length - * - * The result is cached, repeated queries don't result in repeated - * OpenGL calls. If OpenGL 4.3 is not supported and @extension{KHR,debug} - * desktop or ES extension is not available, returns `0`. - * @see @fn_gl{Get} with @def_gl{MAX_DEBUG_MESSAGE_LENGTH} - */ - static Int maxMessageLength(); - - /** - * @brief Insert message - * @param source Message source. Allowed values are - * @ref Source::ThirdParty or @ref Source::Application. - * @param type Message type - * @param id Message-specific ID - * @param severity Message severity - * @param string The actual message - * - * If OpenGL 4.3 is not supported and none of @extension{KHR,debug}, - * @extension2{EXT,debug_marker} or @extension{GREMEDY,string_marker} - * is available, this function does nothing. - * - * If @extension{KHR,debug} is not available and only @extension2{EXT,debug_marker} - * or @extension{GREMEDY,string_marker} are available, only @p string - * is used and all other parameters are ignored. The call is then - * equivalent to the following: - * @code - * DebugMessage::insert(DebugMessage::Source::Application, - * DebugMessage::Type::Marker, 0, DebugMessage::Severity::Notification, string); - * @endcode - * - * @see @ref maxMessageLength(), @fn_gl{DebugMessageInsert}, - * @fn_gl_extension2{InsertEventMarker,EXT,debug_marker} or - * @fn_gl_extension{StringMarker,GREMEDY,string_marker} - */ - static void insert(Source source, Type type, UnsignedInt id, Severity severity, const std::string& string) { - insertInternal(source, type, id, severity, {string.data(), string.size()}); - } - - /** @overload */ - template static void insert(Source source, Type type, UnsignedInt id, Severity severity, const char(&string)[size]) { - insertInternal(source, type, id, severity, {string, size - 1}); - } - - /** - * @brief Enable or disable particular message type - * - * @see @ref Renderer::Feature::DebugOutput, @fn_gl{DebugMessageControl} - */ - static void setEnabled(Source source, Type type, std::initializer_list ids, bool enabled) { - setEnabledInternal(GLenum(source), GLenum(type), GL_DONT_CARE, ids, enabled); - } - - /** @overload */ - static void setEnabled(Source source, Type type, Severity severity, bool enabled) { - setEnabledInternal(GLenum(source), GLenum(type), GLenum(severity), {}, enabled); - } - - /** @overload */ - static void setEnabled(Source source, Type type, bool enabled) { - setEnabledInternal(GLenum(source), GLenum(type), GL_DONT_CARE, {}, enabled); - } - - /** @overload */ - static void setEnabled(Source source, Severity severity, bool enabled) { - setEnabledInternal(GLenum(source), GL_DONT_CARE, GLenum(severity), {}, enabled); - } - - /** @overload */ - static void setEnabled(Source source, bool enabled) { - setEnabledInternal(GLenum(source), GL_DONT_CARE, GL_DONT_CARE, {}, enabled); - } - - /** @overload */ - static void setEnabled(Type type, Severity severity, bool enabled) { - setEnabledInternal(GL_DONT_CARE, GLenum(type), GLenum(severity), {}, enabled); - } - - /** @overload */ - static void setEnabled(Type type, bool enabled) { - setEnabledInternal(GL_DONT_CARE, GLenum(type), GL_DONT_CARE, {}, enabled); - } - - /** @overload */ - static void setEnabled(Severity severity, bool enabled) { - setEnabledInternal(GL_DONT_CARE, GL_DONT_CARE, GLenum(severity), {}, enabled); - } - - /** @overload */ - static void setEnabled(bool enabled) { - setEnabledInternal(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, {}, enabled); - } - - /** - * @brief Set debug message callback - * - * The messages are sent to the callback only if - * @ref Renderer::Feature::DebugOutput is enabled. If OpenGL 4.3 is not - * supported and @extension{KHR,debug} is not available, this function - * does nothing. - * @see @ref setDefaultCallback(), - * @ref Renderer::Feature::DebugOutputSynchronous, - * @fn_gl{DebugMessageCallback} - */ - static void setCallback(Callback callback, const void* userParam = nullptr); - - /** - * @brief Set default debug message callback - * - * See @ref setCallback() for more information. The message is printed - * to either @ref Corrade::Utility::Error "Error", @ref Corrade::Utility::Warning "Warning" - * or @ref Corrade::Utility::Debug "Debug" in the following format: - * @code - * DebugMessage::insert(DebugMessage::Source::Application, - * DebugMessage::Type::Marker, 1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!"); - * @endcode - * - * > %DebugMessage::Source::Application %DebugMessage::Type::Marker -1 %DebugMessage::Severity::Notification\n - * >     Hello from OpenGL command stream! - */ - static void setDefaultCallback(); - - DebugMessage() = delete; - - private: - static void insertInternal(Source source, Type type, UnsignedInt id, Severity severity, Containers::ArrayReference string); - static MAGNUM_LOCAL void insertImplementationNoOp(Source, Type, UnsignedInt, Severity, Containers::ArrayReference); - static MAGNUM_LOCAL void insertImplementationKhr(Source source, Type type, UnsignedInt id, Severity severity, Containers::ArrayReference string); - static MAGNUM_LOCAL void insertImplementationExt(Source, Type, UnsignedInt, Severity, Containers::ArrayReference string); - #ifndef MAGNUM_TARGET_GLES - static MAGNUM_LOCAL void insertImplementationGremedy(Source, Type, UnsignedInt, Severity, Containers::ArrayReference string); - #endif - - static void setEnabledInternal(GLenum source, GLenum type, GLenum severity, std::initializer_list ids, bool enabled); - static MAGNUM_LOCAL void controlImplementationNoOp(GLenum, GLenum, GLenum, std::initializer_list, bool); - static MAGNUM_LOCAL void controlImplementationKhr(GLenum source, GLenum type, GLenum severity, std::initializer_list ids, bool enabled); - - static MAGNUM_LOCAL void callbackImplementationNoOp(Callback, const void*); - static MAGNUM_LOCAL void callbackImplementationKhr(Callback callback, const void* userParam); -}; - -/** @debugoperatorclassenum{Magnum::DebugMessage,Magnum::DebugMessage::Source} */ -Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Source value); - -/** @debugoperatorclassenum{Magnum::DebugMessage,Magnum::DebugMessage::Type} */ -Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Type value); - -/** @debugoperatorclassenum{Magnum::DebugMessage,Magnum::DebugMessage::Severity} */ -Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Severity value); - -} +#include "Magnum/DebugOutput.h" #endif diff --git a/src/Magnum/DebugOutput.cpp b/src/Magnum/DebugOutput.cpp new file mode 100644 index 000000000..26a80a5b0 --- /dev/null +++ b/src/Magnum/DebugOutput.cpp @@ -0,0 +1,421 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "DebugOutput.h" + +#include + +#include "Magnum/Context.h" +#include "Magnum/Extensions.h" +#include "Magnum/Implementation/State.h" +#include "Magnum/Implementation/DebugState.h" + +namespace Magnum { + +namespace { + +#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) +void +#ifdef CORRADE_TARGET_WINDOWS +APIENTRY +#endif +callbackWrapper(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) { + Context::current()->state().debug->messageCallback(DebugOutput::Source(source), DebugOutput::Type(type), id, DebugOutput::Severity(severity), std::string{message, std::size_t(length)}, userParam); +} +#endif + +void defaultCallback(const DebugOutput::Source source, const DebugOutput::Type type, const UnsignedInt id, const DebugOutput::Severity severity, const std::string& string, const void*) { + Debug output; + output << "Debug output:"; + + switch(severity) { + case DebugOutput::Severity::High: + output << "high severity"; break; + + case DebugOutput::Severity::Medium: + output << "medium severity"; break; + + case DebugOutput::Severity::Low: + output << "low severity"; break; + + case DebugOutput::Severity::Notification: ; + } + + switch(source) { + case DebugOutput::Source::Api: + output << "API"; break; + case DebugOutput::Source::WindowSystem: + output << "window system"; break; + case DebugOutput::Source::ShaderCompiler: + output << "shader compiler"; break; + case DebugOutput::Source::ThirdParty: + output << "third party"; break; + case DebugOutput::Source::Application: + output << "application"; break; + + case DebugOutput::Source::Other: ; + } + + switch(type) { + case DebugOutput::Type::Error: + output << "error"; break; + case DebugOutput::Type::DeprecatedBehavior: + output << "deprecated behavior note"; break; + case DebugOutput::Type::UndefinedBehavior: + output << "undefined behavior note"; break; + case DebugOutput::Type::Portability: + output << "portability note"; break; + case DebugOutput::Type::Performance: + output << "performance note"; break; + case DebugOutput::Type::Marker: + output << "marker"; break; + case DebugOutput::Type::PushGroup: + output << "debug group enter"; break; + case DebugOutput::Type::PopGroup: + output << "debug group leave"; break; + + case DebugOutput::Type::Other: ; + } + + output << '(' + std::to_string(id) + "):" << string; +} + +} + +Int DebugOutput::maxLoggedMessages() { + if(!Context::current()->isExtensionSupported()) + return 0; + + GLint& value = Context::current()->state().debug->maxLoggedMessages; + + if(value == 0) { + #ifndef MAGNUM_TARGET_GLES + glGetIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES, &value); + #else + glGetIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES_KHR, &value); + #endif + } + + return value; +} + +Int DebugOutput::maxMessageLength() { + if(!Context::current()->isExtensionSupported()) + return 0; + + GLint& value = Context::current()->state().debug->maxMessageLength; + + if(value == 0) { + #ifndef MAGNUM_TARGET_GLES + glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &value); + #else + glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH_KHR, &value); + #endif + } + + return value; +} + +void DebugOutput::setCallback(const Callback callback, const void* userParam) { + Context::current()->state().debug->callbackImplementation(callback, userParam); +} + +void DebugOutput::setDefaultCallback() { + setCallback(defaultCallback, nullptr); +} + +void DebugOutput::setEnabledInternal(const GLenum source, const GLenum type, const GLenum severity, const std::initializer_list ids, const bool enabled) { + Context::current()->state().debug->controlImplementation(source, type, severity, ids, enabled); +} + +void DebugOutput::controlImplementationNoOp(GLenum, GLenum, GLenum, std::initializer_list, bool) {} + +void DebugOutput::controlImplementationKhr(const GLenum source, const GLenum type, const GLenum severity, const std::initializer_list ids, const bool enabled) { + #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + #ifndef MAGNUM_TARGET_GLES + glDebugMessageControl + #else + glDebugMessageControlKHR + #endif + (source, type, severity, ids.size(), ids.begin(), enabled); + #else + static_cast(source); + static_cast(type); + static_cast(severity); + static_cast(ids); + static_cast(enabled); + CORRADE_ASSERT_UNREACHABLE(); + #endif +} + +void DebugOutput::callbackImplementationNoOp(Callback, const void*) {} + +void DebugOutput::callbackImplementationKhr(const Callback callback, const void* userParam) { + /* Replace the callback */ + const Callback original = Context::current()->state().debug->messageCallback; + Context::current()->state().debug->messageCallback = callback; + + /* Adding callback */ + if(!original && callback) { + #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + #ifndef MAGNUM_TARGET_GLES + glDebugMessageCallback + #else + glDebugMessageCallbackKHR + #endif + (callbackWrapper, userParam); + #else + static_cast(userParam); + CORRADE_ASSERT_UNREACHABLE(); + #endif + + /* Deleting callback */ + } else if(original && !callback) { + #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + #ifndef MAGNUM_TARGET_GLES + glDebugMessageCallback + #else + glDebugMessageCallbackKHR + #endif + (nullptr, nullptr); + #else + CORRADE_ASSERT_UNREACHABLE(); + #endif + } +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +Debug operator<<(Debug debug, const DebugOutput::Source value) { + switch(value) { + #define _c(value) case DebugOutput::Source::value: return debug << "DebugOutput::Source::" #value; + _c(Api) + _c(WindowSystem) + _c(ShaderCompiler) + _c(ThirdParty) + _c(Application) + _c(Other) + #undef _c + } + + return debug << "DebugOutput::Source::(invalid)"; +} + +Debug operator<<(Debug debug, const DebugOutput::Type value) { + switch(value) { + #define _c(value) case DebugOutput::Type::value: return debug << "DebugOutput::Type::" #value; + _c(Error) + _c(DeprecatedBehavior) + _c(UndefinedBehavior) + _c(Portability) + _c(Performance) + _c(Marker) + _c(PushGroup) + _c(PopGroup) + _c(Other) + #undef _c + } + + return debug << "DebugOutput::Type::(invalid)"; +} + +Debug operator<<(Debug debug, const DebugOutput::Severity value) { + switch(value) { + #define _c(value) case DebugOutput::Severity::value: return debug << "DebugOutput::Severity::" #value; + _c(High) + _c(Medium) + _c(Low) + _c(Notification) + #undef _c + } + + return debug << "DebugOutput::Severity::(invalid)"; +} +#endif + +void DebugMessage::insertInternal(const Source source, const Type type, const UnsignedInt id, const DebugOutput::Severity severity, const Containers::ArrayReference string) { + Context::current()->state().debug->messageInsertImplementation(source, type, id, severity, string); +} + +void DebugMessage::insertImplementationNoOp(Source, Type, UnsignedInt, DebugOutput::Severity, const Containers::ArrayReference) {} + +void DebugMessage::insertImplementationKhr(const Source source, const Type type, const UnsignedInt id, const DebugOutput::Severity severity, const Containers::ArrayReference string) { + #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + #ifndef MAGNUM_TARGET_GLES + glDebugMessageInsert + #else + glDebugMessageInsertKHR + #endif + (GLenum(source), GLenum(type), id, GLenum(severity), string.size(), string.data()); + #else + static_cast(source); + static_cast(type); + static_cast(id); + static_cast(severity); + static_cast(string); + CORRADE_ASSERT_UNREACHABLE(); + #endif +} + +void DebugMessage::insertImplementationExt(Source, Type, UnsignedInt, DebugOutput::Severity, const Containers::ArrayReference string) { + #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + glInsertEventMarkerEXT(string.size(), string.data()); + #else + static_cast(string); + CORRADE_ASSERT_UNREACHABLE(); + #endif +} + +#ifndef MAGNUM_TARGET_GLES +void DebugMessage::insertImplementationGremedy(Source, Type, UnsignedInt, DebugOutput::Severity, const Containers::ArrayReference string) { + glStringMarkerGREMEDY(string.size(), string.data()); +} +#endif + +#ifndef DOXYGEN_GENERATING_OUTPUT +Debug operator<<(Debug debug, const DebugMessage::Source value) { + switch(value) { + #define _c(value) case DebugMessage::Source::value: return debug << "DebugMessage::Source::" #value; + _c(ThirdParty) + _c(Application) + #undef _c + #ifdef MAGNUM_BUILD_DEPRECATED + case DebugMessage::Source::Api: + case DebugMessage::Source::WindowSystem: + case DebugMessage::Source::ShaderCompiler: + case DebugMessage::Source::Other: + return debug << DebugOutput::Source(value); + #endif + } + + return debug << "DebugMessage::Source::(invalid)"; +} + +Debug operator<<(Debug debug, const DebugMessage::Type value) { + switch(value) { + #define _c(value) case DebugMessage::Type::value: return debug << "DebugMessage::Type::" #value; + _c(Error) + _c(DeprecatedBehavior) + _c(UndefinedBehavior) + _c(Portability) + _c(Performance) + _c(Other) + _c(Marker) + #undef _c + } + + return debug << "DebugMessage::Type::(invalid)"; +} +#endif + +Int DebugGroup::maxStackDepth() { + if(!Context::current()->isExtensionSupported()) + return 0; + + GLint& value = Context::current()->state().debug->maxStackDepth; + + if(value == 0) { + #ifndef MAGNUM_TARGET_GLES + glGetIntegerv(GL_MAX_DEBUG_GROUP_STACK_DEPTH, &value); + #else + glGetIntegerv(GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR, &value); + #endif + } + + return value; +} + +void DebugGroup::pushInternal(const Source source, const UnsignedInt id, const Containers::ArrayReference message) { + CORRADE_ASSERT(!_active, "DebugGroup::push(): group is already active", ); + Context::current()->state().debug->pushGroupImplementation(source, id, message); + _active = true; +} + +void DebugGroup::pop() { + CORRADE_ASSERT(_active, "DebugGroup::pop(): group is not active", ); + Context::current()->state().debug->popGroupImplementation(); + _active = false; +} + +void DebugGroup::pushImplementationNoOp(Source, UnsignedInt, Containers::ArrayReference) {} + +void DebugGroup::pushImplementationKhr(const Source source, const UnsignedInt id, const Containers::ArrayReference message) { + #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + #ifndef MAGNUM_TARGET_GLES + glPushDebugGroup + #else + glPushDebugGroupKHR + #endif + (GLenum(source), id, message.size(), message.data()); + #else + static_cast(source); + static_cast(id); + static_cast(message); + CORRADE_ASSERT_UNREACHABLE(); + #endif +} + +void DebugGroup::pushImplementationExt(Source, UnsignedInt, const Containers::ArrayReference message) { + #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + glPushGroupMarkerEXT(message.size(), message.data()); + #else + static_cast(message); + CORRADE_ASSERT_UNREACHABLE(); + #endif +} + +void DebugGroup::popImplementationNoOp() {} + +void DebugGroup::popImplementationKhr() { + #ifndef MAGNUM_TARGET_GLES + glPopDebugGroup(); + #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + glPopDebugGroupKHR(); + #else + CORRADE_ASSERT_UNREACHABLE(); + #endif +} + +void DebugGroup::popImplementationExt() { + #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) + glPopGroupMarkerEXT(); + #else + CORRADE_ASSERT_UNREACHABLE(); + #endif +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +Debug operator<<(Debug debug, const DebugGroup::Source value) { + switch(value) { + #define _c(value) case DebugGroup::Source::value: return debug << "DebugGroup::Source::" #value; + _c(ThirdParty) + _c(Application) + #undef _c + } + + return debug << "DebugGroup::Source::(invalid)"; +} +#endif + +} diff --git a/src/Magnum/DebugOutput.h b/src/Magnum/DebugOutput.h new file mode 100644 index 000000000..2b34c2f64 --- /dev/null +++ b/src/Magnum/DebugOutput.h @@ -0,0 +1,892 @@ +#ifndef Magnum_DebugOutput_h +#define Magnum_DebugOutput_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::DebugOutput, @ref Magnum::DebugMessage, @ref Magnum::DebugGroup + */ + +#include +#include + +#include "Magnum/Magnum.h" +#include "Magnum/OpenGL.h" +#include "Magnum/visibility.h" + +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif + +namespace Magnum { + +namespace Implementation { struct DebugState; } + +/** +@brief Debug output + +Manages OpenGL debug output. The debug messages are emitted either from driver +(such as GL error descriptions and various performance and optimization hints) +or from third party software and the application itself using @ref DebugMessage +and @ref DebugGroup, which can be also used to mark various portions of command +stream in various graphics debuggers, such as Apitrace or gDEBugger. + +## Basic usage + +Support for debug output is provided by OpenGL 4.3 or @extension{KHR,debug} +(desktop/ES extension). Subset of the functionality is provided also by +@extension2{EXT,debug_marker} (desktop/ES extensions) or +@extension{GREMEDY,string_marker} (desktop only extension). + +With OpenGL 4.3 or @extension{KHR,debug} desktop/ES extension, the debug output +needs to be enabled first. It can be enabled globally using +@ref Platform::Sdl2Application::Configuration::Flag::Debug "Platform::*Application::Configuration::Flag::Debug" +when creating context or only for some portions of the code using +@ref Renderer::Feature::DebugOutput. If enabled globally, some OpenGL drivers +may provide additional debugging information. In addition to that you can +control the output at even finer granularity using @ref setEnabled(). + +You can gather the messages either through graphics debugger or in the +application itself by setting up message callback using @ref setCallback() or +@ref setDefaultCallback(). You might also want to enable +@ref Renderer::Feature::DebugOutputSynchronous. Example usage, completely with +@ref DebugGroup and @link DebugMessage @endlink: + +@code +Renderer::enable(Renderer::Feature::DebugOutput); +Renderer::enable(Renderer::Feature::DebugOutputSynchronous); +DebugOutput::setDefaultCallback(); + +// Disable rather spammy "Buffer detailed info" debug messages on NVidia drivers +DebugOutput::setEnabled(DebugOutput::Source::Api, DebugOutput::Type::Other, {131185}, false); + +{ + DebugGroup group{DebugGroup::Source::Application, 42, "Scene rendering"}; + + DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, + 1337, DebugOutput::Severity::Notification, "Rendering transparent mesh"); + + Renderer::enable(Renderer::Feature::Blending); + mesh.draw(shader); + Renderer::disable(Renderer::Feature::Blending); + + // ... +} +@endcode + +With default callback the group entering/leaving and the inserted message (and +possibly also other messages) will be printed on standard output: + +> Debug output: application debug group enter (42): Scene rendering\n +> Debug output: application marker (1337): Rendering transparent mesh\n +> ...\n +> Debug output: application debug group leave (42): Scene rendering + +If only @extension2{EXT,debug_marker} or @extension{GREMEDY,string_marker} are +supported, only user-inserted messages and debug groups are supported and they +can be seen only through graphics debugger. + +If OpenGL 4.3 is not supported and neither @extension{KHR,debug} nor +@extension2{EXT,debug_marker} nor @extension{GREMEDY,string_marker} are +available, all the functions are essentially a no-op. + +Besides inserting messages into GL command stream you can also annotate OpenGL +objects with labels. See @ref AbstractQuery::setLabel(), +@ref AbstractShaderProgram::setLabel(), @ref AbstractTexture::setLabel(), +@ref Buffer::setLabel(), @ref Framebuffer::setLabel(), @ref Mesh::setLabel(), +@ref Renderbuffer::setLabel(), @ref Shader::setLabel() and +@ref TransformFeedback::setLabel() for more information. +*/ +class MAGNUM_EXPORT DebugOutput { + friend Implementation::DebugState; + + public: + /** + * @brief Message source + * + * @see @ref setEnabled() + */ + enum class Source: GLenum { + /** OpenGL */ + #ifndef MAGNUM_TARGET_GLES + Api = GL_DEBUG_SOURCE_API, + #else + Api = GL_DEBUG_SOURCE_API_KHR, + #endif + + /** Window system (GLX, WGL) */ + #ifndef MAGNUM_TARGET_GLES + WindowSystem = GL_DEBUG_SOURCE_WINDOW_SYSTEM, + #else + WindowSystem = GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR, + #endif + + /** Shader compiler */ + #ifndef MAGNUM_TARGET_GLES + ShaderCompiler = GL_DEBUG_SOURCE_SHADER_COMPILER, + #else + ShaderCompiler = GL_DEBUG_SOURCE_SHADER_COMPILER_KHR, + #endif + + /** External debugger or third-party middleware */ + #ifndef MAGNUM_TARGET_GLES + ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY, + #else + ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY_KHR, + #endif + + /** The application */ + #ifndef MAGNUM_TARGET_GLES + Application = GL_DEBUG_SOURCE_APPLICATION, + #else + Application = GL_DEBUG_SOURCE_APPLICATION_KHR, + #endif + + /** Any other source */ + #ifndef MAGNUM_TARGET_GLES + Other = GL_DEBUG_SOURCE_OTHER + #else + Other = GL_DEBUG_SOURCE_OTHER_KHR + #endif + }; + + /** + * @brief Message type + * + * @see @ref setEnabled() + */ + enum class Type: GLenum { + /** OpenGL error */ + #ifndef MAGNUM_TARGET_GLES + Error = GL_DEBUG_TYPE_ERROR, + #else + Error = GL_DEBUG_TYPE_ERROR_KHR, + #endif + + /** Behavior that has been marked for deprecation */ + #ifndef MAGNUM_TARGET_GLES + DeprecatedBehavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, + #else + DeprecatedBehavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR, + #endif + + /** Behavior that is undefined according to the specification */ + #ifndef MAGNUM_TARGET_GLES + UndefinedBehavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, + #else + UndefinedBehavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR, + #endif + + /** Non-portable usage of extensions or shaders */ + #ifndef MAGNUM_TARGET_GLES + Portability = GL_DEBUG_TYPE_PORTABILITY, + #else + Portability = GL_DEBUG_TYPE_PORTABILITY_KHR, + #endif + + /** Implementation-dependent performance warning */ + #ifndef MAGNUM_TARGET_GLES + Performance = GL_DEBUG_TYPE_PERFORMANCE, + #else + Performance = GL_DEBUG_TYPE_PERFORMANCE_KHR, + #endif + + /** Annotation of the command stream */ + #ifndef MAGNUM_TARGET_GLES + Marker = GL_DEBUG_TYPE_MARKER, + #else + Marker = GL_DEBUG_TYPE_MARKER_KHR, + #endif + + /** Entering a debug group */ + #ifndef MAGNUM_TARGET_GLES + PushGroup = GL_DEBUG_TYPE_PUSH_GROUP, + #else + PushGroup = GL_DEBUG_TYPE_PUSH_GROUP_KHR, + #endif + + /** Leaving a debug group */ + #ifndef MAGNUM_TARGET_GLES + PopGroup = GL_DEBUG_TYPE_POP_GROUP, + #else + PopGroup = GL_DEBUG_TYPE_POP_GROUP_KHR, + #endif + + /** Any other type */ + #ifndef MAGNUM_TARGET_GLES + Other = GL_DEBUG_TYPE_OTHER, + #else + Other = GL_DEBUG_TYPE_OTHER_KHR, + #endif + }; + + /** + * @brief Message severity + * + * @see @ref setEnabled() + */ + enum class Severity: GLenum { + /** + * Any OpenGL error, dangerous undefined behavior, shader + * compilation errors. + */ + #ifndef MAGNUM_TARGET_GLES + High = GL_DEBUG_SEVERITY_HIGH, + #else + High = GL_DEBUG_SEVERITY_HIGH_KHR, + #endif + + /** + * Severe performance warnings, shader compilation warnings, use of + * deprecated behavior. + */ + #ifndef MAGNUM_TARGET_GLES + Medium = GL_DEBUG_SEVERITY_MEDIUM, + #else + Medium = GL_DEBUG_SEVERITY_MEDIUM_KHR, + #endif + + /** Minor performance warnings, trivial undefined behavior. */ + #ifndef MAGNUM_TARGET_GLES + Low = GL_DEBUG_SEVERITY_LOW, + #else + Low = GL_DEBUG_SEVERITY_LOW_KHR, + #endif + + /** Any message other than error or performance warning. */ + #ifndef MAGNUM_TARGET_GLES + Notification = GL_DEBUG_SEVERITY_NOTIFICATION + #else + Notification = GL_DEBUG_SEVERITY_NOTIFICATION_KHR + #endif + }; + + /** + * @brief Debug callback + * + * @see @ref setCallback() + */ + typedef void(*Callback)(Source, Type, UnsignedInt, Severity, const std::string&, const void*); + + /** + * @brief Max count of debug messages in log + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If OpenGL 4.3 is not supported and @extension{KHR,debug} + * desktop or ES extension is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_DEBUG_LOGGED_MESSAGES} + */ + static Int maxLoggedMessages(); + + /** + * @brief Max debug message length + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If OpenGL 4.3 is not supported and @extension{KHR,debug} + * desktop or ES extension is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_DEBUG_MESSAGE_LENGTH} + */ + static Int maxMessageLength(); + + /** + * @brief Enable or disable particular output type + * + * @attention If any @ref DebugGroup is active when making this call, + * the setting will be remembered only for the time in which the + * group is active and leaving it will revert the setting to state + * set in parent debug group. See @ref DebugGroup documentation + * for more information. + * + * If OpenGL 4.3 is not supported and @extension{KHR,debug} desktop or + * ES extension is not available, this function does nothing. + * @see @ref Renderer::Feature::DebugOutput, @fn_gl{DebugMessageControl} + */ + static void setEnabled(Source source, Type type, std::initializer_list ids, bool enabled) { + setEnabledInternal(GLenum(source), GLenum(type), GL_DONT_CARE, ids, enabled); + } + + /** @overload */ + static void setEnabled(Source source, Type type, Severity severity, bool enabled) { + setEnabledInternal(GLenum(source), GLenum(type), GLenum(severity), {}, enabled); + } + + /** @overload */ + static void setEnabled(Source source, Type type, bool enabled) { + setEnabledInternal(GLenum(source), GLenum(type), GL_DONT_CARE, {}, enabled); + } + + /** @overload */ + static void setEnabled(Source source, Severity severity, bool enabled) { + setEnabledInternal(GLenum(source), GL_DONT_CARE, GLenum(severity), {}, enabled); + } + + /** @overload */ + static void setEnabled(Source source, bool enabled) { + setEnabledInternal(GLenum(source), GL_DONT_CARE, GL_DONT_CARE, {}, enabled); + } + + /** @overload */ + static void setEnabled(Type type, Severity severity, bool enabled) { + setEnabledInternal(GL_DONT_CARE, GLenum(type), GLenum(severity), {}, enabled); + } + + /** @overload */ + static void setEnabled(Type type, bool enabled) { + setEnabledInternal(GL_DONT_CARE, GLenum(type), GL_DONT_CARE, {}, enabled); + } + + /** @overload */ + static void setEnabled(Severity severity, bool enabled) { + setEnabledInternal(GL_DONT_CARE, GL_DONT_CARE, GLenum(severity), {}, enabled); + } + + /** @overload */ + static void setEnabled(bool enabled) { + setEnabledInternal(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, {}, enabled); + } + + /** + * @brief Set debug message callback + * + * The messages are sent to the callback only if + * @ref Renderer::Feature::DebugOutput is enabled. If OpenGL 4.3 is not + * supported and @extension{KHR,debug} desktop or ES extension is not + * available, this function does nothing. + * @see @ref setDefaultCallback(), + * @ref Renderer::Feature::DebugOutputSynchronous, + * @fn_gl{DebugMessageCallback} + */ + static void setCallback(Callback callback, const void* userParam = nullptr); + + /** + * @brief Set default debug message callback + * + * See @ref setCallback() for more information. The message is printed + * to @ref Corrade::Utility::Debug "Debug" output in the following + * format: + * @code + * DebugMessage::insert(DebugMessage::Source::Application, + * DebugMessage::Type::Marker, 1337, DebugOutput::Severity::Notification, "Hello from OpenGL command stream!"); + * @endcode + * + * > Debug output: application marker (1337): Hello from OpenGL command stream! + */ + static void setDefaultCallback(); + + /** @brief There's no point in having an instance of this class */ + DebugOutput() = delete; + + private: + static void setEnabledInternal(GLenum source, GLenum type, GLenum severity, std::initializer_list ids, bool enabled); + static MAGNUM_LOCAL void controlImplementationNoOp(GLenum, GLenum, GLenum, std::initializer_list, bool); + static MAGNUM_LOCAL void controlImplementationKhr(GLenum source, GLenum type, GLenum severity, std::initializer_list ids, bool enabled); + + static MAGNUM_LOCAL void callbackImplementationNoOp(Callback, const void*); + static MAGNUM_LOCAL void callbackImplementationKhr(Callback callback, const void* userParam); +}; + +/** @debugoperatorclassenum{Magnum::DebugOutput,Magnum::DebugOutput::Source} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, DebugOutput::Source value); + +/** @debugoperatorclassenum{Magnum::DebugOutput,Magnum::DebugOutput::Type} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, DebugOutput::Type value); + +/** @debugoperatorclassenum{Magnum::DebugOutput,Magnum::DebugOutput::Severity} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, DebugOutput::Severity value); + +/** +@brief Debug message + +Allows inserting messages GL command stream with labels, useful for example +with conjunction with various graphics debuggers, such as Apitrace or +gDEBugger. + +## Basic usage + +See @ref DebugOutput for introduction. + +If OpenGL 4.3 is supported or @extension{KHR,debug} desktop or ES extension is +available and default debug output callback is enabled for given kind of +messages, the inserted message will be printed on standard output in the +following form: + +@code +DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, + 1337, DebugOutput::Severity::Notification, "Hello from OpenGL command stream!"); +@endcode + +> Debug output: application marker (1337): Hello from OpenGL command stream! + +If only @extension2{EXT,debug_marker} or @extension{GREMEDY,string_marker} are +available, the message can be seen only through graphics debugger. + +If OpenGL 4.3 is not supported and neither @extension{KHR,debug} nor +@extension2{EXT,debug_marker} nor @extension{GREMEDY,string_marker} are +available, the function is essentially a no-op. + +## Performance notes + +If you ensure that you always use the `const char` overload of @ref insert() +and the debug output is either not supported or turned off, the calls will not +result in any allocations and thus won't have any negative performance effects. + +@see @ref DebugGroup +*/ +class MAGNUM_EXPORT DebugMessage { + friend Implementation::DebugState; + + public: + /** + * @brief Message source + * + * @see @ref insert() + */ + enum class Source: GLenum { + #ifdef MAGNUM_BUILD_DEPRECATED + /** @copydoc DebugOutput::Source::Api + * @deprecated Use @ref DebugOutput::Source::Api instead. + */ + Api = GLenum(DebugOutput::Source::Api), + + /** @copydoc DebugOutput::Source::WindowSystem + * @deprecated Use @ref DebugOutput::Source::WindowSystem instead. + */ + WindowSystem = GLenum(DebugOutput::Source::WindowSystem), + + /** @copydoc DebugOutput::Source::ShaderCompiler + * @deprecated Use @ref DebugOutput::Source::ShaderCompiler instead. + */ + ShaderCompiler = GLenum(DebugOutput::Source::ShaderCompiler), + #endif + + /** External debugger or third-party middleware */ + #ifndef MAGNUM_TARGET_GLES + ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY, + #else + ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY_KHR, + #endif + + /** The application */ + #ifndef MAGNUM_TARGET_GLES + Application = GL_DEBUG_SOURCE_APPLICATION, + #else + Application = GL_DEBUG_SOURCE_APPLICATION_KHR, + #endif + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @copydoc DebugOutput::Source::Other + * @deprecated Use @ref DebugOutput::Source::Other instead. + */ + Other = GLenum(DebugOutput::Source::Other) + #endif + }; + + /** + * @brief Message type + * + * @see @ref insert() + */ + enum class Type: GLenum { + /** OpenGL error */ + #ifndef MAGNUM_TARGET_GLES + Error = GL_DEBUG_TYPE_ERROR, + #else + Error = GL_DEBUG_TYPE_ERROR_KHR, + #endif + + /** Behavior that has been marked for deprecation */ + #ifndef MAGNUM_TARGET_GLES + DeprecatedBehavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, + #else + DeprecatedBehavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR, + #endif + + /** Behavior that is undefined according to the specification */ + #ifndef MAGNUM_TARGET_GLES + UndefinedBehavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, + #else + UndefinedBehavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR, + #endif + + /** Non-portable usage of extensions or shaders */ + #ifndef MAGNUM_TARGET_GLES + Portability = GL_DEBUG_TYPE_PORTABILITY, + #else + Portability = GL_DEBUG_TYPE_PORTABILITY_KHR, + #endif + + /** Implementation-dependent performance warning */ + #ifndef MAGNUM_TARGET_GLES + Performance = GL_DEBUG_TYPE_PERFORMANCE, + #else + Performance = GL_DEBUG_TYPE_PERFORMANCE_KHR, + #endif + + /** Annotation of the command stream */ + #ifndef MAGNUM_TARGET_GLES + Marker = GL_DEBUG_TYPE_MARKER, + #else + Marker = GL_DEBUG_TYPE_MARKER_KHR, + #endif + + /** Any other type */ + #ifndef MAGNUM_TARGET_GLES + Other = GL_DEBUG_TYPE_OTHER + #else + Other = GL_DEBUG_TYPE_OTHER_KHR + #endif + }; + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @copybrief DebugOutput::Severity + * @deprecated Use @ref DebugOutput::Severity instead. + */ + CORRADE_DEPRECATED("use DebugOutput::Severity instead") typedef DebugOutput::Severity Severity; + + /** @copybrief DebugOutput::Callback + * @deprecated Use @ref DebugOutput::Callback instead. + */ + /* Can't mark this as deprecated because compiler then complains when I use it as a parameter in setCallback() */ + typedef void(*Callback)(DebugMessage::Source, DebugMessage::Type, UnsignedInt, DebugOutput::Severity, const std::string&, const void*); + + /** @copybrief DebugOutput::maxLoggedMessages() + * @deprecated Use @ref DebugOutput::maxLoggedMessages() instead. + */ + CORRADE_DEPRECATED("use DebugOutput::maxLoggedMessages() instead") static Int maxLoggedMessages() { + return DebugOutput::maxLoggedMessages(); + } + + /** @copybrief DebugOutput::maxMessageLength() + * @deprecated Use @ref DebugOutput::maxMessageLength() instead. + */ + CORRADE_DEPRECATED("use DebugOutput::maxMessageLength() instead") static Int maxMessageLength() { + return DebugOutput::maxMessageLength(); + } + + /** @copybrief DebugOutput::setEnabled() + * @deprecated Use @ref DebugOutput::setEnabled() instead. + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + template static void setEnabled(T... args); + #else + CORRADE_DEPRECATED("use DebugOutput::setEnabled() instead") static void setEnabled(Source source, Type type, std::initializer_list ids, bool enabled) { + DebugOutput::setEnabled(DebugOutput::Source(source), DebugOutput::Type(type), ids, enabled); + } + CORRADE_DEPRECATED("use DebugOutput::setEnabled() instead") static void setEnabled(Source source, Type type, DebugOutput::Severity severity, bool enabled) { + DebugOutput::setEnabled(DebugOutput::Source(source), DebugOutput::Type(type), severity, enabled); + } + CORRADE_DEPRECATED("use DebugOutput::setEnabled() instead") static void setEnabled(Source source, Type type, bool enabled) { + DebugOutput::setEnabled(DebugOutput::Source(source), DebugOutput::Type(type), enabled); + } + CORRADE_DEPRECATED("use DebugOutput::setEnabled() instead") static void setEnabled(Source source, DebugOutput::Severity severity, bool enabled) { + DebugOutput::setEnabled(DebugOutput::Source(source), severity, enabled); + } + CORRADE_DEPRECATED("use DebugOutput::setEnabled() instead") static void setEnabled(Source source, bool enabled) { + DebugOutput::setEnabled(DebugOutput::Source(source), enabled); + } + CORRADE_DEPRECATED("use DebugOutput::setEnabled() instead") static void setEnabled(Type type, DebugOutput::Severity severity, bool enabled) { + DebugOutput::setEnabled(DebugOutput::Type(type), severity, enabled); + } + CORRADE_DEPRECATED("use DebugOutput::setEnabled() instead") static void setEnabled(Type type, bool enabled) { + DebugOutput::setEnabled(DebugOutput::Type(type), enabled); + } + CORRADE_DEPRECATED("use DebugOutput::setEnabled() instead") static void setEnabled(DebugOutput::Severity severity, bool enabled) { + DebugOutput::setEnabled(severity, enabled); + } + CORRADE_DEPRECATED("use DebugOutput::setEnabled() instead") static void setEnabled(bool enabled) { + DebugOutput::setEnabled(enabled); + } + #endif + + /** @copybrief DebugOutput::setCallback() + * @deprecated Use @ref DebugOutput::setCallback() instead. + */ + CORRADE_DEPRECATED("use DebugOutput::setCallback() instead") static void setCallback(Callback callback, const void* userParam = nullptr) { + DebugOutput::setCallback(reinterpret_cast(callback), userParam); + } + + /** @copybrief DebugOutput::setDefaultCallback() + * @deprecated Use @ref DebugOutput::setDefaultCallback() instead. + */ + CORRADE_DEPRECATED("use DebugOutput::setDefaultCallback() instead") static void setDefaultCallback() { + DebugOutput::setDefaultCallback(); + } + #endif + + /** + * @brief Insert message + * @param source Message source + * @param type Message type + * @param id Message-specific ID + * @param severity Message severity + * @param string The actual message + * + * If OpenGL 4.3 is not supported and neither @extension{KHR,debug} nor + * @extension2{EXT,debug_marker} (desktop or ES extensions) nor + * @extension{GREMEDY,string_marker} (desktop only extension) are + * available, this function does nothing. + * + * If @extension{KHR,debug} is not available and only @extension2{EXT,debug_marker} + * or @extension{GREMEDY,string_marker} are available, only @p string + * is used and all other parameters are ignored. + * @see @ref DebugOutput::maxMessageLength(), @fn_gl{DebugMessageInsert}, + * @fn_gl_extension2{InsertEventMarker,EXT,debug_marker} or + * @fn_gl_extension{StringMarker,GREMEDY,string_marker} + */ + static void insert(Source source, Type type, UnsignedInt id, DebugOutput::Severity severity, const std::string& string) { + insertInternal(source, type, id, severity, {string.data(), string.size()}); + } + + /** @overload */ + template static void insert(Source source, Type type, UnsignedInt id, DebugOutput::Severity severity, const char(&string)[size]) { + insertInternal(source, type, id, severity, {string, size - 1}); + } + + /** @brief There's no point in having an instance of this class */ + DebugMessage() = delete; + + private: + static void insertInternal(Source source, Type type, UnsignedInt id, DebugOutput::Severity severity, Containers::ArrayReference string); + static MAGNUM_LOCAL void insertImplementationNoOp(Source, Type, UnsignedInt, DebugOutput::Severity, Containers::ArrayReference); + static MAGNUM_LOCAL void insertImplementationKhr(Source source, Type type, UnsignedInt id, DebugOutput::Severity severity, Containers::ArrayReference string); + static MAGNUM_LOCAL void insertImplementationExt(Source, Type, UnsignedInt, DebugOutput::Severity, Containers::ArrayReference string); + #ifndef MAGNUM_TARGET_GLES + static MAGNUM_LOCAL void insertImplementationGremedy(Source, Type, UnsignedInt, DebugOutput::Severity, Containers::ArrayReference string); + #endif +}; + +/** @debugoperatorclassenum{Magnum::DebugMessage,Magnum::DebugMessage::Source} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Source value); + +/** @debugoperatorclassenum{Magnum::DebugMessage,Magnum::DebugMessage::Type} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Type value); + +/** +@brief Debug group + +Allows marking portions of GL command stream with labels, useful for example +with conjunction with various graphics debuggers, such as Apitrace or gDEBugger. + +## Basic usage + +See @ref DebugOutput for introduction. + +Easiest way is to push debug group by creating instance and pop it +automatically at the end of scope: +@code +{ + // Push debug group + DebugGroup group{DebugGroup::Source::Application, 42, "Scene rendering"}; + + Renderer::enable(Renderer::Feature::Blending); + mesh.draw(shader); + Renderer::disable(Renderer::Feature::Blending); + + // The debug group is popped automatically at the end of the scope +} +@endcode + +If, for some reason, you need to pop in different scope, you can call @ref push() +and @ref pop() manually: +@code +DebugGroup group; + +group.push(DebugGroup::Source::Application, 42, "Scene rendering"); + +Renderer::enable(Renderer::Feature::Blending); +mesh.draw(shader); +Renderer::disable(Renderer::Feature::Blending); + +group.pop(); +@endcode + +If OpenGL 4.3 is supported or @extension{KHR,debug} desktop or ES extension is +available and the default debug output callback is enabled for these kinds of +messages, the group entering and leaving will be printed on standard output in +the following form: + +> Debug output: application debug group enter (42): Scene rendering\n +> Debug output: application debug group leave (42): Scene rendering + +If only @extension2{EXT,debug_marker} is available, the group can be seen only +through graphics debugger. + +If OpenGL 4.3 is not supported and neither @extension{KHR,debug} nor +@extension2{EXT,debug_marker} are available, the functions are essentially a +no-op. + +@attention To avoid accidental debug group stack overflow/underflow, you cannot + call @ref push() again when the group is already pushed onto the stack, + similarly for @ref pop(). So if you want to have nested debug groups, you + need to create one instance for each level. + +## Interaction with debug output volume control + +Besides putting hierarchical messages in debug output, the group also affects +settings done by @ref DebugOutput::setEnabled(). Entering debug group inherits +the settings from previously active debug group, call to +@ref DebugOutput::setEnabled() will be remembered only for +the time in which given group is active and leaving it will revert the setting +to state set in parent debug group. No state is preserved, thus calling +@ref push() after previous @ref pop() will not restore settings done when the +group was active previously. + +## Performance notes + +If you ensure that you always use the `const char` overload of @ref push() +and the debug output is either not supported or turned off, the calls will not +result in any allocations and thus won't have any negative performance effects. + +@see @ref DebugMessage +*/ +class MAGNUM_EXPORT DebugGroup { + friend Implementation::DebugState; + + public: + /** + * @brief Message source + * + * @see @ref DebugGroup(), @ref push() + */ + enum class Source: GLenum { + /** External debugger or third-party middleware */ + #ifndef MAGNUM_TARGET_GLES + ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY, + #else + ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY_KHR, + #endif + + /** The application */ + #ifndef MAGNUM_TARGET_GLES + Application = GL_DEBUG_SOURCE_APPLICATION + #else + Application = GL_DEBUG_SOURCE_APPLICATION_KHR + #endif + }; + + /** + * @brief Max debug group stack depth + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If OpenGL 4.3 is not supported and @extension{KHR,debug} + * desktop or ES extension is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_DEBUG_GROUP_STACK_DEPTH} + */ + static Int maxStackDepth(); + + /** + * @brief Default constructor + * + * Doesn't do anything. Call @ref push() to enter debug group. + */ + explicit DebugGroup(): _active{false} {} + + /** + * @brief Constructor + * + * Calls @ref push(). + * @see @link ~DebugGroup() @endlink, @ref pop() + */ + explicit DebugGroup(Source source, UnsignedInt id, const std::string& message): DebugGroup{} { + push(source, id, message); + } + + /** @overload */ + template explicit DebugGroup(Source source, UnsignedInt id, const char(&message)[size]): DebugGroup{} { + push(source, id, message); + } + + /** + * @brief Destructor + * + * If the group is active, calls @ref pop(). + */ + ~DebugGroup() { if(_active) pop(); } + + /** + * @brief Push debug group onto the stack + * + * Expects that the group isn't already pushed on the stack. The group + * entering message is put into debug output with + * @ref DebugOutput::Type::PushGroup and + * @ref DebugOutput::Severity::Notification. + * + * If OpenGL 4.3 is not supported and neither @extension{KHR,debug} nor + * @extension2{EXT,debug_marker} is available, this function does + * nothing. If @extension{KHR,debug} is not available and only + * @extension2{EXT,debug_marker} is available, only @p message is used + * and all other parameters are ignored. + * @see @ref pop(), @ref maxStackDepth(), @ref DebugOutput::maxMessageLength(), + * @ref Renderer::Error::StackOverflow, @fn_gl{PushDebugGroup} or + * @fn_gl_extension2{PushGroupMarker,EXT,debug_marker} + */ + void push(Source source, UnsignedInt id, const std::string& message) { + pushInternal(source, id, {message.data(), message.size()}); + } + + /** @overload */ + template void push(Source source, UnsignedInt id, const char(&message)[size]) { + pushInternal(source, id, {message, size - 1}); + } + + /** + * @brief Pop debug group from the stack + * + * Expects that the group is currently pushed on the stack. Leaving the + * group will also revert all @ref DebugOutput::setEnabled() settings + * done when the group was active. See class documentation for more + * information. The group leaving message is put into debug output with + * @ref DebugOutput::Type::PopGroup and + * @ref DebugOutput::Severity::Notification. + * + * If OpenGL 4.3 is not supported and neither @extension{KHR,debug} nor + * @extension2{EXT,debug_marker} is available, this function does + * nothing. + * @see @ref push(), @ref Renderer::Error::StackUnderflow, + * @fn_gl{PopDebugGroup} or + * @fn_gl_extension2{PopGroupMarker,EXT,debug_marker} + */ + void pop(); + + private: + void pushInternal(Source source, UnsignedInt id, Containers::ArrayReference message); + + static MAGNUM_LOCAL void pushImplementationNoOp(Source source, UnsignedInt id, Containers::ArrayReference message); + static MAGNUM_LOCAL void pushImplementationKhr(Source source, UnsignedInt id, Containers::ArrayReference message); + static MAGNUM_LOCAL void pushImplementationExt(Source source, UnsignedInt id, Containers::ArrayReference message); + + static MAGNUM_LOCAL void popImplementationNoOp(); + static MAGNUM_LOCAL void popImplementationKhr(); + static MAGNUM_LOCAL void popImplementationExt(); + + bool _active; +}; + +/** @debugoperatorclassenum{Magnum::DebugGroup,Magnum::DebugGroup::Source} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, DebugGroup::Source value); + +} + +#endif diff --git a/src/Magnum/DebugTools/CMakeLists.txt b/src/Magnum/DebugTools/CMakeLists.txt index d7dd783b3..794dc2473 100644 --- a/src/Magnum/DebugTools/CMakeLists.txt +++ b/src/Magnum/DebugTools/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -66,15 +66,16 @@ set(MagnumDebugTools_PRIVATE_HEADERS Implementation/PointRenderer.h Implementation/SphereRenderer.h) +# DebugTools library add_library(MagnumDebugTools ${SHARED_OR_STATIC} ${MagnumDebugTools_SRCS} ${MagnumDebugTools_HEADERS} ${MagnumDebugTools_PRIVATE_HEADERS}) set_target_properties(MagnumDebugTools PROPERTIES DEBUG_POSTFIX "-d") if(BUILD_STATIC_PIC) - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumDebugTools PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") + set_target_properties(MagnumDebugTools PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() + target_link_libraries(MagnumDebugTools Magnum MagnumMeshTools diff --git a/src/Magnum/DebugTools/DebugTools.h b/src/Magnum/DebugTools/DebugTools.h index a8ff1c809..02ac6daed 100644 --- a/src/Magnum/DebugTools/DebugTools.h +++ b/src/Magnum/DebugTools/DebugTools.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,6 +33,7 @@ namespace Magnum { namespace DebugTools { +#ifndef DOXYGEN_GENERATING_OUTPUT template class ForceRenderer; typedef ForceRenderer<2> ForceRenderer2D; typedef ForceRenderer<3> ForceRenderer3D; @@ -50,6 +51,7 @@ template class ShapeRenderer; typedef ShapeRenderer<2> ShapeRenderer2D; typedef ShapeRenderer<3> ShapeRenderer3D; class ShapeRendererOptions; +#endif }} diff --git a/src/Magnum/DebugTools/ForceRenderer.cpp b/src/Magnum/DebugTools/ForceRenderer.cpp index ba180f59b..f08eb9d02 100644 --- a/src/Magnum/DebugTools/ForceRenderer.cpp +++ b/src/Magnum/DebugTools/ForceRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/ForceRenderer.h b/src/Magnum/DebugTools/ForceRenderer.h index 8523a12ed..769e877ec 100644 --- a/src/Magnum/DebugTools/ForceRenderer.h +++ b/src/Magnum/DebugTools/ForceRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/AbstractBoxRenderer.cpp b/src/Magnum/DebugTools/Implementation/AbstractBoxRenderer.cpp index 998de880b..91dfc687c 100644 --- a/src/Magnum/DebugTools/Implementation/AbstractBoxRenderer.cpp +++ b/src/Magnum/DebugTools/Implementation/AbstractBoxRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/AbstractBoxRenderer.h b/src/Magnum/DebugTools/Implementation/AbstractBoxRenderer.h index 5ca8a856d..ca2bff5a0 100644 --- a/src/Magnum/DebugTools/Implementation/AbstractBoxRenderer.h +++ b/src/Magnum/DebugTools/Implementation/AbstractBoxRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp b/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp index ce3eb0316..e8243d155 100644 --- a/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp +++ b/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.h b/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.h index 361bc4461..719e6cf3b 100644 --- a/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.h +++ b/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp b/src/Magnum/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp index 33e014ca5..5ab1f2ba3 100644 --- a/src/Magnum/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp +++ b/src/Magnum/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/AxisAlignedBoxRenderer.h b/src/Magnum/DebugTools/Implementation/AxisAlignedBoxRenderer.h index 1fd1b9a1a..197085b86 100644 --- a/src/Magnum/DebugTools/Implementation/AxisAlignedBoxRenderer.h +++ b/src/Magnum/DebugTools/Implementation/AxisAlignedBoxRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/BoxRenderer.cpp b/src/Magnum/DebugTools/Implementation/BoxRenderer.cpp index e070188c9..ab3ee8330 100644 --- a/src/Magnum/DebugTools/Implementation/BoxRenderer.cpp +++ b/src/Magnum/DebugTools/Implementation/BoxRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/BoxRenderer.h b/src/Magnum/DebugTools/Implementation/BoxRenderer.h index 8d33f3a1f..052729d28 100644 --- a/src/Magnum/DebugTools/Implementation/BoxRenderer.h +++ b/src/Magnum/DebugTools/Implementation/BoxRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/CapsuleRenderer.cpp b/src/Magnum/DebugTools/Implementation/CapsuleRenderer.cpp index 5c359e593..494ed8b4a 100644 --- a/src/Magnum/DebugTools/Implementation/CapsuleRenderer.cpp +++ b/src/Magnum/DebugTools/Implementation/CapsuleRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/CapsuleRenderer.h b/src/Magnum/DebugTools/Implementation/CapsuleRenderer.h index 1be24d538..3f4c3c101 100644 --- a/src/Magnum/DebugTools/Implementation/CapsuleRenderer.h +++ b/src/Magnum/DebugTools/Implementation/CapsuleRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/CapsuleRendererTransformation.h b/src/Magnum/DebugTools/Implementation/CapsuleRendererTransformation.h index 6dbcb9d86..1caf10d3e 100644 --- a/src/Magnum/DebugTools/Implementation/CapsuleRendererTransformation.h +++ b/src/Magnum/DebugTools/Implementation/CapsuleRendererTransformation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -74,7 +74,7 @@ template<> std::array capsuleRendererTransformation<3>(const Vector3 Vector3 capDistance; if(length >= Math::TypeTraits::epsilon()) { const Vector3 directionNormalized = direction/length; - const Float dot = Vector3::dot(directionNormalized, Vector3::zAxis()); + const Float dot = Math::dot(directionNormalized, Vector3::zAxis()); /* Direction is parallel to Z axis, special rotation case */ if(Math::abs(dot) > 1.0f - Math::TypeTraits::epsilon()) { @@ -85,8 +85,8 @@ template<> std::array capsuleRendererTransformation<3>(const Vector3 /* Common case */ } else { rotation.up() = directionNormalized; - rotation.right() = Vector3::cross(rotation.up(), Vector3::zAxis()).normalized(); - rotation.backward() = Vector3::cross(rotation.right(), rotation.up()); + rotation.right() = Math::cross(rotation.up(), Vector3::zAxis()).normalized(); + rotation.backward() = Math::cross(rotation.right(), rotation.up()); CORRADE_INTERNAL_ASSERT(rotation.up().isNormalized() && rotation.backward().isNormalized()); } diff --git a/src/Magnum/DebugTools/Implementation/CylinderRenderer.cpp b/src/Magnum/DebugTools/Implementation/CylinderRenderer.cpp index 20f3e1798..677047146 100644 --- a/src/Magnum/DebugTools/Implementation/CylinderRenderer.cpp +++ b/src/Magnum/DebugTools/Implementation/CylinderRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/CylinderRenderer.h b/src/Magnum/DebugTools/Implementation/CylinderRenderer.h index 88f85eee2..240ffdefd 100644 --- a/src/Magnum/DebugTools/Implementation/CylinderRenderer.h +++ b/src/Magnum/DebugTools/Implementation/CylinderRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/CylinderRendererTransformation.h b/src/Magnum/DebugTools/Implementation/CylinderRendererTransformation.h index 2f21dc130..0fe621d54 100644 --- a/src/Magnum/DebugTools/Implementation/CylinderRendererTransformation.h +++ b/src/Magnum/DebugTools/Implementation/CylinderRendererTransformation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -63,7 +63,7 @@ template<> Matrix4 cylinderRendererTransformation<3>(const Vector3& a, const Vec Matrix4 rotation; if(length >= Math::TypeTraits::epsilon()) { const Vector3 directionNormalized = direction/length; - const Float dot = Vector3::dot(directionNormalized, Vector3::zAxis()); + const Float dot = Math::dot(directionNormalized, Vector3::zAxis()); /* Direction is parallel to Z axis, special rotation case */ if(Math::abs(dot) > 1.0f - Math::TypeTraits::epsilon()) { @@ -74,8 +74,8 @@ template<> Matrix4 cylinderRendererTransformation<3>(const Vector3& a, const Vec /* Common case */ } else { rotation.up() = directionNormalized; - rotation.right() = Vector3::cross(rotation.up(), Vector3::zAxis()).normalized(); - rotation.backward() = Vector3::cross(rotation.right(), rotation.up()); + rotation.right() = Math::cross(rotation.up(), Vector3::zAxis()).normalized(); + rotation.backward() = Math::cross(rotation.right(), rotation.up()); CORRADE_INTERNAL_ASSERT(rotation.up().isNormalized() && rotation.backward().isNormalized()); } } diff --git a/src/Magnum/DebugTools/Implementation/ForceRendererTransformation.h b/src/Magnum/DebugTools/Implementation/ForceRendererTransformation.h index bef0566be..0feb052fd 100644 --- a/src/Magnum/DebugTools/Implementation/ForceRendererTransformation.h +++ b/src/Magnum/DebugTools/Implementation/ForceRendererTransformation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -47,17 +47,17 @@ template<> Matrix4 forceRendererTransformation<3>(const Vector3& forcePosition, if(forceLength < Math::TypeTraits::epsilon()) return translation*Matrix4::scaling(Vector3(0.0f)); - const Float dot = Vector3::dot(force/forceLength, Vector3::xAxis()); + const Float dot = Math::dot(force/forceLength, Vector3::xAxis()); /* Force is parallel to X axis, just scaling */ if(Math::abs(dot) > 1.0f - Math::TypeTraits::epsilon()) return translation*Matrix4::scaling({Math::sign(dot)*forceLength, forceLength, forceLength}); /* Normal of plane going through force vector and X axis vector */ - const Vector3 normal = Vector3::cross(Vector3::xAxis(), force).normalized(); + const Vector3 normal = Math::cross(Vector3::xAxis(), force).normalized(); /* Third base vector, orthogonal to force and normal */ - const Vector3 binormal = Vector3::cross(normal, force/forceLength); + const Vector3 binormal = Math::cross(normal, force/forceLength); CORRADE_INTERNAL_ASSERT(binormal.isNormalized()); /* Transformation matrix from scaled base vectors and translation vector */ diff --git a/src/Magnum/DebugTools/Implementation/LineSegmentRenderer.cpp b/src/Magnum/DebugTools/Implementation/LineSegmentRenderer.cpp index 956bbae84..0e9fd7da7 100644 --- a/src/Magnum/DebugTools/Implementation/LineSegmentRenderer.cpp +++ b/src/Magnum/DebugTools/Implementation/LineSegmentRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/LineSegmentRenderer.h b/src/Magnum/DebugTools/Implementation/LineSegmentRenderer.h index 01ef6f09f..09dd9d482 100644 --- a/src/Magnum/DebugTools/Implementation/LineSegmentRenderer.h +++ b/src/Magnum/DebugTools/Implementation/LineSegmentRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/LineSegmentRendererTransformation.h b/src/Magnum/DebugTools/Implementation/LineSegmentRendererTransformation.h index e18403986..61ea7018b 100644 --- a/src/Magnum/DebugTools/Implementation/LineSegmentRendererTransformation.h +++ b/src/Magnum/DebugTools/Implementation/LineSegmentRendererTransformation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/PointRenderer.cpp b/src/Magnum/DebugTools/Implementation/PointRenderer.cpp index 29614f3da..7ecfc578a 100644 --- a/src/Magnum/DebugTools/Implementation/PointRenderer.cpp +++ b/src/Magnum/DebugTools/Implementation/PointRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/PointRenderer.h b/src/Magnum/DebugTools/Implementation/PointRenderer.h index fdde4278d..8d9bcfea1 100644 --- a/src/Magnum/DebugTools/Implementation/PointRenderer.h +++ b/src/Magnum/DebugTools/Implementation/PointRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/SphereRenderer.cpp b/src/Magnum/DebugTools/Implementation/SphereRenderer.cpp index dbdf66ab4..66e511892 100644 --- a/src/Magnum/DebugTools/Implementation/SphereRenderer.cpp +++ b/src/Magnum/DebugTools/Implementation/SphereRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Implementation/SphereRenderer.h b/src/Magnum/DebugTools/Implementation/SphereRenderer.h index e90455b12..a88a84a72 100644 --- a/src/Magnum/DebugTools/Implementation/SphereRenderer.h +++ b/src/Magnum/DebugTools/Implementation/SphereRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/ObjectRenderer.cpp b/src/Magnum/DebugTools/ObjectRenderer.cpp index 3ad94768a..e9eb72c6f 100644 --- a/src/Magnum/DebugTools/ObjectRenderer.cpp +++ b/src/Magnum/DebugTools/ObjectRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/ObjectRenderer.h b/src/Magnum/DebugTools/ObjectRenderer.h index 5d61a6677..40c00cfb0 100644 --- a/src/Magnum/DebugTools/ObjectRenderer.h +++ b/src/Magnum/DebugTools/ObjectRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Profiler.cpp b/src/Magnum/DebugTools/Profiler.cpp index 0431ab4e2..ae3334cce 100644 --- a/src/Magnum/DebugTools/Profiler.cpp +++ b/src/Magnum/DebugTools/Profiler.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Profiler.h b/src/Magnum/DebugTools/Profiler.h index 610d7f675..1693f71fc 100644 --- a/src/Magnum/DebugTools/Profiler.h +++ b/src/Magnum/DebugTools/Profiler.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -41,7 +41,7 @@ namespace Magnum { namespace DebugTools { /** -@brief %Profiler +@brief Profiler Measures time passed during specified sections of each frame. It's meant to be used in rendering and event loops (e.g. @ref Platform::Sdl2Application::drawEvent()), diff --git a/src/Magnum/DebugTools/ResourceManager.cpp b/src/Magnum/DebugTools/ResourceManager.cpp index 0103133e5..578634b6d 100644 --- a/src/Magnum/DebugTools/ResourceManager.cpp +++ b/src/Magnum/DebugTools/ResourceManager.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,24 +23,22 @@ DEALINGS IN THE SOFTWARE. */ -#define MAGNUM_RESOURCEMANAGER_DEFINE_INTERNALINSTANCE - #include "ResourceManager.h" +#include "Magnum/AbstractShaderProgram.h" #include "Magnum/Buffer.h" #include "Magnum/Mesh.h" #include "Magnum/MeshView.h" +#include "Magnum/ResourceManager.hpp" #include "Magnum/DebugTools/ForceRenderer.h" #include "Magnum/DebugTools/ObjectRenderer.h" #include "Magnum/DebugTools/ShapeRenderer.h" namespace Magnum { -template class -#if defined(CORRADE_TARGET_WINDOWS) && _MSC_VER -MAGNUM_DEBUGTOOLS_EXPORT -#endif -ResourceManager; +namespace Implementation { + template struct MAGNUM_DEBUGTOOLS_EXPORT ResourceManagerLocalInstanceImplementation; +} namespace DebugTools { diff --git a/src/Magnum/DebugTools/ResourceManager.h b/src/Magnum/DebugTools/ResourceManager.h index 5bf2d0f74..16369df5e 100644 --- a/src/Magnum/DebugTools/ResourceManager.h +++ b/src/Magnum/DebugTools/ResourceManager.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,9 +29,6 @@ * @brief Class @ref Magnum::DebugTools::ResourceManager */ -#ifndef MAGNUM_RESOURCEMANAGER_DEFINE_INTERNALINSTANCE -#define MAGNUM_RESOURCEMANAGER_DONT_DEFINE_INTERNALINSTANCE -#endif #include "Magnum/ResourceManager.h" #include "Magnum/Magnum.h" @@ -52,23 +49,15 @@ namespace Magnum { -/** @todo Do the listing in one place, not five thousand! */ - -#ifndef CORRADE_TARGET_WINDOWS -extern template ResourceManager MAGNUM_DEBUGTOOLS_EXPORT *& ResourceManager::internalInstance(); -#else -extern template class MAGNUM_DEBUGTOOLS_EXPORT ResourceManager; -#endif - namespace DebugTools { /** -@brief %Resource manager for debug tools +@brief Resource manager for debug tools Stores various data used by debug renderers. See @ref debug-tools for more information. */ -class MAGNUM_DEBUGTOOLS_EXPORT ResourceManager: public Magnum::ResourceManager { +class MAGNUM_DEBUGTOOLS_EXPORT ResourceManager: public Magnum::ResourceManager { public: explicit ResourceManager(); ~ResourceManager(); diff --git a/src/Magnum/DebugTools/ShapeRenderer.cpp b/src/Magnum/DebugTools/ShapeRenderer.cpp index 06c71aac7..7f8c1372f 100644 --- a/src/Magnum/DebugTools/ShapeRenderer.cpp +++ b/src/Magnum/DebugTools/ShapeRenderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/ShapeRenderer.h b/src/Magnum/DebugTools/ShapeRenderer.h index 7113415b8..a7f318c39 100644 --- a/src/Magnum/DebugTools/ShapeRenderer.h +++ b/src/Magnum/DebugTools/ShapeRenderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Test/CMakeLists.txt b/src/Magnum/DebugTools/Test/CMakeLists.txt index ec5156fb3..6df4e5ea8 100644 --- a/src/Magnum/DebugTools/Test/CMakeLists.txt +++ b/src/Magnum/DebugTools/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DebugTools/Test/CapsuleRendererTest.cpp b/src/Magnum/DebugTools/Test/CapsuleRendererTest.cpp index 0c6225ee7..776be03a4 100644 --- a/src/Magnum/DebugTools/Test/CapsuleRendererTest.cpp +++ b/src/Magnum/DebugTools/Test/CapsuleRendererTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,17 +29,16 @@ namespace Magnum { namespace DebugTools { namespace Test { -class CapsuleRendererTest: public TestSuite::Tester { - public: - explicit CapsuleRendererTest(); +struct CapsuleRendererTest: TestSuite::Tester { + explicit CapsuleRendererTest(); - void zeroLength2D(); - void common2D(); + void zeroLength2D(); + void common2D(); - void zeroLength3D(); - void parallel3D(); - void antiParallel3D(); - void common3D(); + void zeroLength3D(); + void parallel3D(); + void antiParallel3D(); + void common3D(); }; CapsuleRendererTest::CapsuleRendererTest() { @@ -83,7 +82,7 @@ void CapsuleRendererTest::common2D() { CORRADE_COMPARE(transformation[2].right(), right); /* Orthogonality */ - CORRADE_COMPARE(Vector2::dot(transformation[0].up(), transformation[0].right()), 0.0f); + CORRADE_COMPARE(Math::dot(transformation[0].up(), transformation[0].right()), 0.0f); const Vector2 capDistance = up.resized(3.5f); CORRADE_COMPARE(transformation[0].translation(), a+capDistance); @@ -163,9 +162,9 @@ void CapsuleRendererTest::common3D() { CORRADE_COMPARE(transformation[2].backward(), backward); /* Orthogonality */ - CORRADE_COMPARE(Vector3::dot(transformation[0].up(), transformation[0].right()), 0.0f); - CORRADE_COMPARE(Vector3::dot(transformation[0].up(), transformation[0].backward()), 0.0f); - CORRADE_COMPARE(Vector3::dot(transformation[0].right(), transformation[0].backward()), 0.0f); + CORRADE_COMPARE(Math::dot(transformation[0].up(), transformation[0].right()), 0.0f); + CORRADE_COMPARE(Math::dot(transformation[0].up(), transformation[0].backward()), 0.0f); + CORRADE_COMPARE(Math::dot(transformation[0].right(), transformation[0].backward()), 0.0f); const Vector3 capDistance = up.resized(3.5f); CORRADE_COMPARE(transformation[0].translation(), a+capDistance); diff --git a/src/Magnum/DebugTools/Test/CylinderRendererTest.cpp b/src/Magnum/DebugTools/Test/CylinderRendererTest.cpp index 3cbb7212c..a41c0b5f6 100644 --- a/src/Magnum/DebugTools/Test/CylinderRendererTest.cpp +++ b/src/Magnum/DebugTools/Test/CylinderRendererTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,17 +29,16 @@ namespace Magnum { namespace DebugTools { namespace Test { -class CylinderRendererTest: public TestSuite::Tester { - public: - explicit CylinderRendererTest(); +struct CylinderRendererTest: TestSuite::Tester { + explicit CylinderRendererTest(); - void zeroLength2D(); - void common2D(); + void zeroLength2D(); + void common2D(); - void zeroLength3D(); - void parallel3D(); - void antiParallel3D(); - void common3D(); + void zeroLength3D(); + void parallel3D(); + void antiParallel3D(); + void common3D(); }; CylinderRendererTest::CylinderRendererTest() { @@ -68,7 +67,7 @@ void CylinderRendererTest::common2D() { /* Rotation + scaling, test orthogonality */ CORRADE_COMPARE(transformation.up(), Vector2(3.5f, -2.0f)); CORRADE_COMPARE(transformation.right(), Vector2(4.0f, 7.0f).resized(3.5f)); - CORRADE_COMPARE(Vector2::dot(transformation.up(), transformation.right()), 0.0f); + CORRADE_COMPARE(Math::dot(transformation.up(), transformation.right()), 0.0f); CORRADE_COMPARE(transformation.translation(), 0.5f*(a + b)); } @@ -114,9 +113,9 @@ void CylinderRendererTest::common3D() { CORRADE_COMPARE(transformation.backward(), Vector3(9.625f, -5.5f, 16.25f).resized(3.5f)); /* Orthogonality */ - CORRADE_COMPARE(Vector3::dot(transformation.up(), transformation.right()), 0.0f); - CORRADE_COMPARE(Vector3::dot(transformation.up(), transformation.backward()), 0.0f); - CORRADE_COMPARE(Vector3::dot(transformation.right(), transformation.backward()), 0.0f); + CORRADE_COMPARE(Math::dot(transformation.up(), transformation.right()), 0.0f); + CORRADE_COMPARE(Math::dot(transformation.up(), transformation.backward()), 0.0f); + CORRADE_COMPARE(Math::dot(transformation.right(), transformation.backward()), 0.0f); CORRADE_COMPARE(transformation.translation(), 0.5f*(a + b)); } diff --git a/src/Magnum/DebugTools/Test/ForceRendererTest.cpp b/src/Magnum/DebugTools/Test/ForceRendererTest.cpp index 15ceb580f..5ea7acebc 100644 --- a/src/Magnum/DebugTools/Test/ForceRendererTest.cpp +++ b/src/Magnum/DebugTools/Test/ForceRendererTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,17 +29,16 @@ namespace Magnum { namespace DebugTools { namespace Implementation { namespace Test { -class ForceRendererTest: public TestSuite::Tester { - public: - explicit ForceRendererTest(); +struct ForceRendererTest: TestSuite::Tester { + explicit ForceRendererTest(); - void zero2D(); - void common2D(); + void zero2D(); + void common2D(); - void zero3D(); - void parallel3D(); - void antiParallel3D(); - void arbitrary3D(); + void zero3D(); + void parallel3D(); + void antiParallel3D(); + void arbitrary3D(); }; ForceRendererTest::ForceRendererTest() { @@ -69,7 +68,7 @@ void ForceRendererTest::common2D() { CORRADE_COMPARE(m.up().length(), force.length()); /* All vectors are orthogonal */ - CORRADE_COMPARE(Vector2::dot(m.right(), m.up()), 0.0f); + CORRADE_COMPARE(Math::dot(m.right(), m.up()), 0.0f); } void ForceRendererTest::zero3D() { @@ -100,10 +99,10 @@ void ForceRendererTest::arbitrary3D() { CORRADE_COMPARE(m.backward().length(), force.length()); /* All vectors are orthogonal */ - CORRADE_COMPARE(Vector3::dot(m.right(), m.up()), 0.0f); - CORRADE_COMPARE(Vector3::dot(m.right(), m.backward()), 0.0f); + CORRADE_COMPARE(Math::dot(m.right(), m.up()), 0.0f); + CORRADE_COMPARE(Math::dot(m.right(), m.backward()), 0.0f); /** @todo This shouldn't be too different */ - CORRADE_VERIFY(Math::abs(Vector3::dot(m.up(), m.backward())) < Math::TypeTraits::epsilon()); + CORRADE_VERIFY(Math::abs(Math::dot(m.up(), m.backward())) < Math::TypeTraits::epsilon()); } }}}} diff --git a/src/Magnum/DebugTools/Test/LineSegmentRendererTest.cpp b/src/Magnum/DebugTools/Test/LineSegmentRendererTest.cpp index 3d779af53..746afa7f7 100644 --- a/src/Magnum/DebugTools/Test/LineSegmentRendererTest.cpp +++ b/src/Magnum/DebugTools/Test/LineSegmentRendererTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,12 +33,11 @@ namespace Magnum { namespace DebugTools { namespace Test { -class LineSegmentRendererTest: public TestSuite::Tester { - public: - explicit LineSegmentRendererTest(); +struct LineSegmentRendererTest: TestSuite::Tester { + explicit LineSegmentRendererTest(); - void line2D(); - void line3D(); + void line2D(); + void line3D(); }; LineSegmentRendererTest::LineSegmentRendererTest() { diff --git a/src/Magnum/DebugTools/visibility.h b/src/Magnum/DebugTools/visibility.h index 7f5f080e0..8e3c6db69 100644 --- a/src/Magnum/DebugTools/visibility.h +++ b/src/Magnum/DebugTools/visibility.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/DefaultFramebuffer.cpp b/src/Magnum/DefaultFramebuffer.cpp index e4c86c319..db42064e4 100644 --- a/src/Magnum/DefaultFramebuffer.cpp +++ b/src/Magnum/DefaultFramebuffer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -95,12 +95,13 @@ void DefaultFramebuffer::invalidate(std::initializer_listviewport = Range2Di::fromSize({viewport[0], viewport[1]}, {viewport[2], viewport[3]}); + defaultFramebuffer._viewport = state.viewport = Range2Di::fromSize({viewport[0], viewport[1]}, {viewport[2], viewport[3]}); + CORRADE_INTERNAL_ASSERT(defaultFramebuffer._viewport != Implementation::FramebufferState::DisengagedViewport); /* Fake initial glViewport() call for ApiTrace */ #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/DefaultFramebuffer.h b/src/Magnum/DefaultFramebuffer.h index f15def894..36deb73c0 100644 --- a/src/Magnum/DefaultFramebuffer.h +++ b/src/Magnum/DefaultFramebuffer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,8 +38,7 @@ namespace Magnum { Default framebuffer, i.e. the actual screen surface. It is automatically created when @ref Context is created and it is available through global -variable @ref defaultFramebuffer. It is by default mapped to whole screen -surface. +variable @ref defaultFramebuffer. @anchor DefaultFramebuffer-usage ## Usage @@ -49,8 +48,8 @@ must ensure that it is properly resized when application surface is resized, i.e. you must pass the new size in your @ref Platform::Sdl2Application::viewportEvent() "viewportEvent()" implementation, for example: @code -void viewportEvent(const Vector2i& size) { - defaultFramebuffer.setViewport({}, size); +void viewportEvent(const Vector2i& size) override { + defaultFramebuffer.setViewport({{}, size}); // ... } @@ -60,34 +59,35 @@ Next thing you probably want is to clear all used buffers before performing any drawing in your @ref Platform::Sdl2Application::drawEvent() "drawEvent()" implementation, for example: @code -void drawEvent() { +void drawEvent() override { defaultFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); // ... } @endcode -See Framebuffer documentation for more involved usage, usage of non-default or -multiple framebuffers. +See documentation of particular functions and @ref Framebuffer documentation for +more involved usage, usage of non-default or multiple framebuffers. ## Performance optimizations See also @ref AbstractFramebuffer-performance-optimization "relevant section in AbstractFramebuffer". -If extension @extension{EXT,direct_state_access} is available, functions -@ref mapForDraw() and @ref mapForRead() use DSA to avoid unnecessary calls to -@fn_gl{BindFramebuffer}. See their respective documentation for more -information. +If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL +4.5) or @extension{EXT,direct_state_access} is available, functions +@ref checkStatus(), @ref mapForDraw(), @ref mapForRead() and @ref invalidate() +use DSA to avoid unnecessary calls to @fn_gl{BindFramebuffer}. See their +respective documentation for more information. */ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { - friend class Context; + friend Context; public: /** * @brief Status * * @see @ref checkStatus() - * @requires_gl30 %Extension @extension{ARB,framebuffer_object} + * @requires_gl30 Extension @extension{ARB,framebuffer_object} */ enum class Status: GLenum { /** The framebuffer is complete */ @@ -95,7 +95,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { /** * The default framebuffer does not exist. - * @requires_gles30 %Extension @es_extension{OES,surfaceless_context} + * @requires_gles30 Extension @es_extension{OES,surfaceless_context} * in OpenGL ES 2.0 */ #ifndef MAGNUM_TARGET_GLES2 @@ -173,7 +173,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * @brief Read attachment * * @see @ref mapForRead() - * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} + * @requires_gles30 Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} * in OpenGL ES 2.0 */ enum class ReadAttachment: GLenum { @@ -223,7 +223,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { /** * Read from front buffer. - * @requires_es_extension %Extension @es_extension2{NV,read_buffer_front,GL_NV_read_buffer} + * @requires_es_extension Extension @es_extension2{NV,read_buffer_front,GL_NV_read_buffer} */ Front = GL_FRONT @@ -244,8 +244,8 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * @brief Invalidation attachment * * @see @ref invalidate() - * @requires_gl43 %Extension @extension{ARB,invalidate_subdata} - * @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer} + * @requires_gl43 Extension @extension{ARB,invalidate_subdata} + * @requires_gles30 Extension @es_extension{EXT,discard_framebuffer} * in OpenGL ES 2.0 */ enum class InvalidationAttachment: GLenum { @@ -315,12 +315,17 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * @brief Check framebuffer status * @param target Target for which to check the status * - * If @extension{EXT,direct_state_access} is not available and the - * framebuffer is not currently bound, it is bound before the - * operation. - * @see @fn_gl{BindFramebuffer}, @fn_gl{CheckFramebufferStatus} or - * @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access} - * @requires_gl30 %Extension @extension{ARB,framebuffer_object} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * + * On OpenGL ES 2.0, if none of @es_extension{APPLE,framebuffer_multisample}, + * @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit} + * is available, the @p target parameter is ignored. + * @see @fn_gl2{CheckNamedFramebufferStatus,CheckFramebufferStatus}, + * @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl{CheckFramebufferStatus} + * @requires_gl30 Extension @extension{ARB,framebuffer_object} */ Status checkStatus(FramebufferTarget target); @@ -330,20 +335,21 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * @return Reference to self (for method chaining) * * @p attachments is list of shader outputs mapped to buffer - * attachments. %Shader outputs which are not listed are not used, you + * attachments. Shader outputs which are not listed are not used, you * can achieve the same by passing @ref DrawAttachment::None as * attachment. Example usage: * @code - * framebuffer.mapForDraw({{MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::BackLeft}, - * {MyShader::NormalOutput, DefaultFramebuffer::DrawAttachment::None}}); + * defaultFramebuffer.mapForDraw({{MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::BackLeft}, + * {MyShader::NormalOutput, DefaultFramebuffer::DrawAttachment::None}}); * @endcode * - * If @extension{EXT,direct_state_access} is not available and the - * framebuffer is not currently bound, it is bound before the - * operation. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). * @see @ref maxDrawBuffers(), @ref maxDualSourceDrawBuffers(), - * @ref mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffers} - * or @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access} + * @ref mapForRead(), @fn_gl2{NamedFramebufferDrawBuffers,DrawBuffers}, + * @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffers} * @requires_gles30 Draw attachments for default framebuffer are * available only in OpenGL ES 3.0. */ @@ -351,17 +357,18 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { /** * @brief Map shader output to buffer attachment - * @param attachment %Buffer attachment + * @param attachment Buffer attachment * @return Reference to self (for method chaining) * * Similar to above function, can be used in cases when shader has * only one (unnamed) output. * - * If @extension{EXT,direct_state_access} is not available and the - * framebuffer is not currently bound, it is bound before the - * operation. - * @see @ref mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffer} - * or @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access}, + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * @see @ref mapForRead(), @fn_gl2{NamedFramebufferDrawBuffer,DrawBuffer}, + * @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffer} or * @fn_gl{DrawBuffers} in OpenGL ES 3.0 * @requires_gles30 Draw attachments for default framebuffer are * available only in OpenGL ES 3.0. @@ -371,15 +378,16 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { /** * @brief Map given attachment for reading - * @param attachment %Buffer attachment + * @param attachment Buffer attachment * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available and the - * framebuffer is not currently bound, it is bound before the - * operation. - * @see mapForDraw(), @fn_gl{BindFramebuffer}, @fn_gl{ReadBuffer} or - * @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access} - * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * @see @ref mapForDraw(), @fn_gl2{NamedFramebufferReadBuffer,ReadBuffer}, + * @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl{ReadBuffer} + * @requires_gles30 Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} * in OpenGL ES 2.0 */ DefaultFramebuffer& mapForRead(ReadAttachment attachment); @@ -391,26 +399,35 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * If extension @extension{ARB,invalidate_subdata} (part of OpenGL * 4.3), extension @es_extension{EXT,discard_framebuffer} in OpenGL ES * 2.0 or OpenGL ES 3.0 is not available, this function does nothing. - * The framebuffer is bound to some target before the operation, if not - * already. - * @see @fn_gl{InvalidateFramebuffer} or @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer} + * If @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not + * available, the framebuffer is bound before the operation (if not + * already). + * @see @fn_gl2{InvalidateNamedFramebufferData,InvalidateFramebuffer}, + * eventually @fn_gl{InvalidateFramebuffer} or + * @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer} * on OpenGL ES 2.0 */ void invalidate(std::initializer_list attachments); + #ifndef MAGNUM_TARGET_GLES2 /** * @brief Invalidate framebuffer rectangle * @param attachments Attachments to invalidate - * @param rectangle %Rectangle to invalidate + * @param rectangle Rectangle to invalidate * * If extension @extension{ARB,invalidate_subdata} (part of OpenGL - * 4.3) or OpenGL ES 3.0 is not available, this function does nothing. - * The framebuffer is bound to some target before the operation, if not - * already. + * 4.3) is not available, this function does nothing. If + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not + * available, the framebuffer is bound before the operation (if not + * already). * @see @ref invalidate(std::initializer_list), - * @fn_gl{InvalidateSubFramebuffer} + * @fn_gl2{InvalidateNamedFramebufferSubData,InvalidateSubFramebuffer}, + * eventually @fn_gl{InvalidateSubFramebuffer} + * @requires_gles30 Use @ref Magnum::DefaultFramebuffer::invalidate(std::initializer_list) "invalidate(std::initializer_list)" + * in OpenGL ES 2.0 instead. */ void invalidate(std::initializer_list attachments, const Range2Di& rectangle); + #endif /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT @@ -418,6 +435,10 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { AbstractFramebuffer::setViewport(rectangle); return *this; } + DefaultFramebuffer& clear(FramebufferClearMask mask) { + AbstractFramebuffer::clear(mask); + return *this; + } #endif private: @@ -430,11 +451,6 @@ extern DefaultFramebuffer MAGNUM_EXPORT defaultFramebuffer; /** @debugoperatorclassenum{Magnum::DefaultFramebuffer,Magnum::DefaultFramebuffer::Status} */ Debug MAGNUM_EXPORT operator<<(Debug debug, DefaultFramebuffer::Status value); -#ifdef MAGNUM_TARGET_GLES2 -/* No-op implementation on ES2 */ -inline void DefaultFramebuffer::invalidate(std::initializer_list, const Range2Di&) {} -#endif - } #endif diff --git a/src/Magnum/DimensionTraits.h b/src/Magnum/DimensionTraits.h index 6c04a9d03..375e70bed 100644 --- a/src/Magnum/DimensionTraits.h +++ b/src/Magnum/DimensionTraits.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -47,6 +47,14 @@ template struct DimensionTraits { */ typedef U VectorType; + /** + * @brief Range type + * + * @ref Math::Range1D, @ref Math::Range2D or @ref Math::Range3D based on + * dimension count. + */ + typedef U RangeType; + /** * @brief Matrix type * @@ -57,11 +65,37 @@ template struct DimensionTraits { #endif }; +#ifndef CORRADE_GCC46_COMPATIBILITY /** -@todo `using VectorTypeForDimension = typename DimensionTraits::VectorType` - etc. shortcuts when support for GCC 4.6 is dropped (similarly to what C++14 - does with type traits) - */ +@brief Vector type for given dimension count and type + +Convenience alternative to `typename DimensionTraits::VectorType`. +See @ref DimensionTraits::VectorType for more information. +@note Not available on GCC < 4.7. Use `typename DimensionTraits::VectorType` + instead. +*/ +template using VectorTypeFor = typename DimensionTraits::VectorType; + +/** +@brief Range type for given dimension count and type + +Convenience alternative to `typename DimensionTraits::RangeType`. +See @ref DimensionTraits::RangeType for more information. +@note Not available on GCC < 4.7. Use `typename DimensionTraits::RangeType` + instead. +*/ +template using RangeTypeFor = typename DimensionTraits::RangeType; + +/** +@brief Matrix type for given dimension count and type + +Convenience alternative to `typename DimensionTraits::MatrixType`. +See @ref DimensionTraits::MatrixType for more information. +@note Not available on GCC < 4.7. Use `typename DimensionTraits::MatrixType` + instead. +*/ +template using MatrixTypeFor = typename DimensionTraits::MatrixType; +#endif #ifndef DOXYGEN_GENERATING_OUTPUT /* One dimension */ @@ -69,6 +103,7 @@ template struct DimensionTraits<1, T> { DimensionTraits() = delete; typedef Math::Vector<1, T> VectorType; + typedef Math::Range1D RangeType; }; /* Two dimensions - integral */ @@ -76,6 +111,7 @@ template struct DimensionTraits<2, T> { DimensionTraits() = delete; typedef Math::Vector2 VectorType; + typedef Math::Range2D RangeType; }; /* Two dimensions - floating-point */ @@ -83,6 +119,7 @@ template<> struct DimensionTraits<2, Float> { DimensionTraits() = delete; typedef Math::Vector2 VectorType; + typedef Math::Range2D RangeType; typedef Math::Matrix3 MatrixType; }; #ifndef MAGNUM_TARGET_GLES @@ -90,6 +127,7 @@ template<> struct DimensionTraits<2, Double> { DimensionTraits() = delete; typedef Math::Vector2 VectorType; + typedef Math::Range2D RangeType; typedef Math::Matrix3 MatrixType; }; #endif @@ -99,6 +137,7 @@ template struct DimensionTraits<3, T> { DimensionTraits() = delete; typedef Math::Vector3 VectorType; + typedef Math::Range3D RangeType; }; /* Three dimensions - floating-point */ @@ -106,6 +145,7 @@ template<> struct DimensionTraits<3, Float> { DimensionTraits() = delete; typedef Math::Vector3 VectorType; + typedef Math::Range3D RangeType; typedef Math::Matrix4 MatrixType; }; #ifndef MAGNUM_TARGET_GLES @@ -113,6 +153,7 @@ template<> struct DimensionTraits<3, Double> { DimensionTraits() = delete; typedef Math::Vector3 VectorType; + typedef Math::Range3D RangeType; typedef Math::Matrix4 MatrixType; }; #endif diff --git a/src/Magnum/Extensions.h b/src/Magnum/Extensions.h index 7e8312138..52d317f8d 100644 --- a/src/Magnum/Extensions.h +++ b/src/Magnum/Extensions.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -45,7 +45,7 @@ extensions are available only on @ref MAGNUM_TARGET_GLES "OpenGL ES builds". Each struct has the same public methods as Extension class (requiredVersion(), coreVersion() and string(), but these structs are better suited for -compile-time decisions rather than %Extension instances. See +compile-time decisions rather than Extension instances. See @ref Context::isExtensionSupported() for example usage. This namespace is built by default. To use it, you need to add `${MAGNUM_INCLUDE_DIRS}` @@ -337,6 +337,7 @@ namespace GL { _extension(GL,OES,texture_float_linear, GLES200, GLES300) // #35 _extension(GL,OES,texture_half_float, GLES200, GLES300) // #36 _extension(GL,OES,texture_float, GLES200, GLES300) // #36 + _extension(GL,OES,texture_npot, GLES200, GLES300) // #37 _extension(GL,OES,vertex_half_float, GLES200, GLES300) // #38 _extension(GL,OES,packed_depth_stencil, GLES200, GLES300) // #43 _extension(GL,OES,depth_texture, GLES200, GLES300) // #44 diff --git a/src/Magnum/Framebuffer.cpp b/src/Magnum/Framebuffer.cpp index 5aec61e0e..9ae189db6 100644 --- a/src/Magnum/Framebuffer.cpp +++ b/src/Magnum/Framebuffer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -80,6 +80,7 @@ Int Framebuffer::maxColorAttachments() { } Framebuffer::Framebuffer(const Range2Di& viewport) { + CORRADE_INTERNAL_ASSERT(viewport != Implementation::FramebufferState::DisengagedViewport); _viewport = viewport; (this->*Context::current()->state().framebuffer->createImplementation)(); CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding); @@ -102,18 +103,18 @@ Framebuffer::~Framebuffer() { if(!_id) return; /* If bound, remove itself from state */ - Implementation::FramebufferState* state = Context::current()->state().framebuffer; - if(state->readBinding == _id) state->readBinding = 0; + Implementation::FramebufferState& state = *Context::current()->state().framebuffer; + if(state.readBinding == _id) state.readBinding = 0; /* For draw binding reset also viewport */ - if(state->drawBinding == _id) { - state->drawBinding = 0; + if(state.drawBinding == _id) { + state.drawBinding = 0; /** * @todo Less ugly solution (need to call setViewportInternal() to * reset the viewport to size of default framebuffer) */ - defaultFramebuffer.bind(FramebufferTarget::Draw); + defaultFramebuffer.bind(); } glDeleteFramebuffers(1, &_id); @@ -267,6 +268,10 @@ void Framebuffer::renderbufferImplementationDefault(BufferAttachment attachment, } #ifndef MAGNUM_TARGET_GLES +void Framebuffer::renderbufferImplementationDSA(const BufferAttachment attachment, Renderbuffer& renderbuffer) { + glNamedFramebufferRenderbuffer(_id, GLenum(attachment), GL_RENDERBUFFER, renderbuffer.id()); +} + void Framebuffer::renderbufferImplementationDSAEXT(BufferAttachment attachment, Renderbuffer& renderbuffer) { _created = true; glNamedFramebufferRenderbufferEXT(_id, GLenum(attachment), GL_RENDERBUFFER, renderbuffer.id()); @@ -276,6 +281,10 @@ void Framebuffer::texture1DImplementationDefault(BufferAttachment attachment, GL glFramebufferTexture1D(GLenum(bindInternal()), GLenum(attachment), GL_TEXTURE_1D, textureId, mipLevel); } +void Framebuffer::texture1DImplementationDSA(const BufferAttachment attachment, const GLuint textureId, const GLint mipLevel) { + glNamedFramebufferTexture(_id, GLenum(attachment), textureId, mipLevel); +} + void Framebuffer::texture1DImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint mipLevel) { _created = true; glNamedFramebufferTexture1DEXT(_id, GLenum(attachment), GL_TEXTURE_1D, textureId, mipLevel); @@ -287,6 +296,10 @@ void Framebuffer::texture2DImplementationDefault(BufferAttachment attachment, GL } #ifndef MAGNUM_TARGET_GLES +void Framebuffer::texture2DImplementationDSA(const BufferAttachment attachment, GLenum, const GLuint textureId, const GLint mipLevel) { + glNamedFramebufferTexture(_id, GLenum(attachment), textureId, mipLevel); +} + void Framebuffer::texture2DImplementationDSAEXT(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel) { _created = true; glNamedFramebufferTexture2DEXT(_id, GLenum(attachment), textureTarget, textureId, mipLevel); @@ -308,6 +321,10 @@ void Framebuffer::textureLayerImplementationDefault(BufferAttachment attachment, } #ifndef MAGNUM_TARGET_GLES +void Framebuffer::textureLayerImplementationDSA(const BufferAttachment attachment, const GLuint textureId, const GLint mipLevel, const GLint layer) { + glNamedFramebufferTextureLayer(_id, GLenum(attachment), textureId, mipLevel, layer); +} + void Framebuffer::textureLayerImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint mipLevel, GLint layer) { _created = true; glNamedFramebufferTextureLayerEXT(_id, GLenum(attachment), textureId, mipLevel, layer); diff --git a/src/Magnum/Framebuffer.h b/src/Magnum/Framebuffer.h index ebc6310e9..396ed0f3a 100644 --- a/src/Magnum/Framebuffer.h +++ b/src/Magnum/Framebuffer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,7 +39,7 @@ namespace Magnum { /** -@brief %Framebuffer +@brief Framebuffer Unlike @ref DefaultFramebuffer, which is used for on-screen rendering, this class is used for off-screen rendering, usable either in windowless @@ -55,7 +55,7 @@ textures for actual on-screen rendering. First you need to create the framebuffer with the same viewport as default framebuffer and attach textures and renderbuffers to desired outputs: @code -Framebuffer framebuffer(defaultFramebuffer.viewportPosition(), defaultFramebuffer.viewportSize()); +Framebuffer framebuffer({defaultFramebuffer.viewportPosition(), defaultFramebuffer.viewportSize()}); Texture2D color, normal; Renderbuffer depthStencil; @@ -81,10 +81,10 @@ void drawEvent() { defaultFramebuffer.clear(FramebufferClear::Color) framebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth|FramebufferClear::Stencil); - framebuffer.bind(FramebufferTarget::Draw); + framebuffer.bind(); // ... - defaultFramebuffer.bind(Framebuffer::Target::Draw); + defaultFramebuffer.bind(); // ... } @endcode @@ -93,17 +93,19 @@ void drawEvent() { See also @ref AbstractFramebuffer-performance-optimization "relevant section in AbstractFramebuffer". -If extension @extension{EXT,direct_state_access} is available, functions -@ref mapForDraw(), @ref mapForRead(), @ref attachRenderbuffer(), -@ref attachTexture1D(), @ref attachTexture2D(), @ref attachCubeMapTexture() and -@ref attachTexture3D() use DSA to avoid unnecessary calls to @fn_gl{BindFramebuffer}. -See their respective documentation for more information. +If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL +4.5) or @extension{EXT,direct_state_access} is available, functions +@ref checkStatus(), @ref mapForDraw(), @ref mapForRead(), @ref invalidate(), +@ref attachRenderbuffer(), @ref attachTexture(), @ref attachCubeMapTexture() +and @ref attachTextureLayer() use DSA to avoid unnecessary calls to +@fn_gl{BindFramebuffer}. See their respective documentation for more +information. -@requires_gl30 %Extension @extension{ARB,framebuffer_object} +@requires_gl30 Extension @extension{ARB,framebuffer_object} @todo `MAX_COLOR_ATTACHMENTS` */ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObject { - friend struct Implementation::FramebufferState; + friend Implementation::FramebufferState; public: /** @@ -114,14 +116,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje * @ref attachCubeMapTexture(), @ref attachTexture3D() */ class ColorAttachment { - friend class Framebuffer; + friend Framebuffer; public: /** * @brief Constructor * @param id Color attachment ID * - * @requires_gles30 %Extension @es_extension{NV,fbo_color_attachments} + * @requires_gles30 Extension @es_extension{NV,fbo_color_attachments} * is required for @p id greater than 0 in OpenGL ES 2.0 */ constexpr explicit ColorAttachment(UnsignedInt id): attachment(GL_COLOR_ATTACHMENT0 + id) {} @@ -166,7 +168,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje }; /** - * @brief %Buffer attachment + * @brief Buffer attachment * * @see @ref attachRenderbuffer(), @ref attachTexture1D(), * @ref attachTexture2D(), @ref attachCubeMapTexture(), @@ -215,8 +217,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje * @brief Invalidation attachment * * @see @ref invalidate() - * @requires_gl43 %Extension @extension{ARB,invalidate_subdata} - * @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer} + * @requires_gl43 Extension @extension{ARB,invalidate_subdata} + * @requires_gles30 Extension @es_extension{EXT,discard_framebuffer} * in OpenGL ES 2.0 */ class InvalidationAttachment { @@ -283,7 +285,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje /** * Sample count or locations are not the same for all attached * images. - * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_multisample}, + * @requires_gles30 Extension @es_extension{ANGLE,framebuffer_multisample}, * @es_extension{APPLE,framebuffer_multisample}, * @es_extension{EXT,multisampled_render_to_texture} or * @es_extension{NV,framebuffer_multisample} in OpenGL ES 2.0 @@ -350,7 +352,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje GLuint id() const { return _id; } /** - * @brief %Framebuffer label + * @brief Framebuffer label * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. If OpenGL 4.3 is not supported and neither @@ -379,18 +381,23 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje /** @overload */ template Framebuffer& setLabel(const char(&label)[size]) { - return setLabelInternal(label); + return setLabelInternal({label, size - 1}); } /** * @brief Check framebuffer status * @param target Target for which check the status * - * If @extension{EXT,direct_state_access} is not available and the - * framebuffer is not currently bound, it is bound before the - * operation. - * @see @fn_gl{BindFramebuffer}, @fn_gl{CheckFramebufferStatus} or - * @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * + * On OpenGL ES 2.0, if none of @es_extension{APPLE,framebuffer_multisample}, + * @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit} + * is available, the @p target parameter is ignored. + * @see @fn_gl2{CheckNamedFramebufferStatus,CheckFramebufferStatus}, + * @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl{CheckFramebufferStatus} */ Status checkStatus(FramebufferTarget target); @@ -399,7 +406,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje * @return Reference to self (for method chaining) * * @p attachments is list of shader outputs mapped to framebuffer - * color attachment IDs. %Shader outputs which are not listed are not + * color attachment IDs. Shader outputs which are not listed are not * used, you can achieve the same by passing @ref Framebuffer::DrawAttachment::None * as color attachment ID. Example usage: * @code @@ -407,14 +414,15 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje * {MyShader::NormalOutput, Framebuffer::DrawAttachment::None}}); * @endcode * - * If @extension{EXT,direct_state_access} is not available and the - * framebufferbuffer is not currently bound, it is bound before the - * operation. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). * @see @ref maxDrawBuffers(), @ref maxDualSourceDrawBuffers(), * @ref maxColorAttachments(), @ref mapForRead(), - * @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffers} or - * @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access} - * @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} + * @fn_gl2{NamedFramebufferDrawBuffers,DrawBuffers}, + * @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffers} + * @requires_gles30 Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} * in OpenGL ES 2.0 */ Framebuffer& mapForDraw(std::initializer_list> attachments); @@ -427,14 +435,15 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje * Similar to above function, can be used in cases when shader has * only one (unnamed) output. * - * If @extension{EXT,direct_state_access} is not available and the - * framebufferbuffer is not currently bound, it is bound before the - * operation. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). * @see @ref maxColorAttachments(), @ref mapForRead(), - * @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffer} or + * @fn_gl2{NamedFramebufferDrawBuffer,DrawBuffer}, * @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffer} or * @fn_gl{DrawBuffers} in OpenGL ES 3.0 - * @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} + * @requires_gles30 Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} * in OpenGL ES 2.0 */ Framebuffer& mapForDraw(DrawAttachment attachment); @@ -444,12 +453,13 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje * @param attachment Color attachment * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available and the - * framebufferbuffer is not currently bound, it is bound before the - * operation. - * @see @ref mapForDraw(), @fn_gl{BindFramebuffer}, @fn_gl{ReadBuffer} - * or @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access} - * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * @see @ref mapForDraw(), @fn_gl2{NamedFramebufferReadBuffer,ReadBuffer}, + * @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl{ReadBuffer} + * @requires_gles30 Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} * in OpenGL ES 2.0 */ Framebuffer& mapForRead(ColorAttachment attachment); @@ -458,63 +468,69 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje * @brief Invalidate framebuffer * @param attachments Attachments to invalidate * - * The framebuffer is bound to some target before the operation, if - * not already. - * @see @fn_gl{InvalidateFramebuffer} or @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer} + * If extension @extension{ARB,invalidate_subdata} (part of OpenGL + * 4.3), extension @es_extension{EXT,discard_framebuffer} in OpenGL ES + * 2.0 or OpenGL ES 3.0 is not available, this function does nothing. + * If @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not + * available, the framebuffer is bound before the operation (if not + * already). + * @see @fn_gl2{InvalidateNamedFramebufferData,InvalidateFramebuffer}, + * eventually @fn_gl{InvalidateFramebuffer} or + * @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer} * on OpenGL ES 2.0 - * @requires_gl43 %Extension @extension{ARB,invalidate_subdata}. Use - * @ref Magnum::Framebuffer::clear() "clear()" instead where the - * extension is not supported. - * @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer} - * in OpenGL ES 2.0. Use @ref Magnum::Framebuffer::clear() "clear()" - * instead where the extension is not supported. */ void invalidate(std::initializer_list attachments); + #ifndef MAGNUM_TARGET_GLES2 /** * @brief Invalidate framebuffer rectangle * @param attachments Attachments to invalidate - * @param rectangle %Rectangle to invalidate + * @param rectangle Rectangle to invalidate * * If extension @extension{ARB,invalidate_subdata} (part of OpenGL - * 4.3) or OpenGL ES 3.0 is not available, this function does nothing. - * The framebuffer is bound to some target before the operation, if not - * already. + * 4.3) is not available, this function does nothing. If + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not + * available, the framebuffer is bound before the operation (if not + * already). * @see @ref invalidate(std::initializer_list), - * @fn_gl{InvalidateFramebuffer} + * @fn_gl2{InvalidateNamedFramebufferSubData,InvalidateSubFramebuffer}, + * eventually @fn_gl{InvalidateSubFramebuffer} + * @requires_gles30 Use @ref Magnum::DefaultFramebuffer::invalidate(std::initializer_list) "invalidate(std::initializer_list)" + * in OpenGL ES 2.0 instead. */ void invalidate(std::initializer_list attachments, const Range2Di& rectangle); + #endif /** * @brief Attach renderbuffer to given buffer - * @param attachment %Buffer attachment - * @param renderbuffer %Renderbuffer + * @param attachment Buffer attachment + * @param renderbuffer Renderbuffer * @return Reference to self (for method chaining) * - * If extension @extension{ARB,invalidate_subdata} (part of OpenGL - * 4.3), extension @es_extension{EXT,discard_framebuffer} in OpenGL ES - * 2.0 or OpenGL ES 3.0 is not available, this function does nothing. - * The framebuffer is bound to some target before the operation, if not - * already. - * @see @fn_gl{InvalidateSubFramebuffer} or @fn_gles_extension{DiscardSubFramebuffer,EXT,discard_framebuffer} - * on OpenGL ES 2.0 + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * @see @fn_gl2{NamedFramebufferRenderbuffer,FramebufferRenderbuffer}, + * @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl{FramebufferRenderbuffer} */ Framebuffer& attachRenderbuffer(BufferAttachment attachment, Renderbuffer& renderbuffer); #ifndef MAGNUM_TARGET_GLES /** * @brief Attach texture to given buffer - * @param attachment %Buffer attachment - * @param texture %Texture + * @param attachment Buffer attachment + * @param texture Texture * @param level Mip level * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available and the - * framebufferbuffer is not currently bound, it is bound before the - * operation. - * @see @ref attachCubeMapTexture(), @fn_gl{BindFramebuffer}, - * @fn_gl2{FramebufferTexture1D,FramebufferTexture} or - * @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * @see @ref attachCubeMapTexture(), @fn_gl2{NamedFramebufferTexture,FramebufferTexture}, + * @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and + * @fn_gl2{FramebufferTexture1D,FramebufferTexture} * @requires_gl Only 2D and 3D textures are available in OpenGL ES. */ Framebuffer& attachTexture(BufferAttachment attachment, Texture1D& texture, Int level); @@ -522,23 +538,24 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje /** * @brief Attach texture to given buffer - * @param attachment %Buffer attachment - * @param texture %Texture + * @param attachment Buffer attachment + * @param texture Texture * @param level Mip level * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available and the - * framebufferbuffer is not currently bound, it is bound before the - * operation. - * @see @ref attachCubeMapTexture(), @fn_gl{BindFramebuffer}, - * @fn_gl2{FramebufferTexture2D,FramebufferTexture} or - * @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * @see @ref attachCubeMapTexture(), @fn_gl2{NamedFramebufferTexture,FramebufferTexture}, + * @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and + * @fn_gl2{FramebufferTexture2D,FramebufferTexture} */ Framebuffer& attachTexture(BufferAttachment attachment, Texture2D& texture, Int level); #ifndef MAGNUM_TARGET_GLES /** @overload - * @requires_gl31 %Extension @extension{ARB,texture_rectangle} + * @requires_gl31 Extension @extension{ARB,texture_rectangle} * @requires_gl Rectangle textures are not available in OpenGL ES. */ Framebuffer& attachTexture(BufferAttachment attachment, RectangleTexture& texture); @@ -546,7 +563,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje #ifndef MAGNUM_TARGET_GLES2 /** @overload - * @requires_gl32 %Extension @extension{ARB,texture_multisample} + * @requires_gl32 Extension @extension{ARB,texture_multisample} * @requires_gles31 Multisample textures are not available in OpenGL ES * 3.0 and older. */ @@ -555,43 +572,45 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje /** * @brief Attach cube map texture to given buffer - * @param attachment %Buffer attachment - * @param texture %Texture + * @param attachment Buffer attachment + * @param texture Texture * @param coordinate Cube map coordinate * @param level Mip level * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available and the - * framebufferbuffer is not currently bound, it is bound before the - * operation. - * @see @ref attachTexture2D(), @fn_gl{BindFramebuffer}, - * @fn_gl2{FramebufferTexture2D,FramebufferTexture} or - * @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * @see @ref attachTexture2D(), @fn_gl2{NamedFramebufferTexture,FramebufferTexture}, + * @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl2{FramebufferTexture2D,FramebufferTexture} */ Framebuffer& attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture& texture, CubeMapTexture::Coordinate coordinate, Int level); /** * @brief Attach texture layer to given buffer - * @param attachment %Buffer attachment - * @param texture %Texture + * @param attachment Buffer attachment + * @param texture Texture * @param level Mip level * @param layer Layer * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available and the - * framebufferbuffer is not currently bound, it is bound before the - * operation. - * @see @fn_gl{BindFramebuffer}, @fn_gl2{FramebufferTextureLayer,FramebufferTexture} - * or @fn_gl_extension{NamedFramebufferTextureLayer,EXT,direct_state_access}, - * @fn_gles_extension{FramebufferTexture3D,OES,texture_3D} in OpenGL ES 2.0 - * @requires_gles30 %Extension @es_extension{OES,texture_3D} in OpenGL + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the framebuffer is bound before the operation (if not already). + * @see @fn_gl2{NamedFramebufferTextureLayer,FramebufferTextureLayer}, + * @fn_gl_extension{NamedFramebufferTextureLayer,EXT,direct_state_access}, + * eventually @fn_gl{BindFramebuffer} and @fn_gl2{FramebufferTextureLayer,FramebufferTexture} + * or @fn_gles_extension{FramebufferTexture3D,OES,texture_3D} in + * OpenGL ES 2.0 + * @requires_gles30 Extension @es_extension{OES,texture_3D} in OpenGL * ES 2.0 */ Framebuffer& attachTextureLayer(BufferAttachment attachment, Texture3D& texture, Int level, Int layer); #ifndef MAGNUM_TARGET_GLES /** @overload - * @requires_gl30 %Extension @extension{EXT,texture_array} + * @requires_gl30 Extension @extension{EXT,texture_array} * @requires_gl Only 2D array textures are available in OpenGL ES. */ Framebuffer& attachTextureLayer(BufferAttachment attachment, Texture1DArray& texture, Int level, Int layer); @@ -599,21 +618,21 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje #ifndef MAGNUM_TARGET_GLES2 /** @overload - * @requires_gl30 %Extension @extension{EXT,texture_array} - * @requires_gles30 %Array textures are not available in OpenGL ES 2.0 + * @requires_gl30 Extension @extension{EXT,texture_array} + * @requires_gles30 Array textures are not available in OpenGL ES 2.0 */ Framebuffer& attachTextureLayer(BufferAttachment attachment, Texture2DArray& texture, Int level, Int layer); #endif #ifndef MAGNUM_TARGET_GLES /** @overload - * @requires_gl40 %Extension @extension{ARB,texture_cube_map_array} + * @requires_gl40 Extension @extension{ARB,texture_cube_map_array} * @requires_gl Cube map texture arrays are not available in OpenGL ES. */ Framebuffer& attachTextureLayer(BufferAttachment attachment, CubeMapTextureArray& texture, Int level, Int layer); /** @overload - * @requires_gl32 %Extension @extension{ARB,texture_multisample} + * @requires_gl32 Extension @extension{ARB,texture_multisample} * @requires_gl Multisample array textures are not available in OpenGL ES. */ Framebuffer& attachTextureLayer(BufferAttachment attachment, MultisampleTexture2DArray& texture, Int layer); @@ -651,6 +670,10 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje AbstractFramebuffer::setViewport(rectangle); return *this; } + Framebuffer& clear(FramebufferClearMask mask) { + AbstractFramebuffer::clear(mask); + return *this; + } #endif private: @@ -663,21 +686,25 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje void MAGNUM_LOCAL renderbufferImplementationDefault(BufferAttachment attachment, Renderbuffer& renderbuffer); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL renderbufferImplementationDSA(BufferAttachment attachment, Renderbuffer& renderbuffer); void MAGNUM_LOCAL renderbufferImplementationDSAEXT(BufferAttachment attachment, Renderbuffer& renderbuffer); #endif #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL texture1DImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level); + void MAGNUM_LOCAL texture1DImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint level); void MAGNUM_LOCAL texture1DImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint level); #endif void MAGNUM_LOCAL texture2DImplementationDefault(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL texture2DImplementationDSA(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level); void MAGNUM_LOCAL texture2DImplementationDSAEXT(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level); #endif void MAGNUM_LOCAL textureLayerImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL textureLayerImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer); void MAGNUM_LOCAL textureLayerImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer); #endif }; @@ -694,17 +721,13 @@ inline Framebuffer::Framebuffer(Framebuffer&& other) noexcept { } inline Framebuffer& Framebuffer::operator=(Framebuffer&& other) noexcept { - std::swap(_id, other._id); - std::swap(_viewport, other._viewport); - std::swap(_created, other._created); + using std::swap; + swap(_id, other._id); + swap(_viewport, other._viewport); + swap(_created, other._created); return *this; } -#ifdef MAGNUM_TARGET_GLES2 -/* No-op implementation on ES2 */ -inline void Framebuffer::invalidate(std::initializer_list, const Range2Di&) {} -#endif - } #endif diff --git a/src/Magnum/Image.cpp b/src/Magnum/Image.cpp index 72ac20ccc..78ab8be81 100644 --- a/src/Magnum/Image.cpp +++ b/src/Magnum/Image.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,7 +32,7 @@ template void Image::setData(ColorFormat for _format = format; _type = type; _size = size; - _data = reinterpret_cast(data); + _data = reinterpret_cast(data); } #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Magnum/Image.h b/src/Magnum/Image.h index 5cd691983..66a8f14b7 100644 --- a/src/Magnum/Image.h +++ b/src/Magnum/Image.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,7 +34,7 @@ namespace Magnum { /** -@brief %Image +@brief Image Stores image data on client memory. Interchangeable with @ref ImageReference, @ref BufferImage or @ref Trade::ImageData. @@ -42,19 +42,19 @@ Stores image data on client memory. Interchangeable with @ref ImageReference, */ template class Image: public AbstractImage { public: - const static UnsignedInt Dimensions = dimensions; /**< @brief %Image dimension count */ + const static UnsignedInt Dimensions = dimensions; /**< @brief Image dimension count */ /** * @brief Constructor * @param format Format of pixel data * @param type Data type of pixel data - * @param size %Image size - * @param data %Image data + * @param size Image size + * @param data Image data * * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - explicit Image(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} + explicit Image(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} /** * @brief Constructor @@ -64,7 +64,7 @@ template class Image: public AbstractImage { * Dimensions are set to zero and data pointer to `nullptr`, call * @ref setData() to fill the image with data. */ - explicit Image(ColorFormat format, ColorType type): AbstractImage(format, type), _data(nullptr) {} + /*implicit*/ Image(ColorFormat format, ColorType type): AbstractImage(format, type), _data{} {} /** @brief Copying is not allowed */ Image(const Image&) = delete; @@ -94,7 +94,7 @@ template class Image: public AbstractImage { /*implicit*/ operator ImageReference() const && = delete; #endif - /** @brief %Image size */ + /** @brief Image size */ typename DimensionTraits::VectorType size() const { return _size; } /** @@ -113,12 +113,12 @@ template class Image: public AbstractImage { * * @see @ref release() */ - template T* data() { + template T* data() { return reinterpret_cast(_data); } /** @overload */ - template const T* data() const { + template const T* data() const { return reinterpret_cast(_data); } @@ -126,8 +126,8 @@ template class Image: public AbstractImage { * @brief Set image data * @param format Format of pixel data * @param type Data type of pixel data - * @param size %Image size - * @param data %Image data + * @param size Image size + * @param data Image data * * Deletes previous data and replaces them with new. Note that the * data are not copied, but they are deleted on destruction. @@ -142,11 +142,11 @@ template class Image: public AbstractImage { * to default. Deleting the returned array is then user responsibility. * @see @ref setData() */ - unsigned char* release(); + char* release(); private: Math::Vector _size; - unsigned char* _data; + char* _data; }; /** @brief One-dimensional image */ @@ -165,8 +165,9 @@ template inline Image::Image(Image inline Image& Image::operator=(Image&& other) noexcept { AbstractImage::operator=(std::move(other)); - std::swap(_size, other._size); - std::swap(_data, other._data); + using std::swap; + swap(_size, other._size); + swap(_data, other._data); return *this; } @@ -180,9 +181,9 @@ const return ImageReference(AbstractImage::format(), AbstractImage::type(), _size, _data); } -template inline unsigned char* Image::release() { +template inline char* Image::release() { /** @todo I need `std::exchange` NOW. */ - unsigned char* const data = _data; + char* const data = _data; _size = {}; _data = nullptr; return data; diff --git a/src/Magnum/ImageReference.h b/src/Magnum/ImageReference.h index d2cef6001..478e89a6d 100644 --- a/src/Magnum/ImageReference.h +++ b/src/Magnum/ImageReference.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,7 @@ namespace Magnum { /** -@brief %Image reference +@brief Image reference Adds information about dimensions, color components and component type to some data in memory. @@ -52,29 +52,29 @@ Interchangeable with @ref Image, @ref BufferImage or @ref Trade::ImageData. */ template class ImageReference: public AbstractImage { public: - const static UnsignedInt Dimensions = dimensions; /**< @brief %Image dimension count */ + const static UnsignedInt Dimensions = dimensions; /**< @brief Image dimension count */ /** * @brief Constructor * @param format Format of pixel data * @param type Data type of pixel data - * @param size %Image size - * @param data %Image data + * @param size Image size + * @param data Image data */ - constexpr explicit ImageReference(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, const void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} + constexpr explicit ImageReference(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, const void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} /** * @brief Constructor * @param format Format of pixel data * @param type Data type of pixel data - * @param size %Image size + * @param size Image size * * Data pointer is set to `nullptr`, call @ref setData() to fill the * image with data. */ constexpr explicit ImageReference(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size): AbstractImage(format, type), _size(size), _data(nullptr) {} - /** @brief %Image size */ + /** @brief Image size */ constexpr typename DimensionTraits::VectorType size() const { return _size; } /** @copydoc Image::dataSize() */ @@ -83,28 +83,28 @@ template class ImageReference: public AbstractImage { } /** @brief Pointer to raw data */ - constexpr const unsigned char* data() const { return _data; } + constexpr const char* data() const { return _data; } /** @overload */ - template const T* data() const { + template const T* data() const { return reinterpret_cast(_data); } /** * @brief Set image data - * @param data %Image data + * @param data Image data * * Dimensions, color compnents and data type remains the same as * passed in constructor. The data are not copied nor deleted on * destruction. */ void setData(const void* data) { - _data = reinterpret_cast(data); + _data = reinterpret_cast(data); } private: Math::Vector _size; - const unsigned char* _data; + const char* _data; }; /** @brief One-dimensional image wrapper */ diff --git a/src/Magnum/Implementation/BufferState.cpp b/src/Magnum/Implementation/BufferState.cpp index e8c2de2a0..b9574436c 100644 --- a/src/Magnum/Implementation/BufferState.cpp +++ b/src/Magnum/Implementation/BufferState.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -99,7 +99,19 @@ BufferState::BufferState(Context& context, std::vector& extensions) } #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) { + extensions.push_back(Extensions::GL::ARB::direct_state_access::string()); + + copyImplementation = &Buffer::copyImplementationDSA; + getParameterImplementation = &Buffer::getParameterImplementationDSA; + getSubDataImplementation = &Buffer::getSubDataImplementationDSA; + dataImplementation = &Buffer::dataImplementationDSA; + subDataImplementation = &Buffer::subDataImplementationDSA; + mapImplementation = &Buffer::mapImplementationDSA; + mapRangeImplementation = &Buffer::mapRangeImplementationDSA; + flushMappedRangeImplementation = &Buffer::flushMappedRangeImplementationDSA; + unmapImplementation = &Buffer::unmapImplementationDSA; + } else if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::EXT::direct_state_access::string()); copyImplementation = &Buffer::copyImplementationDSAEXT; diff --git a/src/Magnum/Implementation/BufferState.h b/src/Magnum/Implementation/BufferState.h index 29eaabec0..388c674ca 100644 --- a/src/Magnum/Implementation/BufferState.h +++ b/src/Magnum/Implementation/BufferState.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/DebugState.cpp b/src/Magnum/Implementation/DebugState.cpp index 25764ae95..cdc5a4f8b 100644 --- a/src/Magnum/Implementation/DebugState.cpp +++ b/src/Magnum/Implementation/DebugState.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,15 +31,23 @@ namespace Magnum { namespace Implementation { -DebugState::DebugState(Context& context, std::vector& extensions): maxLabelLength(0), maxLoggedMessages(0), maxMessageLength(0), messageCallback(nullptr) { +DebugState::DebugState(Context& context, std::vector& extensions): + maxLabelLength{0}, + maxLoggedMessages{0}, + maxMessageLength{0}, + maxStackDepth{0}, + messageCallback(nullptr) +{ if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::KHR::debug::string()); getLabelImplementation = &AbstractObject::getLabelImplementationKhr; labelImplementation = &AbstractObject::labelImplementationKhr; + controlImplementation = &DebugOutput::controlImplementationKhr; + callbackImplementation = &DebugOutput::callbackImplementationKhr; messageInsertImplementation = &DebugMessage::insertImplementationKhr; - messageControlImplementation = &DebugMessage::controlImplementationKhr; - messageCallbackImplementation = &DebugMessage::callbackImplementationKhr; + pushGroupImplementation = &DebugGroup::pushImplementationKhr; + popGroupImplementation = &DebugGroup::popImplementationKhr; } else { if(context.isExtensionSupported()) { @@ -64,8 +72,8 @@ DebugState::DebugState(Context& context, std::vector& extensions): #endif } else messageInsertImplementation = &DebugMessage::insertImplementationNoOp; - messageControlImplementation = &DebugMessage::controlImplementationNoOp; - messageCallbackImplementation = &DebugMessage::callbackImplementationNoOp; + controlImplementation = &DebugOutput::controlImplementationNoOp; + callbackImplementation = &DebugOutput::callbackImplementationNoOp; } } diff --git a/src/Magnum/Implementation/DebugState.h b/src/Magnum/Implementation/DebugState.h index c080a2c3f..4c5051853 100644 --- a/src/Magnum/Implementation/DebugState.h +++ b/src/Magnum/Implementation/DebugState.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -28,7 +28,7 @@ #include #include -#include "Magnum/DebugMessage.h" +#include "Magnum/DebugOutput.h" namespace Magnum { namespace Implementation { @@ -38,12 +38,14 @@ struct DebugState { std::string(*getLabelImplementation)(GLenum, GLuint); void(*labelImplementation)(GLenum, GLuint, Containers::ArrayReference); - void(*messageInsertImplementation)(DebugMessage::Source, DebugMessage::Type, UnsignedInt, DebugMessage::Severity, Containers::ArrayReference); - void(*messageControlImplementation)(GLenum, GLenum, GLenum, std::initializer_list, bool); - void(*messageCallbackImplementation)(DebugMessage::Callback, const void*); + void(*messageInsertImplementation)(DebugMessage::Source, DebugMessage::Type, UnsignedInt, DebugOutput::Severity, Containers::ArrayReference); + void(*controlImplementation)(GLenum, GLenum, GLenum, std::initializer_list, bool); + void(*callbackImplementation)(DebugOutput::Callback, const void*); + void(*pushGroupImplementation)(DebugGroup::Source, UnsignedInt, Containers::ArrayReference); + void(*popGroupImplementation)(); - GLint maxLabelLength, maxLoggedMessages, maxMessageLength; - DebugMessage::Callback messageCallback; + GLint maxLabelLength, maxLoggedMessages, maxMessageLength, maxStackDepth; + DebugOutput::Callback messageCallback; }; }} diff --git a/src/Magnum/Implementation/FramebufferState.cpp b/src/Magnum/Implementation/FramebufferState.cpp index f7fe3540b..b10210775 100644 --- a/src/Magnum/Implementation/FramebufferState.cpp +++ b/src/Magnum/Implementation/FramebufferState.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,10 +33,13 @@ namespace Magnum { namespace Implementation { -FramebufferState::FramebufferState(Context& context, std::vector& extensions): readBinding(0), drawBinding(0), renderbufferBinding(0), maxDrawBuffers(0), maxColorAttachments(0), maxRenderbufferSize(0), maxSamples(0) +constexpr const Range2Di FramebufferState::DisengagedViewport; + +FramebufferState::FramebufferState(Context& context, std::vector& extensions): readBinding{0}, drawBinding{0}, renderbufferBinding{0}, maxDrawBuffers{0}, maxColorAttachments{0}, maxRenderbufferSize{0}, maxSamples{0}, #ifndef MAGNUM_TARGET_GLES - , maxDualSourceDrawBuffers(0) + maxDualSourceDrawBuffers{0}, #endif + viewport{DisengagedViewport} { /* Create implementation */ #ifndef MAGNUM_TARGET_GLES @@ -54,7 +57,22 @@ FramebufferState::FramebufferState(Context& context, std::vector& e /* DSA/non-DSA implementation */ #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) { + /* Extension added above */ + + checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSA; + drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationDSA; + drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSA; + readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSA; + + renderbufferImplementation = &Framebuffer::renderbufferImplementationDSA; + texture1DImplementation = &Framebuffer::texture1DImplementationDSA; + texture2DImplementation = &Framebuffer::texture2DImplementationDSA; + textureLayerImplementation = &Framebuffer::textureLayerImplementationDSA; + + renderbufferStorageImplementation = &Renderbuffer::storageImplementationDSA; + + } else if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::EXT::direct_state_access::string()); checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSAEXT; @@ -86,12 +104,13 @@ FramebufferState::FramebufferState(Context& context, std::vector& e renderbufferStorageImplementation = &Renderbuffer::storageImplementationDefault; } - /* Framebuffer binding on ES2 */ #ifdef MAGNUM_TARGET_GLES2 + /* Framebuffer binding and checking on ES2 */ /* Optimistically set separate binding targets and check if one of the extensions providing them is available */ - readTarget = FramebufferTarget::Read; - drawTarget = FramebufferTarget::Draw; + bindImplementation = &Framebuffer::bindImplementationDefault; + bindInternalImplementation = &Framebuffer::bindImplementationDefault; + checkStatusImplementation = &Framebuffer::checkStatusImplementationDefault; if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::ANGLE::framebuffer_blit::string()); @@ -109,8 +128,12 @@ FramebufferState::FramebufferState(Context& context, std::vector& e } else if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::NV::framebuffer_multisample::string()); - /* If no such extension is available, reset back to unified target */ - } else readTarget = drawTarget = FramebufferTarget::ReadDraw; + /* If no such extension is available, reset back to single target */ + } else { + bindImplementation = &Framebuffer::bindImplementationSingle; + bindInternalImplementation = &Framebuffer::bindImplementationSingle; + checkStatusImplementation = &Framebuffer::checkStatusImplementationSingle; + } #endif /* Framebuffer reading implementation */ @@ -131,7 +154,12 @@ FramebufferState::FramebufferState(Context& context, std::vector& e /* Multisample renderbuffer storage implementation */ #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) { + /* Extension added above */ + + renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSA; + + } else if(context.isExtensionSupported()) { /* Extension added above */ renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSAEXT; @@ -158,8 +186,15 @@ FramebufferState::FramebufferState(Context& context, std::vector& e if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::ARB::invalidate_subdata::string()); - invalidateImplementation = &AbstractFramebuffer::invalidateImplementationDefault; - invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationDefault; + if(context.isExtensionSupported()) { + /* Extension added above */ + invalidateImplementation = &AbstractFramebuffer::invalidateImplementationDSA; + invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationDSA; + } else { + invalidateImplementation = &AbstractFramebuffer::invalidateImplementationDefault; + invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationDefault; + } + } else { invalidateImplementation = &AbstractFramebuffer::invalidateImplementationNoOp; invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationNoOp; @@ -181,8 +216,16 @@ FramebufferState::FramebufferState(Context& context, std::vector& e invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationDefault; #endif + /* Blit implementation on desktop GL */ + #ifndef MAGNUM_TARGET_GLES + if(context.isExtensionSupported()) { + /* Extension added above */ + blitImplementation = &AbstractFramebuffer::blitImplementationDSA; + + } else blitImplementation = &AbstractFramebuffer::blitImplementationDefault; + /* Blit implementation on ES2 */ - #ifdef MAGNUM_TARGET_GLES2 + #elif defined(MAGNUM_TARGET_GLES2) if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::ANGLE::framebuffer_blit::string()); blitImplementation = &AbstractFramebuffer::blitImplementationANGLE; @@ -192,12 +235,16 @@ FramebufferState::FramebufferState(Context& context, std::vector& e blitImplementation = &AbstractFramebuffer::blitImplementationNV; } else blitImplementation = nullptr; + + /* Always available on ES3 */ + #else + blitImplementation = &AbstractFramebuffer::blitImplementationDefault; #endif } void FramebufferState::reset() { readBinding = drawBinding = renderbufferBinding = State::DisengagedBinding; - viewport = {}; + viewport = DisengagedViewport; } }} diff --git a/src/Magnum/Implementation/FramebufferState.h b/src/Magnum/Implementation/FramebufferState.h index 426b497e4..72505d719 100644 --- a/src/Magnum/Implementation/FramebufferState.h +++ b/src/Magnum/Implementation/FramebufferState.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -43,13 +43,13 @@ namespace Magnum { namespace Implementation { struct FramebufferState { + constexpr static const Range2Di DisengagedViewport{{}, {-1, -1}}; + explicit FramebufferState(Context& context, std::vector& extensions); void reset(); - #ifdef MAGNUM_TARGET_GLES2 - void(*blitImplementation)(const Range2Di&, const Range2Di&, FramebufferBlitMask, FramebufferBlitFilter); - #endif + void(*blitImplementation)(AbstractFramebuffer&, AbstractFramebuffer&, const Range2Di&, const Range2Di&, FramebufferBlitMask, FramebufferBlitFilter); GLenum(AbstractFramebuffer::*checkStatusImplementation)(FramebufferTarget); void(AbstractFramebuffer::*drawBuffersImplementation)(GLsizei, const GLenum*); void(AbstractFramebuffer::*drawBufferImplementation)(GLenum); @@ -58,6 +58,10 @@ struct FramebufferState { #ifndef MAGNUM_TARGET_GLES2 void(AbstractFramebuffer::*invalidateSubImplementation)(GLsizei, const GLenum*, const Range2Di&); #endif + #ifdef MAGNUM_TARGET_GLES2 + void(AbstractFramebuffer::*bindImplementation)(FramebufferTarget); + FramebufferTarget(AbstractFramebuffer::*bindInternalImplementation)(); + #endif void(Framebuffer::*createImplementation)(); void(Framebuffer::*renderbufferImplementation)(Framebuffer::BufferAttachment, Renderbuffer&); @@ -71,9 +75,7 @@ struct FramebufferState { void(Renderbuffer::*renderbufferStorageImplementation)(RenderbufferFormat, const Vector2i&); void(Renderbuffer::*renderbufferStorageMultisampleImplementation)(GLsizei, RenderbufferFormat, const Vector2i&); - void(*readImplementation)(const Vector2i&, const Vector2i&, ColorFormat, ColorType, std::size_t, GLvoid*); - - FramebufferTarget readTarget, drawTarget; + void(*readImplementation)(const Range2Di&, ColorFormat, ColorType, std::size_t, GLvoid*); GLuint readBinding, drawBinding, renderbufferBinding; GLint maxDrawBuffers, maxColorAttachments, maxRenderbufferSize, maxSamples; diff --git a/src/Magnum/Implementation/MeshState.cpp b/src/Magnum/Implementation/MeshState.cpp index e2e595c91..7cc6b9ee9 100644 --- a/src/Magnum/Implementation/MeshState.cpp +++ b/src/Magnum/Implementation/MeshState.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -137,7 +137,16 @@ MeshState::MeshState(Context& context, std::vector& extensions): cu drawArraysInstancedImplementation = nullptr; drawElementsInstancedImplementation = nullptr; } + #endif + #ifndef MAGNUM_TARGET_GLES + /* Partial EXT_DSA implementation of vertex attrib divisor */ + if(context.isExtensionSupported()) { + if(glVertexArrayVertexAttribDivisorEXT) + vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationDSAEXT; + else vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAO; + } else vertexAttribDivisorImplementation = nullptr; + #elif defined(MAGNUM_TARGET_GLES2) /* Instanced arrays implementation on ES2 */ if(context.isExtensionSupported()) { /* Extension added above */ diff --git a/src/Magnum/Implementation/MeshState.h b/src/Magnum/Implementation/MeshState.h index 9095a6ff0..967d2abaa 100644 --- a/src/Magnum/Implementation/MeshState.h +++ b/src/Magnum/Implementation/MeshState.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,14 +39,14 @@ struct MeshState { void(Mesh::*createImplementation)(); void(Mesh::*destroyImplementation)(); - void(Mesh::*attributePointerImplementation)(const Mesh::Attribute&); + void(Mesh::*attributePointerImplementation)(const Mesh::GenericAttribute&); #ifndef MAGNUM_TARGET_GLES2 void(Mesh::*attributeIPointerImplementation)(const Mesh::IntegerAttribute&); #ifndef MAGNUM_TARGET_GLES void(Mesh::*attributeLPointerImplementation)(const Mesh::LongAttribute&); #endif #endif - #ifdef MAGNUM_TARGET_GLES2 + #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2) void(Mesh::*vertexAttribDivisorImplementation)(GLuint, GLuint); #endif void(Mesh::*bindIndexBufferImplementation)(Buffer&); diff --git a/src/Magnum/Implementation/QueryState.cpp b/src/Magnum/Implementation/QueryState.cpp index bec5f3d00..54b0b72e1 100644 --- a/src/Magnum/Implementation/QueryState.cpp +++ b/src/Magnum/Implementation/QueryState.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/QueryState.h b/src/Magnum/Implementation/QueryState.h index 75d0f3d45..e05a3d45d 100644 --- a/src/Magnum/Implementation/QueryState.h +++ b/src/Magnum/Implementation/QueryState.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/RendererState.cpp b/src/Magnum/Implementation/RendererState.cpp index 13fc2dc7d..7989c0b63 100644 --- a/src/Magnum/Implementation/RendererState.cpp +++ b/src/Magnum/Implementation/RendererState.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/RendererState.h b/src/Magnum/Implementation/RendererState.h index 33483e632..0440043df 100644 --- a/src/Magnum/Implementation/RendererState.h +++ b/src/Magnum/Implementation/RendererState.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/ShaderProgramState.cpp b/src/Magnum/Implementation/ShaderProgramState.cpp index e55a22313..b3fc06e4d 100644 --- a/src/Magnum/Implementation/ShaderProgramState.cpp +++ b/src/Magnum/Implementation/ShaderProgramState.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/ShaderProgramState.h b/src/Magnum/Implementation/ShaderProgramState.h index 0ce583620..edabbf8ab 100644 --- a/src/Magnum/Implementation/ShaderProgramState.h +++ b/src/Magnum/Implementation/ShaderProgramState.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/ShaderState.h b/src/Magnum/Implementation/ShaderState.h index a8f3a3cf3..6c6f678b0 100644 --- a/src/Magnum/Implementation/ShaderState.h +++ b/src/Magnum/Implementation/ShaderState.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/State.cpp b/src/Magnum/Implementation/State.cpp index 987e68055..533e38bc7 100644 --- a/src/Magnum/Implementation/State.cpp +++ b/src/Magnum/Implementation/State.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,6 +39,9 @@ #include "ShaderState.h" #include "ShaderProgramState.h" #include "TextureState.h" +#ifndef MAGNUM_TARGET_GLES2 +#include "TransformFeedbackState.h" +#endif namespace Magnum { namespace Implementation { @@ -52,15 +55,18 @@ State::State(Context& context) { extensions.reserve(8); #endif - buffer = new BufferState(context, extensions); - debug = new DebugState(context, extensions); - framebuffer = new FramebufferState(context, extensions); - mesh = new MeshState(context, extensions); - query = new QueryState(context, extensions); - renderer = new RendererState(context, extensions); - shader = new ShaderState; - shaderProgram = new ShaderProgramState(context, extensions); - texture = new TextureState(context, extensions); + buffer.reset(new BufferState{context, extensions}); + debug.reset(new DebugState{context, extensions}); + framebuffer.reset(new FramebufferState{context, extensions}); + mesh.reset(new MeshState{context, extensions}); + query.reset(new QueryState{context, extensions}); + renderer.reset(new RendererState{context, extensions}); + shader.reset(new ShaderState); + shaderProgram.reset(new ShaderProgramState{context, extensions}); + texture.reset(new TextureState{context, extensions}); + #ifndef MAGNUM_TARGET_GLES2 + transformFeedback.reset(new TransformFeedbackState{context, extensions}); + #endif /* Sort the features and remove duplicates */ std::sort(extensions.begin(), extensions.end()); @@ -71,15 +77,6 @@ State::State(Context& context) { Debug() << " " << *it; } -State::~State() { - delete texture; - delete shaderProgram; - delete shader; - delete renderer; - delete mesh; - delete framebuffer; - delete debug; - delete buffer; -} +State::~State() = default; }} diff --git a/src/Magnum/Implementation/State.h b/src/Magnum/Implementation/State.h index 481e6ad73..6a578ccd7 100644 --- a/src/Magnum/Implementation/State.h +++ b/src/Magnum/Implementation/State.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,6 +25,8 @@ DEALINGS IN THE SOFTWARE. */ +#include + #include "Magnum/Magnum.h" #include "Magnum/OpenGL.h" @@ -39,24 +41,30 @@ struct RendererState; struct ShaderState; struct ShaderProgramState; struct TextureState; +#ifndef MAGNUM_TARGET_GLES2 +struct TransformFeedbackState; +#endif struct State { /* Initializes context-based functionality */ - State(Context& context); + explicit State(Context& context); ~State(); enum: GLuint { DisengagedBinding = ~0u }; - BufferState* buffer; - DebugState* debug; - FramebufferState* framebuffer; - MeshState* mesh; - QueryState* query; - RendererState* renderer; - ShaderState* shader; - ShaderProgramState* shaderProgram; - TextureState* texture; + std::unique_ptr buffer; + std::unique_ptr debug; + std::unique_ptr framebuffer; + std::unique_ptr mesh; + std::unique_ptr query; + std::unique_ptr renderer; + std::unique_ptr shader; + std::unique_ptr shaderProgram; + std::unique_ptr texture; + #ifndef MAGNUM_TARGET_GLES2 + std::unique_ptr transformFeedback; + #endif }; }} diff --git a/src/Magnum/Implementation/TextureState.cpp b/src/Magnum/Implementation/TextureState.cpp index e53f4a27e..b3dceca5a 100644 --- a/src/Magnum/Implementation/TextureState.cpp +++ b/src/Magnum/Implementation/TextureState.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -69,33 +69,69 @@ TextureState::TextureState(Context& context, std::vector& extension createImplementation = &AbstractTexture::createImplementationDefault; } - /* Bind implementation */ + /* Single bind implementation */ #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { - extensions.push_back(Extensions::GL::ARB::multi_bind::string()); + if(context.isExtensionSupported()) { + /* Extension name added below */ + + unbindImplementation = &AbstractTexture::unbindImplementationDSA; + bindImplementation = &AbstractTexture::bindImplementationDSA; + } else if(context.isExtensionSupported()) { + /* Extension name added below */ unbindImplementation = &AbstractTexture::unbindImplementationMulti; - bindMultiImplementation = &AbstractTexture::bindImplementationMulti; bindImplementation = &AbstractTexture::bindImplementationMulti; } else if(context.isExtensionSupported()) { /* Extension name added below */ unbindImplementation = &AbstractTexture::unbindImplementationDSAEXT; - bindMultiImplementation = &AbstractTexture::bindImplementationFallback; bindImplementation = &AbstractTexture::bindImplementationDSAEXT; } else #endif { unbindImplementation = &AbstractTexture::unbindImplementationDefault; - bindMultiImplementation = &AbstractTexture::bindImplementationFallback; bindImplementation = &AbstractTexture::bindImplementationDefault; } + /* Multi bind implementation */ + #ifndef MAGNUM_TARGET_GLES + if(context.isExtensionSupported()) { + extensions.push_back(Extensions::GL::ARB::multi_bind::string()); + + bindMultiImplementation = &AbstractTexture::bindImplementationMulti; + + } else + #endif + { + bindMultiImplementation = &AbstractTexture::bindImplementationFallback; + } + /* DSA/non-DSA implementation */ #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) { + extensions.push_back(Extensions::GL::ARB::direct_state_access::string()); + + parameteriImplementation = &AbstractTexture::parameterImplementationDSA; + parameterfImplementation = &AbstractTexture::parameterImplementationDSA; + parameterivImplementation = &AbstractTexture::parameterImplementationDSA; + parameterfvImplementation = &AbstractTexture::parameterImplementationDSA; + parameterIuivImplementation = &AbstractTexture::parameterIImplementationDSA; + parameterIivImplementation = &AbstractTexture::parameterIImplementationDSA; + getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSA; + mipmapImplementation = &AbstractTexture::mipmapImplementationDSA; + subImage1DImplementation = &AbstractTexture::subImageImplementationDSA; + subImage2DImplementation = &AbstractTexture::subImageImplementationDSA; + subImage3DImplementation = &AbstractTexture::subImageImplementationDSA; + + setBufferImplementation = &BufferTexture::setBufferImplementationDSA; + setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSA; + + getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDSA; + cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSA; + + } else if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::EXT::direct_state_access::string()); parameteriImplementation = &AbstractTexture::parameterImplementationDSAEXT; @@ -106,16 +142,16 @@ TextureState::TextureState(Context& context, std::vector& extension parameterIivImplementation = &AbstractTexture::parameterIImplementationDSAEXT; getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSAEXT; mipmapImplementation = &AbstractTexture::mipmapImplementationDSAEXT; - getImageImplementation = &AbstractTexture::getImageImplementationDSAEXT; - image1DImplementation = &AbstractTexture::imageImplementationDSAEXT; - image2DImplementation = &AbstractTexture::imageImplementationDSAEXT; - image3DImplementation = &AbstractTexture::imageImplementationDSAEXT; subImage1DImplementation = &AbstractTexture::subImageImplementationDSAEXT; subImage2DImplementation = &AbstractTexture::subImageImplementationDSAEXT; subImage3DImplementation = &AbstractTexture::subImageImplementationDSAEXT; setBufferImplementation = &BufferTexture::setBufferImplementationDSAEXT; setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSAEXT; + + getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDSAEXT; + cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSAEXT; + } else #endif { @@ -134,12 +170,6 @@ TextureState::TextureState(Context& context, std::vector& extension #endif mipmapImplementation = &AbstractTexture::mipmapImplementationDefault; #ifndef MAGNUM_TARGET_GLES - getImageImplementation = &AbstractTexture::getImageImplementationDefault; - image1DImplementation = &AbstractTexture::imageImplementationDefault; - #endif - image2DImplementation = &AbstractTexture::imageImplementationDefault; - image3DImplementation = &AbstractTexture::imageImplementationDefault; - #ifndef MAGNUM_TARGET_GLES subImage1DImplementation = &AbstractTexture::subImageImplementationDefault; #endif subImage2DImplementation = &AbstractTexture::subImageImplementationDefault; @@ -149,6 +179,11 @@ TextureState::TextureState(Context& context, std::vector& extension setBufferImplementation = &BufferTexture::setBufferImplementationDefault; setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault; #endif + + #ifndef MAGNUM_TARGET_GLES2 + getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDefault; + #endif + cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDefault; } /* Data invalidation implementation */ @@ -165,14 +200,36 @@ TextureState::TextureState(Context& context, std::vector& extension invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp; } - /* Image retrieval implementation */ #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported() && - !context.isExtensionSupported()) { - extensions.push_back(Extensions::GL::ARB::robustness::string()); + /* Image retrieval implementation */ + if(context.isExtensionSupported()) { + /* Extension name added above */ + getImageImplementation = &AbstractTexture::getImageImplementationDSA; + } else if(context.isExtensionSupported()) { + extensions.push_back(Extensions::GL::ARB::robustness::string()); getImageImplementation = &AbstractTexture::getImageImplementationRobustness; + + } else if(context.isExtensionSupported()) { + /* Extension name added above */ + getImageImplementation = &AbstractTexture::getImageImplementationDSAEXT; + } else getImageImplementation = &AbstractTexture::getImageImplementationDefault; + + /* Image retrieval implementation for cube map */ + if(context.isExtensionSupported()) { + extensions.push_back(Extensions::GL::ARB::get_texture_sub_image::string()); + getCubeImageImplementation = &CubeMapTexture::getImageImplementationDSA; + + } else if(context.isExtensionSupported()) { + /* Extension name added above */ + getCubeImageImplementation = &CubeMapTexture::getImageImplementationRobustness; + + } else if(context.isExtensionSupported()) { + /* Extension name added above */ + getCubeImageImplementation = &CubeMapTexture::getImageImplementationDSAEXT; + + } else getCubeImageImplementation = &CubeMapTexture::getImageImplementationDefault; #endif /* Texture storage implementation */ @@ -189,7 +246,12 @@ TextureState::TextureState(Context& context, std::vector& extension #endif #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) { + storage1DImplementation = &AbstractTexture::storageImplementationDSA; + storage2DImplementation = &AbstractTexture::storageImplementationDSA; + storage3DImplementation = &AbstractTexture::storageImplementationDSA; + + } else if(context.isExtensionSupported()) { storage1DImplementation = &AbstractTexture::storageImplementationDSAEXT; storage2DImplementation = &AbstractTexture::storageImplementationDSAEXT; storage3DImplementation = &AbstractTexture::storageImplementationDSAEXT; @@ -219,7 +281,10 @@ TextureState::TextureState(Context& context, std::vector& extension if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::ARB::texture_storage_multisample::string()); - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) { + storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA; + storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA; + } else if(context.isExtensionSupported()) { storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT; storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT; } else { diff --git a/src/Magnum/Implementation/TextureState.h b/src/Magnum/Implementation/TextureState.h index df3ac72b1..55266d953 100644 --- a/src/Magnum/Implementation/TextureState.h +++ b/src/Magnum/Implementation/TextureState.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -28,8 +28,7 @@ #include #include -#include "Magnum/Magnum.h" -#include "Magnum/OpenGL.h" +#include "Magnum/CubeMapTexture.h" #ifdef CORRADE_GCC45_COMPATIBILITY #ifndef MAGNUM_TARGET_GLES @@ -73,29 +72,26 @@ struct TextureState { #endif void(AbstractTexture::*setMaxAnisotropyImplementation)(GLfloat); #ifndef MAGNUM_TARGET_GLES2 - void(AbstractTexture::*getLevelParameterivImplementation)(GLenum, GLint, GLenum, GLint*); + void(AbstractTexture::*getLevelParameterivImplementation)(GLint, GLenum, GLint*); #endif void(AbstractTexture::*mipmapImplementation)(); #ifndef MAGNUM_TARGET_GLES - void(AbstractTexture::*storage1DImplementation)(GLenum, GLsizei, TextureFormat, const Math::Vector<1, GLsizei>&); + void(AbstractTexture::*storage1DImplementation)(GLsizei, TextureFormat, const Math::Vector<1, GLsizei>&); #endif - void(AbstractTexture::*storage2DImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&); - void(AbstractTexture::*storage3DImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&); + void(AbstractTexture::*storage2DImplementation)(GLsizei, TextureFormat, const Vector2i&); + void(AbstractTexture::*storage3DImplementation)(GLsizei, TextureFormat, const Vector3i&); #ifndef MAGNUM_TARGET_GLES2 - void(AbstractTexture::*storage2DMultisampleImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&, GLboolean); + void(AbstractTexture::*storage2DMultisampleImplementation)(GLsizei, TextureFormat, const Vector2i&, GLboolean); #endif #ifndef MAGNUM_TARGET_GLES - void(AbstractTexture::*storage3DMultisampleImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&, GLboolean); - void(AbstractTexture::*getImageImplementation)(GLenum, GLint, ColorFormat, ColorType, std::size_t, GLvoid*); - void(AbstractTexture::*image1DImplementation)(GLenum, GLint, TextureFormat, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*); + void(AbstractTexture::*storage3DMultisampleImplementation)(GLsizei, TextureFormat, const Vector3i&, GLboolean); + void(AbstractTexture::*getImageImplementation)(GLint, ColorFormat, ColorType, std::size_t, GLvoid*); #endif - void(AbstractTexture::*image2DImplementation)(GLenum, GLint, TextureFormat, const Vector2i&, ColorFormat, ColorType, const GLvoid*); - void(AbstractTexture::*image3DImplementation)(GLenum, GLint, TextureFormat, const Vector3i&, ColorFormat, ColorType, const GLvoid*); #ifndef MAGNUM_TARGET_GLES - void(AbstractTexture::*subImage1DImplementation)(GLenum, GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*); + void(AbstractTexture::*subImage1DImplementation)(GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*); #endif - void(AbstractTexture::*subImage2DImplementation)(GLenum, GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*); - void(AbstractTexture::*subImage3DImplementation)(GLenum, GLint, const Vector3i&, const Vector3i&, ColorFormat, ColorType, const GLvoid*); + void(AbstractTexture::*subImage2DImplementation)(GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*); + void(AbstractTexture::*subImage3DImplementation)(GLint, const Vector3i&, const Vector3i&, ColorFormat, ColorType, const GLvoid*); void(AbstractTexture::*invalidateImageImplementation)(GLint); void(AbstractTexture::*invalidateSubImageImplementation)(GLint, const Vector3i&, const Vector3i&); @@ -104,6 +100,14 @@ struct TextureState { void(BufferTexture::*setBufferRangeImplementation)(BufferTextureFormat, Buffer&, GLintptr, GLsizeiptr); #endif + #ifndef MAGNUM_TARGET_GLES2 + Vector2i(CubeMapTexture::*getCubeImageSizeImplementation)(Int); + #endif + #ifndef MAGNUM_TARGET_GLES + void(CubeMapTexture::*getCubeImageImplementation)(CubeMapTexture::Coordinate, GLint, const Vector2i&, ColorFormat, ColorType, std::size_t, GLvoid*); + #endif + void(CubeMapTexture::*cubeSubImageImplementation)(CubeMapTexture::Coordinate, GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*); + GLint maxSize, max3DSize, maxCubeMapSize; diff --git a/src/Magnum/Implementation/TransformFeedbackState.cpp b/src/Magnum/Implementation/TransformFeedbackState.cpp new file mode 100644 index 000000000..dd90c63f4 --- /dev/null +++ b/src/Magnum/Implementation/TransformFeedbackState.cpp @@ -0,0 +1,45 @@ +#include "TransformFeedbackState.h" + +#include "Magnum/Extensions.h" +#include "Magnum/TransformFeedback.h" + +#include "State.h" + +namespace Magnum { namespace Implementation { + +TransformFeedbackState::TransformFeedbackState(Context& context, std::vector& extensions): maxInterleavedComponents{0}, maxSeparateAttributes{0}, maxSeparateComponents{0} + #ifndef MAGNUM_TARGET_GLES + , maxBuffers{0} + #endif +{ + #ifndef MAGNUM_TARGET_GLES + if(context.isExtensionSupported()) { + extensions.push_back(Extensions::GL::ARB::direct_state_access::string()); + + createImplementation = &TransformFeedback::createImplementationDSA; + attachRangeImplementation = &TransformFeedback::attachImplementationDSA; + attachBaseImplementation = &TransformFeedback::attachImplementationDSA; + attachRangesImplementation = &TransformFeedback::attachImplementationDSA; + attachBasesImplementation = &TransformFeedback::attachImplementationDSA; + + } else + #endif + { + createImplementation = &TransformFeedback::createImplementationDefault; + attachRangeImplementation = &TransformFeedback::attachImplementationFallback; + attachBaseImplementation = &TransformFeedback::attachImplementationFallback; + attachRangesImplementation = &TransformFeedback::attachImplementationFallback; + attachBasesImplementation = &TransformFeedback::attachImplementationFallback; + } + + #ifdef MAGNUM_TARGET_GLES + static_cast(context); + static_cast(extensions); + #endif +} + +void TransformFeedbackState::reset() { + binding = State::DisengagedBinding; +} + +}} diff --git a/src/Magnum/Implementation/TransformFeedbackState.h b/src/Magnum/Implementation/TransformFeedbackState.h new file mode 100644 index 000000000..da10f9579 --- /dev/null +++ b/src/Magnum/Implementation/TransformFeedbackState.h @@ -0,0 +1,55 @@ +#ifndef Magnum_Implementation_TransformFeedbackState_h +#define Magnum_Implementation_TransformFeedbackState_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Magnum/Context.h" + +namespace Magnum { namespace Implementation { + +struct TransformFeedbackState { + explicit TransformFeedbackState(Context& context, std::vector& extensions); + + void reset(); + + GLint maxInterleavedComponents, + maxSeparateAttributes, + maxSeparateComponents; + #ifndef MAGNUM_TARGET_GLES + GLint maxBuffers; + #endif + + GLuint binding; + + void(TransformFeedback::*createImplementation)(); + void(TransformFeedback::*attachRangeImplementation)(GLuint, Buffer&, GLintptr, GLsizeiptr); + void(TransformFeedback::*attachBaseImplementation)(GLuint, Buffer&); + void(TransformFeedback::*attachRangesImplementation)(GLuint, std::initializer_list>); + void(TransformFeedback::*attachBasesImplementation)(GLuint, std::initializer_list); +}; + +}} + +#endif diff --git a/src/Magnum/Implementation/detectedDriver.cpp b/src/Magnum/Implementation/detectedDriver.cpp index ca52c6620..813c6ea33 100644 --- a/src/Magnum/Implementation/detectedDriver.cpp +++ b/src/Magnum/Implementation/detectedDriver.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,16 +33,23 @@ auto Context::detectedDriver() -> DetectedDrivers { _detectedDrivers = DetectedDrivers{}; - /* AMD binary desktop drivers */ #ifndef MAGNUM_TARGET_GLES const std::string vendor = vendorString(); + + /* AMD binary desktop drivers */ if(vendor.find("ATI Technologies Inc.") != std::string::npos) return *_detectedDrivers |= DetectedDriver::AMD; + + #ifdef CORRADE_TARGET_WINDOWS + /* Intel Windows drivers */ + if(vendor.find("Intel") != std::string::npos) + return *_detectedDrivers |= DetectedDriver::IntelWindows; + #endif #endif + #ifdef MAGNUM_TARGET_GLES2 /* OpenGL ES 2.0 implementation using ANGLE. Taken from http://stackoverflow.com/a/20149090 */ - #ifdef MAGNUM_TARGET_GLES2 { Range1Di range; glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range.data()); diff --git a/src/Magnum/Implementation/maxTextureSize.cpp b/src/Magnum/Implementation/maxTextureSize.cpp index e43b78c70..19599edd3 100644 --- a/src/Magnum/Implementation/maxTextureSize.cpp +++ b/src/Magnum/Implementation/maxTextureSize.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/maxTextureSize.h b/src/Magnum/Implementation/maxTextureSize.h index b269c1463..97c967abf 100644 --- a/src/Magnum/Implementation/maxTextureSize.h +++ b/src/Magnum/Implementation/maxTextureSize.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Implementation/setupDriverWorkarounds.cpp b/src/Magnum/Implementation/setupDriverWorkarounds.cpp index 7c4c05049..6f8af7739 100644 --- a/src/Magnum/Implementation/setupDriverWorkarounds.cpp +++ b/src/Magnum/Implementation/setupDriverWorkarounds.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,9 +37,14 @@ void Context::setupDriverWorkarounds() { /* This extension causes crash in GLSL compiler on AMD linux drivers 13.251 */ if(detectedDriver() & DetectedDriver::AMD) _setRequiredVersion(GL::ARB::explicit_uniform_location, None); + + #ifdef CORRADE_TARGET_WINDOWS + /* On Windows Intel drivers ARB_shading_language_420pack is exposed in GLSL + even that the extension (e.g. binding keyword) is not supported */ + if((detectedDriver() & DetectedDriver::IntelWindows) && !Context::current()->isExtensionSupported()) + _setRequiredVersion(GL::ARB::shading_language_420pack, None); #endif - #ifndef MAGNUM_TARGET_GLES /* Layout qualifier causes compiler error with GLSL 1.20 on Mesa, GLSL 1.30 on NVidia and 1.40 on Mac OS X */ /** @todo Different version on different vendors? */ diff --git a/src/Magnum/Magnum.h b/src/Magnum/Magnum.h index f8ce5d5ff..a5a813e1d 100644 --- a/src/Magnum/Magnum.h +++ b/src/Magnum/Magnum.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,10 +34,6 @@ #include "Magnum/Types.h" #include "Magnum/Math/Math.h" -#ifdef MAGNUM_BUILD_DEPRECATED -#include -#endif - #ifndef DOXYGEN_GENERATING_OUTPUT typedef unsigned int GLenum; /* Needed for *Format and *Type enums */ #endif @@ -45,10 +41,9 @@ typedef unsigned int GLenum; /* Needed for *Format and *Type enums */ namespace Magnum { namespace Math { - template struct Constants; - - /** @todoc Remove `ifndef` when Doxygen is able to handle operator"" */ #ifndef DOXYGEN_GENERATING_OUTPUT + template struct Constants; + #if !defined(CORRADE_GCC46_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) #ifndef MAGNUM_TARGET_GLES constexpr Rad operator "" _rad(long double); @@ -73,7 +68,7 @@ using Corrade::Utility::Error; @brief Build with deprecated API included Defined if the library contains deprecated API (which will be removed in the -future). To preserve backward compatibility, %Magnum is by default built with +future). To preserve backward compatibility, Magnum is by default built with deprecated API included. @see @ref building, @ref cmake */ @@ -350,20 +345,6 @@ typedef Math::Range2D Range2Di; /** @brief Signed integer 3D range */ typedef Math::Range3D Range3Di; -#ifdef MAGNUM_BUILD_DEPRECATED -/** -@copybrief Range2D -@deprecated Use @ref Magnum::Range2D "Range2D" instead. -*/ -typedef CORRADE_DEPRECATED("use Range2D instead") Math::Geometry::Rectangle Rectangle; - -/** -@copybrief Range2Di -@deprecated Use @ref Magnum::Range2Di "Range2Di" instead. -*/ -typedef CORRADE_DEPRECATED("use Range2Di instead") Math::Geometry::Rectangle Rectanglei; -#endif - /*@}*/ #ifndef MAGNUM_TARGET_GLES @@ -506,14 +487,6 @@ typedef Math::Range2D Range2Dd; /** @brief Double 3D range */ typedef Math::Range3D Range3Dd; -#ifdef MAGNUM_BUILD_DEPRECATED -/** -@copybrief Range2Dd -@deprecated Use @ref Magnum::Range2Dd instead. -*/ -typedef CORRADE_DEPRECATED("use Range2Dd instead") Math::Geometry::Rectangle Rectangled; -#endif - /*@}*/ #endif @@ -529,6 +502,7 @@ using Math::operator "" _radf; /* Forward declarations for all types in root namespace */ +#ifndef DOXYGEN_GENERATING_OUTPUT /* FramebufferClear[Mask], FramebufferBlit[Mask], FramebufferBlitFilter, FramebufferTarget enums used only directly with framebuffer instance */ class AbstractFramebuffer; @@ -542,6 +516,8 @@ template class Array1D; template class Array2D; template class Array3D; +template class Attribute; + #ifndef CORRADE_GCC45_COMPATIBILITY enum class BufferUsage: GLenum; #endif @@ -655,11 +631,13 @@ typedef TextureArray<2> Texture2DArray; enum class TextureFormat: GLenum; #endif +class TransformFeedback; class Timeline; #ifndef CORRADE_GCC45_COMPATIBILITY enum class Version: Int; #endif +#endif } diff --git a/src/Magnum/Math/Algorithms/CMakeLists.txt b/src/Magnum/Math/Algorithms/CMakeLists.txt index deeec09df..05d621b4e 100644 --- a/src/Magnum/Math/Algorithms/CMakeLists.txt +++ b/src/Magnum/Math/Algorithms/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Math/Algorithms/GaussJordan.h b/src/Magnum/Math/Algorithms/GaussJordan.h index b749696dc..b00f02d27 100644 --- a/src/Magnum/Math/Algorithms/GaussJordan.h +++ b/src/Magnum/Math/Algorithms/GaussJordan.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -62,8 +62,9 @@ template bool gaussJordanInPlaceTra rowMax = row2; /* Swap the rows */ - std::swap(a[row], a[rowMax]); - std::swap(t[row], t[rowMax]); + using std::swap; + swap(a[row], a[rowMax]); + swap(t[row], t[rowMax]); /* Singular */ if(TypeTraits::equals(a[row][row], T(0))) diff --git a/src/Magnum/Math/Algorithms/GramSchmidt.h b/src/Magnum/Math/Algorithms/GramSchmidt.h index a35aa392e..cc78af8e3 100644 --- a/src/Magnum/Math/Algorithms/GramSchmidt.h +++ b/src/Magnum/Math/Algorithms/GramSchmidt.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -35,7 +35,7 @@ namespace Magnum { namespace Math { namespace Algorithms { /** @brief In-place Gram-Schmidt matrix orthogonalization -@param[in,out] matrix %Matrix to perform orthogonalization on +@param[in,out] matrix Matrix to perform orthogonalization on */ template void gramSchmidtOrthogonalizeInPlace(RectangularMatrix& matrix) { static_assert(cols <= rows, "Unsupported matrix aspect ratio"); @@ -58,7 +58,7 @@ template RectangularMatrix void gramSchmidtOrthonormalizeInPlace(RectangularMatrix& matrix) { static_assert(cols <= rows, "Unsupported matrix aspect ratio"); diff --git a/src/Magnum/Math/Algorithms/Svd.h b/src/Magnum/Math/Algorithms/Svd.h index 1838c17c6..b2257b8e6 100644 --- a/src/Magnum/Math/Algorithms/Svd.h +++ b/src/Magnum/Math/Algorithms/Svd.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Math/Algorithms/Test/CMakeLists.txt b/src/Magnum/Math/Algorithms/Test/CMakeLists.txt index d320c3e6d..f29ac1e37 100644 --- a/src/Magnum/Math/Algorithms/Test/CMakeLists.txt +++ b/src/Magnum/Math/Algorithms/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Math/Algorithms/Test/GaussJordanTest.cpp b/src/Magnum/Math/Algorithms/Test/GaussJordanTest.cpp index 7b9c9288a..5c6c855a6 100644 --- a/src/Magnum/Math/Algorithms/Test/GaussJordanTest.cpp +++ b/src/Magnum/Math/Algorithms/Test/GaussJordanTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,12 +29,11 @@ namespace Magnum { namespace Math { namespace Algorithms { namespace Test { -class GaussJordanTest: public Corrade::TestSuite::Tester { - public: - explicit GaussJordanTest(); +struct GaussJordanTest: Corrade::TestSuite::Tester { + explicit GaussJordanTest(); - void singular(); - void invert(); + void singular(); + void invert(); }; typedef RectangularMatrix<4, 4, Float> Matrix4x4; diff --git a/src/Magnum/Math/Algorithms/Test/GramSchmidtTest.cpp b/src/Magnum/Math/Algorithms/Test/GramSchmidtTest.cpp index a3a1169c9..9fc111f30 100644 --- a/src/Magnum/Math/Algorithms/Test/GramSchmidtTest.cpp +++ b/src/Magnum/Math/Algorithms/Test/GramSchmidtTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,12 +29,11 @@ namespace Magnum { namespace Math { namespace Algorithms { namespace Test { -class GramSchmidtTest: public Corrade::TestSuite::Tester { - public: - GramSchmidtTest(); +struct GramSchmidtTest: Corrade::TestSuite::Tester { + explicit GramSchmidtTest(); - void orthogonalize(); - void orthonormalize(); + void orthogonalize(); + void orthonormalize(); }; typedef RectangularMatrix<3, 3, Float> Matrix3x3; @@ -58,9 +57,9 @@ void GramSchmidtTest::orthogonalize() { /* (The vectors don't need to unit length) */ /* Verify the vectors are orthogonal */ - CORRADE_COMPARE(Vector3::dot(orthogonalized[0], orthogonalized[1]), 0.0f); - CORRADE_COMPARE(Vector3::dot(orthogonalized[0], orthogonalized[2]), 0.0f); - CORRADE_COMPARE(Vector3::dot(orthogonalized[1], orthogonalized[2]), 0.0f); + CORRADE_COMPARE(dot(orthogonalized[0], orthogonalized[1]), 0.0f); + CORRADE_COMPARE(dot(orthogonalized[0], orthogonalized[2]), 0.0f); + CORRADE_COMPARE(dot(orthogonalized[1], orthogonalized[2]), 0.0f); /* Just to be sure */ Matrix3x3 expected(Vector3( 3.0f, 5.0f, 1.0f), @@ -85,9 +84,9 @@ void GramSchmidtTest::orthonormalize() { CORRADE_COMPARE(orthonormalized[2].length(), 1.0f); /* Verify the vectors are orthogonal */ - CORRADE_COMPARE(Vector3::dot(orthonormalized[0], orthonormalized[1]), 0.0f); - CORRADE_COMPARE(Vector3::dot(orthonormalized[0], orthonormalized[2]), 0.0f); - CORRADE_COMPARE(Vector3::dot(orthonormalized[1], orthonormalized[2]), 0.0f); + CORRADE_COMPARE(dot(orthonormalized[0], orthonormalized[1]), 0.0f); + CORRADE_COMPARE(dot(orthonormalized[0], orthonormalized[2]), 0.0f); + CORRADE_COMPARE(dot(orthonormalized[1], orthonormalized[2]), 0.0f); /* Just to be sure */ Matrix3x3 expected(Vector3( 0.3030458f, 0.5050763f, 0.8081220f), diff --git a/src/Magnum/Math/Algorithms/Test/SvdTest.cpp b/src/Magnum/Math/Algorithms/Test/SvdTest.cpp index e3153259c..29c892a2a 100644 --- a/src/Magnum/Math/Algorithms/Test/SvdTest.cpp +++ b/src/Magnum/Math/Algorithms/Test/SvdTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,12 +29,11 @@ namespace Magnum { namespace Math { namespace Algorithms { namespace Test { -class SvdTest: public Corrade::TestSuite::Tester { - public: - explicit SvdTest(); +struct SvdTest: Corrade::TestSuite::Tester { + explicit SvdTest(); - void testDouble(); - void testFloat(); + void testDouble(); + void testFloat(); }; #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/Math/Angle.h b/src/Magnum/Math/Angle.h index 378e100d5..17da23e7c 100644 --- a/src/Magnum/Math/Angle.h +++ b/src/Magnum/Math/Angle.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -148,7 +148,7 @@ template class Deg: public Unit { #if !defined(CORRADE_GCC46_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) #ifndef MAGNUM_TARGET_GLES -/** @relates Deg +/** @relatesalso Deg @brief Double-precision degree value literal Example usage: @@ -156,15 +156,14 @@ Example usage: Double cosine = Math::cos(60.0_deg); // cosine = 0.5 Double cosine = Math::cos(1.047_rad); // cosine = 0.5 @endcode -@see Magnum::operator""_deg(), operator""_degf(), operator""_rad() +@see @link operator""_degf() @endlink, @link operator""_rad() @endlink @note Not available on GCC < 4.7 and MSVC 2013. Use @ref Deg::Deg(T) instead. @requires_gl Only single-precision types are available in OpenGL ES. -@todoc Make references explicit when Doxygen can link to operator"" */ constexpr Deg operator "" _deg(long double value) { return Deg(value); } #endif -/** @relates Deg +/** @relatesalso Deg @brief Single-precision degree value literal Example usage: @@ -172,9 +171,8 @@ Example usage: Float tangent = Math::tan(60.0_degf); // tangent = 1.732f Float tangent = Math::tan(1.047_radf); // tangent = 1.732f @endcode -@see Magnum::operator""_degf(), operator""_deg(), operator""_radf() +@see @link operator""_deg() @endlink, @link operator""_radf() @endlink @note Not available on GCC < 4.7 and MSVC 2013. Use @ref Deg::Deg(T) instead. -@todoc Make references explicit when Doxygen can link to operator"" */ constexpr Deg operator "" _degf(long double value) { return Deg(value); } #endif @@ -212,23 +210,22 @@ template class Rad: public Unit { #if !defined(CORRADE_GCC46_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY) #ifndef MAGNUM_TARGET_GLES -/** @relates Rad +/** @relatesalso Rad @brief Double-precision radian value literal -See operator""_rad() for more information. -@see Magnum::operator""_rad(), operator""_radf(), operator""_deg() +See @link operator""_rad() @endlink for more information. +@see @link operator""_radf() @endlink, @link operator""_deg() @endlink @note Not available on GCC < 4.7 and MSVC 2013. Use @ref Rad::Rad(T) instead. @requires_gl Only single-precision types are available in OpenGL ES. -@todoc Make references explicit when Doxygen can link to operator"" */ constexpr Rad operator "" _rad(long double value) { return Rad(value); } #endif -/** @relates Rad +/** @relatesalso Rad @brief Single-precision radian value literal -See operator""_degf() for more information. -@see Magnum::operator""_radf(), operator""_rad(), operator""_degf() +See @link operator""_degf() @endlink for more information. +@see @link operator""_rad() @endlink, @link operator""_degf() @endlink @note Not available on GCC < 4.7 and MSVC 2013. Use @ref Rad::Rad(T) instead. @todoc Make references explicit when Doxygen can link to operator"" */ diff --git a/src/Magnum/Math/BoolVector.h b/src/Magnum/Math/BoolVector.h index 8afd65af4..b511a4eb8 100644 --- a/src/Magnum/Math/BoolVector.h +++ b/src/Magnum/Math/BoolVector.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -58,7 +58,7 @@ namespace Implementation { } /** -@brief %Vector storing boolean values +@brief Vector storing boolean values @tparam size Bit count Result of component-wise comparison from Vector. The boolean values are stored @@ -70,8 +70,8 @@ template class BoolVector { static_assert(size != 0, "BoolVector cannot have zero elements"); public: - static const std::size_t Size = size; /**< @brief %Vector size */ - static const std::size_t DataSize = (size-1)/8+1; /**< @brief %Vector storage size */ + static const std::size_t Size = size; /**< @brief Vector size */ + static const std::size_t DataSize = (size-1)/8+1; /**< @brief Vector storage size */ /** @brief Construct zero-filled boolean vector */ constexpr BoolVector(): _data() {} @@ -113,7 +113,7 @@ template class BoolVector { /** * @brief Raw data - * @return %Array of DataSize length + * @return Array of DataSize length * * @see @ref operator[](), @ref set() */ diff --git a/src/Magnum/Math/CMakeLists.txt b/src/Magnum/Math/CMakeLists.txt index bcffdce8b..6df45abe6 100644 --- a/src/Magnum/Math/CMakeLists.txt +++ b/src/Magnum/Math/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Math/Complex.h b/src/Magnum/Math/Complex.h index bbfb92416..9de3346d7 100644 --- a/src/Magnum/Math/Complex.h +++ b/src/Magnum/Math/Complex.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,7 +29,6 @@ * @brief Class @ref Magnum::Math::Complex */ -#include #include #include @@ -46,8 +45,36 @@ namespace Implementation { } } +/** @relatesalso Complex +@brief Dot product of two complex numbers + +@f[ + c_0 \cdot c_1 = a_0 a_1 + b_0 b_1 +@f] +@see @ref Complex::dot() const +*/ +template inline T dot(const Complex& a, const Complex& b) { + return a.real()*b.real() + a.imaginary()*b.imaginary(); +} + +/** @relatesalso Complex +@brief Angle between normalized complex numbers + +Expects that both complex numbers are normalized. @f[ + \theta = acos \left( \frac{Re(c_0 \cdot c_1))}{|c_0| |c_1|} \right) = acos (a_0 a_1 + b_0 b_1) +@f] +@see @ref Complex::isNormalized(), + @ref angle(const Quaternion&, const Quaternion&), + @ref angle(const Vector&, const Vector&) +*/ +template inline Rad angle(const Complex& normalizedA, const Complex& normalizedB) { + CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), + "Math::angle(): complex numbers must be normalized", {}); + return Rad(std::acos(normalizedA.real()*normalizedB.real() + normalizedA.imaginary()*normalizedB.imaginary())); +} + /** -@brief %Complex number +@brief Complex number @tparam T Data type Represents 2D rotation. See @ref transformations for brief introduction. @@ -57,33 +84,25 @@ template class Complex { public: typedef T Type; /**< @brief Underlying data type */ + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Dot product - * - * @f[ - * c_0 \cdot c_1 = a_0 a_1 + b_0 b_1 - * @f] - * @see dot() const - * @todoc Explicit reference when Doxygen can handle const + * @copybrief Math::dot(const Complex&, const Complex&) + * @deprecated Use @ref Math::dot(const Complex&, const Complex&) + * instead. */ - static T dot(const Complex& a, const Complex& b) { - return a._real*b._real + a._imaginary*b._imaginary; + CORRADE_DEPRECATED("use Math::dot() instead") static T dot(const Complex& a, const Complex& b) { + return Math::dot(a, b); } /** - * @brief Angle between normalized complex numbers - * - * Expects that both complex numbers are normalized. @f[ - * \theta = acos \left( \frac{Re(c_0 \cdot c_1))}{|c_0| |c_1|} \right) = acos (a_0 a_1 + b_0 b_1) - * @f] - * @see @ref isNormalized(), @ref Quaternion::angle(), - * @ref Vector::angle() + * @copybrief Math::angle(const Complex&, const Complex&) + * @deprecated Use @ref Math::angle(const Complex&, const Complex&) + * instead. */ - static Rad angle(const Complex& normalizedA, const Complex& normalizedB) { - CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), - "Math::Complex::angle(): complex numbers must be normalized", Rad(std::numeric_limits::quiet_NaN())); - return Rad(std::acos(normalizedA._real*normalizedB._real + normalizedA._imaginary*normalizedB._imaginary)); + CORRADE_DEPRECATED("use Math::angle() instead") static Rad angle(const Complex& normalizedA, const Complex& normalizedB) { + return Math::angle(normalizedA, normalizedB); } + #endif /** * @brief Rotation complex number @@ -136,8 +155,7 @@ template class Complex { * To be used in transformations later. @f[ * c = v_x + iv_y * @f] - * @see operator Vector2(), @ref transformVector() - * @todoc Explicit reference when Doxygen can handle conversion operators + * @see @ref operator Vector2(), @ref transformVector() */ constexpr explicit Complex(const Vector2& vector): _real(vector.x()), _imaginary(vector.y()) {} @@ -335,12 +353,10 @@ template class Complex { * @f] * @see @ref dot(const Complex&, const Complex&), @ref isNormalized() */ - T dot() const { - return dot(*this, *this); - } + T dot() const { return Math::dot(*this, *this); } /** - * @brief %Complex number length + * @brief Complex number length * * See also @ref dot() const which is faster for comparing length with * other values. @f[ @@ -400,8 +416,7 @@ template class Complex { */ Complex invertedNormalized() const { CORRADE_ASSERT(isNormalized(), - "Math::Complex::invertedNormalized(): complex number must be normalized", - Complex(std::numeric_limits::quiet_NaN(), {})); + "Math::Complex::invertedNormalized(): complex number must be normalized", {}); return conjugated(); } @@ -411,9 +426,8 @@ template class Complex { * @f[ * v' = c v = c (v_x + iv_y) * @f] - * @see @ref Complex(const Vector2&), operator Vector2(), + * @see @ref Complex(const Vector2&), @ref operator Vector2(), * @ref Matrix3::transformVector() - * @todoc Explicit reference when Doxygen can handle conversion operators */ Vector2 transformVector(const Vector2& vector) const { return Vector2((*this)*Complex(vector)); diff --git a/src/Magnum/Math/Constants.h b/src/Magnum/Math/Constants.h index fc14397f6..a3f7670f6 100644 --- a/src/Magnum/Math/Constants.h +++ b/src/Magnum/Math/Constants.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,6 +29,13 @@ * @brief Class @ref Magnum::Math::Constants */ +#include + +#include "Magnum/configure.h" +#ifndef MAGNUM_TARGET_GLES +#include +#endif + #include "Magnum/Types.h" namespace Magnum { namespace Math { @@ -37,6 +44,7 @@ namespace Magnum { namespace Math { @brief Numeric constants @see @ref Magnum::Constants, @ref Magnum::Constantsd +@todo Invent a way to generate double NaN/infinity without including whole limits header */ template struct Constants { Constants() = delete; @@ -46,12 +54,31 @@ template struct Constants { /** * @brief Pi * - * @see @ref Deg, @ref Rad + * @see @ref piHalf(), @ref tau(), @ref Deg, @ref Rad */ static constexpr T pi(); - static constexpr T sqrt2(); /**< @brief Square root of 2 */ - static constexpr T sqrt3(); /**< @brief Square root of 3 */ + /** + * @brief Half pi + * + * @see @ref pi(), @ref tau(), @ref Deg, @ref Rad + */ + static constexpr T piHalf(); + + /** + * @brief Tau + * + * Or two pi. + * @see @ref pi(), @ref piHalf(), @ref Deg, @ref Rad + */ + static constexpr T tau(); + + static constexpr T e(); /**< @brief Euler's number */ + static constexpr T sqrt2(); /**< @brief Square root of 2 */ + static constexpr T sqrt3(); /**< @brief Square root of 3 */ + + static constexpr T nan(); /**< @brief Quiet NaN */ + static constexpr T inf(); /**< @brief Positive infinity */ #endif }; @@ -60,17 +87,29 @@ template struct Constants { template<> struct Constants { Constants() = delete; - static constexpr Double pi() { return 3.141592653589793; } - static constexpr Double sqrt2() { return 1.414213562373095; } - static constexpr Double sqrt3() { return 1.732050807568877; } + static constexpr Double pi() { return 3.141592653589793; } + static constexpr Double piHalf() { return 1.570796326794897; } + static constexpr Double tau() { return 6.283185307179586; } + static constexpr Double e() { return 2.718281828459045; } + static constexpr Double sqrt2() { return 1.414213562373095; } + static constexpr Double sqrt3() { return 1.732050807568877; } + + static constexpr Double nan() { return std::numeric_limits::quiet_NaN(); } + static constexpr Double inf() { return std::numeric_limits::infinity(); } }; #endif template<> struct Constants { Constants() = delete; - static constexpr Float pi() { return 3.141592654f; } - static constexpr Float sqrt2() { return 1.414213562f; } - static constexpr Float sqrt3() { return 1.732050808f; } + static constexpr Float pi() { return 3.141592654f; } + static constexpr Float piHalf() { return 1.570796327f; } + static constexpr Float tau() { return 6.283185307f; } + static constexpr Float e() { return 2.718281828f; } + static constexpr Float sqrt2() { return 1.414213562f; } + static constexpr Float sqrt3() { return 1.732050808f; } + + static constexpr Float nan() { return NAN; } + static constexpr Float inf() { return INFINITY; } }; #endif diff --git a/src/Magnum/Math/Dual.h b/src/Magnum/Math/Dual.h index 7d5533353..ae86d28eb 100644 --- a/src/Magnum/Math/Dual.h +++ b/src/Magnum/Math/Dual.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,7 +37,7 @@ namespace Magnum { namespace Math { /** -@brief %Dual number +@brief Dual number @tparam T Underlying data type */ template class Dual { @@ -76,7 +76,7 @@ template class Dual { /** @brief Real part */ constexpr T real() const { return _real; } - /** @brief %Dual part */ + /** @brief Dual part */ constexpr T dual() const { return _dual; } /** diff --git a/src/Magnum/Math/DualComplex.h b/src/Magnum/Math/DualComplex.h index 01e1436e6..142d772d0 100644 --- a/src/Magnum/Math/DualComplex.h +++ b/src/Magnum/Math/DualComplex.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,7 @@ namespace Magnum { namespace Math { /** -@brief %Dual complex number +@brief Dual complex number @tparam T Underlying data type Represents 2D rotation and translation. See @ref transformations for brief @@ -71,11 +71,9 @@ template class DualComplex: public Dual> { * @f[ * \hat c = (0 + i1) + \epsilon (v_x + iv_y) * @f] - * @see translation() const, - * @ref Matrix3::translation(const Vector2&), + * @see @ref translation() const, @ref Matrix3::translation(const Vector2&), * @ref DualQuaternion::translation(), @ref Vector2::xAxis(), * @ref Vector2::yAxis() - * @todoc Explicit reference when Doxygen can handle const */ static DualComplex translation(const Vector2& vector) { return {{}, {vector.x(), vector.y()}}; @@ -227,7 +225,7 @@ template class DualComplex: public Dual> { } /** - * @brief %Complex number length squared + * @brief Complex number length squared * * Should be used instead of length() for comparing complex number * length with other values, because it doesn't compute the square root. @f[ @@ -240,7 +238,7 @@ template class DualComplex: public Dual> { } /** - * @brief %Dual quaternion length + * @brief Dual quaternion length * * See lengthSquared() which is faster for comparing length with other * values. @f[ diff --git a/src/Magnum/Math/DualQuaternion.h b/src/Magnum/Math/DualQuaternion.h index 4803a0c6d..694e080e1 100644 --- a/src/Magnum/Math/DualQuaternion.h +++ b/src/Magnum/Math/DualQuaternion.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,7 @@ namespace Magnum { namespace Math { /** -@brief %Dual quaternion +@brief Dual quaternion @tparam T Underlying data type Represents 3D rotation and translation. See @ref transformations for brief @@ -56,11 +56,10 @@ template class DualQuaternion: public Dual> { * Expects that the rotation axis is normalized. @f[ * \hat q = [\boldsymbol a \cdot sin \frac \theta 2, cos \frac \theta 2] + \epsilon [\boldsymbol 0, 0] * @f] - * @see rotation() const, @ref Quaternion::rotation(), + * @see @ref rotation() const, @ref Quaternion::rotation(), * @ref Matrix4::rotation(), @ref DualComplex::rotation(), * @ref Vector3::xAxis(), @ref Vector3::yAxis(), * @ref Vector3::zAxis(), @ref Vector::isNormalized() - * @todoc Explicit reference when Doxygen can handle const */ static DualQuaternion rotation(Rad angle, const Vector3& normalizedAxis) { return {Quaternion::rotation(angle, normalizedAxis), {{}, T(0)}}; @@ -75,11 +74,10 @@ template class DualQuaternion: public Dual> { * @f[ * \hat q = [\boldsymbol 0, 1] + \epsilon [\frac{\boldsymbol v}{2}, 0] * @f] - * @see translation() const, + * @see @ref translation() const, * @ref Matrix4::translation(const Vector3&), * @ref DualComplex::translation(), @ref Vector3::xAxis(), * @ref Vector3::yAxis(), @ref Vector3::zAxis() - * @todoc Explicit reference when Doxygen can handle const */ static DualQuaternion translation(const Vector3& vector) { return {{}, {vector/T(2), T(0)}}; @@ -226,7 +224,7 @@ template class DualQuaternion: public Dual> { } /** - * @brief %Dual quaternion length squared + * @brief Dual quaternion length squared * * Should be used instead of @ref length() for comparing dual * quaternion length with other values, because it doesn't compute the @@ -235,11 +233,11 @@ template class DualQuaternion: public Dual> { * @f] */ Dual lengthSquared() const { - return {Dual>::real().dot(), T(2)*Quaternion::dot(Dual>::real(), Dual>::dual())}; + return {Dual>::real().dot(), T(2)*dot(Dual>::real(), Dual>::dual())}; } /** - * @brief %Dual quaternion length + * @brief Dual quaternion length * * See @ref lengthSquared() which is faster for comparing length with other * values. @f[ @@ -316,8 +314,7 @@ template class DualQuaternion: public Dual> { */ Vector3 transformPointNormalized(const Vector3& vector) const { CORRADE_ASSERT(isNormalized(), - "Math::DualQuaternion::transformPointNormalized(): dual quaternion must be normalized", - Vector3(std::numeric_limits::quiet_NaN())); + "Math::DualQuaternion::transformPointNormalized(): dual quaternion must be normalized", {}); return ((*this)*DualQuaternion(vector)*conjugated()).dual().vector(); } diff --git a/src/Magnum/Math/Functions.cpp b/src/Magnum/Math/Functions.cpp index 159eed792..ec4179b34 100644 --- a/src/Magnum/Math/Functions.cpp +++ b/src/Magnum/Math/Functions.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Math/Functions.h b/src/Magnum/Math/Functions.h index 8e62c2f96..12e867daa 100644 --- a/src/Magnum/Math/Functions.h +++ b/src/Magnum/Math/Functions.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -80,6 +80,26 @@ UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number); */ UnsignedInt MAGNUM_EXPORT log(UnsignedInt base, UnsignedInt number); +/** +@brief Integer division with remainder + +Example usage: +@code +Int quotient, remainder; +std::tie(quotient, remainder) = Math::div(57, 6); // {9, 3} +@endcode +Equivalent to the following, but possibly done in a single CPU instruction: +@code +Int quotient = 57/6; +Int remainder = 57%6; +@endcode +*/ +template std::pair div(Integral x, Integral y) { + static_assert(std::is_integral{}, "Math::div(): not an integral type"); + const auto result = std::div(x, y); + return {result.quot, result.rem}; +} + /** @todo Can't trigonometric functions be done with only one overload? */ /** @brief Sine */ @@ -126,18 +146,19 @@ perform the operations component-wise. /** @brief Minimum +NaNs passed in @p value parameter are propagated. @see @ref max(), @ref minmax(), @ref clamp(), @ref Vector::min() */ #ifdef DOXYGEN_GENERATING_OUTPUT -template inline T min(T a, T b); +template inline T min(T value, T min); #else -template inline typename std::enable_if::value, T>::type min(T a, T b) { - return std::min(a, b); +template inline typename std::enable_if::value, T>::type min(T value, T min) { + return std::min(value, min); } -template inline Vector min(const Vector& a, const Vector& b) { +template inline Vector min(const Vector& value, const Vector& min) { Vector out; for(std::size_t i = 0; i != size; ++i) - out[i] = std::min(a[i], b[i]); + out[i] = std::min(value[i], min[i]); return out; } #endif @@ -153,18 +174,19 @@ template inline T min(std::initializer_list list) { /** @brief Maximum +NaNs passed in @p value parameter are propagated. @see @ref min(), @ref minmax(), @ref clamp(), @ref Vector::max() */ #ifdef DOXYGEN_GENERATING_OUTPUT -template inline T max(const T& a, const T& b); +template inline T max(T value, T max); #else -template inline typename std::enable_if::value, T>::type max(T a, T b) { - return std::max(a, b); +template inline typename std::enable_if::value, T>::type max(T value, T max) { + return std::max(value, max); } -template Vector max(const Vector& a, const Vector& b) { +template Vector max(const Vector& value, const Vector& max) { Vector out; for(std::size_t i = 0; i != size; ++i) - out[i] = std::max(a[i], b[i]); + out[i] = std::max(value[i], max[i]); return out; } #endif @@ -189,9 +211,35 @@ template inline typename std::enable_if::value, s return a < b ? std::make_pair(a, b) : std::make_pair(b, a); } template std::pair, Vector> minmax(const Vector& a, const Vector& b) { + using std::swap; std::pair, Vector> out{a, b}; for(std::size_t i = 0; i != size; ++i) - if(out.first[i] > out.second[i]) std::swap(out.first[i], out.second[i]); + if(out.first[i] > out.second[i]) swap(out.first[i], out.second[i]); + return out; +} +#endif + +/** +@brief Clamp value + +Values smaller than @p min are set to @p min, values larger than @p max are +set to @p max. Equivalent to: +@code +Math::min(Math::max(value, min), max) +@endcode +NaNs passed in @p value parameter are propagated. +@see @ref min(), @ref max() +*/ +#ifdef DOXYGEN_GENERATING_OUTPUT +template inline T clamp(const T& value, U min, U max); +#else +template inline typename std::enable_if::value, T>::type clamp(T value, T min, T max) { + return std::min(std::max(value, min), max); +} +template Vector clamp(const Vector& value, T min, T max) { + Vector out; + for(std::size_t i = 0; i != size; ++i) + out[i] = clamp(value[i], min, max); return out; } #endif @@ -322,27 +370,6 @@ template Vector sqrtInverted(const Vector inline T clamp(const T& value, U min, U max); -#else -template inline typename std::enable_if::value, T>::type clamp(T value, T min, T max) { - return std::min(std::max(value, min), max); -} -template Vector clamp(const Vector& value, T min, T max) { - Vector out; - for(std::size_t i = 0; i != size; ++i) - out[i] = clamp(value[i], min, max); - return out; -} -#endif - /** @brief Linear interpolation of two values @param a First value @@ -352,9 +379,7 @@ template Vector clamp(const Vector& The interpolation for vectors is done as in following, similarly for scalars: @f[ \boldsymbol v_{LERP} = (1 - t) \boldsymbol v_A + t \boldsymbol v_B @f] -@see @ref lerpInverted(), @ref Quaternion::lerp() -@todo http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ - (when SIMD is in place) +@see @ref lerpInverted(), @ref lerp(const Quaternion&, const Quaternion&, T) */ #ifdef DOXYGEN_GENERATING_OUTPUT template inline T lerp(const T& a, const T& b, U t); @@ -426,10 +451,10 @@ value in range @f$ [0, 1] @f$ or from *signed* integral to range @f$ [-1, 1] @f$ explicit, e.g.: @code // Literal type is (signed) char, but we assumed unsigned char, a != 1.0f -Float a = normalize('\xFF'); +Float a = Math::normalize('\xFF'); // b = 1.0f -Float b = normalize('\xFF'); +Float b = Math::normalize('\xFF'); @endcode @see @ref denormalize() diff --git a/src/Magnum/Math/Geometry/CMakeLists.txt b/src/Magnum/Math/Geometry/CMakeLists.txt index ac7fb7ff8..48f1d49c7 100644 --- a/src/Magnum/Math/Geometry/CMakeLists.txt +++ b/src/Magnum/Math/Geometry/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -27,12 +27,6 @@ set(MagnumMathGeometry_HEADERS Distance.h Intersection.h) -# Deprecated headers -if(BUILD_DEPRECATED) - set(MagnumMathGeometry_HEADERS ${MagnumMathGeometry_HEADERS} - Rectangle.h) -endif() - # Force IDEs to display all header files in project view add_custom_target(MagnumMathGeometry SOURCES ${MagnumMathGeometry_HEADERS}) diff --git a/src/Magnum/Math/Geometry/Distance.h b/src/Magnum/Math/Geometry/Distance.h index 26dee4b2d..7c514990b 100644 --- a/src/Magnum/Math/Geometry/Distance.h +++ b/src/Magnum/Math/Geometry/Distance.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,13 +40,13 @@ class Distance { Distance() = delete; /** - * @brief %Distance of line and point in 2D + * @brief Distance of line and point in 2D * @param a First point of the line * @param b Second point of the line * @param point Point * * The distance *d* is computed from point **p** and line defined by **a** - * and **b** using @ref Vector2::cross() "perp-dot product": @f[ + * and **b** using @ref cross(const Vector2&, const Vector2&) "perp-dot product": @f[ * d = \frac{|(\boldsymbol b - \boldsymbol a)_\bot \cdot (\boldsymbol a - \boldsymbol p)|} {|\boldsymbol b - \boldsymbol a|} * @f] * Source: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html @@ -54,11 +54,11 @@ class Distance { */ template static T linePoint(const Vector2& a, const Vector2& b, const Vector2& point) { const Vector2 bMinusA = b - a; - return std::abs(Vector2::cross(bMinusA, a - point))/bMinusA.length(); + return std::abs(cross(bMinusA, a - point))/bMinusA.length(); } /** - * @brief %Distance of line and point in 2D, squared + * @brief Distance of line and point in 2D, squared * @param a First point of the line * @param b Second point of the line * @param point Point @@ -70,17 +70,17 @@ class Distance { */ template static T linePointSquared(const Vector2& a, const Vector2& b, const Vector2& point) { const Vector2 bMinusA = b - a; - return Math::pow<2>(Vector2::cross(bMinusA, a - point))/bMinusA.dot(); + return Math::pow<2>(cross(bMinusA, a - point))/bMinusA.dot(); } /** - * @brief %Distance of line and point in 3D + * @brief Distance of line and point in 3D * @param a First point of the line * @param b Second point of the line * @param point Point * * The distance *d* is computed from point **p** and line defined by **a** - * and **b** using @ref Vector3::cross() "cross product": @f[ + * and **b** using @ref cross(const Vector3&, const Vector3&) "cross product": @f[ * d = \frac{|(\boldsymbol p - \boldsymbol a) \times (\boldsymbol p - \boldsymbol b)|} * {|\boldsymbol b - \boldsymbol a|} * @f] @@ -92,18 +92,18 @@ class Distance { } /** - * @brief %Distance of line and point in 3D, squared + * @brief Distance of line and point in 3D, squared * * More efficient than @ref linePoint(const Vector3&, const Vector3&, const Vector3&) * for comparing distance with other values, because it doesn't * compute the square root. */ template static T linePointSquared(const Vector3& a, const Vector3& b, const Vector3& point) { - return Vector3::cross(point - a, point - b).dot()/(b - a).dot(); + return cross(point - a, point - b).dot()/(b - a).dot(); } /** - * @brief %Dístance of point from line segment in 2D + * @brief Dístance of point from line segment in 2D * @param a Starting point of the line * @param b Ending point of the line * @param point Point @@ -131,7 +131,7 @@ class Distance { template static T lineSegmentPoint(const Vector2& a, const Vector2& b, const Vector2& point); /** - * @brief %Distance of point from line segment in 2D, squared + * @brief Distance of point from line segment in 2D, squared * * More efficient than @ref lineSegmentPoint() for comparing distance * with other values, because it doesn't compute the square root. @@ -139,7 +139,7 @@ class Distance { template static T lineSegmentPointSquared(const Vector2& a, const Vector2& b, const Vector2& point); /** - * @brief %Dístance of point from line segment in 3D + * @brief Dístance of point from line segment in 3D * @param a Starting point of the line * @param b Ending point of the line * @param point Point @@ -154,7 +154,7 @@ class Distance { } /** - * @brief %Distance of point from line segment in 3D, squared + * @brief Distance of point from line segment in 3D, squared * * More efficient than * @ref lineSegmentPoint(const Vector3&, const Vector3&, const Vector3&) @@ -181,7 +181,7 @@ template T Distance::lineSegmentPoint(const Vector2& a, const Vector return std::sqrt(pointDistanceB); /* Between A and B */ - return std::abs(Vector2::cross(bMinusA, -pointMinusA))/std::sqrt(bDistanceA); + return std::abs(cross(bMinusA, -pointMinusA))/std::sqrt(bDistanceA); } template T Distance::lineSegmentPointSquared(const Vector2& a, const Vector2& b, const Vector2& point) { @@ -201,7 +201,7 @@ template T Distance::lineSegmentPointSquared(const Vector2& a, const return pointDistanceB; /* Between A and B */ - return Math::pow<2>(Vector2::cross(bMinusA, -pointMinusA))/bDistanceA; + return Math::pow<2>(cross(bMinusA, -pointMinusA))/bDistanceA; } template T Distance::lineSegmentPointSquared(const Vector3& a, const Vector3& b, const Vector3& point) { @@ -220,7 +220,7 @@ template T Distance::lineSegmentPointSquared(const Vector3& a, const return pointDistanceB; /* Between A and B */ - return Vector3::cross(pointMinusA, pointMinusB).dot()/bDistanceA; + return cross(pointMinusA, pointMinusB).dot()/bDistanceA; } }}} diff --git a/src/Magnum/Math/Geometry/Intersection.h b/src/Magnum/Math/Geometry/Intersection.h index fc06ec9cd..78ba97b9c 100644 --- a/src/Magnum/Math/Geometry/Intersection.h +++ b/src/Magnum/Math/Geometry/Intersection.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,14 +39,14 @@ class Intersection { Intersection() = delete; /** - * @brief %Intersection of two line segments in 2D + * @brief Intersection of two line segments in 2D * @param p Starting point of first line segment * @param r Direction of first line segment * @param q Starting point of second line segment * @param s Direction of second line segment - * @return %Intersection point positions `t`, `u` on both lines, NaN if + * @return Intersection point positions `t`, `u` on both lines, NaN if * the lines are collinear or infinity if they are parallel. - * %Intersection point can be then computed with `p + t*r` or + * Intersection point can be then computed with `p + t*r` or * `q + u*s`. If `t` is in range @f$ [ 0 ; 1 ] @f$, the * intersection is inside the line segment defined by `p` and * `p + r`, if `u` is in range @f$ [ 0 ; 1 ] @f$, the intersection @@ -72,38 +72,37 @@ class Intersection { */ template static std::pair lineSegmentLineSegment(const Vector2& p, const Vector2& r, const Vector2& q, const Vector2& s) { const Vector2 qp = q - p; - const T rs = Vector2::cross(r, s); - return {Vector2::cross(qp, s)/rs, - Vector2::cross(qp, r)/rs}; + const T rs = cross(r, s); + return {cross(qp, s)/rs, cross(qp, r)/rs}; } /** - * @brief %Intersection of line segment and line in 2D + * @brief Intersection of line segment and line in 2D * @param p Starting point of first line segment * @param r Direction of first line segment * @param q Starting point of second line * @param s Direction of second line - * @return %Intersection point position `t` on first line, NaN if the + * @return Intersection point position `t` on first line, NaN if the * lines are collinear or infinity if they are parallel. - * %Intersection point can be then with `p + t*r`. If returned + * Intersection point can be then with `p + t*r`. If returned * value is in range @f$ [ 0 ; 1 ] @f$, the intersection is inside * the line segment defined by `p` and `p + r`. * * Unlike @ref lineSegmentLineSegment() computes only **t**. */ template static T lineSegmentLine(const Vector2& p, const Vector2& r, const Vector2& q, const Vector2& s) { - return Vector2::cross(q - p, s)/Vector2::cross(r, s); + return cross(q - p, s)/cross(r, s); } /** - * @brief %Intersection of a plane and line + * @brief Intersection of a plane and line * @param planePosition Plane position * @param planeNormal Plane normal * @param p Starting point of the line * @param r Direction of the line - * @return %Intersection point position `t` on the line, NaN if the + * @return Intersection point position `t` on the line, NaN if the * line lies on the plane or infinity if the intersection doesn't - * exist. %Intersection point can be then computed from with + * exist. Intersection point can be then computed from with * `p + t*r`. If returned value is in range @f$ [ 0 ; 1 ] @f$, the * intersection is inside the line segment defined by `p` and `r`. * @@ -121,8 +120,8 @@ class Intersection { * @f] */ template static T planeLine(const Vector3& planePosition, const Vector3& planeNormal, const Vector3& p, const Vector3& r) { - const T f = Vector3::dot(planePosition, planeNormal); - return (f-Vector3::dot(planeNormal, p))/Vector3::dot(planeNormal, r); + const T f = dot(planePosition, planeNormal); + return (f-dot(planeNormal, p))/dot(planeNormal, r); } }; diff --git a/src/Magnum/Math/Geometry/Rectangle.h b/src/Magnum/Math/Geometry/Rectangle.h deleted file mode 100644 index 0f0c99f67..000000000 --- a/src/Magnum/Math/Geometry/Rectangle.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef Magnum_Math_Geometry_Rectangle_h -#define Magnum_Math_Geometry_Rectangle_h -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013, 2014 - Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -/** @file - * @brief Class @ref Magnum::Math::Geometry::Rectangle - * @deprecated Use @ref Magnum/Math/Range.h instead. - */ - -#include "Magnum/Math/Range.h" - -#ifdef MAGNUM_BUILD_DEPRECATED -#include - -namespace Magnum { namespace Math { namespace Geometry { - -/** -@copybrief Math::Range2D -@deprecated Use @ref Magnum::Math::Range2D "Math::Range2D" instead. -*/ -template class CORRADE_DEPRECATED("use Math::Range2D instead") Rectangle: public Range2D { - public: - /** @copydoc Range2D() */ - constexpr Rectangle() = default; - - /** @copydoc Range2D(const VectorType&, const VectorType&) */ - constexpr Rectangle(const Vector2& min, const Vector2& max): Range2D(min, max) {} - - /** @copydoc Range2D(const Range&) */ - constexpr Rectangle(const Range<2, T>& other): Range2D(other) {} - - /** @copydoc Range2D(const Range&) */ - template constexpr explicit Rectangle(const Range2D& other): Range2D(other) {} - - /** @copydoc Range2D::sizeX() */ - T width() const { return Range2D::sizeX(); } - - /** @copydoc Range2D::sizeY() */ - T height() const { return Range2D::sizeY(); } -}; - -}}} - -namespace Corrade { namespace Utility { - /** @configurationvalue{Magnum::Math::Geometry::Rectangle} */ - template struct ConfigurationValue>: public ConfigurationValue> {}; -}} -#else -#error use Magnum/Math/Range.h instead -#endif - -#endif diff --git a/src/Magnum/Math/Geometry/Test/CMakeLists.txt b/src/Magnum/Math/Geometry/Test/CMakeLists.txt index 65e4ddda1..913b8624f 100644 --- a/src/Magnum/Math/Geometry/Test/CMakeLists.txt +++ b/src/Magnum/Math/Geometry/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Math/Geometry/Test/DistanceTest.cpp b/src/Magnum/Math/Geometry/Test/DistanceTest.cpp index d4c8ded1f..002d6ad88 100644 --- a/src/Magnum/Math/Geometry/Test/DistanceTest.cpp +++ b/src/Magnum/Math/Geometry/Test/DistanceTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,7 +23,6 @@ DEALINGS IN THE SOFTWARE. */ -#include #include #include "Magnum/Math/Constants.h" @@ -31,14 +30,13 @@ namespace Magnum { namespace Math { namespace Geometry { namespace Test { -class DistanceTest: public Corrade::TestSuite::Tester { - public: - DistanceTest(); +struct DistanceTest: Corrade::TestSuite::Tester { + explicit DistanceTest(); - void linePoint2D(); - void linePoint3D(); - void lineSegmentPoint2D(); - void lineSegmentPoint3D(); + void linePoint2D(); + void linePoint3D(); + void lineSegmentPoint2D(); + void lineSegmentPoint3D(); }; typedef Math::Vector2 Vector2; diff --git a/src/Magnum/Math/Geometry/Test/IntersectionTest.cpp b/src/Magnum/Math/Geometry/Test/IntersectionTest.cpp index 00734c5c2..07b7d82f9 100644 --- a/src/Magnum/Math/Geometry/Test/IntersectionTest.cpp +++ b/src/Magnum/Math/Geometry/Test/IntersectionTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,23 +23,22 @@ DEALINGS IN THE SOFTWARE. */ -#include #include #include "Magnum/Math/Geometry/Intersection.h" namespace Magnum { namespace Math { namespace Geometry { namespace Test { -class IntersectionTest: public Corrade::TestSuite::Tester { - public: - IntersectionTest(); +struct IntersectionTest: Corrade::TestSuite::Tester { + explicit IntersectionTest(); - void planeLine(); - void lineLine(); + void planeLine(); + void lineLine(); }; typedef Math::Vector2 Vector2; typedef Math::Vector3 Vector3; +typedef Math::Constants Constants; IntersectionTest::IntersectionTest() { addTests({&IntersectionTest::planeLine, @@ -60,11 +59,11 @@ void IntersectionTest::planeLine() { /* Line lies on the plane */ CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, - Vector3{1.0f, 0.5f, 0.5f}, Vector3{-1.0f, 0.5f, 0.0f}), std::numeric_limits::quiet_NaN()); + Vector3{1.0f, 0.5f, 0.5f}, Vector3{-1.0f, 0.5f, 0.0f}), Constants::nan()); /* Line is parallel to the plane */ CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, - Vector3{1.0f, 0.0f, 1.0f}, Vector3{-1.0f, 0.0f, 0.0f}), -std::numeric_limits::infinity()); + Vector3{1.0f, 0.0f, 1.0f}, Vector3{-1.0f, 0.0f, 0.0f}), -Constants::inf()); } void IntersectionTest::lineLine() { @@ -86,17 +85,16 @@ void IntersectionTest::lineLine() { /* Collinear lines */ const auto tu = Intersection::lineSegmentLineSegment(p, r, Vector2{0.0f, 1.0f}, Vector2{-1.0f, -2.0f}); - CORRADE_COMPARE(tu.first, -std::numeric_limits::quiet_NaN()); - CORRADE_COMPARE(tu.second, -std::numeric_limits::quiet_NaN()); + CORRADE_COMPARE(tu.first, -Constants::nan()); + CORRADE_COMPARE(tu.second, -Constants::nan()); CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, - Vector2{0.0f, 1.0f}, Vector2{-1.0f, -2.0f}), -std::numeric_limits::quiet_NaN()); + Vector2{0.0f, 1.0f}, Vector2{-1.0f, -2.0f}), -Constants::nan()); /* Parallel lines */ CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r, - Vector2{0.0f, 0.0f}, Vector2{1.0f, 2.0f}), std::make_pair(std::numeric_limits::infinity(), - std::numeric_limits::infinity())); + Vector2{0.0f, 0.0f}, Vector2{1.0f, 2.0f}), std::make_pair(Constants::inf(), Constants::inf())); CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, - Vector2{0.0f, 0.0f}, Vector2{1.0f, 2.0f}), std::numeric_limits::infinity()); + Vector2{0.0f, 0.0f}, Vector2{1.0f, 2.0f}), Constants::inf()); } }}}} diff --git a/src/Magnum/Math/Math.h b/src/Magnum/Math/Math.h index a9acb5c95..b6a86e38e 100644 --- a/src/Magnum/Math/Math.h +++ b/src/Magnum/Math/Math.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,6 +38,7 @@ namespace Magnum { namespace Math { /** @todo Denormals to zero */ +#ifndef DOXYGEN_GENERATING_OUTPUT /* Class Constants used only statically */ template class Complex; @@ -82,11 +83,6 @@ template using Range1D = Range<1, T>; #endif template class Range2D; template class Range3D; - -#ifdef MAGNUM_BUILD_DEPRECATED -namespace Geometry { - template class Rectangle; -} #endif }} diff --git a/src/Magnum/Math/Matrix.h b/src/Magnum/Math/Matrix.h index b8cafb357..abdec30de 100644 --- a/src/Magnum/Math/Matrix.h +++ b/src/Magnum/Math/Matrix.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,7 +39,7 @@ namespace Implementation { /** @brief Square matrix -@tparam size %Matrix size +@tparam size Matrix size @tparam T Data type See @ref matrix-vector for brief introduction. @@ -49,7 +49,7 @@ See @ref matrix-vector for brief introduction. */ template class Matrix: public RectangularMatrix { public: - const static std::size_t Size = size; /**< @brief %Matrix size */ + const static std::size_t Size = size; /**< @brief Matrix size */ /** @brief Pass to constructor to create zero-filled matrix */ enum ZeroType { Zero }; @@ -57,7 +57,7 @@ template class Matrix: public RectangularMatrix class Matrix: public RectangularMatrix(typename Implementation::GenerateSequence::Type(), @@ -81,7 +81,7 @@ template class Matrix: public RectangularMatrix class Matrix: public RectangularMatrix::diagonal().sum(); } - /** @brief %Matrix without given column and row */ + /** @brief Matrix without given column and row */ Matrix ij(std::size_t skipCol, std::size_t skipRow) const; /** @@ -196,7 +196,7 @@ template class Matrix: public RectangularMatrix%Matrix<2, T>. See @ref Matrix for more +Convenience alternative to `Matrix<2, T>`. See @ref Matrix for more information. @note Not available on GCC < 4.7. Use %Matrix<2, T> instead. @see @ref Magnum::Matrix2x2, @ref Magnum::Matrix2x2d @@ -208,7 +208,7 @@ template using Matrix2x2 = Matrix<2, T>; /** @brief 3x3 matrix -Convenience alternative to %Matrix<3, T>. See @ref Matrix for more +Convenience alternative to `Matrix<3, T>`. See @ref Matrix for more information. Note that this is different from @ref Matrix3, which contains additional functions for transformations in 2D. @note Not available on GCC < 4.7. Use %Matrix<3, T> instead. @@ -221,7 +221,7 @@ template using Matrix3x3 = Matrix<3, T>; /** @brief 4x4 matrix -Convenience alternative to %Matrix<4, T>. See @ref Matrix for more +Convenience alternative to `Matrix<4, T>`. See @ref Matrix for more information. Note that this is different from @ref Matrix4, which contains additional functions for transformations in 3D. @note Not available on GCC < 4.7. Use %Matrix<3, T> instead. @@ -306,7 +306,7 @@ template bool Matrix::isOrthogonal() const { /* Orthogonality */ for(std::size_t i = 0; i != size-1; ++i) for(std::size_t j = i+1; j != size; ++j) - if(Vector::dot((*this)[i], (*this)[j]) > TypeTraits::epsilon()) + if(dot((*this)[i], (*this)[j]) > TypeTraits::epsilon()) return false; return true; diff --git a/src/Magnum/Math/Matrix3.h b/src/Magnum/Math/Matrix3.h index 46e1c046f..1e94aa9cc 100644 --- a/src/Magnum/Math/Matrix3.h +++ b/src/Magnum/Math/Matrix3.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -49,10 +49,9 @@ template class Matrix3: public Matrix<3, T> { * @brief 2D translation matrix * @param vector Translation vector * - * @see translation() const, @ref DualComplex::translation(), + * @see @ref translation() const, @ref DualComplex::translation(), * @ref Matrix4::translation(const Vector3&), * @ref Vector2::xAxis(), @ref Vector2::yAxis() - * @todoc Explicit reference when Doxygen can handle const */ constexpr static Matrix3 translation(const Vector2& vector) { return {{ T(1), T(0), T(0)}, @@ -78,10 +77,9 @@ template class Matrix3: public Matrix<3, T> { * @brief 2D rotation matrix * @param angle Rotation angle (counterclockwise) * - * @see rotation() const, @ref Complex::rotation(), + * @see @ref rotation() const, @ref Complex::rotation(), * @ref DualComplex::rotation(), * @ref Matrix4::rotation(Rad, const Vector3&) - * @todoc Explicit reference when Doxygen can handle const */ static Matrix3 rotation(Rad angle); @@ -89,7 +87,10 @@ template class Matrix3: public Matrix<3, T> { * @brief 2D reflection matrix * @param normal Normal of the line through which to reflect * - * Expects that the normal is normalized. + * Expects that the normal is normalized. Reflection along axes can be + * done in a slightly simpler way also using @ref scaling(), e.g. + * `Matrix3::reflection(Vector2::yAxis())` is equivalent to + * `Matrix3::scaling(Vector2::yScale(-1.0f))`. * @see @ref Matrix4::reflection(), @ref Vector::isNormalized() */ static Matrix3 reflection(const Vector2& normal) { @@ -98,6 +99,34 @@ template class Matrix3: public Matrix<3, T> { return from(Matrix<2, T>() - T(2)*normal*RectangularMatrix<1, 2, T>(normal).transposed(), {}); } + /** + * @brief 2D shearing matrix along X axis + * @param amount Shearing amount + * + * Y axis remains unchanged. + * @see @ref shearingY(), @ref Matrix4::shearingXY(), + * @ref Matrix4::shearingXZ(), @ref Matrix4::shearingYZ() + */ + constexpr static Matrix3 shearingX(T amount) { + return {{ T(1), T(0), T(0)}, + {amount, T(1), T(0)}, + { T(0), T(0), T(1)}}; + } + + /** + * @brief 2D shearing matrix along Y axis + * @param amount Shearing amount + * + * X axis remains unchanged. + * @see @ref shearingX(), @ref Matrix4::shearingXY(), + * @ref Matrix4::shearingXZ(), @ref Matrix4::shearingYZ() + */ + constexpr static Matrix3 shearingY(T amount) { + return {{T(1), amount, T(0)}, + {T(0), T(1), T(0)}, + {T(0), T(0), T(1)}}; + } + /** * @brief 2D projection matrix * @param size Size of the view @@ -116,8 +145,7 @@ template class Matrix3: public Matrix<3, T> { * @param translation Translation part (first two elements of * third column) * - * @see @ref rotationScaling(), translation() const - * @todoc Explicit reference when Doxygen can handle const + * @see @ref rotationScaling(), @ref translation() const */ constexpr static Matrix3 from(const Matrix<2, T>& rotationScaling, const Vector2& translation) { return {{rotationScaling[0], T(0)}, @@ -132,12 +160,12 @@ template class Matrix3: public Matrix<3, T> { * @brief Default constructor * * Creates identity matrix. You can also explicitly call this - * constructor with `%Matrix3 m(Matrix3::Identity);`. Optional + * constructor with `Matrix3 m(Matrix3::Identity);`. Optional * parameter @p value allows you to specify value on diagonal. */ constexpr /*implicit*/ Matrix3(typename Matrix<3, T>::IdentityType = (Matrix<3, T>::Identity), T value = T(1)): Matrix<3, T>(Matrix<3, T>::Identity, value) {} - /** @brief %Matrix from column vectors */ + /** @brief Matrix from column vectors */ constexpr /*implicit*/ Matrix3(const Vector3& first, const Vector3& second, const Vector3& third): Matrix<3, T>(first, second, third) {} /** @copydoc Matrix::Matrix(const RectangularMatrix&) */ @@ -169,10 +197,9 @@ template class Matrix3: public Matrix<3, T> { * * Upper-left 2x2 part of the matrix. * @see @ref from(const Matrix<2, T>&, const Vector2&), - * rotation() const, @ref rotationNormalized(), + * @ref rotation() const, @ref rotationNormalized(), * @ref uniformScaling(), @ref rotation(Rad), * @ref Matrix4::rotationScaling() - * @todoc Explicit reference when Doxygen can handle const */ constexpr Matrix<2, T> rotationScaling() const { return {(*this)[0].xy(), @@ -184,10 +211,9 @@ template class Matrix3: public Matrix<3, T> { * * Similar to @ref rotationScaling(), but additionally checks that the * base vectors are normalized. - * @see rotation() const, @ref uniformScaling(), + * @see @ref rotation() const, @ref uniformScaling(), * @ref Matrix4::rotationNormalized() * @todo assert also orthogonality or this is good enough? - * @todoc Explicit reference when Doxygen can handle const */ Matrix<2, T> rotationNormalized() const { CORRADE_ASSERT((*this)[0].xy().isNormalized() && (*this)[1].xy().isNormalized(), @@ -203,8 +229,7 @@ template class Matrix3: public Matrix<3, T> { * scaling. * @see @ref rotationNormalized(), @ref rotationScaling(), * @ref uniformScaling(), @ref rotation(Rad), - * Matrix4::rotation() const - * @todoc Explicit reference when Doxygen can handle const + * @ref Matrix4::rotation() const */ Matrix<2, T> rotation() const { CORRADE_ASSERT(TypeTraits::equals((*this)[0].xy().dot(), (*this)[1].xy().dot()), @@ -220,10 +245,9 @@ template class Matrix3: public Matrix<3, T> { * Expects that the scaling is the same in all axes. Faster alternative * to @ref uniformScaling(), because it doesn't compute the square * root. - * @see @ref rotationScaling(), rotation() const, + * @see @ref rotationScaling(), @ref rotation() const, * @ref rotationNormalized(), @ref scaling(const Vector2&), * @ref Matrix4::uniformScaling() - * @todoc Explicit reference when Doxygen can handle const */ T uniformScalingSquared() const { const T scalingSquared = (*this)[0].xy().dot(); @@ -238,10 +262,9 @@ template class Matrix3: public Matrix<3, T> { * Length of vectors in upper-left 2x2 part of the matrix. Expects that * the scaling is the same in all axes. Use faster alternative * @ref uniformScalingSquared() where possible. - * @see @ref rotationScaling(), rotation() const, + * @see @ref rotationScaling(), @ref rotation() const, * @ref rotationNormalized(), @ref scaling(const Vector2&), * @ref Matrix4::uniformScaling() - * @todoc Explicit reference when Doxygen can handle const */ T uniformScaling() const { return std::sqrt(uniformScalingSquared()); } @@ -284,9 +307,8 @@ template class Matrix3: public Matrix<3, T> { * @f$ A^{i, j} @f$ is matrix without i-th row and j-th column, see * @ref ij() * @see @ref isRigidTransformation(), @ref invertedOrthogonal(), - * @ref rotationScaling(), translation() const, + * @ref rotationScaling(), @ref translation() const, * @ref Matrix4::invertedRigid() - * @todoc Explicit reference when Doxygen can handle const */ Matrix3 invertedRigid() const; @@ -335,7 +357,9 @@ template class Matrix3: public Matrix<3, T> { MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(3, Matrix3, Vector3) }; +#ifndef DOXYGEN_GENERATING_OUTPUT MAGNUM_MATRIXn_OPERATOR_IMPLEMENTATION(3, Matrix3) +#endif /** @debugoperator{Magnum::Math::Matrix3} */ template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Matrix3& value) { diff --git a/src/Magnum/Math/Matrix4.h b/src/Magnum/Math/Matrix4.h index 37198accd..34e7e07ec 100644 --- a/src/Magnum/Math/Matrix4.h +++ b/src/Magnum/Math/Matrix4.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -90,11 +90,10 @@ template class Matrix4: public Matrix<4, T> { * Expects that the rotation axis is normalized. If possible, use * faster alternatives like @ref rotationX(), @ref rotationY() and * @ref rotationZ(). - * @see rotation() const, @ref Quaternion::rotation(), + * @see @ref rotation() const, @ref Quaternion::rotation(), * @ref DualQuaternion::rotation(), @ref Matrix3::rotation(Rad), * @ref Vector3::xAxis(), @ref Vector3::yAxis(), * @ref Vector3::zAxis(), @ref Vector::isNormalized() - * @todoc Explicit reference when Doxygen can handle const */ static Matrix4 rotation(Rad angle, const Vector3& normalizedAxis); @@ -102,11 +101,10 @@ template class Matrix4: public Matrix<4, T> { * @brief 3D rotation around X axis * @param angle Rotation angle (counterclockwise) * - * Faster than calling `%Matrix4::rotation(angle, %Vector3::xAxis())`. + * Faster than calling `Matrix4::rotation(angle, Vector3::xAxis())`. * @see @ref rotation(Rad, const Vector3&), @ref rotationY(), - * @ref rotationZ(), rotation() const, + * @ref rotationZ(), @ref rotation() const, * @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad) - * @todoc Explicit reference when Doxygen can handle const */ static Matrix4 rotationX(Rad angle); @@ -114,11 +112,10 @@ template class Matrix4: public Matrix<4, T> { * @brief 3D rotation around Y axis * @param angle Rotation angle (counterclockwise) * - * Faster than calling `%Matrix4::rotation(angle, %Vector3::yAxis())`. + * Faster than calling `Matrix4::rotation(angle, Vector3::yAxis())`. * @see @ref rotation(Rad, const Vector3&), @ref rotationX(), - * @ref rotationZ(), rotation() const, + * @ref rotationZ(), @ref rotation() const, * @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad) - * @todoc Explicit reference when Doxygen can handle const */ static Matrix4 rotationY(Rad angle); @@ -126,11 +123,10 @@ template class Matrix4: public Matrix<4, T> { * @brief 3D rotation matrix around Z axis * @param angle Rotation angle (counterclockwise) * - * Faster than calling `%Matrix4::rotation(angle, %Vector3::zAxis())`. + * Faster than calling `Matrix4::rotation(angle, Vector3::zAxis())`. * @see @ref rotation(Rad, const Vector3&), @ref rotationX(), - * @ref rotationY(), rotation() const, + * @ref rotationY(), @ref rotation() const, * @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad) - * @todoc Explicit reference when Doxygen can handle const */ static Matrix4 rotationZ(Rad angle); @@ -138,11 +134,62 @@ template class Matrix4: public Matrix<4, T> { * @brief 3D reflection matrix * @param normal Normal of the plane through which to reflect * - * Expects that the normal is normalized. + * Expects that the normal is normalized. Reflection along axes can be + * done in a slightly simpler way also using @ref scaling(), e.g. + * `Matrix4::reflection(Vector3::yAxis())` is equivalent to + * `Matrix4::scaling(Vector3::yScale(-1.0f))`. * @see @ref Matrix3::reflection(), @ref Vector::isNormalized() */ static Matrix4 reflection(const Vector3& normal); + /** + * @brief 3D shearing along XY plane + * @param amountX Amount of shearing along X axis + * @param amountY Amount of shearing along Y axis + * + * Z axis remains unchanged. + * @see @ref shearingXZ(), @ref shearingYZ(), @ref Matrix3::shearingX(), + * @ref Matrix3::shearingY() + */ + constexpr static Matrix4 shearingXY(T amountX, T amountY) { + return {{ (1), T(0), T(0), T(0)}, + { (0), T(1), T(0), T(0)}, + {amountX, amountY, T(1), T(0)}, + { (0), T(0), T(0), T(1)}}; + } + + /** + * @brief 3D shearing along XZ plane + * @param amountX Amount of shearing along X axis + * @param amountZ Amount of shearing along Z axis + * + * Y axis remains unchanged. + * @see @ref shearingXY(), @ref shearingYZ(), @ref Matrix3::shearingX(), + * @ref Matrix3::shearingY() + */ + constexpr static Matrix4 shearingXZ(T amountX, T amountZ) { + return {{ T(1), T(0), T(0), T(0)}, + {amountX, T(1), amountZ, T(0)}, + { T(0), T(0), T(1), T(0)}, + { T(0), T(0), T(0), T(1)}}; + } + + /** + * @brief 3D shearing along YZ plane + * @param amountY Amount of shearing along Y axis + * @param amountZ Amount of shearing along Z axis + * + * X axis remains unchanged. + * @see @ref shearingXY(), @ref shearingXZ(), @ref Matrix3::shearingX(), + * @ref Matrix3::shearingY() + */ + constexpr static Matrix4 shearingYZ(T amountY, T amountZ) { + return {{T(1), amountY, amountZ, T(0)}, + {T(0), T(1), T(0), T(0)}, + {T(0), T(0), T(1), T(0)}, + {T(0), T(0), T(0), T(1)}}; + } + /** * @brief 3D orthographic projection matrix * @param size Size of the view @@ -177,6 +224,15 @@ template class Matrix4: public Matrix<4, T> { return perspectiveProjection(Vector2(xyScale, xyScale/aspectRatio), near, far); } + /** + * @brief Matrix oriented towards a specific point + * @param eye Location to place the matrix + * @param target Location towards which the matrix is oriented + * @param up Vector as a guide of which way is up (should not be + * the same direction as `target - eye`) + */ + static Matrix4 lookAt(const Vector3& eye, const Vector3& target, const Vector3& up); + /** * @brief Create matrix from rotation/scaling part and translation part * @param rotationScaling Rotation/scaling part (upper-left 3x3 @@ -184,8 +240,7 @@ template class Matrix4: public Matrix<4, T> { * @param translation Translation part (first three elements of * fourth column) * - * @see @ref rotationScaling(), translation() const - * @todoc Explicit reference when Doxygen can handle const + * @see @ref rotationScaling(), @ref translation() const */ constexpr static Matrix4 from(const Matrix<3, T>& rotationScaling, const Vector3& translation) { return {{rotationScaling[0], T(0)}, @@ -201,12 +256,12 @@ template class Matrix4: public Matrix<4, T> { * @brief Default constructor * * Creates identity matrix. You can also explicitly call this - * constructor with `%Matrix4 m(Matrix4::Identity);`. Optional + * constructor with `Matrix4 m(Matrix4::Identity);`. Optional * parameter @p value allows you to specify value on diagonal. */ constexpr /*implicit*/ Matrix4(typename Matrix<4, T>::IdentityType = (Matrix<4, T>::Identity), T value = T(1)): Matrix<4, T>(Matrix<4, T>::Identity, value) {} - /** @brief %Matrix from column vectors */ + /** @brief Matrix from column vectors */ constexpr /*implicit*/ Matrix4(const Vector4& first, const Vector4& second, const Vector4& third, const Vector4& fourth): Matrix<4, T>(first, second, third, fourth) {} /** @copydoc Matrix::Matrix(const RectangularMatrix&) */ @@ -238,10 +293,9 @@ template class Matrix4: public Matrix<4, T> { * * Upper-left 3x3 part of the matrix. * @see @ref from(const Matrix<3, T>&, const Vector3&), - * rotation() const, @ref rotationNormalized(), + * @ref rotation() const, @ref rotationNormalized(), * @ref uniformScaling(), @ref rotation(Rad, const Vector3&), - * Matrix3::rotationScaling() const - * @todoc Explicit reference when Doxygen can handle const + * @ref Matrix3::rotationScaling() const */ /* Not Matrix3, because it is for affine 2D transformations */ constexpr Matrix<3, T> rotationScaling() const { @@ -255,10 +309,9 @@ template class Matrix4: public Matrix<4, T> { * * Similar to @ref rotationScaling(), but additionally checks that the * base vectors are normalized. - * @see rotation() const, @ref uniformScaling(), + * @see @ref rotation() const, @ref uniformScaling(), * @ref Matrix3::rotationNormalized() * @todo assert also orthogonality or this is good enough? - * @todoc Explicit reference when Doxygen can handle const */ /* Not Matrix3, because it is for affine 2D transformations */ Matrix<3, T> rotationNormalized() const { @@ -276,8 +329,7 @@ template class Matrix4: public Matrix<4, T> { * scaling. * @see @ref rotationNormalized(), @ref rotationScaling(), * @ref uniformScaling(), @ref rotation(Rad, const Vector3&), - * Matrix3::rotation() const - * @todoc Explicit reference when Doxygen can handle const + * @ref Matrix3::rotation() const */ /* Not Matrix3, because it is for affine 2D transformations */ Matrix<3, T> rotation() const; @@ -289,10 +341,9 @@ template class Matrix4: public Matrix<4, T> { * Expects that the scaling is the same in all axes. Faster alternative * to @ref uniformScaling(), because it doesn't compute the square * root. - * @see @ref rotationScaling(), rotation() const, + * @see @ref rotationScaling(), @ref rotation() const, * @ref rotationNormalized(), @ref scaling(const Vector3&), * @ref Matrix3::uniformScaling() - * @todoc Explicit reference when Doxygen can handle const */ T uniformScalingSquared() const; @@ -302,10 +353,9 @@ template class Matrix4: public Matrix<4, T> { * Length of vectors in upper-left 3x3 part of the matrix. Expects that * the scaling is the same in all axes. Use faster alternative * @ref uniformScalingSquared() where possible. - * @see @ref rotationScaling(), rotation() const, + * @see @ref rotationScaling(), @ref rotation() const, * @ref rotationNormalized(), @ref scaling(const Vector3&), * @ref Matrix3::uniformScaling() - * @todoc Explicit reference when Doxygen can handle const */ T uniformScaling() const { return std::sqrt(uniformScalingSquared()); } @@ -359,9 +409,8 @@ template class Matrix4: public Matrix<4, T> { * @f$ A^{i, j} @f$ is matrix without i-th row and j-th column, see * @ref ij() * @see @ref isRigidTransformation(), @ref invertedOrthogonal(), - * @ref rotationScaling(), translation() const, + * @ref rotationScaling(), @ref translation() const, * @ref Matrix3::invertedRigid() - * @todoc Explicit reference when Doxygen can handle const */ Matrix4 invertedRigid() const; @@ -410,7 +459,9 @@ template class Matrix4: public Matrix<4, T> { MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(4, Matrix4, Vector4) }; +#ifndef DOXYGEN_GENERATING_OUTPUT MAGNUM_MATRIXn_OPERATOR_IMPLEMENTATION(4, Matrix4) +#endif /** @debugoperator{Magnum::Math::Matrix4} */ template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Matrix4& value) { @@ -505,6 +556,17 @@ template Matrix4 Matrix4::perspectiveProjection(const Vector2& { T(0), T(0), T(2)*far*near*zScale, T(0)}}; } +template Matrix4 Matrix4::lookAt(const Vector3& eye, const Vector3& target, const Vector3& up) { + const Vector3 backward = (eye - target).normalized(); + const Vector3 right = cross(up, backward).normalized(); + const Vector3 realUp = cross(backward, right); + + return {{ right, T(0)}, + { realUp, T(0)}, + {backward, T(0)}, + { eye, T(1)}}; +} + template inline Matrix<3, T> Matrix4::rotation() const { CORRADE_ASSERT(TypeTraits::equals((*this)[0].xyz().dot(), (*this)[1].xyz().dot()) && TypeTraits::equals((*this)[1].xyz().dot(), (*this)[2].xyz().dot()), diff --git a/src/Magnum/Math/Quaternion.h b/src/Magnum/Math/Quaternion.h index 56d8fee6b..af078d6dc 100644 --- a/src/Magnum/Math/Quaternion.h +++ b/src/Magnum/Math/Quaternion.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,8 +39,81 @@ namespace Magnum { namespace Math { +/** @relatesalso Quaternion +@brief Dot product between two quaternions + +@f[ + p \cdot q = \boldsymbol p_V \cdot \boldsymbol q_V + p_S q_S +@f] +@see @ref Quaternion::dot() const +*/ +template inline T dot(const Quaternion& a, const Quaternion& b) { + return dot(a.vector(), b.vector()) + a.scalar()*b.scalar(); +} + +namespace Implementation { + /* Used in angle() and slerp() (no assertions) */ + template inline T angle(const Quaternion& normalizedA, const Quaternion& normalizedB) { + return std::acos(dot(normalizedA, normalizedB)); + } +} + +/** @relatesalso Quaternion +@brief Angle between normalized quaternions + +Expects that both quaternions are normalized. @f[ + \theta = acos \left( \frac{p \cdot q}{|p| |q|} \right) = acos(p \cdot q) +@f] +@see @ref Quaternion::isNormalized(), + @ref angle(const Complex&, const Complex&), + @ref angle(const Vector&, const Vector&) + */ +template inline Rad angle(const Quaternion& normalizedA, const Quaternion& normalizedB) { + CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), + "Math::angle(): quaternions must be normalized", {}); + return Rad{Implementation::angle(normalizedA, normalizedB)}; +} + +/** @relatesalso Quaternion +@brief Linear interpolation of two quaternions +@param normalizedA First quaternion +@param normalizedB Second quaternion +@param t Interpolation phase (from range @f$ [0; 1] @f$) + +Expects that both quaternions are normalized. @f[ + q_{LERP} = \frac{(1 - t) q_A + t q_B}{|(1 - t) q_A + t q_B|} +@f] +@see @ref Quaternion::isNormalized(), @ref slerp(const Quaternion&, const Quaternion&, T), + @ref lerp(const T&, const T&, U) + */ +template inline Quaternion lerp(const Quaternion& normalizedA, const Quaternion& normalizedB, T t) { + CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), + "Math::lerp(): quaternions must be normalized", {}); + return ((T(1) - t)*normalizedA + t*normalizedB).normalized(); +} + +/** @relatesalso Quaternion +@brief Spherical linear interpolation of two quaternions +@param normalizedA First quaternion +@param normalizedB Second quaternion +@param t Interpolation phase (from range @f$ [0; 1] @f$) + +Expects that both quaternions are normalized. @f[ + q_{SLERP} = \frac{sin((1 - t) \theta) q_A + sin(t \theta) q_B}{sin \theta} + ~ ~ ~ ~ ~ ~ ~ + \theta = acos \left( \frac{q_A \cdot q_B}{|q_A| \cdot |q_B|} \right) = acos(q_A \cdot q_B) +@f] +@see @ref Quaternion::isNormalized(), @ref lerp(const Quaternion&, const Quaternion&, T) + */ +template inline Quaternion slerp(const Quaternion& normalizedA, const Quaternion& normalizedB, T t) { + CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), + "Math::slerp(): quaternions must be normalized", {}); + const T a = Implementation::angle(normalizedA, normalizedB); + return (std::sin((T(1) - t)*a)*normalizedA + std::sin(t*a)*normalizedB)/std::sin(a); +} + /** -@brief %Quaternion +@brief Quaternion @tparam T Underlying data type Represents 3D rotation. See @ref transformations for brief introduction. @@ -51,58 +124,43 @@ template class Quaternion { public: typedef T Type; /**< @brief Underlying data type */ + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Dot product - * - * @f[ - * p \cdot q = \boldsymbol p_V \cdot \boldsymbol q_V + p_S q_S - * @f] - * @see dot() const - * @todoc Explicit reference when Doxygen can handle const + * @copybrief Math::dot(const Quaternion&, const Quaternion&) + * @deprecated Use @ref Math::dot(const Quaternion&, const Quaternion&) + * instead. */ - static T dot(const Quaternion& a, const Quaternion& b) { - /** @todo Use four-component SIMD implementation when available */ - return Vector3::dot(a.vector(), b.vector()) + a.scalar()*b.scalar(); + CORRADE_DEPRECATED("use Math::dot() instead") static T dot(const Quaternion& a, const Quaternion& b) { + return Math::dot(a, b); } /** - * @brief Angle between normalized quaternions - * - * Expects that both quaternions are normalized. @f[ - * \theta = acos \left( \frac{p \cdot q}{|p| |q|} \right) = acos(p \cdot q) - * @f] - * @see @ref isNormalized(), @ref Complex::angle(), - * @ref Vector::angle() + * @copybrief Math::angle(const Quaternion&, const Quaternion&) + * @deprecated Use @ref Math::angle(const Quaternion&, const Quaternion&) + * instead. */ - static Rad angle(const Quaternion& normalizedA, const Quaternion& normalizedB); + CORRADE_DEPRECATED("use Math::angle() instead") static Rad angle(const Quaternion& normalizedA, const Quaternion& normalizedB) { + return Math::angle(normalizedA, normalizedB); + } /** - * @brief Linear interpolation of two quaternions - * @param normalizedA First quaternion - * @param normalizedB Second quaternion - * @param t Interpolation phase (from range @f$ [0; 1] @f$) - * - * Expects that both quaternions are normalized. @f[ - * q_{LERP} = \frac{(1 - t) q_A + t q_B}{|(1 - t) q_A + t q_B|} - * @f] - * @see @ref isNormalized(), @ref slerp(), @ref Math::lerp() + * @copybrief Math::lerp(const Quaternion&, const Quaternion&, T) + * @deprecated Use @ref Math::lerp(const Quaternion&, const Quaternion&, T) + * instead. */ - static Quaternion lerp(const Quaternion& normalizedA, const Quaternion& normalizedB, T t); + CORRADE_DEPRECATED("use Math::lerp() instead") static Quaternion lerp(const Quaternion& normalizedA, const Quaternion& normalizedB, T t) { + return Math::lerp(normalizedA, normalizedB, t); + } /** - * @brief Spherical linear interpolation of two quaternions - * @param normalizedA First quaternion - * @param normalizedB Second quaternion - * @param t Interpolation phase (from range @f$ [0; 1] @f$) - * - * Expects that both quaternions are normalized. @f[ - * q_{SLERP} = \frac{sin((1 - t) \theta) q_A + sin(t \theta) q_B}{sin \theta} - * ~~~~~~~~~~ - * \theta = acos \left( \frac{q_A \cdot q_B}{|q_A| \cdot |q_B|} \right) = acos(q_A \cdot q_B) - * @f] - * @see @ref isNormalized(), @ref lerp() + * @copybrief Math::slerp(const Quaternion&, const Quaternion&, T) + * @deprecated Use @ref Math::slerp(const Quaternion&, const Quaternion&, T) + * instead. */ - static Quaternion slerp(const Quaternion& normalizedA, const Quaternion& normalizedB, T t); + CORRADE_DEPRECATED("use Math::slerp() instead") static Quaternion slerp(const Quaternion& normalizedA, const Quaternion& normalizedB, T t) { + return Math::slerp(normalizedA, normalizedB, t); + } + #endif /** * @brief Rotation quaternion @@ -169,7 +227,7 @@ template class Quaternion { /** * @brief Whether the quaternion is normalized * - * %Quaternion is normalized if it has unit length: @f[ + * Quaternion is normalized if it has unit length: @f[ * |q \cdot q - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon * @f] * @see @ref dot(), @ref normalized() @@ -178,10 +236,10 @@ template class Quaternion { return Implementation::isNormalizedSquared(dot()); } - /** @brief %Vector part */ + /** @brief Vector part */ constexpr Vector3 vector() const { return _vector; } - /** @brief %Scalar part */ + /** @brief Scalar part */ constexpr T scalar() const { return _scalar; } /** @@ -332,17 +390,16 @@ template class Quaternion { * @see @ref isNormalized(), * @ref dot(const Quaternion&, const Quaternion&) */ - T dot() const { return dot(*this, *this); } + T dot() const { return Math::dot(*this, *this); } /** - * @brief %Quaternion length + * @brief Quaternion length * - * See also dot() const which is faster for comparing length with + * See also @ref dot() const which is faster for comparing length with * other values. @f[ * |q| = \sqrt{q \cdot q} * @f] * @see @ref isNormalized() - * @todoc Explicit reference when Doxygen can handle const */ T length() const { return std::sqrt(dot()); } @@ -403,7 +460,14 @@ template class Quaternion { * @brief Rotate vector with normalized quaternion * * Faster alternative to @ref transformVector(), expects that the - * quaternion is normalized. @f[ + * quaternion is normalized. Done using the following equation: @f[ + * \begin{array}{rcl} + * \boldsymbol t & = & 2 (\boldsymbol q_V \times \boldsymbol v) \\ + * \boldsymbol v' & = & \boldsymbol v + q_S \boldsymbol t + \boldsymbol q_V \times \boldsymbol t + * \end{array} + * @f] + * Which is equivalent to the common equation (source: + * https://molecularmusings.wordpress.com/2013/05/24/a-faster-quaternion-vector-multiplication/): @f[ * v' = qvq^{-1} = qvq^* = q [\boldsymbol v, 0] q^* * @f] * @see @ref isNormalized(), @ref Quaternion(const Vector3&), @@ -419,11 +483,6 @@ template class Quaternion { return value*value; } - /* Used in angle() and slerp() (no assertions) */ - static T angleInternal(const Quaternion& normalizedA, const Quaternion& normalizedB) { - return std::acos(dot(normalizedA, normalizedB)); - } - Vector3 _vector; T _scalar; }; @@ -458,16 +517,12 @@ template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug deb return debug; } -/** @todoc Remove the workaround when Doxygen is really able to preprocessor */ - /* Explicit instantiation for commonly used types */ #ifndef DOXYGEN_GENERATING_OUTPUT -/** @privatesection */ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Quaternion&); #ifndef MAGNUM_TARGET_GLES extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Quaternion&); #endif -/** @endprivatesection */ #endif namespace Implementation { @@ -505,25 +560,6 @@ template Quaternion quaternionFromMatrix(const Matrix<3, T>& m) { } -template inline Rad Quaternion::angle(const Quaternion& normalizedA, const Quaternion& normalizedB) { - CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), - "Math::Quaternion::angle(): quaternions must be normalized", Rad(std::numeric_limits::quiet_NaN())); - return Rad(angleInternal(normalizedA, normalizedB)); -} - -template inline Quaternion Quaternion::lerp(const Quaternion& normalizedA, const Quaternion& normalizedB, const T t) { - CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), - "Math::Quaternion::lerp(): quaternions must be normalized", Quaternion({}, std::numeric_limits::quiet_NaN())); - return ((T(1) - t)*normalizedA + t*normalizedB).normalized(); -} - -template inline Quaternion Quaternion::slerp(const Quaternion& normalizedA, const Quaternion& normalizedB, const T t) { - CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), - "Math::Quaternion::slerp(): quaternions must be normalized", Quaternion({}, std::numeric_limits::quiet_NaN())); - const T a = angleInternal(normalizedA, normalizedB); - return (std::sin((T(1) - t)*a)*normalizedA + std::sin(t*a)*normalizedB)/std::sin(a); -} - template inline Quaternion Quaternion::rotation(const Rad angle, const Vector3& normalizedAxis) { CORRADE_ASSERT(normalizedAxis.isNormalized(), "Math::Quaternion::rotation(): axis must be normalized", {}); @@ -536,8 +572,7 @@ template inline Quaternion Quaternion::fromMatrix(const Matrix<3, } template inline Rad Quaternion::angle() const { - CORRADE_ASSERT(isNormalized(), "Math::Quaternion::angle(): quaternion must be normalized", - Rad(std::numeric_limits::quiet_NaN())); + CORRADE_ASSERT(isNormalized(), "Math::Quaternion::angle(): quaternion must be normalized", {}); return Rad(T(2)*std::acos(_scalar)); } @@ -561,20 +596,19 @@ template Matrix<3, T> Quaternion::toMatrix() const { } template inline Quaternion Quaternion::operator*(const Quaternion& other) const { - return {_scalar*other._vector + other._scalar*_vector + Vector3::cross(_vector, other._vector), - _scalar*other._scalar - Vector3::dot(_vector, other._vector)}; + return {_scalar*other._vector + other._scalar*_vector + Math::cross(_vector, other._vector), + _scalar*other._scalar - Math::dot(_vector, other._vector)}; } template inline Quaternion Quaternion::invertedNormalized() const { - CORRADE_ASSERT(isNormalized(), "Math::Quaternion::invertedNormalized(): quaternion must be normalized", - Quaternion({}, std::numeric_limits::quiet_NaN())); + CORRADE_ASSERT(isNormalized(), "Math::Quaternion::invertedNormalized(): quaternion must be normalized", {}); return conjugated(); } -template inline Vector3 Quaternion::transformVectorNormalized(const Vector3< T >& vector) const { - CORRADE_ASSERT(isNormalized(), "Math::Quaternion::transformVectorNormalized(): quaternion must be normalized", - Vector3(std::numeric_limits::quiet_NaN())); - return ((*this)*Quaternion(vector)*conjugated()).vector(); +template inline Vector3 Quaternion::transformVectorNormalized(const Vector3& vector) const { + CORRADE_ASSERT(isNormalized(), "Math::Quaternion::transformVectorNormalized(): quaternion must be normalized", {}); + const Vector3 t = T(2)*Math::cross(_vector, vector); + return vector + _scalar*t + Math::cross(_vector, t); } }} diff --git a/src/Magnum/Math/Range.h b/src/Magnum/Math/Range.h index a9c1f52f8..ac1cbf4ae 100644 --- a/src/Magnum/Math/Range.h +++ b/src/Magnum/Math/Range.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -62,7 +62,7 @@ template class Range { /** * Create range from minimal coordinates and size * @param min Minimal coordinates - * @param size %Range size + * @param size Range size */ static Range fromSize(const VectorType& min, const VectorType& size) { return {min, min+size}; @@ -129,7 +129,7 @@ template class Range { constexpr const VectorType max() const { return _max; } /**< @overload */ /** - * @brief %Range size + * @brief Range size * * @see @ref min(), @ref max(), @ref Range2D::sizeX(), * @ref Range2D::sizeY(), @ref Range3D::sizeX(), @@ -138,7 +138,7 @@ template class Range { VectorType size() const { return _max - _min; } /** - * @brief %Range center + * @brief Range center * * @see @ref Range2D::centerX(), @ref Range2D::centerY(), * @ref Range3D::centerX(), @ref Range3D::centerY(), @@ -196,7 +196,7 @@ template class Range { /** @brief One-dimensional range -Convenience alternative to %Range<1, T>. See @ref Range for more +Convenience alternative to `Range<1, T>`. See @ref Range for more information. @note Not available on GCC < 4.7. Use %Range<1, T> instead. */ @@ -268,7 +268,7 @@ template class Range2D: public Range<2, T> { constexpr T top() const { return Range<2, T>::max().y(); } /**< @overload */ /** - * @brief %Range width + * @brief Range width * * @see @ref size() */ @@ -277,7 +277,7 @@ template class Range2D: public Range<2, T> { } /** - * @brief %Range height + * @brief Range height * * @see @ref size() */ @@ -286,7 +286,7 @@ template class Range2D: public Range<2, T> { } /** - * @brief %Range center on X axis + * @brief Range center on X axis * * @see @ref center() */ @@ -295,7 +295,7 @@ template class Range2D: public Range<2, T> { } /** - * @brief %Range center on Y axis + * @brief Range center on Y axis * * @see @ref center() */ @@ -397,7 +397,7 @@ template class Range3D: public Range<3, T> { constexpr T front() const { return Range<3, T>::max().z(); } /**< @overload */ /** - * @brief %Range width + * @brief Range width * * @see @ref size() */ @@ -406,7 +406,7 @@ template class Range3D: public Range<3, T> { } /** - * @brief %Range height + * @brief Range height * * @see @ref size() */ @@ -415,7 +415,7 @@ template class Range3D: public Range<3, T> { } /** - * @brief %Range depth + * @brief Range depth * * @see @ref size() */ @@ -425,7 +425,7 @@ template class Range3D: public Range<3, T> { /** * - * @brief %Range center on X axis + * @brief Range center on X axis * * @see @ref center() */ @@ -434,7 +434,7 @@ template class Range3D: public Range<3, T> { } /** - * @brief %Range center on Y axis + * @brief Range center on Y axis * * @see @ref center() */ @@ -443,7 +443,7 @@ template class Range3D: public Range<3, T> { } /** - * @brief %Range center on Z axis + * @brief Range center on Z axis * * @see @ref center() */ diff --git a/src/Magnum/Math/RectangularMatrix.h b/src/Magnum/Math/RectangularMatrix.h index 6e7046117..86501ae6e 100644 --- a/src/Magnum/Math/RectangularMatrix.h +++ b/src/Magnum/Math/RectangularMatrix.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -59,8 +59,8 @@ template class RectangularMatrix { public: typedef T Type; /**< @brief Underlying data type */ - const static std::size_t Cols = cols; /**< @brief %Matrix column count */ - const static std::size_t Rows = rows; /**< @brief %Matrix row count */ + const static std::size_t Cols = cols; /**< @brief Matrix column count */ + const static std::size_t Rows = rows; /**< @brief Matrix row count */ /** * @brief Size of matrix diagonal @@ -70,7 +70,7 @@ template class RectangularMatrix { const static std::size_t DiagonalSize = (cols < rows ? cols : rows); /** - * @brief %Matrix from array + * @brief Matrix from array * @return Reference to the data as if it was matrix, thus doesn't * perform any copying. * @@ -191,7 +191,7 @@ template class RectangularMatrix { constexpr const T* data() const { return _data[0].data(); } /**< @overload */ /** - * @brief %Matrix column + * @brief Matrix column * * Particular elements can be accessed using @ref Vector::operator[](), * e.g.: @@ -206,7 +206,7 @@ template class RectangularMatrix { constexpr const Vector& operator[](std::size_t col) const { return _data[col]; } /**< @overload */ /** - * @brief %Matrix row + * @brief Matrix row * * Consider using @ref transposed() when accessing rows frequently, as * this is slower than accessing columns due to the way the matrix is @@ -425,9 +425,9 @@ template class RectangularMatrix { #ifndef CORRADE_GCC46_COMPATIBILITY /** -@brief %Matrix with 2 columns and 3 rows +@brief Matrix with 2 columns and 3 rows -Convenience alternative to %RectangularMatrix<2, 3, T>. See +Convenience alternative to `RectangularMatrix<2, 3, T>`. See @ref RectangularMatrix for more information. @note Not available on GCC < 4.7. Use %RectangularMatrix<2, 3, T> instead. @@ -438,9 +438,9 @@ template using Matrix2x3 = RectangularMatrix<2, 3, T>; #endif /** -@brief %Matrix with 3 columns and 2 rows +@brief Matrix with 3 columns and 2 rows -Convenience alternative to %RectangularMatrix<3, 2, T>. See +Convenience alternative to `RectangularMatrix<3, 2, T>`. See @ref RectangularMatrix for more information. @note Not available on GCC < 4.7. Use %RectangularMatrix<3, 2, T> instead. @@ -451,9 +451,9 @@ template using Matrix3x2 = RectangularMatrix<3, 2, T>; #endif /** -@brief %Matrix with 2 columns and 4 rows +@brief Matrix with 2 columns and 4 rows -Convenience alternative to %RectangularMatrix<2, 4, T>. See +Convenience alternative to `RectangularMatrix<2, 4, T>`. See @ref RectangularMatrix for more information. @note Not available on GCC < 4.7. Use %RectangularMatrix<2, 4, T> instead. @@ -464,9 +464,9 @@ template using Matrix2x4 = RectangularMatrix<2, 4, T>; #endif /** -@brief %Matrix with 4 columns and 2 rows +@brief Matrix with 4 columns and 2 rows -Convenience alternative to %RectangularMatrix<4, 2, T>. See +Convenience alternative to `RectangularMatrix<4, 2, T>`. See @ref RectangularMatrix for more information. @note Not available on GCC < 4.7. Use %RectangularMatrix<4, 2, T> instead. @@ -477,9 +477,9 @@ template using Matrix4x2 = RectangularMatrix<4, 2, T>; #endif /** -@brief %Matrix with 3 columns and 4 rows +@brief Matrix with 3 columns and 4 rows -Convenience alternative to %RectangularMatrix<3, 4, T>. See +Convenience alternative to `RectangularMatrix<3, 4, T>`. See @ref RectangularMatrix for more information. @note Not available on GCC < 4.7. Use %RectangularMatrix<3, 4, T> instead. @@ -490,9 +490,9 @@ template using Matrix3x4 = RectangularMatrix<3, 4, T>; #endif /** -@brief %Matrix with 4 columns and 3 rows +@brief Matrix with 4 columns and 3 rows -Convenience alternative to %RectangularMatrix<4, 3, T>. See +Convenience alternative to `RectangularMatrix<4, 3, T>`. See @ref RectangularMatrix for more information. @note Not available on GCC < 4.7. Use %RectangularMatrix<4, 3, T> instead. @@ -666,16 +666,16 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit #endif namespace Implementation { - template inline constexpr Vector diagonalMatrixColumn2(Implementation::Sequence, const T& number) { + template constexpr Vector diagonalMatrixColumn2(Implementation::Sequence, const T& number) { return {(sequence == i ? number : T(0))...}; } - template inline constexpr Vector diagonalMatrixColumn(const T& number) { + template constexpr Vector diagonalMatrixColumn(const T& number) { return diagonalMatrixColumn2(typename Implementation::GenerateSequence::Type(), number); } } #ifndef CORRADE_GCC45_COMPATIBILITY -template template inline constexpr RectangularMatrix::RectangularMatrix(Implementation::Sequence, const Vector& diagonal): +template template constexpr RectangularMatrix::RectangularMatrix(Implementation::Sequence, const Vector& diagonal): #ifndef CORRADE_MSVC2013_COMPATIBILITY _data{Implementation::diagonalMatrixColumn(sequence < DiagonalSize ? diagonal[sequence] : T{})...} {} #else @@ -726,10 +726,10 @@ template inline RectangularMatrix inline constexpr auto RectangularMatrix::diagonal() const -> Vector { return diagonalInternal(typename Implementation::GenerateSequence::Type()); } +template constexpr auto RectangularMatrix::diagonal() const -> Vector { return diagonalInternal(typename Implementation::GenerateSequence::Type()); } #ifndef DOXYGEN_GENERATING_OUTPUT -template template inline constexpr auto RectangularMatrix::diagonalInternal(Implementation::Sequence) const -> Vector { +template template constexpr auto RectangularMatrix::diagonalInternal(Implementation::Sequence) const -> Vector { return {(*this)[sequence][sequence]...}; } #endif diff --git a/src/Magnum/Math/Swizzle.h b/src/Magnum/Math/Swizzle.h index 47786aeae..5a83e55a6 100644 --- a/src/Magnum/Math/Swizzle.h +++ b/src/Magnum/Math/Swizzle.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Math/Test/AngleTest.cpp b/src/Magnum/Math/Test/AngleTest.cpp index 3760b7d57..177df9f71 100644 --- a/src/Magnum/Math/Test/AngleTest.cpp +++ b/src/Magnum/Math/Test/AngleTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,16 +30,15 @@ namespace Magnum { namespace Math { namespace Test { -class AngleTest: public Corrade::TestSuite::Tester { - public: - explicit AngleTest(); +struct AngleTest: Corrade::TestSuite::Tester { + explicit AngleTest(); - void construct(); - void literals(); - void conversion(); + void construct(); + void literals(); + void conversion(); - void debugDeg(); - void debugRad(); + void debugDeg(); + void debugRad(); }; typedef Math::Deg Deg; diff --git a/src/Magnum/Math/Test/BoolVectorTest.cpp b/src/Magnum/Math/Test/BoolVectorTest.cpp index d40ba6733..9b09a1a8f 100644 --- a/src/Magnum/Math/Test/BoolVectorTest.cpp +++ b/src/Magnum/Math/Test/BoolVectorTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,27 +30,26 @@ namespace Magnum { namespace Math { namespace Test { -class BoolVectorTest: public Corrade::TestSuite::Tester { - public: - explicit BoolVectorTest(); +struct BoolVectorTest: Corrade::TestSuite::Tester { + explicit BoolVectorTest(); - void construct(); - void constructDefault(); - void constructOneValue(); - void constructOneElement(); - void constructCopy(); - void data(); + void construct(); + void constructDefault(); + void constructOneValue(); + void constructOneElement(); + void constructCopy(); + void data(); - void compare(); - void compareUndefined(); - void all(); - void none(); - void any(); + void compare(); + void compareUndefined(); + void all(); + void none(); + void any(); - void bitInverse(); - void bitAndOrXor(); + void bitInverse(); + void bitAndOrXor(); - void debug(); + void debug(); }; static_assert(BoolVector<15>::DataSize == 2, "Improper DataSize"); diff --git a/src/Magnum/Math/Test/CMakeLists.txt b/src/Magnum/Math/Test/CMakeLists.txt index 1f0819cfe..f504b0036 100644 --- a/src/Magnum/Math/Test/CMakeLists.txt +++ b/src/Magnum/Math/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Math/Test/ComplexTest.cpp b/src/Magnum/Math/Test/ComplexTest.cpp index e1a51bfbf..92eb7a22f 100644 --- a/src/Magnum/Math/Test/ComplexTest.cpp +++ b/src/Magnum/Math/Test/ComplexTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,38 +31,37 @@ namespace Magnum { namespace Math { namespace Test { -class ComplexTest: public Corrade::TestSuite::Tester { - public: - explicit ComplexTest(); +struct ComplexTest: Corrade::TestSuite::Tester { + explicit ComplexTest(); - void construct(); - void constructDefault(); - void constructFromVector(); - void constructCopy(); + void construct(); + void constructDefault(); + void constructFromVector(); + void constructCopy(); - void compare(); - void isNormalized(); + void compare(); + void isNormalized(); - void addSubtract(); - void negated(); - void multiplyDivideScalar(); - void multiply(); + void addSubtract(); + void negated(); + void multiplyDivideScalar(); + void multiply(); - void dot(); - void dotSelf(); - void length(); - void normalized(); + void dot(); + void dotSelf(); + void length(); + void normalized(); - void conjugated(); - void inverted(); - void invertedNormalized(); + void conjugated(); + void inverted(); + void invertedNormalized(); - void angle(); - void rotation(); - void matrix(); - void transformVector(); + void angle(); + void rotation(); + void matrix(); + void transformVector(); - void debug(); + void debug(); }; ComplexTest::ComplexTest() { @@ -194,7 +193,7 @@ void ComplexTest::dot() { Complex a(5.0f, 3.0f); Complex b(6.0f, -7.0f); - CORRADE_COMPARE(Complex::dot(a, b), 9.0f); + CORRADE_COMPARE(Math::dot(a, b), 9.0f); } void ComplexTest::dotSelf() { @@ -234,8 +233,7 @@ void ComplexTest::invertedNormalized() { Complex a(-0.6f, 0.8f); Complex b(-0.6f, -0.8f); - Complex notInverted = (a*2).invertedNormalized(); - CORRADE_VERIFY(notInverted != notInverted); + (a*2).invertedNormalized(); CORRADE_COMPARE(o.str(), "Math::Complex::invertedNormalized(): complex number must be normalized\n"); Complex inverted = a.invertedNormalized(); @@ -247,20 +245,18 @@ void ComplexTest::invertedNormalized() { void ComplexTest::angle() { std::ostringstream o; Error::setOutput(&o); - auto angle = Complex::angle(Complex(1.5f, -2.0f).normalized(), {-4.0f, 3.5f}); - CORRADE_VERIFY(angle != angle); - CORRADE_COMPARE(o.str(), "Math::Complex::angle(): complex numbers must be normalized\n"); + Math::angle(Complex(1.5f, -2.0f).normalized(), {-4.0f, 3.5f}); + CORRADE_COMPARE(o.str(), "Math::angle(): complex numbers must be normalized\n"); o.str({}); - angle = Complex::angle({1.5f, -2.0f}, Complex(-4.0f, 3.5f).normalized()); - CORRADE_VERIFY(angle != angle); - CORRADE_COMPARE(o.str(), "Math::Complex::angle(): complex numbers must be normalized\n"); + Math::angle({1.5f, -2.0f}, Complex(-4.0f, 3.5f).normalized()); + CORRADE_COMPARE(o.str(), "Math::angle(): complex numbers must be normalized\n"); /* Verify also that the angle is the same as angle between 2D vectors */ - angle = Complex::angle(Complex( 1.5f, -2.0f).normalized(), - Complex(-4.0f, 3.5f).normalized()); - CORRADE_COMPARE(angle, Vector2::angle(Vector2( 1.5f, -2.0f).normalized(), - Vector2(-4.0f, 3.5f).normalized())); + Rad angle = Math::angle(Complex( 1.5f, -2.0f).normalized(), + Complex(-4.0f, 3.5f).normalized()); + CORRADE_COMPARE(angle, Math::angle(Vector2( 1.5f, -2.0f).normalized(), + Vector2(-4.0f, 3.5f).normalized())); CORRADE_COMPARE(angle, Rad(2.933128f)); } diff --git a/src/Magnum/Math/Test/ConstantsTest.cpp b/src/Magnum/Math/Test/ConstantsTest.cpp index 4122403d7..22c0f0ff3 100644 --- a/src/Magnum/Math/Test/ConstantsTest.cpp +++ b/src/Magnum/Math/Test/ConstantsTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,6 +23,7 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include "Magnum/Math/Constants.h" @@ -30,37 +31,65 @@ namespace Magnum { namespace Math { namespace Test { -class ConstantsTest: public Corrade::TestSuite::Tester { - public: - ConstantsTest(); +struct ConstantsTest: Corrade::TestSuite::Tester { + explicit ConstantsTest(); - void constantsFloat(); - void constantsDouble(); + void constants(); + void specials(); + + private: + template void _constants(); + template void _specials(); }; ConstantsTest::ConstantsTest() { - addTests({&ConstantsTest::constantsFloat, - &ConstantsTest::constantsDouble}); + addTests({&ConstantsTest::constants, + &ConstantsTest::specials}); } -void ConstantsTest::constantsFloat() { - constexpr Float a = Constants::sqrt2(); - constexpr Float b = Constants::sqrt3(); - CORRADE_COMPARE(Math::pow<2>(a), 2.0f); - CORRADE_COMPARE(Math::pow<2>(b), 3.0f); +void ConstantsTest::constants() { + _constants(); + #ifndef MAGNUM_TARGET_GLES + _constants(); + #endif } -void ConstantsTest::constantsDouble() { +void ConstantsTest::specials() { + _specials(); #ifndef MAGNUM_TARGET_GLES - constexpr Double c = Constants::sqrt2(); - constexpr Double d = Constants::sqrt3(); - CORRADE_COMPARE(Math::pow<2>(c), 2.0); - CORRADE_COMPARE(Math::pow<2>(d), 3.0); - #else - CORRADE_SKIP("Double precision is not supported when targeting OpenGL ES."); + _specials(); #endif } +template void ConstantsTest::_constants() { + constexpr T a = Constants::sqrt2(); + constexpr T b = Constants::sqrt3(); + CORRADE_COMPARE(Math::pow<2>(a), T(2)); + CORRADE_COMPARE(Math::pow<2>(b), T(3)); + + constexpr T c = Constants::pi(); + constexpr T d = Constants::piHalf(); + constexpr T e = Constants::tau(); + CORRADE_COMPARE(T(0.5)*c, d); + CORRADE_COMPARE(T(2.0)*c, e); + + constexpr T f = Constants::e(); + CORRADE_COMPARE(std::log(f), T(1)); +} + +template void ConstantsTest::_specials() { + constexpr T a = Constants::nan(); + CORRADE_VERIFY(std::isnan(a)); + CORRADE_VERIFY(a != a); + + constexpr T b = Constants::inf(); + CORRADE_VERIFY(std::isinf(b)); + + /* Clang complains that producing NaN is not constexpr */ + T h = Constants::inf() - Constants::inf(); + CORRADE_VERIFY(h != h); +} + }}} CORRADE_TEST_MAIN(Magnum::Math::Test::ConstantsTest) diff --git a/src/Magnum/Math/Test/DualComplexTest.cpp b/src/Magnum/Math/Test/DualComplexTest.cpp index ec6fb1c81..dd6a7bde8 100644 --- a/src/Magnum/Math/Test/DualComplexTest.cpp +++ b/src/Magnum/Math/Test/DualComplexTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,36 +31,35 @@ namespace Magnum { namespace Math { namespace Test { -class DualComplexTest: public Corrade::TestSuite::Tester { - public: - explicit DualComplexTest(); +struct DualComplexTest: Corrade::TestSuite::Tester { + explicit DualComplexTest(); - void construct(); - void constructDefault(); - void constructFromVector(); - void constructCopy(); + void construct(); + void constructDefault(); + void constructFromVector(); + void constructCopy(); - void isNormalized(); + void isNormalized(); - void multiply(); + void multiply(); - void lengthSquared(); - void length(); - void normalized(); + void lengthSquared(); + void length(); + void normalized(); - void complexConjugated(); - void dualConjugated(); - void conjugated(); - void inverted(); - void invertedNormalized(); + void complexConjugated(); + void dualConjugated(); + void conjugated(); + void inverted(); + void invertedNormalized(); - void rotation(); - void translation(); - void combinedTransformParts(); - void matrix(); - void transformPoint(); + void rotation(); + void translation(); + void combinedTransformParts(); + void matrix(); + void transformPoint(); - void debug(); + void debug(); }; typedef Math::Deg Deg; @@ -192,8 +191,7 @@ void DualComplexTest::invertedNormalized() { std::ostringstream o; Error::setOutput(&o); - DualComplex notInverted = DualComplex({-1.0f, -2.5f}, {}).invertedNormalized(); - CORRADE_VERIFY(notInverted != notInverted); + DualComplex({-1.0f, -2.5f}, {}).invertedNormalized(); CORRADE_COMPARE(o.str(), "Math::Complex::invertedNormalized(): complex number must be normalized\n"); DualComplex inverted = a.invertedNormalized(); diff --git a/src/Magnum/Math/Test/DualQuaternionTest.cpp b/src/Magnum/Math/Test/DualQuaternionTest.cpp index 318bf33c2..6d1c010fb 100644 --- a/src/Magnum/Math/Test/DualQuaternionTest.cpp +++ b/src/Magnum/Math/Test/DualQuaternionTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,35 +30,34 @@ namespace Magnum { namespace Math { namespace Test { -class DualQuaternionTest: public Corrade::TestSuite::Tester { - public: - explicit DualQuaternionTest(); +struct DualQuaternionTest: Corrade::TestSuite::Tester { + explicit DualQuaternionTest(); - void construct(); - void constructDefault(); - void constructFromVector(); - void constructCopy(); + void construct(); + void constructDefault(); + void constructFromVector(); + void constructCopy(); - void isNormalized(); + void isNormalized(); - void lengthSquared(); - void length(); - void normalized(); + void lengthSquared(); + void length(); + void normalized(); - void quaternionConjugated(); - void dualConjugated(); - void conjugated(); - void inverted(); - void invertedNormalized(); + void quaternionConjugated(); + void dualConjugated(); + void conjugated(); + void inverted(); + void invertedNormalized(); - void rotation(); - void translation(); - void combinedTransformParts(); - void matrix(); - void transformPoint(); - void transformPointNormalized(); + void rotation(); + void translation(); + void combinedTransformParts(); + void matrix(); + void transformPoint(); + void transformPointNormalized(); - void debug(); + void debug(); }; typedef Math::Deg Deg; @@ -283,8 +282,7 @@ void DualQuaternionTest::transformPointNormalized() { std::ostringstream o; Corrade::Utility::Error::setOutput(&o); - Vector3 notTransformed = (a*Dual(2)).transformPointNormalized(v); - CORRADE_VERIFY(notTransformed != notTransformed); + (a*Dual(2)).transformPointNormalized(v); CORRADE_COMPARE(o.str(), "Math::DualQuaternion::transformPointNormalized(): dual quaternion must be normalized\n"); Vector3 transformedA = a.transformPointNormalized(v); diff --git a/src/Magnum/Math/Test/DualTest.cpp b/src/Magnum/Math/Test/DualTest.cpp index e2afe2663..012ed07bb 100644 --- a/src/Magnum/Math/Test/DualTest.cpp +++ b/src/Magnum/Math/Test/DualTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,24 +30,23 @@ namespace Magnum { namespace Math { namespace Test { -class DualTest: public Corrade::TestSuite::Tester { - public: - explicit DualTest(); +struct DualTest: Corrade::TestSuite::Tester { + explicit DualTest(); - void construct(); - void constructDefault(); - void constructCopy(); + void construct(); + void constructDefault(); + void constructCopy(); - void compare(); + void compare(); - void addSubtract(); - void negated(); - void multiplyDivide(); + void addSubtract(); + void negated(); + void multiplyDivide(); - void conjugated(); - void sqrt(); + void conjugated(); + void sqrt(); - void debug(); + void debug(); }; typedef Math::Dual Dual; diff --git a/src/Magnum/Math/Test/FunctionsTest.cpp b/src/Magnum/Math/Test/FunctionsTest.cpp index c24bfa25c..62b3ac6cb 100644 --- a/src/Magnum/Math/Test/FunctionsTest.cpp +++ b/src/Magnum/Math/Test/FunctionsTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,6 +23,7 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include "Magnum/Math/Functions.h" @@ -30,47 +31,50 @@ namespace Magnum { namespace Math { namespace Test { -class FunctionsTest: public Corrade::TestSuite::Tester { - public: - FunctionsTest(); - - void min(); - void minList(); - void max(); - void maxList(); - void minmax(); - void sign(); - void abs(); - - void floor(); - void round(); - void ceil(); - - void sqrt(); - void sqrtInverted(); - void clamp(); - void lerp(); - void lerpInverted(); - void fma(); - void normalizeUnsigned(); - void normalizeSigned(); - void denormalizeUnsigned(); - void denormalizeSigned(); - void renormalizeUnsinged(); - void renormalizeSinged(); - - void normalizeTypeDeduction(); - - void pow(); - void log(); - void log2(); - void trigonometric(); - void trigonometricWithBase(); +struct FunctionsTest: Corrade::TestSuite::Tester { + explicit FunctionsTest(); + + void min(); + void minList(); + void max(); + void maxList(); + void minmax(); + void clamp(); + void nanPropagation(); + + void sign(); + void abs(); + + void floor(); + void round(); + void ceil(); + + void sqrt(); + void sqrtInverted(); + void lerp(); + void lerpInverted(); + void fma(); + void normalizeUnsigned(); + void normalizeSigned(); + void denormalizeUnsigned(); + void denormalizeSigned(); + void renormalizeUnsinged(); + void renormalizeSinged(); + + void normalizeTypeDeduction(); + + void pow(); + void log(); + void log2(); + void div(); + void trigonometric(); + void trigonometricWithBase(); }; typedef Math::Constants Constants; typedef Math::Deg Deg; typedef Math::Rad Rad; +typedef Math::Vector2 Vector2; typedef Math::Vector3 Vector3; typedef Math::Vector3 Vector3ub; typedef Math::Vector3 Vector3b; @@ -82,6 +86,9 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::max, &FunctionsTest::maxList, &FunctionsTest::minmax, + &FunctionsTest::clamp, + &FunctionsTest::nanPropagation, + &FunctionsTest::sign, &FunctionsTest::abs, @@ -91,7 +98,6 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::sqrt, &FunctionsTest::sqrtInverted, - &FunctionsTest::clamp, &FunctionsTest::lerp, &FunctionsTest::lerpInverted, &FunctionsTest::fma, @@ -107,6 +113,7 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::pow, &FunctionsTest::log, &FunctionsTest::log2, + &FunctionsTest::div, &FunctionsTest::trigonometric, &FunctionsTest::trigonometricWithBase}); } @@ -147,6 +154,28 @@ void FunctionsTest::minmax() { CORRADE_COMPARE_AS(Math::minmax(b, a), expectedVector, std::pair); } +void FunctionsTest::clamp() { + CORRADE_COMPARE(Math::clamp(0.5f, -1.0f, 5.0f), 0.5f); + CORRADE_COMPARE(Math::clamp(-1.6f, -1.0f, 5.0f), -1.0f); + CORRADE_COMPARE(Math::clamp(9.5f, -1.0f, 5.0f), 5.0f); + + CORRADE_COMPARE(Math::clamp(Vector3(0.5f, -1.6f, 9.5f), -1.0f, 5.0f), Vector3(0.5f, -1.0f, 5.0f)); +} + +void FunctionsTest::nanPropagation() { + CORRADE_COMPARE(Math::min(Constants::nan(), 5.0f), Constants::nan()); + CORRADE_COMPARE(Math::min(Vector2{Constants::nan(), 6.0f}, Vector2{5.0f})[0], Constants::nan()); + CORRADE_COMPARE(Math::min(Vector2{Constants::nan(), 6.0f}, Vector2{5.0f})[1], 5.0f); + + CORRADE_COMPARE(Math::max(Constants::nan(), 5.0f), Constants::nan()); + CORRADE_COMPARE(Math::max(Vector2{Constants::nan(), 4.0f}, Vector2{5.0f})[0], Constants::nan()); + CORRADE_COMPARE(Math::max(Vector2{Constants::nan(), 4.0f}, Vector2{5.0f})[1], 5.0f); + + CORRADE_COMPARE(Math::clamp(Constants::nan(), 2.0f, 6.0f), Constants::nan()); + CORRADE_COMPARE(Math::clamp(Vector2{Constants::nan(), 1.0f}, 2.0f, 6.0f)[0], Constants::nan()); + CORRADE_COMPARE(Math::clamp(Vector2{Constants::nan(), 1.0f}, 2.0f, 6.0f)[1], 2.0f); +} + void FunctionsTest::sign() { CORRADE_COMPARE(Math::sign(3516), 1); CORRADE_COMPARE(Math::sign(0.0f), 0.0f); @@ -194,14 +223,6 @@ void FunctionsTest::sqrtInverted() { CORRADE_COMPARE(Math::sqrtInverted(Vector3(1.0f, 4.0f, 16.0f)), Vector3(1.0f, 0.5f, 0.25f)); } -void FunctionsTest::clamp() { - CORRADE_COMPARE(Math::clamp(0.5f, -1.0f, 5.0f), 0.5f); - CORRADE_COMPARE(Math::clamp(-1.6f, -1.0f, 5.0f), -1.0f); - CORRADE_COMPARE(Math::clamp(9.5f, -1.0f, 5.0f), 5.0f); - - CORRADE_COMPARE(Math::clamp(Vector3(0.5f, -1.6f, 9.5f), -1.0f, 5.0f), Vector3(0.5f, -1.0f, 5.0f)); -} - void FunctionsTest::lerp() { /* Floating-point / integral scalar */ CORRADE_COMPARE(Math::lerp(2.0f, 5.0f, 0.5f), 3.5f); @@ -392,6 +413,13 @@ void FunctionsTest::log2() { CORRADE_COMPARE(Math::log2(2153), 11); } +void FunctionsTest::div() { + Int quotient, remainder; + std::tie(quotient, remainder) = Math::div(57, 6); + CORRADE_COMPARE(quotient, 9); + CORRADE_COMPARE(remainder, 3); +} + void FunctionsTest::trigonometric() { CORRADE_COMPARE(Math::sin(Deg(30.0f)), 0.5f); CORRADE_COMPARE(Math::sin(Rad(Constants::pi()/6)), 0.5f); diff --git a/src/Magnum/Math/Test/Matrix3Test.cpp b/src/Magnum/Math/Test/Matrix3Test.cpp index 6eafa7e6d..2b836ffcc 100644 --- a/src/Magnum/Math/Test/Matrix3Test.cpp +++ b/src/Magnum/Math/Test/Matrix3Test.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -56,36 +56,38 @@ template<> struct RectangularMatrixConverter<3, 3, float, Mat3> { namespace Test { -class Matrix3Test: public Corrade::TestSuite::Tester { - public: - Matrix3Test(); - - void construct(); - void constructIdentity(); - void constructZero(); - void constructConversion(); - void constructCopy(); - - void convert(); - - void isRigidTransformation(); - - void translation(); - void scaling(); - void rotation(); - void reflection(); - void projection(); - void fromParts(); - void rotationScalingPart(); - void rotationNormalizedPart(); - void rotationPart(); - void uniformScalingPart(); - void vectorParts(); - void invertedRigid(); - void transform(); - - void debug(); - void configuration(); +struct Matrix3Test: Corrade::TestSuite::Tester { + explicit Matrix3Test(); + + void construct(); + void constructIdentity(); + void constructZero(); + void constructConversion(); + void constructCopy(); + + void convert(); + + void isRigidTransformation(); + + void translation(); + void scaling(); + void rotation(); + void reflection(); + void reflectionIsScaling(); + void shearingX(); + void shearingY(); + void projection(); + void fromParts(); + void rotationScalingPart(); + void rotationNormalizedPart(); + void rotationPart(); + void uniformScalingPart(); + void vectorParts(); + void invertedRigid(); + void transform(); + + void debug(); + void configuration(); }; typedef Math::Deg Deg; @@ -110,6 +112,9 @@ Matrix3Test::Matrix3Test() { &Matrix3Test::scaling, &Matrix3Test::rotation, &Matrix3Test::reflection, + &Matrix3Test::reflectionIsScaling, + &Matrix3Test::shearingX, + &Matrix3Test::shearingY, &Matrix3Test::projection, &Matrix3Test::fromParts, &Matrix3Test::rotationScalingPart, @@ -265,6 +270,26 @@ void Matrix3Test::reflection() { CORRADE_COMPARE(actual, expected); } +void Matrix3Test::reflectionIsScaling() { + CORRADE_COMPARE(Matrix3::reflection(Vector2::yAxis()), Matrix3::scaling(Vector2::yScale(-1.0f))); +} + +void Matrix3Test::shearingX() { + constexpr Matrix3 a = Matrix3::shearingX(3.0f); + CORRADE_COMPARE(a, Matrix3({1.0f, 0.0f, 0.0f}, + {3.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector2(1.0f)), Vector2(4.0f, 1.0f)); +} + +void Matrix3Test::shearingY() { + constexpr Matrix3 a = Matrix3::shearingY(3.0f); + CORRADE_COMPARE(a, Matrix3({1.0f, 3.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector2(1.0f)), Vector2(1.0f, 4.0f)); +} + void Matrix3Test::projection() { Matrix3 expected({2.0f/4.0f, 0.0f, 0.0f}, { 0.0f, 2.0f/3.0f, 0.0f}, diff --git a/src/Magnum/Math/Test/Matrix4Test.cpp b/src/Magnum/Math/Test/Matrix4Test.cpp index 0403aaf68..6d8be959f 100644 --- a/src/Magnum/Math/Test/Matrix4Test.cpp +++ b/src/Magnum/Math/Test/Matrix4Test.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -58,41 +58,46 @@ template<> struct RectangularMatrixConverter<4, 4, float, Mat4> { namespace Test { -class Matrix4Test: public Corrade::TestSuite::Tester { - public: - Matrix4Test(); - - void construct(); - void constructIdentity(); - void constructZero(); - void constructConversion(); - void constructCopy(); - - void convert(); - - void isRigidTransformation(); - - void translation(); - void scaling(); - void rotation(); - void rotationX(); - void rotationY(); - void rotationZ(); - void reflection(); - void orthographicProjection(); - void perspectiveProjection(); - void perspectiveProjectionFov(); - void fromParts(); - void rotationScalingPart(); - void rotationNormalizedPart(); - void rotationPart(); - void uniformScalingPart(); - void vectorParts(); - void invertedRigid(); - void transform(); - - void debug(); - void configuration(); +struct Matrix4Test: Corrade::TestSuite::Tester { + explicit Matrix4Test(); + + void construct(); + void constructIdentity(); + void constructZero(); + void constructConversion(); + void constructCopy(); + + void convert(); + + void isRigidTransformation(); + + void translation(); + void scaling(); + void rotation(); + void rotationX(); + void rotationY(); + void rotationZ(); + void reflection(); + void reflectionIsScaling(); + void shearingXY(); + void shearingXZ(); + void shearingYZ(); + void orthographicProjection(); + void perspectiveProjection(); + void perspectiveProjectionFov(); + void lookAt(); + + void fromParts(); + void rotationScalingPart(); + void rotationNormalizedPart(); + void rotationPart(); + void uniformScalingPart(); + void vectorParts(); + void invertedRigid(); + void transform(); + + void debug(); + void configuration(); }; typedef Math::Deg Deg; @@ -101,6 +106,7 @@ typedef Math::Matrix4 Matrix4; typedef Math::Matrix4 Matrix4i; typedef Math::Matrix<3, Float> Matrix3x3; typedef Math::Vector3 Vector3; +typedef Math::Constants Constants; Matrix4Test::Matrix4Test() { addTests({&Matrix4Test::construct, @@ -120,9 +126,15 @@ Matrix4Test::Matrix4Test() { &Matrix4Test::rotationY, &Matrix4Test::rotationZ, &Matrix4Test::reflection, + &Matrix4Test::reflectionIsScaling, + &Matrix4Test::shearingXY, + &Matrix4Test::shearingXZ, + &Matrix4Test::shearingYZ, &Matrix4Test::orthographicProjection, &Matrix4Test::perspectiveProjection, &Matrix4Test::perspectiveProjectionFov, + &Matrix4Test::lookAt, + &Matrix4Test::fromParts, &Matrix4Test::rotationScalingPart, &Matrix4Test::rotationNormalizedPart, @@ -286,8 +298,8 @@ void Matrix4Test::rotationX() { {0.0f, 0.90096887f, 0.43388374f, 0.0f}, {0.0f, -0.43388374f, 0.90096887f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}); - CORRADE_COMPARE(Matrix4::rotation(Rad(Math::Constants::pi()/7), Vector3::xAxis()), matrix); - CORRADE_COMPARE(Matrix4::rotationX(Rad(Math::Constants::pi()/7)), matrix); + CORRADE_COMPARE(Matrix4::rotation(Rad(Constants::pi()/7), Vector3::xAxis()), matrix); + CORRADE_COMPARE(Matrix4::rotationX(Rad(Constants::pi()/7)), matrix); } void Matrix4Test::rotationY() { @@ -295,8 +307,8 @@ void Matrix4Test::rotationY() { { 0.0f, 1.0f, 0.0f, 0.0f}, {0.43388374f, 0.0f, 0.90096887f, 0.0f}, { 0.0f, 0.0f, 0.0f, 1.0f}); - CORRADE_COMPARE(Matrix4::rotation(Rad(Math::Constants::pi()/7), Vector3::yAxis()), matrix); - CORRADE_COMPARE(Matrix4::rotationY(Rad(Math::Constants::pi()/7)), matrix); + CORRADE_COMPARE(Matrix4::rotation(Rad(Constants::pi()/7), Vector3::yAxis()), matrix); + CORRADE_COMPARE(Matrix4::rotationY(Rad(Constants::pi()/7)), matrix); } void Matrix4Test::rotationZ() { @@ -304,8 +316,8 @@ void Matrix4Test::rotationZ() { {-0.43388374f, 0.90096887f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, 0.0f, 1.0f}); - CORRADE_COMPARE(Matrix4::rotation(Rad(Math::Constants::pi()/7), Vector3::zAxis()), matrix); - CORRADE_COMPARE(Matrix4::rotationZ(Rad(Math::Constants::pi()/7)), matrix); + CORRADE_COMPARE(Matrix4::rotation(Rad(Constants::pi()/7), Vector3::zAxis()), matrix); + CORRADE_COMPARE(Matrix4::rotationZ(Rad(Constants::pi()/7)), matrix); } void Matrix4Test::reflection() { @@ -328,6 +340,37 @@ void Matrix4Test::reflection() { CORRADE_COMPARE(actual, expected); } +void Matrix4Test::reflectionIsScaling() { + CORRADE_COMPARE(Matrix4::reflection(Vector3::yAxis()), Matrix4::scaling(Vector3::yScale(-1.0f))); +} + +void Matrix4Test::shearingXY() { + constexpr Matrix4 a = Matrix4::shearingXY(3.0f, -5.0f); + CORRADE_COMPARE(a, Matrix4({1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {3.0f, -5.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector3(1.0f)), Vector3(4.0f, -4.0f, 1.0f)); +} + +void Matrix4Test::shearingXZ() { + constexpr Matrix4 a = Matrix4::shearingXZ(3.0f, -5.0f); + CORRADE_COMPARE(a, Matrix4({1.0f, 0.0f, 0.0f, 0.0f}, + {3.0f, 1.0f, -5.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector3(1.0f)), Vector3(4.0f, 1.0f, -4.0f)); +} + +void Matrix4Test::shearingYZ() { + constexpr Matrix4 a = Matrix4::shearingYZ(3.0f, -5.0f); + CORRADE_COMPARE(a, Matrix4({1.0f, 3.0f, -5.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector3(1.0f)), Vector3(1.0f, 4.0f, -4.0f)); +} + void Matrix4Test::orthographicProjection() { Matrix4 expected({0.4f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.5f, 0.0f, 0.0f}, @@ -479,6 +522,44 @@ void Matrix4Test::transform() { CORRADE_COMPARE(a.transformPoint(v), Vector3(3.0f, -4.0f, 9.0f)); } +void Matrix4Test::lookAt() { + Matrix4 a = Matrix4::lookAt({0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f}); + CORRADE_VERIFY(a.isRigidTransformation()); + CORRADE_COMPARE(a, Matrix4({1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {0.0f, -1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f})); + + Matrix4 b = Matrix4::lookAt({100.0f, 200.0f, 300.0f}, + { 0.0f, 0.0f, 0.0f}, + { 0.0f, 1.0f, 0.0f}); + CORRADE_VERIFY(b.isRigidTransformation()); + CORRADE_COMPARE(b, Matrix4({ 0.948683f, 0.0f, -0.316228f, 0.0f}, + {-0.169031f, 0.845154f, -0.507093f, 0.0f}, + { 0.267261f, 0.534522f, 0.801784f, 0.0f}, + { 100.0f, 200.0f, 300.0f, 1.0f})); + + Matrix4 c = Matrix4::lookAt({3.0f, 0.0f, 0.0f}, + {0.0f, 4.0f, 5.0f}, + {0.0f, 0.0f, 1.0f}); + CORRADE_VERIFY(c.isRigidTransformation()); + CORRADE_COMPARE(c, Matrix4({ 0.8f, 0.6f, 0.0f, 0.0f}, + {0.424264f, -0.565685f, 0.707107f, 0.0f}, + {0.424264f, -0.565685f, -0.707107f, 0.0f}, + { 3.0f, 0.0f, 0.0f, 1.0f})); + + Matrix4 d = Matrix4::lookAt({ 0.0f, 3.0f, 0.0f}, + {-5.0f, 0.0f, -4.0f}, + { 0.0f, 1.0f, 0.0f}); + CORRADE_VERIFY(d.isRigidTransformation()); + CORRADE_COMPARE(d, Matrix4({ 0.624695f, 0.0f, -0.780869f, 0.0f}, + {-0.331295f, 0.905539f, -0.265036f, 0.0f}, + { 0.707107f, 0.424264f, 0.565685f, 0.0f}, + { 0.0f, 3.0f, 0.0f, 1.0f})); +} + void Matrix4Test::debug() { Matrix4 m({3.0f, 5.0f, 8.0f, 4.0f}, {4.0f, 4.0f, 7.0f, 3.0f}, diff --git a/src/Magnum/Math/Test/MatrixTest.cpp b/src/Magnum/Math/Test/MatrixTest.cpp index 74795bfcd..c210d6993 100644 --- a/src/Magnum/Math/Test/MatrixTest.cpp +++ b/src/Magnum/Math/Test/MatrixTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -56,31 +56,30 @@ template<> struct RectangularMatrixConverter<3, 3, float, Mat3> { namespace Test { -class MatrixTest: public Corrade::TestSuite::Tester { - public: - MatrixTest(); +struct MatrixTest: Corrade::TestSuite::Tester { + explicit MatrixTest(); - void construct(); - void constructIdentity(); - void constructZero(); - void constructConversion(); - void constructCopy(); + void construct(); + void constructIdentity(); + void constructZero(); + void constructConversion(); + void constructCopy(); - void convert(); + void convert(); - void isOrthogonal(); + void isOrthogonal(); - void trace(); - void ij(); - void determinant(); - void inverted(); - void invertedOrthogonal(); + void trace(); + void ij(); + void determinant(); + void inverted(); + void invertedOrthogonal(); - void subclassTypes(); - void subclass(); + void subclassTypes(); + void subclass(); - void debug(); - void configuration(); + void debug(); + void configuration(); }; typedef Matrix<4, Float> Matrix4x4; diff --git a/src/Magnum/Math/Test/QuaternionTest.cpp b/src/Magnum/Math/Test/QuaternionTest.cpp index a4a064bcf..cf3c8dd50 100644 --- a/src/Magnum/Math/Test/QuaternionTest.cpp +++ b/src/Magnum/Math/Test/QuaternionTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,41 +31,40 @@ namespace Magnum { namespace Math { namespace Test { -class QuaternionTest: public Corrade::TestSuite::Tester { - public: - explicit QuaternionTest(); - - void construct(); - void constructDefault(); - void constructFromVector(); - void constructCopy(); - - void compare(); - void isNormalized(); - - void addSubtract(); - void negated(); - void multiplyDivideScalar(); - void multiply(); - - void dot(); - void dotSelf(); - void length(); - void normalized(); - - void conjugated(); - void inverted(); - void invertedNormalized(); - - void rotation(); - void angle(); - void matrix(); - void lerp(); - void slerp(); - void transformVector(); - void transformVectorNormalized(); - - void debug(); +struct QuaternionTest: Corrade::TestSuite::Tester { + explicit QuaternionTest(); + + void construct(); + void constructDefault(); + void constructFromVector(); + void constructCopy(); + + void compare(); + void isNormalized(); + + void addSubtract(); + void negated(); + void multiplyDivideScalar(); + void multiply(); + + void dot(); + void dotSelf(); + void length(); + void normalized(); + + void conjugated(); + void inverted(); + void invertedNormalized(); + + void rotation(); + void angle(); + void matrix(); + void lerp(); + void slerp(); + void transformVector(); + void transformVectorNormalized(); + + void debug(); }; typedef Math::Deg Deg; @@ -185,7 +184,7 @@ void QuaternionTest::dot() { Quaternion a({ 1.0f, 3.0f, -2.0f}, -4.0f); Quaternion b({-0.5f, 1.5f, 3.0f}, 12.0f); - CORRADE_COMPARE(Quaternion::dot(a, b), -50.0f); + CORRADE_COMPARE(Math::dot(a, b), -50.0f); } void QuaternionTest::dotSelf() { @@ -221,9 +220,7 @@ void QuaternionTest::invertedNormalized() { std::ostringstream o; Error::setOutput(&o); - Quaternion notInverted = a.invertedNormalized(); - CORRADE_COMPARE(notInverted.vector(), Vector3()); - CORRADE_COMPARE(notInverted.scalar(), std::numeric_limits::quiet_NaN()); + a.invertedNormalized(); CORRADE_COMPARE(o.str(), "Math::Quaternion::invertedNormalized(): quaternion must be normalized\n"); Quaternion aNormalized = a.normalized(); @@ -263,20 +260,18 @@ void QuaternionTest::rotation() { void QuaternionTest::angle() { std::ostringstream o; Error::setOutput(&o); - auto angle = Quaternion::angle(Quaternion({1.0f, 2.0f, -3.0f}, -4.0f).normalized(), {{4.0f, -3.0f, 2.0f}, -1.0f}); - CORRADE_VERIFY(angle != angle); - CORRADE_COMPARE(o.str(), "Math::Quaternion::angle(): quaternions must be normalized\n"); + Math::angle(Quaternion({1.0f, 2.0f, -3.0f}, -4.0f).normalized(), {{4.0f, -3.0f, 2.0f}, -1.0f}); + CORRADE_COMPARE(o.str(), "Math::angle(): quaternions must be normalized\n"); o.str({}); - angle = Quaternion::angle({{1.0f, 2.0f, -3.0f}, -4.0f}, Quaternion({4.0f, -3.0f, 2.0f}, -1.0f).normalized()); - CORRADE_VERIFY(angle != angle); - CORRADE_COMPARE(o.str(), "Math::Quaternion::angle(): quaternions must be normalized\n"); + Math::angle({{1.0f, 2.0f, -3.0f}, -4.0f}, Quaternion({4.0f, -3.0f, 2.0f}, -1.0f).normalized()); + CORRADE_COMPARE(o.str(), "Math::angle(): quaternions must be normalized\n"); /* Verify also that the angle is the same as angle between 4D vectors */ - angle = Quaternion::angle(Quaternion({1.0f, 2.0f, -3.0f}, -4.0f).normalized(), - Quaternion({4.0f, -3.0f, 2.0f}, -1.0f).normalized()); - CORRADE_COMPARE(angle, Vector4::angle(Vector4(1.0f, 2.0f, -3.0f, -4.0f).normalized(), - Vector4(4.0f, -3.0f, 2.0f, -1.0f).normalized())); + Rad angle = Math::angle(Quaternion({1.0f, 2.0f, -3.0f}, -4.0f).normalized(), + Quaternion({4.0f, -3.0f, 2.0f}, -1.0f).normalized()); + CORRADE_COMPARE(angle, Math::angle(Vector4(1.0f, 2.0f, -3.0f, -4.0f).normalized(), + Vector4(4.0f, -3.0f, 2.0f, -1.0f).normalized())); CORRADE_COMPARE(angle, Rad(1.704528f)); } @@ -313,18 +308,14 @@ void QuaternionTest::lerp() { std::ostringstream o; Corrade::Utility::Error::setOutput(&o); - Quaternion notLerpA = Quaternion::lerp(a*3.0f, b, 0.35f); - CORRADE_COMPARE(notLerpA.vector(), Vector3()); - CORRADE_COMPARE(notLerpA.scalar(), std::numeric_limits::quiet_NaN()); - CORRADE_COMPARE(o.str(), "Math::Quaternion::lerp(): quaternions must be normalized\n"); + Math::lerp(a*3.0f, b, 0.35f); + CORRADE_COMPARE(o.str(), "Math::lerp(): quaternions must be normalized\n"); o.str({}); - Quaternion notLerpB = Quaternion::lerp(a, b*-3.0f, 0.35f); - CORRADE_COMPARE(notLerpB.vector(), Vector3()); - CORRADE_COMPARE(notLerpB.scalar(), std::numeric_limits::quiet_NaN()); - CORRADE_COMPARE(o.str(), "Math::Quaternion::lerp(): quaternions must be normalized\n"); + Math::lerp(a, b*-3.0f, 0.35f); + CORRADE_COMPARE(o.str(), "Math::lerp(): quaternions must be normalized\n"); - Quaternion lerp = Quaternion::lerp(a, b, 0.35f); + Quaternion lerp = Math::lerp(a, b, 0.35f); CORRADE_COMPARE(lerp, Quaternion({0.119127f, 0.049134f, 0.049134f}, 0.990445f)); } @@ -335,18 +326,14 @@ void QuaternionTest::slerp() { std::ostringstream o; Corrade::Utility::Error::setOutput(&o); - Quaternion notSlerpA = Quaternion::slerp(a*3.0f, b, 0.35f); - CORRADE_COMPARE(notSlerpA.vector(), Vector3()); - CORRADE_COMPARE(notSlerpA.scalar(), std::numeric_limits::quiet_NaN()); - CORRADE_COMPARE(o.str(), "Math::Quaternion::slerp(): quaternions must be normalized\n"); + Math::slerp(a*3.0f, b, 0.35f); + CORRADE_COMPARE(o.str(), "Math::slerp(): quaternions must be normalized\n"); o.str({}); - Quaternion notSlerpB = Quaternion::slerp(a, b*-3.0f, 0.35f); - CORRADE_COMPARE(notSlerpB.vector(), Vector3()); - CORRADE_COMPARE(notSlerpB.scalar(), std::numeric_limits::quiet_NaN()); - CORRADE_COMPARE(o.str(), "Math::Quaternion::slerp(): quaternions must be normalized\n"); + Math::slerp(a, b*-3.0f, 0.35f); + CORRADE_COMPARE(o.str(), "Math::slerp(): quaternions must be normalized\n"); - Quaternion slerp = Quaternion::slerp(a, b, 0.35f); + Quaternion slerp = Math::slerp(a, b, 0.35f); CORRADE_COMPARE(slerp, Quaternion({0.1191653f, 0.0491109f, 0.0491109f}, 0.9904423f)); } @@ -367,8 +354,7 @@ void QuaternionTest::transformVectorNormalized() { std::ostringstream o; Error::setOutput(&o); - Vector3 notRotated = (a*2).transformVectorNormalized(v); - CORRADE_VERIFY(notRotated != notRotated); + (a*2).transformVectorNormalized(v); CORRADE_COMPARE(o.str(), "Math::Quaternion::transformVectorNormalized(): quaternion must be normalized\n"); Vector3 rotated = a.transformVectorNormalized(v); diff --git a/src/Magnum/Math/Test/RangeTest.cpp b/src/Magnum/Math/Test/RangeTest.cpp index dc3b87c14..6e842d8da 100644 --- a/src/Magnum/Math/Test/RangeTest.cpp +++ b/src/Magnum/Math/Test/RangeTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,40 +29,31 @@ #include "Magnum/Math/Range.h" -#ifdef MAGNUM_BUILD_DEPRECATED -#include "Magnum/Math/Geometry/Rectangle.h" -#endif - namespace Magnum { namespace Math { namespace Test { -class RangeTest: public Corrade::TestSuite::Tester { - public: - RangeTest(); +struct RangeTest: Corrade::TestSuite::Tester { + explicit RangeTest(); - void construct(); - void constructDefault(); - void constructFromSize(); - void constructConversion(); - void constructCopy(); + void construct(); + void constructDefault(); + void constructFromSize(); + void constructConversion(); + void constructCopy(); - void access(); - void compare(); - void size(); - void center(); + void access(); + void compare(); + void size(); + void center(); - void translated(); - void padded(); - void scaled(); + void translated(); + void padded(); + void scaled(); - void subclassTypes(); - void subclass(); + void subclassTypes(); + void subclass(); - #ifdef MAGNUM_BUILD_DEPRECATED - void deprecated(); - #endif - - void debug(); - void configuration(); + void debug(); + void configuration(); }; #ifndef CORRADE_GCC46_COMPATIBILITY @@ -101,10 +92,6 @@ RangeTest::RangeTest() { &RangeTest::subclassTypes, &RangeTest::subclass, - #ifdef MAGNUM_BUILD_DEPRECATED - &RangeTest::deprecated, - #endif - &RangeTest::debug, &RangeTest::configuration}); } @@ -357,32 +344,6 @@ void RangeTest::debug() { CORRADE_COMPARE(o.str(), "Range({34, 23}, {47, 30})\n"); } -#ifdef MAGNUM_BUILD_DEPRECATED -void RangeTest::deprecated() { - typedef Geometry::Rectangle Rectangle; - typedef Geometry::Rectangle Rectanglei; - - Rectanglei a({45, 23}, {-17, 35}); - CORRADE_COMPARE(Rectanglei(), Range2Di({0, 0}, {0, 0})); - CORRADE_COMPARE(a, Range2Di({45, 23}, {-17, 35})); - CORRADE_COMPARE(Rectanglei(a), Range2Di({45, 23}, {-17, 35})); - CORRADE_COMPARE(Rectangle(a), Range2D({45.0f, 23.0f}, {-17.0f, 35.0f})); - - CORRADE_COMPARE(a.width(), -62); - CORRADE_COMPARE(a.height(), 12); - - CORRADE_VERIFY(!(std::is_convertible::value)); - - Corrade::Utility::Configuration c; - Rectangle rect({3.0f, 3.125f}, {9.0f, 9.55f}); - std::string value("3 3.125 9 9.55"); - - c.setValue("rectangle", rect); - CORRADE_COMPARE(c.value("rectangle"), value); - CORRADE_COMPARE(c.value("rectangle"), rect); -} -#endif - void RangeTest::configuration() { Corrade::Utility::Configuration c; diff --git a/src/Magnum/Math/Test/RectangularMatrixTest.cpp b/src/Magnum/Math/Test/RectangularMatrixTest.cpp index f88f173a4..bf0111342 100644 --- a/src/Magnum/Math/Test/RectangularMatrixTest.cpp +++ b/src/Magnum/Math/Test/RectangularMatrixTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -54,39 +54,38 @@ template<> struct RectangularMatrixConverter<2, 3, float, Mat2x3> { namespace Test { -class RectangularMatrixTest: public Corrade::TestSuite::Tester { - public: - RectangularMatrixTest(); +struct RectangularMatrixTest: Corrade::TestSuite::Tester { + explicit RectangularMatrixTest(); - void construct(); - void constructDefault(); - void constructConversion(); - void constructFromData(); - void constructFromDiagonal(); - void constructCopy(); + void construct(); + void constructDefault(); + void constructConversion(); + void constructFromData(); + void constructFromDiagonal(); + void constructCopy(); - void convert(); - void data(); - void row(); + void convert(); + void data(); + void row(); - void compare(); + void compare(); - void negative(); - void addSubtract(); - void multiplyDivide(); - void multiply(); - void multiplyVector(); + void negative(); + void addSubtract(); + void multiplyDivide(); + void multiply(); + void multiplyVector(); - void transposed(); - void diagonal(); + void transposed(); + void diagonal(); - void vector(); + void vector(); - void subclassTypes(); - void subclass(); + void subclassTypes(); + void subclass(); - void debug(); - void configuration(); + void debug(); + void configuration(); }; typedef RectangularMatrix<4, 3, Float> Matrix4x3; diff --git a/src/Magnum/Math/Test/SwizzleTest.cpp b/src/Magnum/Math/Test/SwizzleTest.cpp index 39abd7de7..c1c240f22 100644 --- a/src/Magnum/Math/Test/SwizzleTest.cpp +++ b/src/Magnum/Math/Test/SwizzleTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,14 +29,13 @@ namespace Magnum { namespace Math { namespace Test { -class SwizzleTest: public Corrade::TestSuite::Tester { - public: - SwizzleTest(); +struct SwizzleTest: Corrade::TestSuite::Tester { + explicit SwizzleTest(); - void components(); - void constants(); - void rgba(); - void sizes(); + void components(); + void constants(); + void rgba(); + void sizes(); }; typedef Vector<4, Int> Vector4i; diff --git a/src/Magnum/Math/Test/TypeTraitsTest.cpp b/src/Magnum/Math/Test/TypeTraitsTest.cpp index ebdc96466..515b3caf3 100644 --- a/src/Magnum/Math/Test/TypeTraitsTest.cpp +++ b/src/Magnum/Math/Test/TypeTraitsTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,23 +23,22 @@ DEALINGS IN THE SOFTWARE. */ -#include #include #include "Magnum/Math/TypeTraits.h" +#include "Magnum/Math/Constants.h" namespace Magnum { namespace Math { namespace Test { -class TypeTraitsTest: public Corrade::TestSuite::Tester { - public: - TypeTraitsTest(); +struct TypeTraitsTest: Corrade::TestSuite::Tester { + explicit TypeTraitsTest(); - void equalsIntegral(); - void equalsFloatingPoint0(); - void equalsFloatingPoint1(); - void equalsFloatingPointLarge(); - void equalsFloatingPointInfinity(); - void equalsFloatingPointNaN(); + void equalsIntegral(); + void equalsFloatingPoint0(); + void equalsFloatingPoint1(); + void equalsFloatingPointLarge(); + void equalsFloatingPointInfinity(); + void equalsFloatingPointNaN(); private: template void _equalsIntegral(); @@ -118,8 +117,8 @@ void TypeTraitsTest::equalsFloatingPointInfinity() { } template void TypeTraitsTest::_equalsFloatingPointInfinity() { - CORRADE_VERIFY(TypeTraits::equals(std::numeric_limits::infinity(), - std::numeric_limits::infinity())); + CORRADE_VERIFY(TypeTraits::equals(Constants::inf(), + Constants::inf())); } void TypeTraitsTest::equalsFloatingPointNaN() { @@ -130,8 +129,8 @@ void TypeTraitsTest::equalsFloatingPointNaN() { } template void TypeTraitsTest::_equalsFloatingPointNaN() { - CORRADE_VERIFY(!TypeTraits::equals(std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN())); + CORRADE_VERIFY(!TypeTraits::equals(Constants::nan(), + Constants::nan())); } }}} diff --git a/src/Magnum/Math/Test/UnitTest.cpp b/src/Magnum/Math/Test/UnitTest.cpp index adae64f11..cfe0afb26 100644 --- a/src/Magnum/Math/Test/UnitTest.cpp +++ b/src/Magnum/Math/Test/UnitTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,18 +29,17 @@ namespace Magnum { namespace Math { namespace Test { -class UnitTest: public Corrade::TestSuite::Tester { - public: - explicit UnitTest(); +struct UnitTest: Corrade::TestSuite::Tester { + explicit UnitTest(); - void construct(); - void constructDefault(); - void constructConversion(); - void compare(); + void construct(); + void constructDefault(); + void constructConversion(); + void compare(); - void negated(); - void addSubtract(); - void multiplyDivide(); + void negated(); + void addSubtract(); + void multiplyDivide(); }; UnitTest::UnitTest() { diff --git a/src/Magnum/Math/Test/Vector2Test.cpp b/src/Magnum/Math/Test/Vector2Test.cpp index be76ead60..bcf14643a 100644 --- a/src/Magnum/Math/Test/Vector2Test.cpp +++ b/src/Magnum/Math/Test/Vector2Test.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -27,7 +27,7 @@ #include #include -#include "Magnum/Math/Vector3.h" /* Vector3 used in Vector2::cross() */ +#include "Magnum/Math/Vector3.h" /* Vector3 used in Vector2Test::cross() */ struct Vec2 { float x, y; @@ -51,29 +51,28 @@ template<> struct VectorConverter<2, float, Vec2> { namespace Test { -class Vector2Test: public Corrade::TestSuite::Tester { - public: - Vector2Test(); - - void construct(); - void constructDefault(); - void constructOneValue(); - void constructConversion(); - void constructCopy(); - - void convert(); - - void access(); - void cross(); - void axes(); - void scales(); - void perpendicular(); - void aspectRatio(); - void minmax(); - - void swizzleType(); - void debug(); - void configuration(); +struct Vector2Test: Corrade::TestSuite::Tester { + explicit Vector2Test(); + + void construct(); + void constructDefault(); + void constructOneValue(); + void constructConversion(); + void constructCopy(); + + void convert(); + + void access(); + void cross(); + void axes(); + void scales(); + void perpendicular(); + void aspectRatio(); + void minmax(); + + void swizzleType(); + void debug(); + void configuration(); }; typedef Math::Vector3 Vector3i; @@ -185,8 +184,8 @@ void Vector2Test::cross() { Vector2i a(1, -1); Vector2i b(4, 3); - CORRADE_COMPARE(Vector2i::cross(a, b), 7); - CORRADE_COMPARE(Vector3i::cross({a, 0}, {b, 0}), Vector3i(0, 0, Vector2i::cross(a, b))); + CORRADE_COMPARE(Math::cross(a, b), 7); + CORRADE_COMPARE(Math::cross({a, 0}, {b, 0}), Vector3i(0, 0, Math::cross(a, b))); } void Vector2Test::axes() { @@ -206,7 +205,7 @@ void Vector2Test::scales() { void Vector2Test::perpendicular() { const Vector2 a(0.5f, -15.0f); CORRADE_COMPARE(a.perpendicular(), Vector2(15.0f, 0.5f)); - CORRADE_COMPARE(Vector2::dot(a.perpendicular(), a), 0.0f); + CORRADE_COMPARE(dot(a.perpendicular(), a), 0.0f); CORRADE_COMPARE(Vector2::xAxis().perpendicular(), Vector2::yAxis()); } diff --git a/src/Magnum/Math/Test/Vector3Test.cpp b/src/Magnum/Math/Test/Vector3Test.cpp index 07f23e2b7..98b2784f4 100644 --- a/src/Magnum/Math/Test/Vector3Test.cpp +++ b/src/Magnum/Math/Test/Vector3Test.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -51,28 +51,27 @@ template<> struct VectorConverter<3, float, Vec3> { namespace Test { -class Vector3Test: public Corrade::TestSuite::Tester { - public: - Vector3Test(); +struct Vector3Test: Corrade::TestSuite::Tester { + explicit Vector3Test(); - void construct(); - void constructDefault(); - void constructOneValue(); - void constructParts(); - void constructConversion(); - void constructCopy(); + void construct(); + void constructDefault(); + void constructOneValue(); + void constructParts(); + void constructConversion(); + void constructCopy(); - void convert(); + void convert(); - void access(); - void cross(); - void axes(); - void scales(); - void twoComponent(); + void access(); + void cross(); + void axes(); + void scales(); + void twoComponent(); - void swizzleType(); - void debug(); - void configuration(); + void swizzleType(); + void debug(); + void configuration(); }; typedef Math::Vector3 Vector3; @@ -202,7 +201,7 @@ void Vector3Test::cross() { Vector3i a(1, -1, 1); Vector3i b(4, 3, 7); - CORRADE_COMPARE(Vector3i::cross(a, b), Vector3i(-10, -3, 7)); + CORRADE_COMPARE(Math::cross(a, b), Vector3i(-10, -3, 7)); } void Vector3Test::axes() { diff --git a/src/Magnum/Math/Test/Vector4Test.cpp b/src/Magnum/Math/Test/Vector4Test.cpp index 68cd975a2..2c3d9b08d 100644 --- a/src/Magnum/Math/Test/Vector4Test.cpp +++ b/src/Magnum/Math/Test/Vector4Test.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -51,26 +51,26 @@ template<> struct VectorConverter<4, float, Vec4> { namespace Test { -class Vector4Test: public Corrade::TestSuite::Tester { - public: - Vector4Test(); +struct Vector4Test: Corrade::TestSuite::Tester { + explicit Vector4Test(); - void construct(); - void constructDefault(); - void constructOneValue(); - void constructParts(); - void constructConversion(); - void constructCopy(); + void construct(); + void constructPad(); + void constructDefault(); + void constructOneValue(); + void constructParts(); + void constructConversion(); + void constructCopy(); - void convert(); + void convert(); - void access(); - void threeComponent(); - void twoComponent(); + void access(); + void threeComponent(); + void twoComponent(); - void swizzleType(); - void debug(); - void configuration(); + void swizzleType(); + void debug(); + void configuration(); }; typedef Math::Vector4 Vector4; @@ -80,6 +80,7 @@ typedef Math::Vector2 Vector2; Vector4Test::Vector4Test() { addTests({&Vector4Test::construct, + &Vector4Test::constructPad, &Vector4Test::constructDefault, &Vector4Test::constructOneValue, &Vector4Test::constructParts, @@ -106,6 +107,16 @@ void Vector4Test::construct() { CORRADE_COMPARE(a, (Vector<4, Float>(1.0f, -2.5f, 3.0f, 4.1f))); } +void Vector4Test::constructPad() { + constexpr Vector<2, Float> a{3.0f, -1.0f}; + constexpr Vector4 b = Vector4::pad(a); + constexpr Vector4 c = Vector4::pad(a, 5.0f); + constexpr Vector4 d = Vector4::pad(a, 5.0f, 1.0f); + CORRADE_COMPARE(b, Vector4(3.0f, -1.0f, 0.0f, 0.0f)); + CORRADE_COMPARE(c, Vector4(3.0f, -1.0f, 5.0f, 5.0f)); + CORRADE_COMPARE(d, Vector4(3.0f, -1.0f, 5.0f, 1.0f)); +} + void Vector4Test::constructDefault() { constexpr Vector4 a; CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); diff --git a/src/Magnum/Math/Test/VectorTest.cpp b/src/Magnum/Math/Test/VectorTest.cpp index a7fc42247..c582f7cc2 100644 --- a/src/Magnum/Math/Test/VectorTest.cpp +++ b/src/Magnum/Math/Test/VectorTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -51,57 +51,57 @@ template<> struct VectorConverter<3, float, Vec3> { namespace Test { -class VectorTest: public Corrade::TestSuite::Tester { - public: - VectorTest(); - - void construct(); - void constructFromData(); - void constructDefault(); - void constructOneValue(); - void constructOneComponent(); - void constructConversion(); - void constructCopy(); - - void isZero(); - void isNormalized(); - - void convert(); - void data(); - - void negative(); - void addSubtract(); - void multiplyDivide(); - void multiplyDivideIntegral(); - void multiplyDivideComponentWise(); - void multiplyDivideComponentWiseIntegral(); - void modulo(); - void bitwise(); - - void compare(); - void compareComponentWise(); - - void dot(); - void dotSelf(); - void length(); - void lengthInverted(); - void normalized(); - void resized(); - - void sum(); - void product(); - void min(); - void max(); - - void projected(); - void projectedOntoNormalized(); - void angle(); - - void subclassTypes(); - void subclass(); - - void debug(); - void configuration(); +struct VectorTest: Corrade::TestSuite::Tester { + explicit VectorTest(); + + void construct(); + void constructFromData(); + void constructPad(); + void constructDefault(); + void constructOneValue(); + void constructOneComponent(); + void constructConversion(); + void constructCopy(); + + void isZero(); + void isNormalized(); + + void convert(); + void data(); + + void negative(); + void addSubtract(); + void multiplyDivide(); + void multiplyDivideIntegral(); + void multiplyDivideComponentWise(); + void multiplyDivideComponentWiseIntegral(); + void modulo(); + void bitwise(); + + void compare(); + void compareComponentWise(); + + void dot(); + void dotSelf(); + void length(); + void lengthInverted(); + void normalized(); + void resized(); + + void sum(); + void product(); + void min(); + void max(); + + void projected(); + void projectedOntoNormalized(); + void angle(); + + void subclassTypes(); + void subclass(); + + void debug(); + void configuration(); }; typedef Math::Rad Rad; @@ -112,6 +112,7 @@ typedef Vector<4, Int> Vector4i; VectorTest::VectorTest() { addTests({&VectorTest::construct, &VectorTest::constructFromData, + &VectorTest::constructPad, &VectorTest::constructDefault, &VectorTest::constructOneValue, &VectorTest::constructOneComponent, @@ -169,6 +170,18 @@ void VectorTest::constructFromData() { CORRADE_COMPARE(Vector4::from(data), Vector4(1.0f, 2.0f, 3.0f, 4.0f)); } +void VectorTest::constructPad() { + constexpr Vector<2, Float> a{1.0f, -1.0f}; + constexpr Vector4 b = Vector4::pad(a); + constexpr Vector4 c = Vector4::pad(a, 5.0f); + CORRADE_COMPARE(b, Vector4(1.0f, -1.0f, 0.0f, 0.0f)); + CORRADE_COMPARE(c, Vector4(1.0f, -1.0f, 5.0f, 5.0f)); + + constexpr Vector<5, Float> d{1.0f, -1.0f, 8.0f, 2.3f, -1.1f}; + constexpr Vector4 e = Vector4::pad(d); + CORRADE_COMPARE(e, Vector4(1.0f, -1.0f, 8.0f, 2.3f)); +} + void VectorTest::constructDefault() { constexpr Vector4 a; CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); @@ -368,7 +381,7 @@ void VectorTest::bitwise() { } void VectorTest::dot() { - CORRADE_COMPARE(Vector4::dot({1.0f, 0.5f, 0.75f, 1.5f}, {2.0f, 4.0f, 1.0f, 7.0f}), 15.25f); + CORRADE_COMPARE(Math::dot(Vector4{1.0f, 0.5f, 0.75f, 1.5f}, {2.0f, 4.0f, 1.0f, 7.0f}), 15.25f); } void VectorTest::dotSelf() { @@ -427,11 +440,10 @@ void VectorTest::projectedOntoNormalized() { Vector3 vector(1.0f, 2.0f, 3.0f); Vector3 line(1.0f, -1.0f, 0.5f); - Vector3 projected = vector.projectedOntoNormalized(line); - CORRADE_VERIFY(projected != projected); + vector.projectedOntoNormalized(line); CORRADE_COMPARE(o.str(), "Math::Vector::projectedOntoNormalized(): line must be normalized\n"); - projected = vector.projectedOntoNormalized(line.normalized()); + Vector3 projected = vector.projectedOntoNormalized(line.normalized()); CORRADE_COMPARE(projected, Vector3(0.222222f, -0.222222f, 0.111111f)); CORRADE_COMPARE(projected.normalized(), line.normalized()); CORRADE_COMPARE(projected, vector.projected(line)); @@ -440,24 +452,22 @@ void VectorTest::projectedOntoNormalized() { void VectorTest::angle() { std::ostringstream o; Error::setOutput(&o); - auto angle = Vector3::angle(Vector3(2.0f, 3.0f, 4.0f).normalized(), {1.0f, -2.0f, 3.0f}); - CORRADE_VERIFY(angle != angle); - CORRADE_COMPARE(o.str(), "Math::Vector::angle(): vectors must be normalized\n"); + Math::angle(Vector3(2.0f, 3.0f, 4.0f).normalized(), {1.0f, -2.0f, 3.0f}); + CORRADE_COMPARE(o.str(), "Math::angle(): vectors must be normalized\n"); o.str({}); - angle = Vector3::angle({2.0f, 3.0f, 4.0f}, Vector3(1.0f, -2.0f, 3.0f).normalized()); - CORRADE_VERIFY(angle != angle); - CORRADE_COMPARE(o.str(), "Math::Vector::angle(): vectors must be normalized\n"); + Math::angle({2.0f, 3.0f, 4.0f}, Vector3(1.0f, -2.0f, 3.0f).normalized()); + CORRADE_COMPARE(o.str(), "Math::angle(): vectors must be normalized\n"); - CORRADE_COMPARE(Vector3::angle(Vector3(2.0f, 3.0f, 4.0f).normalized(), - Vector3(1.0f, -2.0f, 3.0f).normalized()), + CORRADE_COMPARE(Math::angle(Vector3(2.0f, 3.0f, 4.0f).normalized(), + Vector3(1.0f, -2.0f, 3.0f).normalized()), Rad(1.162514f)); } template class BasicVec2: public Math::Vector<2, T> { public: /* MSVC 2013 can't cope with {} here */ - template constexpr BasicVec2(U&&... args): Math::Vector<2, T>(std::forward(args)...) {} + template constexpr BasicVec2(U&&... args): Math::Vector<2, T>(args...) {} MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(2, BasicVec2) }; @@ -473,6 +483,9 @@ void VectorTest::subclassTypes() { CORRADE_VERIFY((std::is_same::value)); CORRADE_VERIFY((std::is_same::value)); + Vector<1, Float> one; + CORRADE_VERIFY((std::is_same::value)); + /* Const operators */ const Vec2 c; const Vec2 c2; @@ -540,6 +553,14 @@ void VectorTest::subclass() { const Float cdata[] = {1.0f, -2.0f}; CORRADE_COMPARE(Vec2::from(cdata), Vec2(1.0f, -2.0f)); + { + constexpr Vector<1, Float> a = 5.0f; + constexpr Vec2 b = Vec2::pad(a); + constexpr Vec2 c = Vec2::pad(a, -1.0f); + CORRADE_COMPARE(b, Vec2(5.0f, 0.0f)); + CORRADE_COMPARE(c, Vec2(5.0f, -1.0f)); + } + CORRADE_COMPARE(Vec2(-2.0f, 5.0f) + Vec2(1.0f, -3.0f), Vec2(-1.0f, 2.0f)); CORRADE_COMPARE(Vec2(-2.0f, 5.0f) - Vec2(1.0f, -3.0f), Vec2(-3.0f, 8.0f)); diff --git a/src/Magnum/Math/TypeTraits.h b/src/Magnum/Math/TypeTraits.h index 9502f51da..918ed2b6a 100644 --- a/src/Magnum/Math/TypeTraits.h +++ b/src/Magnum/Math/TypeTraits.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -162,7 +162,7 @@ template struct TypeTraitsFloatingPoint { /* Adapted from http://floating-point-gui.de/errors/comparison/ */ template bool TypeTraitsFloatingPoint::equals(const T a, const T b) { /* Shortcut for binary equality (also infinites) */ - if (a == b) return true; + if(a == b) return true; const T absA = std::abs(a); const T absB = std::abs(b); @@ -170,7 +170,7 @@ template bool TypeTraitsFloatingPoint::equals(const T a, const T b) /* One of the numbers is zero or both are extremely close to it, relative error is meaningless */ - if (a == T{} || b == T{} || difference < TypeTraits::epsilon()) + if(a == T{} || b == T{} || difference < TypeTraits::epsilon()) return difference < TypeTraits::epsilon(); /* Relative error */ diff --git a/src/Magnum/Math/Unit.h b/src/Magnum/Math/Unit.h index ec34599c4..abb6df479 100644 --- a/src/Magnum/Math/Unit.h +++ b/src/Magnum/Math/Unit.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index ede23fee0..7ed03f760 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,10 +30,10 @@ */ #include -#include #include -#include #include +#include +#include #include "Magnum/visibility.h" #include "Magnum/Math/Angle.h" @@ -46,9 +46,38 @@ namespace Implementation { template struct VectorConverter; } +/** @relatesalso Vector +@brief Dot product of two vectors + +Returns `0` when two vectors are perpendicular, `1` when two *normalized* +vectors are parallel and `-1` when two *normalized* vectors are antiparallel. @f[ + \boldsymbol a \cdot \boldsymbol b = \sum_{i=0}^{n-1} \boldsymbol a_i \boldsymbol b_i +@f] +@see @ref Vector::dot() const, @ref Vector::operator-(), @ref Vector2::perpendicular() +*/ +template inline T dot(const Vector& a, const Vector& b) { + return (a*b).sum(); +} + +/** @relatesalso Vector +@brief Angle between normalized vectors + +Expects that both vectors are normalized. @f[ + \theta = acos \left( \frac{\boldsymbol a \cdot \boldsymbol b}{|\boldsymbol a| |\boldsymbol b|} \right) = acos (\boldsymbol a \cdot \boldsymbol b) +@f] +@see @ref Vector::isNormalized(), + @ref angle(const Complex&, const Complex&), + @ref angle(const Quaternion&, const Quaternion&) +*/ +template inline Rad angle(const Vector& normalizedA, const Vector& normalizedB) { + CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), + "Math::angle(): vectors must be normalized", {}); + return Rad(std::acos(dot(normalizedA, normalizedB))); +} + /** -@brief %Vector -@tparam size %Vector size +@brief Vector +@tparam size Vector size @tparam T Underlying data type See @ref matrix-vector for brief introduction. @@ -66,10 +95,10 @@ template class Vector { public: typedef T Type; /**< @brief Underlying data type */ - const static std::size_t Size = size; /**< @brief %Vector size */ + const static std::size_t Size = size; /**< @brief Vector size */ /** - * @brief %Vector from array + * @brief Vector from array * @return Reference to the data as if it was Vector, thus doesn't * perform any copying. * @@ -85,31 +114,35 @@ template class Vector { } /** - * @brief Dot product + * @brief Pad vector * - * Returns `0` if two vectors are orthogonal, `1` if two *normalized* - * vectors are parallel and `-1` if two *normalized* vectors are - * antiparallel. @f[ - * \boldsymbol a \cdot \boldsymbol b = \sum_{i=0}^{n-1} \boldsymbol a_i \boldsymbol b_i - * @f] - * @see dot() const, @ref operator-(), - * @ref Vector2::perpendicular() - * @todoc Explicit reference when Doxygen can handle const + * If size of @p a is smaller than @ref Size, it is padded from right + * with @p value, otherwise it's cut. + * @see @ref Vector4::pad(const Vector&, T, T) */ - static T dot(const Vector& a, const Vector& b) { - return (a*b).sum(); + template constexpr static Vector pad(const Vector& a, T value = T(0)) { + return padInternal(typename Implementation::GenerateSequence::Type(), a, value); } + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Angle between normalized vectors - * - * Expects that both vectors are normalized. @f[ - * \theta = acos \left( \frac{\boldsymbol a \cdot \boldsymbol b}{|\boldsymbol a| |\boldsymbol b|} \right) = acos (\boldsymbol a \cdot \boldsymbol b) - * @f] - * @see @ref isNormalized(), @ref Quaternion::angle(), - * @ref Complex::angle() + * @copybrief Math::dot(const Vector&, const Vector&) + * @deprecated Use @ref Math::dot(const Vector&, const Vector&) + * instead. + */ + CORRADE_DEPRECATED("use Math::dot() instead") static T dot(const Vector& a, const Vector& b) { + return Math::dot(a, b); + } + + /** + * @copybrief Math::angle(const Vector&, const Vector&) + * @deprecated Use @ref Math::angle(const Vector&, const Vector&) + * instead. */ - static Rad angle(const Vector& normalizedA, const Vector& normalizedB); + CORRADE_DEPRECATED("use Math::angle() instead") static Rad angle(const Vector& normalizedA, const Vector& normalizedB) { + return Math::angle(normalizedA, normalizedB); + } + #endif /** * @brief Default constructor @@ -454,10 +487,10 @@ template class Vector { * @see @ref dot(const Vector&, const Vector&), * @ref isNormalized() */ - T dot() const { return dot(*this, *this); } + T dot() const { return Math::dot(*this, *this); } /** - * @brief %Vector length + * @brief Vector length * * See also @ref dot() const which is faster for comparing length with * other values. @f[ @@ -503,7 +536,7 @@ template class Vector { } /** - * @brief %Vector projected onto line + * @brief Vector projected onto line * * Returns vector projected onto @p line. @f[ * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b @@ -511,19 +544,18 @@ template class Vector { * @see @ref dot(), @ref projectedOntoNormalized() */ Vector projected(const Vector& line) const { - return line*dot(*this, line)/line.dot(); + return line*Math::dot(*this, line)/line.dot(); } /** - * @brief %Vector projected onto normalized line + * @brief Vector projected onto normalized line * * Slightly faster alternative to @ref projected(), expects @p line to * be normalized. @f[ * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b = * (\boldsymbol a \cdot \boldsymbol b) \boldsymbol b * @f] - * @see dot() const - * @todoc Explicit reference when Doxygen can handle const + * @see @ref dot() const */ Vector projectedOntoNormalized(const Vector& line) const; @@ -572,6 +604,10 @@ template class Vector { _data({Implementation::repeat(value, sequence)...}) {} #endif + template constexpr static Vector padInternal(Implementation::Sequence, const Vector& a, T value) { + return {sequence < otherSize ? a[sequence] : value...}; + } + #ifndef CORRADE_MSVC2013_COMPATIBILITY T _data[size]; #else @@ -1103,6 +1139,9 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit } \ static const Type& from(const T* data) { \ return *reinterpret_cast*>(data); \ + } \ + template constexpr static Type pad(const Math::Vector& a, T value = T(0)) { \ + return Math::Vector::pad(a, value); \ } \ \ Type& operator=(const Type& other) { \ @@ -1267,12 +1306,6 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit } #endif -template inline Rad Vector::angle(const Vector& normalizedA, const Vector& normalizedB) { - CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), - "Math::Vector::angle(): vectors must be normalized", Rad(std::numeric_limits::quiet_NaN())); - return Rad(std::acos(dot(normalizedA, normalizedB))); -} - template inline BoolVector Vector::operator<(const Vector& other) const { BoolVector out; @@ -1319,9 +1352,8 @@ template inline Vector Vector::oper } template inline Vector Vector::projectedOntoNormalized(const Vector& line) const { - CORRADE_ASSERT(line.isNormalized(), "Math::Vector::projectedOntoNormalized(): line must be normalized", - (Vector(std::numeric_limits::quiet_NaN()))); - return line*dot(*this, line); + CORRADE_ASSERT(line.isNormalized(), "Math::Vector::projectedOntoNormalized(): line must be normalized", {}); + return line*Math::dot(*this, line); } template inline T Vector::sum() const { diff --git a/src/Magnum/Math/Vector2.h b/src/Magnum/Math/Vector2.h index 5196c202d..cf44154a9 100644 --- a/src/Magnum/Math/Vector2.h +++ b/src/Magnum/Math/Vector2.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,6 +33,24 @@ namespace Magnum { namespace Math { +/** +@brief 2D cross product + +2D version of cross product, also called perp-dot product, equivalent to +calling @ref cross(const Vector3&, const Vector3&) with Z coordinate set +to `0` and extracting only Z coordinate from the result (X and Y coordinates +are always zero). Returns `0` either when one of the vectors is zero or they +are parallel or antiparallel and `1` when two *normalized* vectors are +perpendicular. @f[ + \boldsymbol a \times \boldsymbol b = \boldsymbol a_\bot \cdot \boldsymbol b = a_xb_y - a_yb_x +@f] +@see @ref Vector2::perpendicular(), + @ref dot(const Vector&, const Vector&) + */ +template inline T cross(const Vector2& a, const Vector2& b) { + return dot(a.perpendicular(), b); +} + /** @brief Two-component vector @tparam T Data type @@ -45,7 +63,7 @@ See @ref matrix-vector for brief introduction. template class Vector2: public Vector<2, T> { public: /** - * @brief %Vector in direction of X axis (right) + * @brief Vector in direction of X axis (right) * * Usable for translation in given axis, for example: * @code @@ -56,7 +74,7 @@ template class Vector2: public Vector<2, T> { constexpr static Vector2 xAxis(T length = T(1)) { return {length, T(0)}; } /** - * @brief %Vector in direction of Y axis (up) + * @brief Vector in direction of Y axis (up) * * See @ref xAxis() for more information. * @see @ref yScale(), @ref Matrix3::up() @@ -82,21 +100,16 @@ template class Vector2: public Vector<2, T> { */ constexpr static Vector2 yScale(T scale) { return {T(1), scale}; } + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief 2D cross product - * - * 2D version of cross product, also called perp-dot product, - * equivalent to calling @ref Vector3::cross() with Z coordinate set to - * `0` and extracting only Z coordinate from the result (X and Y - * coordinates are always zero). @f[ - * \boldsymbol a \times \boldsymbol b = \boldsymbol a_\bot \cdot \boldsymbol b = a_xb_y - a_yb_x - * @f] - * @see @ref perpendicular(), - * @ref dot(const Vector&, const Vector&) + * @copybrief Math::cross(const Vector2&, const Vector2&) + * @deprecated Use @ref Math::cross(const Vector2&, const Vector2&) + * instead. */ - static T cross(const Vector2& a, const Vector2& b) { - return Vector<2, T>::dot(a.perpendicular(), b); + CORRADE_DEPRECATED("use Math::cross() instead") static T cross(const Vector2& a, const Vector2& b) { + return Math::cross(a, b); } + #endif /** @copydoc Vector::Vector() */ constexpr /*implicit*/ Vector2() {} @@ -164,7 +177,9 @@ template class Vector2: public Vector<2, T> { MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(2, Vector2) }; +#ifndef DOXYGEN_GENERATING_OUTPUT MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(2, Vector2) +#endif /** @debugoperator{Magnum::Math::Vector2} */ template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Vector2& value) { diff --git a/src/Magnum/Math/Vector3.h b/src/Magnum/Math/Vector3.h index 87bbe4484..d5a38f5dc 100644 --- a/src/Magnum/Math/Vector3.h +++ b/src/Magnum/Math/Vector3.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,6 +34,27 @@ namespace Magnum { namespace Math { +/** +@brief Cross product + +Result has length of `0` either when one of them is zero or they are parallel +or antiparallel and length of `1` when two *normalized* vectors are +perpendicular. Done using the following equation: @f[ + \boldsymbol a \times \boldsymbol b = \begin{pmatrix} c_y \\ c_z \\ c_x \end{pmatrix} ~~~~~ + \boldsymbol c = \boldsymbol a \begin{pmatrix} b_y \\ b_z \\ b_x \end{pmatrix} - + \boldsymbol b \begin{pmatrix} a_y \\ a_z \\ a_x \end{pmatrix} +@f] +Which is equivalent to the common one (source: +https://twitter.com/sjb3d/status/563640846671953920): @f[ + \boldsymbol a \times \boldsymbol b = \begin{pmatrix}a_yb_z - a_zb_y \\ a_zb_x - a_xb_z \\ a_xb_y - a_yb_x \end{pmatrix} +@f] +@see @ref cross(const Vector2&, const Vector2&) +*/ +template inline Vector3 cross(const Vector3& a, const Vector3& b) { + return swizzle<'y', 'z', 'x'>(a*swizzle<'y', 'z', 'x'>(b) - + b*swizzle<'y', 'z', 'x'>(a)); +} + /** @brief Three-component vector @tparam T Data type @@ -46,7 +67,7 @@ See @ref matrix-vector for brief introduction. template class Vector3: public Vector<3, T> { public: /** - * @brief %Vector in direction of X axis (right) + * @brief Vector in direction of X axis (right) * * Usable for translation or rotation along given axis, for example: * @code @@ -59,7 +80,7 @@ template class Vector3: public Vector<3, T> { constexpr static Vector3 xAxis(T length = T(1)) { return {length, T(0), T(0)}; } /** - * @brief %Vector in direction of Y axis (up) + * @brief Vector in direction of Y axis (up) * * See @ref xAxis() for more information. * @see @ref yScale(), @ref Color3::green(), @ref Matrix4::up() @@ -67,7 +88,7 @@ template class Vector3: public Vector<3, T> { constexpr static Vector3 yAxis(T length = T(1)) { return {T(0), length, T(0)}; } /** - * @brief %Vector in direction of Z axis (backward) + * @brief Vector in direction of Z axis (backward) * * See @ref xAxis() for more information. * @see @ref zScale(), @ref Color3::blue(), @ref Matrix4::backward() @@ -101,19 +122,16 @@ template class Vector3: public Vector<3, T> { */ constexpr static Vector3 zScale(T scale) { return {T(1), T(1), scale}; } + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Cross product - * - * @f[ - * \boldsymbol a \times \boldsymbol b = - * \begin{pmatrix}a_yb_z - a_zb_y \\ a_zb_y - a_xb_z \\ a_xb_y - a_yb_x \end{pmatrix} - * @f] - * @see @ref Vector2::cross() + * @copybrief Math::cross(const Vector3&, const Vector3&) + * @deprecated Use @ref Math::cross(const Vector3&, const Vector3&) + * instead. */ - static Vector3 cross(const Vector3& a, const Vector3& b) { - return swizzle<'y', 'z', 'x'>(a)*swizzle<'z', 'x', 'y'>(b) - - swizzle<'z', 'x', 'y'>(a)*swizzle<'y', 'z', 'x'>(b); + CORRADE_DEPRECATED("use Math::cross() instead") static Vector3 cross(const Vector3& a, const Vector3& b) { + return Math::cross(a, b); } + #endif /** @copydoc Vector::Vector() */ constexpr /*implicit*/ Vector3() {} @@ -212,7 +230,9 @@ template class Vector3: public Vector<3, T> { MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(3, Vector3) }; +#ifndef DOXYGEN_GENERATING_OUTPUT MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(3, Vector3) +#endif /** @debugoperator{Magnum::Math::Vector3} */ template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Vector3& value) { diff --git a/src/Magnum/Math/Vector4.h b/src/Magnum/Math/Vector4.h index a7174f06d..4cd668db5 100644 --- a/src/Magnum/Math/Vector4.h +++ b/src/Magnum/Math/Vector4.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -44,6 +44,21 @@ See @ref matrix-vector for brief introduction. */ template class Vector4: public Vector<4, T> { public: + /** + * @brief Pad vector to four-component one + * + * If size of @p a is smaller than 4, it is padded from right with + * @p xyz for first three component and @p w for fourth component, + * otherwise it's cut. + * @see @ref pad(const Vector&, T) + */ + template constexpr static Vector4 pad(const Vector& a, T xyz, T w) { + return {0 < otherSize ? a[0] : xyz, + 1 < otherSize ? a[1] : xyz, + 2 < otherSize ? a[2] : xyz, + 3 < otherSize ? a[3] : w}; + } + /** @copydoc Vector::Vector() */ constexpr /*implicit*/ Vector4() {} @@ -176,7 +191,9 @@ template class Vector4: public Vector<4, T> { MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(4, Vector4) }; +#ifndef DOXYGEN_GENERATING_OUTPUT MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(4, Vector4) +#endif /** @debugoperator{Magnum::Math::Vector4} */ template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Vector4& value) { diff --git a/src/Magnum/Math/instantiation.cpp b/src/Magnum/Math/instantiation.cpp index cb2e09ac4..e0d70be44 100644 --- a/src/Magnum/Math/instantiation.cpp +++ b/src/Magnum/Math/instantiation.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Mesh.cpp b/src/Magnum/Mesh.cpp index 202ad4411..e124a8d6f 100644 --- a/src/Magnum/Mesh.cpp +++ b/src/Magnum/Mesh.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -27,6 +27,7 @@ #include +#include "Magnum/AbstractShaderProgram.h" #include "Magnum/Buffer.h" #include "Magnum/Context.h" #include "Magnum/Extensions.h" @@ -38,7 +39,9 @@ namespace Magnum { +#ifdef MAGNUM_BUILD_DEPRECATED Int Mesh::maxVertexAttributes() { return AbstractShaderProgram::maxVertexAttributes(); } +#endif #ifndef MAGNUM_TARGET_GLES2 Long Mesh::maxElementIndex() { @@ -129,27 +132,28 @@ Mesh::Mesh(Mesh&& other) noexcept: _id(other._id), _created{other._created}, _pr } Mesh& Mesh::operator=(Mesh&& other) noexcept { - std::swap(_id, other._id); - std::swap(_created, other._created); - std::swap(_primitive, other._primitive); - std::swap(_count, other._count); - std::swap(_baseVertex, other._baseVertex); - std::swap(_instanceCount, other._instanceCount); + using std::swap; + swap(_id, other._id); + swap(_created, other._created); + swap(_primitive, other._primitive); + swap(_count, other._count); + swap(_baseVertex, other._baseVertex); + swap(_instanceCount, other._instanceCount); #ifndef MAGNUM_TARGET_GLES - std::swap(_baseInstance, other._baseInstance); + swap(_baseInstance, other._baseInstance); #endif #ifndef MAGNUM_TARGET_GLES2 - std::swap(_indexStart, other._indexStart); - std::swap(_indexEnd, other._indexEnd); + swap(_indexStart, other._indexStart); + swap(_indexEnd, other._indexEnd); #endif - std::swap(_indexOffset, other._indexOffset); - std::swap(_indexType, other._indexType); - std::swap(_indexBuffer, other._indexBuffer); - std::swap(_attributes, other._attributes); + swap(_indexOffset, other._indexOffset); + swap(_indexType, other._indexType); + swap(_indexBuffer, other._indexBuffer); + swap(_attributes, other._attributes); #ifndef MAGNUM_TARGET_GLES2 - std::swap(_integerAttributes, other._integerAttributes); + swap(_integerAttributes, other._integerAttributes); #ifndef MAGNUM_TARGET_GLES - std::swap(_longAttributes, other._longAttributes); + swap(_longAttributes, other._longAttributes); #endif #endif @@ -207,6 +211,18 @@ Mesh& Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, IndexType type, Unsi return *this; } +void Mesh::draw(AbstractShaderProgram& shader) { + shader.use(); + + #ifndef MAGNUM_TARGET_GLES + drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd); + #elif !defined(MAGNUM_TARGET_GLES2) + drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd); + #else + drawInternal(_count, _baseVertex, _instanceCount, _indexOffset); + #endif +} + #ifndef MAGNUM_TARGET_GLES void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, UnsignedInt baseInstance, GLintptr indexOffset, Int indexStart, Int indexEnd) #elif !defined(MAGNUM_TARGET_GLES2) @@ -365,11 +381,11 @@ void Mesh::destroyImplementationVAO() { #endif } -void Mesh::attributePointerInternal(const Attribute& attribute) { +void Mesh::attributePointerInternal(const GenericAttribute& attribute) { (this->*Context::current()->state().mesh->attributePointerImplementation)(attribute); } -void Mesh::attributePointerImplementationDefault(const Attribute& attribute) { +void Mesh::attributePointerImplementationDefault(const GenericAttribute& attribute) { #if defined(CORRADE_TARGET_NACL) || defined(MAGNUM_TARGET_WEBGL) CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::TargetHint::Array, "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer->targetHint(), ); @@ -378,7 +394,7 @@ void Mesh::attributePointerImplementationDefault(const Attribute& attribute) { _attributes.push_back(attribute); } -void Mesh::attributePointerImplementationVAO(const Attribute& attribute) { +void Mesh::attributePointerImplementationVAO(const GenericAttribute& attribute) { #if defined(CORRADE_TARGET_NACL) || defined(MAGNUM_TARGET_WEBGL) CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::TargetHint::Array, "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer->targetHint(), ); @@ -389,15 +405,16 @@ void Mesh::attributePointerImplementationVAO(const Attribute& attribute) { } #ifndef MAGNUM_TARGET_GLES -void Mesh::attributePointerImplementationDSAEXT(const Attribute& attribute) { +void Mesh::attributePointerImplementationDSAEXT(const GenericAttribute& attribute) { _created = true; glEnableVertexArrayAttribEXT(_id, attribute.location); glVertexArrayVertexAttribOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.offset); - if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor); + if(attribute.divisor) + (this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); } #endif -void Mesh::vertexAttribPointer(const Attribute& attribute) { +void Mesh::vertexAttribPointer(const GenericAttribute& attribute) { glEnableVertexAttribArray(attribute.location); attribute.buffer->bindInternal(Buffer::TargetHint::Array); glVertexAttribPointer(attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, reinterpret_cast(attribute.offset)); @@ -429,7 +446,8 @@ void Mesh::attributePointerImplementationDSAEXT(const IntegerAttribute& attribut _created = true; glEnableVertexArrayAttribEXT(_id, attribute.location); glVertexArrayVertexAttribIOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); - if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor); + if(attribute.divisor) + (this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); } #endif @@ -459,7 +477,8 @@ void Mesh::attributePointerImplementationDSAEXT(const LongAttribute& attribute) _created = true; glEnableVertexArrayAttribEXT(_id, attribute.location); glVertexArrayVertexAttribLOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); - if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor); + if(attribute.divisor) + (this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); } void Mesh::vertexAttribPointer(const LongAttribute& attribute) { @@ -470,7 +489,15 @@ void Mesh::vertexAttribPointer(const LongAttribute& attribute) { } #endif -#ifdef MAGNUM_TARGET_GLES2 +#ifndef MAGNUM_TARGET_GLES +void Mesh::vertexAttribDivisorImplementationVAO(const GLuint index, const GLuint divisor) { + bindVAO(); + glVertexAttribDivisor(index, divisor); +} +void Mesh::vertexAttribDivisorImplementationDSAEXT(const GLuint index, const GLuint divisor) { + glVertexArrayVertexAttribDivisorEXT(_id, index, divisor); +} +#elif defined(MAGNUM_TARGET_GLES2) void Mesh::vertexAttribDivisorImplementationANGLE(const GLuint index, const GLuint divisor) { #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) glVertexAttribDivisorANGLE(index, divisor); @@ -480,7 +507,6 @@ void Mesh::vertexAttribDivisorImplementationANGLE(const GLuint index, const GLui CORRADE_ASSERT_UNREACHABLE(); #endif } - void Mesh::vertexAttribDivisorImplementationEXT(const GLuint index, const GLuint divisor) { #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) glVertexAttribDivisorEXT(index, divisor); @@ -490,7 +516,6 @@ void Mesh::vertexAttribDivisorImplementationEXT(const GLuint index, const GLuint CORRADE_ASSERT_UNREACHABLE(); #endif } - void Mesh::vertexAttribDivisorImplementationNV(const GLuint index, const GLuint divisor) { #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) glVertexAttribDivisorNV(index, divisor); diff --git a/src/Magnum/Mesh.h b/src/Magnum/Mesh.h index fbae5fe19..d311a060a 100644 --- a/src/Magnum/Mesh.h +++ b/src/Magnum/Mesh.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,14 +30,20 @@ */ #include +#include #include -#include "Magnum/AbstractShaderProgram.h" +#include "Magnum/AbstractObject.h" +#include "Magnum/Attribute.h" + +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif namespace Magnum { /** - * @brief %Mesh primitive type + * @brief Mesh primitive type * * @see @ref Mesh::primitive(), @ref Mesh::setPrimitive() */ @@ -63,14 +69,14 @@ enum class MeshPrimitive: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Line strip with adjacency information. - * @requires_gl32 %Extension @extension{ARB,geometry_shader4} + * @requires_gl32 Extension @extension{ARB,geometry_shader4} * @requires_gl Geometry shaders are not available in OpenGL ES. */ LineStripAdjacency = GL_LINE_STRIP_ADJACENCY, /** * Lines with adjacency information. - * @requires_gl32 %Extension @extension{ARB,geometry_shader4} + * @requires_gl32 Extension @extension{ARB,geometry_shader4} * @requires_gl Geometry shaders are not available in OpenGL ES. */ LinesAdjacency = GL_LINES_ADJACENCY, @@ -94,21 +100,21 @@ enum class MeshPrimitive: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Triangle strip with adjacency information. - * @requires_gl32 %Extension @extension{ARB,geometry_shader4} + * @requires_gl32 Extension @extension{ARB,geometry_shader4} * @requires_gl Geometry shaders are not available in OpenGL ES. */ TriangleStripAdjacency = GL_TRIANGLE_STRIP_ADJACENCY, /** * Triangles with adjacency information. - * @requires_gl32 %Extension @extension{ARB,geometry_shader4} + * @requires_gl32 Extension @extension{ARB,geometry_shader4} * @requires_gl Geometry shaders are not available in OpenGL ES. */ TrianglesAdjacency = GL_TRIANGLES_ADJACENCY, /** * Patches. - * @requires_gl40 %Extension @extension{ARB,tessellation_shader} + * @requires_gl40 Extension @extension{ARB,tessellation_shader} * @requires_gl Tessellation shaders are not available in OpenGL ES. */ Patches = GL_PATCHES @@ -118,16 +124,15 @@ enum class MeshPrimitive: GLenum { namespace Implementation { struct MeshState; } /** -@brief %Mesh +@brief Mesh @anchor Mesh-configuration -## %Mesh configuration +## Mesh configuration You have to specify at least primitive and vertex/index count using @ref setPrimitive() and @ref setCount(). Then fill your vertex buffers with -data, add them to the mesh and specify -@ref AbstractShaderProgram::Attribute "shader attribute" layout inside the -buffers using @ref addVertexBuffer(). You can also use +data, add them to the mesh and specify @ref Attribute "shader attribute" layout +inside the buffers using @ref addVertexBuffer(). You can also use @ref MeshTools::interleave() to conveniently interleave vertex data. If you want indexed mesh, fill your index buffer with data and specify its @@ -321,8 +326,8 @@ If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL ES 3.0 or used instead of binding the buffers and specifying vertex attribute pointers in each @ref draw() call. The engine tracks currently bound VAO and currently active shader program to avoid unnecessary calls to @fn_gl{BindVertexArray} and -@fn_gl{UseProgram}. %Mesh limits and implementation-defined values (such as -@ref maxVertexAttributes()) are cached, so repeated queries don't result in +@fn_gl{UseProgram}. Mesh limits and implementation-defined values (such as +@ref maxElementIndex()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. If extension @extension{EXT,direct_state_access} and VAOs are available, @@ -335,18 +340,10 @@ drawing commands are used on desktop OpenGL and OpenGL ES 3.0. See also @ref draw() for more information. */ class MAGNUM_EXPORT Mesh: public AbstractObject { - friend class MeshView; - friend struct Implementation::MeshState; + friend MeshView; + friend Implementation::MeshState; public: - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @copybrief MeshPrimitive - * @deprecated Use @ref Magnum::MeshPrimitive "MeshPrimitive" instead. - */ - typedef CORRADE_DEPRECATED("use MeshPrimitive instead") MeshPrimitive Primitive; - #endif - /** * @brief Index type * @@ -358,21 +355,19 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { /** * Unsigned int - * @requires_gles30 %Extension @es_extension{OES,element_index_uint} + * @requires_gles30 Extension @es_extension{OES,element_index_uint} * in OpenGL ES 2.0 */ UnsignedInt = GL_UNSIGNED_INT }; + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Max supported vertex attribute count - * - * The result is cached, repeated queries don't result in repeated - * OpenGL calls. This function is in fact alias to - * @ref AbstractShaderProgram::maxVertexAttributes(). - * @see @ref addVertexBuffer() + * @copybrief AbstractShaderProgram::maxVertexAttributes() + * @deprecated Use @ref AbstractShaderProgram::maxVertexAttributes() instead. */ - static Int maxVertexAttributes(); + CORRADE_DEPRECATED("use AbstractShaderProgram::maxVertexAttributes() instead") static Int maxVertexAttributes(); + #endif #ifndef MAGNUM_TARGET_GLES2 /** @@ -464,7 +459,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { GLuint id() const { return _id; } /** - * @brief %Mesh label + * @brief Mesh label * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. If OpenGL 4.3 is not supported and neither @@ -493,7 +488,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { /** @overload */ template Mesh& setLabelInternal(const char(&label)[size]) { - return setLabelInternal(label); + return setLabelInternal({label, size - 1}); } /** @@ -551,7 +546,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * Sets number of vertices of which the vertex buffer will be offset * when drawing. Default is `0`. * @see @ref setCount(), @ref setBaseInstance() - * @requires_gl32 %Extension @extension{ARB,draw_elements_base_vertex} + * @requires_gl32 Extension @extension{ARB,draw_elements_base_vertex} * for indexed meshes * @requires_gl Base vertex cannot be specified for indexed meshes in * OpenGL ES. @@ -606,8 +601,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * Default is `1`. * @see @ref setBaseInstance(), @ref setCount(), * @ref addVertexBufferInstanced() - * @requires_gl31 %Extension @extension{ARB,draw_instanced} - * @requires_gles30 %Extension @es_extension{ANGLE,instanced_arrays}, + * @requires_gl31 Extension @extension{ARB,draw_instanced} + * @requires_gles30 Extension @es_extension{ANGLE,instanced_arrays}, * @es_extension2{EXT,draw_instanced,draw_instanced} or * @es_extension{NV,draw_instanced} in OpenGL ES 2.0. */ @@ -626,7 +621,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * * Default is `0`. * @see @ref setInstanceCount(), @ref setBaseVertex() - * @requires_gl42 %Extension @extension{ARB,base_instance} + * @requires_gl42 Extension @extension{ARB,base_instance} * @requires_gl Base instance cannot be specified in OpenGL ES. */ Mesh& setBaseInstance(UnsignedInt baseInstance) { @@ -640,7 +635,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * @return Reference to self (for method chaining) * * Parameter @p offset is offset of the array from the beginning, - * attribute list is combination of @ref AbstractShaderProgram::Attribute "attribute definitions" + * attribute list is combination of @ref Attribute "attribute definitions" * (specified in implementation of given shader) and offsets between * interleaved attributes. * @@ -696,8 +691,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * must be at most 255 bytes. This is not required anywhere else, * but doing so may have performance benefits. * - * @see @ref addVertexBufferInstanced(), @ref maxVertexAttributes(), - * @ref setPrimitive(), @ref setCount(), @fn_gl{BindVertexArray}, + * @see @ref addVertexBufferInstanced(), @ref setPrimitive(), + * @ref setCount(), @fn_gl{BindVertexArray}, * @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer}, * @fn_gl{VertexAttribPointer} or * @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access}, @@ -721,16 +716,16 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is * available, the vertex array object is used to hold the parameters. * - * @see @ref maxVertexAttributes(), @ref setPrimitive(), - * @ref setCount(), @ref setInstanceCount(), @ref setBaseInstance(), + * @see @ref setPrimitive(), @ref setCount(), @ref setInstanceCount(), + * @ref setBaseInstance(), * @fn_gl{BindVertexArray}, @fn_gl{EnableVertexAttribArray}, * @fn_gl{BindBuffer}, @fn_gl{VertexAttribPointer}, * @fn_gl{VertexAttribDivisor} or * @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access}, * @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access}, * @fn_gl_extension{VertexArrayVertexAttribDivisor,EXT,direct_state_access} - * @requires_gl33 %Extension @extension{ARB,instanced_arrays} - * @requires_gles30 %Extension @es_extension{ANGLE,instanced_arrays}, + * @requires_gl33 Extension @extension{ARB,instanced_arrays} + * @requires_gles30 Extension @es_extension{ANGLE,instanced_arrays}, * @es_extension{EXT,instanced_arrays} or * @es_extension{NV,instanced_arrays} in OpenGL ES 2.0. */ @@ -783,7 +778,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { /** * @brief Draw the mesh - * @param shader %Shader to use for drawing + * @param shader Shader to use for drawing * * Expects that the shader is compatible with this mesh and is fully * set up. If vertex/index count or instance count is `0`, no draw @@ -807,17 +802,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * @fn_gl{DrawElementsInstancedBaseVertex}/ * @fn_gl{DrawElementsInstancedBaseVertexBaseInstance} */ - void draw(AbstractShaderProgram& shader) { - shader.use(); - - #ifndef MAGNUM_TARGET_GLES - drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd); - #elif !defined(MAGNUM_TARGET_GLES2) - drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd); - #else - drawInternal(_count, _baseVertex, _instanceCount, _indexOffset); - #endif - } + void draw(AbstractShaderProgram& shader); void draw(AbstractShaderProgram&& shader) { draw(shader); } /**< @overload */ @@ -840,7 +825,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { private: #ifndef DOXYGEN_GENERATING_OUTPUT - struct MAGNUM_LOCAL Attribute { + struct MAGNUM_LOCAL GenericAttribute { Buffer* buffer; GLuint location; GLint size; @@ -881,8 +866,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { Mesh& setLabelInternal(Containers::ArrayReference label); /* Computing stride of interleaved vertex attributes */ - template static GLsizei strideOfInterleaved(const AbstractShaderProgram::Attribute& attribute, const U&... attributes) { - return attribute.vectorSize()*AbstractShaderProgram::Attribute::VectorCount + strideOfInterleaved(attributes...); + template static GLsizei strideOfInterleaved(const Attribute& attribute, const U&... attributes) { + return attribute.vectorSize()*Attribute::VectorCount + strideOfInterleaved(attributes...); } template static GLsizei strideOfInterleaved(GLintptr gap, const T&... attributes) { return gap + strideOfInterleaved(attributes...); @@ -890,11 +875,11 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { static GLsizei strideOfInterleaved() { return 0; } /* Adding interleaved vertex attributes */ - template void addVertexBufferInternal(Buffer& buffer, GLintptr offset, GLsizei stride, GLuint divisor, const AbstractShaderProgram::Attribute& attribute, const U&... attributes) { + template void addVertexBufferInternal(Buffer& buffer, GLintptr offset, GLsizei stride, GLuint divisor, const Attribute& attribute, const U&... attributes) { addVertexAttribute(buffer, attribute, offset, stride, divisor); /* Add size of this attribute to offset for next attribute */ - addVertexBufferInternal(buffer, offset+attribute.vectorSize()*AbstractShaderProgram::Attribute::VectorCount, stride, divisor, attributes...); + addVertexBufferInternal(buffer, offset+attribute.vectorSize()*Attribute::VectorCount, stride, divisor, attributes...); } template void addVertexBufferInternal(Buffer& buffer, GLintptr offset, GLsizei stride, GLuint divisor, GLintptr gap, const T&... attributes) { /* Add the gap to offset for next attribute */ @@ -902,14 +887,14 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { } void addVertexBufferInternal(Buffer&, GLsizei, GLuint, GLintptr) {} - template void addVertexAttribute(typename std::enable_if::ScalarType, Float>::value, Buffer&>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { - for(UnsignedInt i = 0; i != AbstractShaderProgram::Attribute::VectorCount; ++i) - attributePointerInternal(Attribute{ + template void addVertexAttribute(typename std::enable_if::ScalarType, Float>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { + for(UnsignedInt i = 0; i != Attribute::VectorCount; ++i) + attributePointerInternal(GenericAttribute{ &buffer, location+i, GLint(attribute.components()), GLenum(attribute.dataType()), - bool(attribute.dataOptions() & AbstractShaderProgram::Attribute::DataOption::Normalized), + bool(attribute.dataOptions() & Attribute::DataOption::Normalized), GLintptr(offset+i*attribute.vectorSize()), stride, divisor @@ -917,7 +902,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { } #ifndef MAGNUM_TARGET_GLES2 - template void addVertexAttribute(typename std::enable_if::ScalarType>::value, Buffer&>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { + template void addVertexAttribute(typename std::enable_if::ScalarType>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { attributePointerInternal(IntegerAttribute{ &buffer, location, @@ -930,8 +915,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { } #ifndef MAGNUM_TARGET_GLES - template void addVertexAttribute(typename std::enable_if::ScalarType, Double>::value, Buffer&>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { - for(UnsignedInt i = 0; i != AbstractShaderProgram::Attribute::VectorCount; ++i) + template void addVertexAttribute(typename std::enable_if::ScalarType, Double>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { + for(UnsignedInt i = 0; i != Attribute::VectorCount; ++i) attributePointerInternal(LongAttribute{ &buffer, location+i, @@ -964,13 +949,13 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { void MAGNUM_LOCAL destroyImplementationDefault(); void MAGNUM_LOCAL destroyImplementationVAO(); - void attributePointerInternal(const Attribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationDefault(const Attribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationVAO(const Attribute& attribute); + void attributePointerInternal(const GenericAttribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationDefault(const GenericAttribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationVAO(const GenericAttribute& attribute); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const Attribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const GenericAttribute& attribute); #endif - void MAGNUM_LOCAL vertexAttribPointer(const Attribute& attribute); + void MAGNUM_LOCAL vertexAttribPointer(const GenericAttribute& attribute); #ifndef MAGNUM_TARGET_GLES2 void attributePointerInternal(const IntegerAttribute& attribute); @@ -990,7 +975,10 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { void MAGNUM_LOCAL vertexAttribPointer(const LongAttribute& attribute); #endif - #ifdef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL vertexAttribDivisorImplementationVAO(GLuint index, GLuint divisor); + void MAGNUM_LOCAL vertexAttribDivisorImplementationDSAEXT(GLuint index, GLuint divisor); + #elif defined(MAGNUM_TARGET_GLES2) void MAGNUM_LOCAL vertexAttribDivisorImplementationANGLE(GLuint index, GLuint divisor); void MAGNUM_LOCAL vertexAttribDivisorImplementationEXT(GLuint index, GLuint divisor); void MAGNUM_LOCAL vertexAttribDivisorImplementationNV(GLuint index, GLuint divisor); @@ -1029,7 +1017,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { IndexType _indexType; Buffer* _indexBuffer; - std::vector _attributes; + std::vector _attributes; #ifndef MAGNUM_TARGET_GLES2 std::vector _integerAttributes; #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/MeshTools/CMakeLists.txt b/src/Magnum/MeshTools/CMakeLists.txt index 39be0a151..b2ce35e5f 100644 --- a/src/Magnum/MeshTools/CMakeLists.txt +++ b/src/Magnum/MeshTools/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -52,27 +52,26 @@ set(MagnumMeshTools_HEADERS visibility.h) -# Set shared library flags for the objects, as they will be part of shared lib -# TODO: fix when CMake sets target_EXPORTS for OBJECT targets as well +# Objects shared between main and test library add_library(MagnumMeshToolsObjects OBJECT ${MagnumMeshTools_SRCS} ${MagnumMeshTools_HEADERS}) -if(NOT BUILD_SHARED OR BUILD_STATIC_PIC) - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumMeshToolsObjects PROPERTIES COMPILE_FLAGS "-DMagnumMeshToolsObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") -else() +if(NOT BUILD_STATIC) set_target_properties(MagnumMeshToolsObjects PROPERTIES COMPILE_FLAGS "-DMagnumMeshToolsObjects_EXPORTS") endif() +if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) + set_target_properties(MagnumMeshToolsObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() -# Main library +# Main MeshTools library add_library(MagnumMeshTools ${SHARED_OR_STATIC} $ ${MagnumMeshTools_GracefulAssert_SRCS}) set_target_properties(MagnumMeshTools PROPERTIES DEBUG_POSTFIX "-d") if(BUILD_STATIC_PIC) - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumMeshTools PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") + set_target_properties(MagnumMeshTools PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() + target_link_libraries(MagnumMeshTools Magnum) install(TARGETS MagnumMeshTools @@ -89,11 +88,15 @@ if(BUILD_TESTS) set_target_properties(MagnumMeshToolsTestLib PROPERTIES COMPILE_FLAGS "-DCORRADE_GRACEFUL_ASSERT -DMagnumMeshTools_EXPORTS" DEBUG_POSTFIX "-d") + if(BUILD_STATIC_PIC) + set_target_properties(MagnumMeshToolsTestLib PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() + target_link_libraries(MagnumMeshToolsTestLib Magnum) # On Windows we need to install first and then run the tests to avoid "DLL # not found" hell, thus we need to install this too - if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING) + if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING AND NOT BUILD_STATIC) install(TARGETS MagnumMeshToolsTestLib RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} diff --git a/src/Magnum/MeshTools/CombineIndexedArrays.cpp b/src/Magnum/MeshTools/CombineIndexedArrays.cpp index 0de3b868a..313af8705 100644 --- a/src/Magnum/MeshTools/CombineIndexedArrays.cpp +++ b/src/Magnum/MeshTools/CombineIndexedArrays.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/CombineIndexedArrays.h b/src/Magnum/MeshTools/CombineIndexedArrays.h index 1d031331e..38a5e50a3 100644 --- a/src/Magnum/MeshTools/CombineIndexedArrays.h +++ b/src/Magnum/MeshTools/CombineIndexedArrays.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -131,7 +131,8 @@ template void writeCombinedArray(const UnsignedInt stride, const Unsign CORRADE_ASSERT(index < array.size(), "MeshTools::combineIndexedArrays(): index out of range", ); output.push_back(array[index]); } - std::swap(output, array); + using std::swap; + swap(output, array); } /* Terminator for recursive calls */ @@ -147,7 +148,7 @@ template inline void writeCombinedArrays(UnsignedInt stride /** @brief Combine indexed arrays @param[in,out] indexedArrays Index and attribute arrays -@return %Array with resulting indices +@return Array with resulting indices Creates new combined index array and reorders original attribute arrays so they can be indexed with the new single index array. diff --git a/src/Magnum/MeshTools/Compile.cpp b/src/Magnum/MeshTools/Compile.cpp index adc585a6d..686edc056 100644 --- a/src/Magnum/MeshTools/Compile.cpp +++ b/src/Magnum/MeshTools/Compile.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/Compile.h b/src/Magnum/MeshTools/Compile.h index 0e1e978ae..91395151f 100644 --- a/src/Magnum/MeshTools/Compile.h +++ b/src/Magnum/MeshTools/Compile.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -58,6 +58,8 @@ The second returned buffer may be `nullptr` if the mesh is not indexed. This is just a convenience function for creating generic meshes, you might want to use @ref interleave() and @ref compressIndices() functions instead for greater flexibility. + +@see @ref shaders-generic */ MAGNUM_MESHTOOLS_EXPORT std::tuple, std::unique_ptr> compile(const Trade::MeshData2D& meshData, BufferUsage usage); @@ -77,6 +79,8 @@ The second returned buffer may be `nullptr` if the mesh is not indexed. This is just a convenience function for creating generic meshes, you might want to use @ref interleave() and @ref compressIndices() functions instead for greater flexibility. + +@see @ref shaders-generic */ MAGNUM_MESHTOOLS_EXPORT std::tuple, std::unique_ptr> compile(const Trade::MeshData3D& meshData, BufferUsage usage); diff --git a/src/Magnum/MeshTools/CompressIndices.cpp b/src/Magnum/MeshTools/CompressIndices.cpp index b931af946..10fc50ccb 100644 --- a/src/Magnum/MeshTools/CompressIndices.cpp +++ b/src/Magnum/MeshTools/CompressIndices.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/CompressIndices.h b/src/Magnum/MeshTools/CompressIndices.h index 4257939bd..8d7425d28 100644 --- a/src/Magnum/MeshTools/CompressIndices.h +++ b/src/Magnum/MeshTools/CompressIndices.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/Duplicate.h b/src/Magnum/MeshTools/Duplicate.h index 4cef1ce8d..e8d2ef6ce 100644 --- a/src/Magnum/MeshTools/Duplicate.h +++ b/src/Magnum/MeshTools/Duplicate.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/FlipNormals.cpp b/src/Magnum/MeshTools/FlipNormals.cpp index 8c59a0a31..097fd14df 100644 --- a/src/Magnum/MeshTools/FlipNormals.cpp +++ b/src/Magnum/MeshTools/FlipNormals.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,8 +32,9 @@ namespace Magnum { namespace MeshTools { void flipFaceWinding(std::vector& indices) { CORRADE_ASSERT(!(indices.size()%3), "MeshTools::flipNormals(): index count is not divisible by 3!", ); + using std::swap; for(std::size_t i = 0; i != indices.size(); i += 3) - std::swap(indices[i+1], indices[i+2]); + swap(indices[i+1], indices[i+2]); } void flipNormals(std::vector& normals) { diff --git a/src/Magnum/MeshTools/FlipNormals.h b/src/Magnum/MeshTools/FlipNormals.h index 3a5ca49e2..15b9595f5 100644 --- a/src/Magnum/MeshTools/FlipNormals.h +++ b/src/Magnum/MeshTools/FlipNormals.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/FullScreenTriangle.cpp b/src/Magnum/MeshTools/FullScreenTriangle.cpp index b7ce1cc63..26f317f21 100644 --- a/src/Magnum/MeshTools/FullScreenTriangle.cpp +++ b/src/Magnum/MeshTools/FullScreenTriangle.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,7 +25,7 @@ #include "FullScreenTriangle.h" -#include "Magnum/AbstractShaderProgram.h" +#include "Magnum/Attribute.h" #include "Magnum/Buffer.h" #include "Magnum/Context.h" #include "Magnum/Mesh.h" @@ -55,7 +55,7 @@ std::pair, Mesh> fullScreenTriangle(Version version) { buffer->setData(triangle, BufferUsage::StaticDraw); /** @todo Is it possible to attach moveable buffer here to avoid heap allocation? OTOH this is more effective in most (modern) cases */ - mesh.addVertexBuffer(*buffer, 0, AbstractShaderProgram::Attribute<0, Vector2>()); + mesh.addVertexBuffer(*buffer, 0, Attribute<0, Vector2>{}); } return {std::move(buffer), std::move(mesh)}; diff --git a/src/Magnum/MeshTools/FullScreenTriangle.h b/src/Magnum/MeshTools/FullScreenTriangle.h index ce3e466ef..e308aad71 100644 --- a/src/Magnum/MeshTools/FullScreenTriangle.h +++ b/src/Magnum/MeshTools/FullScreenTriangle.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/GenerateFlatNormals.cpp b/src/Magnum/MeshTools/GenerateFlatNormals.cpp index c4b78db09..242ff0c1c 100644 --- a/src/Magnum/MeshTools/GenerateFlatNormals.cpp +++ b/src/Magnum/MeshTools/GenerateFlatNormals.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,8 +40,8 @@ std::tuple, std::vector> generateFlatNormals(c std::vector normals; normals.reserve(indices.size()/3); for(std::size_t i = 0; i != indices.size(); i += 3) { - Vector3 normal = Vector3::cross(positions[indices[i+2]]-positions[indices[i+1]], - positions[indices[i]]-positions[indices[i+1]]).normalized(); + const Vector3 normal = Math::cross(positions[indices[i+2]]-positions[indices[i+1]], + positions[indices[i]]-positions[indices[i+1]]).normalized(); /* Use the same normal for all three vertices of the face */ normalIndices.push_back(normals.size()); diff --git a/src/Magnum/MeshTools/GenerateFlatNormals.h b/src/Magnum/MeshTools/GenerateFlatNormals.h index 32d89279c..7b0d0e9a8 100644 --- a/src/Magnum/MeshTools/GenerateFlatNormals.h +++ b/src/Magnum/MeshTools/GenerateFlatNormals.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,7 +39,7 @@ namespace Magnum { namespace MeshTools { /** @brief Generate flat normals -@param indices Array of triangle face indexes +@param indices Array of triangle face indices @param positions Array of vertex positions @return Normal indices and vectors diff --git a/src/Magnum/MeshTools/Interleave.h b/src/Magnum/MeshTools/Interleave.h index 7711a5239..f7b6a10ff 100644 --- a/src/Magnum/MeshTools/Interleave.h +++ b/src/Magnum/MeshTools/Interleave.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -85,7 +85,7 @@ template typename std::enable_if:: } /* Skip gap */ -inline constexpr std::size_t writeOneInterleaved(std::size_t, char*, std::size_t gap) { return gap; } +constexpr std::size_t writeOneInterleaved(std::size_t, char*, std::size_t gap) { return gap; } /* Write interleaved data */ inline void writeInterleaved(std::size_t, char*) {} @@ -96,7 +96,7 @@ template void writeInterleaved(std::size_t stride, char* st } /** -@brief %Interleave vertex attributes +@brief Interleave vertex attributes This function takes list of attribute arrays and returns them interleaved, so data for each attribute are in continuous place in memory. @@ -164,7 +164,7 @@ template typename std::enable_if::va } /** -@brief %Interleave vertex attributes into existing buffer +@brief Interleave vertex attributes into existing buffer Unlike @ref interleave() this function interleaves the data into existing buffer and leaves gaps untouched instead of zero-initializing them. This @@ -187,7 +187,7 @@ template void interleaveInto(Containers::ArrayReference Permission is hereby granted, free of charge, to any person obtaining a @@ -56,7 +56,7 @@ namespace Implementation { } /** -@brief %Remove duplicate floating-point vector data from given array +@brief Remove duplicate floating-point vector data from given array @param[in,out] data Input data array @param[out] epsilon Epsilon value, vertices nearer than this distance will be melt together diff --git a/src/Magnum/MeshTools/Subdivide.h b/src/Magnum/MeshTools/Subdivide.h index 2f19c09b3..4243b239b 100644 --- a/src/Magnum/MeshTools/Subdivide.h +++ b/src/Magnum/MeshTools/Subdivide.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -61,7 +61,7 @@ template class Subdivide { } /** -@brief %Subdivide the mesh +@brief Subdivide the mesh @tparam Vertex Vertex data type @tparam Interpolator See `interpolator` function parameter @param[in,out] indices Index array to operate on diff --git a/src/Magnum/MeshTools/Test/CMakeLists.txt b/src/Magnum/MeshTools/Test/CMakeLists.txt index ec7cfe6b9..5d6e653a9 100644 --- a/src/Magnum/MeshTools/Test/CMakeLists.txt +++ b/src/Magnum/MeshTools/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/Test/CombineIndexedArraysTest.cpp b/src/Magnum/MeshTools/Test/CombineIndexedArraysTest.cpp index 8e3950053..aea581a68 100644 --- a/src/Magnum/MeshTools/Test/CombineIndexedArraysTest.cpp +++ b/src/Magnum/MeshTools/Test/CombineIndexedArraysTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,13 +32,12 @@ namespace Magnum { namespace MeshTools { namespace Test { -class CombineIndexedArraysTest: public TestSuite::Tester { - public: - CombineIndexedArraysTest(); +struct CombineIndexedArraysTest: TestSuite::Tester { + explicit CombineIndexedArraysTest(); - void wrongIndexCount(); - void indexArrays(); - void indexedArrays(); + void wrongIndexCount(); + void indexArrays(); + void indexedArrays(); }; CombineIndexedArraysTest::CombineIndexedArraysTest() { diff --git a/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp b/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp index ddecc90fc..cd634f59d 100644 --- a/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp +++ b/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,13 +31,12 @@ namespace Magnum { namespace MeshTools { namespace Test { -class CompressIndicesTest: public TestSuite::Tester { - public: - CompressIndicesTest(); +struct CompressIndicesTest: TestSuite::Tester { + explicit CompressIndicesTest(); - void compressChar(); - void compressShort(); - void compressInt(); + void compressChar(); + void compressShort(); + void compressInt(); }; CompressIndicesTest::CompressIndicesTest() { diff --git a/src/Magnum/MeshTools/Test/DuplicateTest.cpp b/src/Magnum/MeshTools/Test/DuplicateTest.cpp index 68713ed16..20f1f64b8 100644 --- a/src/Magnum/MeshTools/Test/DuplicateTest.cpp +++ b/src/Magnum/MeshTools/Test/DuplicateTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace MeshTools { namespace Test { -class DuplicateTest: public TestSuite::Tester { - public: - explicit DuplicateTest(); +struct DuplicateTest: TestSuite::Tester { + explicit DuplicateTest(); - void duplicate(); + void duplicate(); }; DuplicateTest::DuplicateTest() { diff --git a/src/Magnum/MeshTools/Test/FlipNormalsTest.cpp b/src/Magnum/MeshTools/Test/FlipNormalsTest.cpp index 252f92049..39ba9b0b4 100644 --- a/src/Magnum/MeshTools/Test/FlipNormalsTest.cpp +++ b/src/Magnum/MeshTools/Test/FlipNormalsTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,13 +31,12 @@ namespace Magnum { namespace MeshTools { namespace Test { -class FlipNormalsTest: public TestSuite::Tester { - public: - FlipNormalsTest(); +struct FlipNormalsTest: TestSuite::Tester { + explicit FlipNormalsTest(); - void wrongIndexCount(); - void flipFaceWinding(); - void flipNormals(); + void wrongIndexCount(); + void flipFaceWinding(); + void flipNormals(); }; FlipNormalsTest::FlipNormalsTest() { diff --git a/src/Magnum/MeshTools/Test/GenerateFlatNormalsTest.cpp b/src/Magnum/MeshTools/Test/GenerateFlatNormalsTest.cpp index d480f784a..f8f42e510 100644 --- a/src/Magnum/MeshTools/Test/GenerateFlatNormalsTest.cpp +++ b/src/Magnum/MeshTools/Test/GenerateFlatNormalsTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,12 +31,11 @@ namespace Magnum { namespace MeshTools { namespace Test { -class GenerateFlatNormalsTest: public TestSuite::Tester { - public: - GenerateFlatNormalsTest(); +struct GenerateFlatNormalsTest: TestSuite::Tester { + explicit GenerateFlatNormalsTest(); - void wrongIndexCount(); - void generate(); + void wrongIndexCount(); + void generate(); }; GenerateFlatNormalsTest::GenerateFlatNormalsTest() { diff --git a/src/Magnum/MeshTools/Test/InterleaveTest.cpp b/src/Magnum/MeshTools/Test/InterleaveTest.cpp index 75c2cb250..c1f1c91d5 100644 --- a/src/Magnum/MeshTools/Test/InterleaveTest.cpp +++ b/src/Magnum/MeshTools/Test/InterleaveTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,18 +32,17 @@ namespace Magnum { namespace MeshTools { namespace Test { -class InterleaveTest: public Corrade::TestSuite::Tester { - public: - InterleaveTest(); +struct InterleaveTest: Corrade::TestSuite::Tester { + explicit InterleaveTest(); - void attributeCount(); - void attributeCountGaps(); - void stride(); - void strideGaps(); - void write(); - void writeGaps(); + void attributeCount(); + void attributeCountGaps(); + void stride(); + void strideGaps(); + void write(); + void writeGaps(); - void interleaveInto(); + void interleaveInto(); }; InterleaveTest::InterleaveTest() { diff --git a/src/Magnum/MeshTools/Test/RemoveDuplicatesTest.cpp b/src/Magnum/MeshTools/Test/RemoveDuplicatesTest.cpp index fd6a9da0b..36aa3444a 100644 --- a/src/Magnum/MeshTools/Test/RemoveDuplicatesTest.cpp +++ b/src/Magnum/MeshTools/Test/RemoveDuplicatesTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace MeshTools { namespace Test { -class RemoveDuplicatesTest: public TestSuite::Tester { - public: - RemoveDuplicatesTest(); +struct RemoveDuplicatesTest: TestSuite::Tester { + explicit RemoveDuplicatesTest(); - void removeDuplicates(); + void removeDuplicates(); }; RemoveDuplicatesTest::RemoveDuplicatesTest() { diff --git a/src/Magnum/MeshTools/Test/SubdivideRemoveDuplicatesBenchmark.cpp b/src/Magnum/MeshTools/Test/SubdivideRemoveDuplicatesBenchmark.cpp index 12f5cdadc..1080aa8ea 100644 --- a/src/Magnum/MeshTools/Test/SubdivideRemoveDuplicatesBenchmark.cpp +++ b/src/Magnum/MeshTools/Test/SubdivideRemoveDuplicatesBenchmark.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/Test/SubdivideRemoveDuplicatesBenchmark.h b/src/Magnum/MeshTools/Test/SubdivideRemoveDuplicatesBenchmark.h index db0db598f..25defa16b 100644 --- a/src/Magnum/MeshTools/Test/SubdivideRemoveDuplicatesBenchmark.h +++ b/src/Magnum/MeshTools/Test/SubdivideRemoveDuplicatesBenchmark.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/Test/SubdivideTest.cpp b/src/Magnum/MeshTools/Test/SubdivideTest.cpp index 56095c4be..a6d3f4f4f 100644 --- a/src/Magnum/MeshTools/Test/SubdivideTest.cpp +++ b/src/Magnum/MeshTools/Test/SubdivideTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,12 +31,11 @@ namespace Magnum { namespace MeshTools { namespace Test { -class SubdivideTest: public TestSuite::Tester { - public: - SubdivideTest(); +struct SubdivideTest: TestSuite::Tester { + explicit SubdivideTest(); - void wrongIndexCount(); - void subdivide(); + void wrongIndexCount(); + void subdivide(); }; namespace { diff --git a/src/Magnum/MeshTools/Test/TipsifyTest.cpp b/src/Magnum/MeshTools/Test/TipsifyTest.cpp index 49e52c08b..2dd3bbf3b 100644 --- a/src/Magnum/MeshTools/Test/TipsifyTest.cpp +++ b/src/Magnum/MeshTools/Test/TipsifyTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,16 +30,11 @@ namespace Magnum { namespace MeshTools { namespace Test { -class TipsifyTest: public TestSuite::Tester { - public: - TipsifyTest(); +struct TipsifyTest: TestSuite::Tester { + explicit TipsifyTest(); - void buildAdjacency(); - void tipsify(); - - private: - std::vector indices; - std::size_t vertexCount; + void buildAdjacency(); + void tipsify(); }; /* @@ -57,38 +52,44 @@ class TipsifyTest: public TestSuite::Tester { */ -/* MSVC 2013 can't cope with only {} here */ -TipsifyTest::TipsifyTest(): indices({ - 4, 1, 0, - 10, 9, 13, - 6, 3, 2, - 9, 5, 4, - 12, 9, 8, - 11, 7, 6, - - 14, 15, 11, - 2, 1, 5, - 10, 6, 5, - 10, 5, 9, - 13, 14, 10, - 1, 4, 5, - - 7, 3, 6, - 6, 2, 5, - 9, 4, 8, - 6, 10, 11, - 13, 9, 12, - 14, 11, 10, - - 16, 17, 18 -}), vertexCount(19) { +namespace { + const std::vector Indices{ + 4, 1, 0, + 10, 9, 13, + 6, 3, 2, + 9, 5, 4, + 12, 9, 8, + 11, 7, 6, + + 14, 15, 11, + 2, 1, 5, + 10, 6, 5, + 10, 5, 9, + 13, 14, 10, + 1, 4, 5, + + 7, 3, 6, + 6, 2, 5, + 9, 4, 8, + 6, 10, 11, + 13, 9, 12, + 14, 11, 10, + + 16, 17, 18 + }; + + constexpr std::size_t VertexCount = 19; +} + +TipsifyTest::TipsifyTest() { addTests({&TipsifyTest::buildAdjacency, &TipsifyTest::tipsify}); } void TipsifyTest::buildAdjacency() { + std::vector indices = Indices; std::vector liveTriangleCount, neighborOffset, neighbors; - Implementation::Tipsify(indices, vertexCount).buildAdjacency(liveTriangleCount, neighborOffset, neighbors); + Implementation::Tipsify(indices, VertexCount).buildAdjacency(liveTriangleCount, neighborOffset, neighbors); CORRADE_COMPARE(liveTriangleCount, (std::vector{ 1, 3, 3, 2, @@ -132,7 +133,8 @@ void TipsifyTest::buildAdjacency() { } void TipsifyTest::tipsify() { - MeshTools::tipsify(indices, vertexCount, 3); + std::vector indices = Indices; + MeshTools::tipsify(indices, VertexCount, 3); CORRADE_COMPARE(indices, (std::vector{ 4, 1, 0, diff --git a/src/Magnum/MeshTools/Test/TransformTest.cpp b/src/Magnum/MeshTools/Test/TransformTest.cpp index e7d828d3e..ea543811d 100644 --- a/src/Magnum/MeshTools/Test/TransformTest.cpp +++ b/src/Magnum/MeshTools/Test/TransformTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,15 +32,14 @@ namespace Magnum { namespace MeshTools { namespace Test { -class TransformTest: public TestSuite::Tester { - public: - explicit TransformTest(); +struct TransformTest: TestSuite::Tester { + explicit TransformTest(); - void transformVectors2D(); - void transformVectors3D(); + void transformVectors2D(); + void transformVectors3D(); - void transformPoints2D(); - void transformPoints3D(); + void transformPoints2D(); + void transformPoints3D(); }; TransformTest::TransformTest() { diff --git a/src/Magnum/MeshTools/Tipsify.cpp b/src/Magnum/MeshTools/Tipsify.cpp index 96277bc5a..34592422b 100644 --- a/src/Magnum/MeshTools/Tipsify.cpp +++ b/src/Magnum/MeshTools/Tipsify.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -127,7 +127,8 @@ void Tipsify::operator()(std::size_t cacheSize) { } /* Swap original index buffer with optimized */ - std::swap(indices, outputIndices); + using std::swap; + swap(indices, outputIndices); } void Tipsify::buildAdjacency(std::vector& liveTriangleCount, std::vector& neighborOffset, std::vector& neighbors) const { diff --git a/src/Magnum/MeshTools/Tipsify.h b/src/Magnum/MeshTools/Tipsify.h index 84476b9b1..a81761df7 100644 --- a/src/Magnum/MeshTools/Tipsify.h +++ b/src/Magnum/MeshTools/Tipsify.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -61,7 +61,7 @@ class MAGNUM_MESHTOOLS_EXPORT Tipsify { } /** -@brief %Tipsify the mesh +@brief Tipsify the mesh @param[in,out] indices Indices array to operate on @param[in] vertexCount Vertex count @param[in] cacheSize Post-transform vertex cache size diff --git a/src/Magnum/MeshTools/Transform.h b/src/Magnum/MeshTools/Transform.h index 2cc2af6ae..966d82625 100644 --- a/src/Magnum/MeshTools/Transform.h +++ b/src/Magnum/MeshTools/Transform.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshTools/visibility.h b/src/Magnum/MeshTools/visibility.h index 567b06c6e..8cfda51de 100644 --- a/src/Magnum/MeshTools/visibility.h +++ b/src/Magnum/MeshTools/visibility.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MeshView.cpp b/src/Magnum/MeshView.cpp index 10a071811..d2265435f 100644 --- a/src/Magnum/MeshView.cpp +++ b/src/Magnum/MeshView.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -28,6 +28,7 @@ #include #include +#include "Magnum/AbstractShaderProgram.h" #include "Magnum/Context.h" #include "Magnum/Mesh.h" diff --git a/src/Magnum/MeshView.h b/src/Magnum/MeshView.h index 2585579ea..64c6dcd6b 100644 --- a/src/Magnum/MeshView.h +++ b/src/Magnum/MeshView.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,6 +36,9 @@ #include "Magnum/OpenGL.h" #include "Magnum/visibility.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif #ifdef CORRADE_MSVC2013_COMPATIBILITY #include "Magnum/Mesh.h" #endif @@ -45,11 +48,11 @@ namespace Magnum { namespace Implementation { struct MeshState; } /** -@brief %Mesh view +@brief Mesh view Allows different interpretation of given @ref Mesh data via different vertex or index count and offset. It is then possible to reuse one mesh buffer -configuration for different views. %Mesh primitive, index type, attribute +configuration for different views. Mesh primitive, index type, attribute bindings and attached buffers are reused from original mesh. The same rules as in @ref Mesh apply, i.e. if the view has non-zero index @@ -61,7 +64,7 @@ You must ensure that the original mesh remains available for whole view lifetime. */ class MAGNUM_EXPORT MeshView { - friend struct Implementation::MeshState; + friend Implementation::MeshState; public: /** @@ -125,7 +128,7 @@ class MAGNUM_EXPORT MeshView { * * Sets number of vertices of which the vertex buffer will be offset * when drawing. Default is `0`. - * @requires_gl32 %Extension @extension{ARB,draw_elements_base_vertex} + * @requires_gl32 Extension @extension{ARB,draw_elements_base_vertex} * for indexed meshes * @requires_gl Base vertex cannot be specified for indexed meshes in * OpenGL ES. @@ -217,8 +220,8 @@ class MAGNUM_EXPORT MeshView { * @return Reference to self (for method chaining) * * Default is `1`. - * @requires_gl31 %Extension @extension{ARB,draw_instanced} - * @requires_gles30 %Extension @es_extension{ANGLE,instanced_arrays}, + * @requires_gl31 Extension @extension{ARB,draw_instanced} + * @requires_gles30 Extension @es_extension{ANGLE,instanced_arrays}, * @es_extension2{EXT,draw_instanced,draw_instanced} or * @es_extension{NV,draw_instanced} in OpenGL ES 2.0. */ @@ -236,7 +239,7 @@ class MAGNUM_EXPORT MeshView { * @return Reference to self (for method chaining) * * Default is `0`. - * @requires_gl42 %Extension @extension{ARB,base_instance} + * @requires_gl42 Extension @extension{ARB,base_instance} * @requires_gl Base instance cannot be specified in OpenGL ES. */ MeshView& setBaseInstance(UnsignedInt baseInstance) { diff --git a/src/Magnum/MultisampleTexture.cpp b/src/Magnum/MultisampleTexture.cpp index ef957b688..363921c33 100644 --- a/src/Magnum/MultisampleTexture.cpp +++ b/src/Magnum/MultisampleTexture.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/MultisampleTexture.h b/src/Magnum/MultisampleTexture.h index e82bef600..64b57a7aa 100644 --- a/src/Magnum/MultisampleTexture.h +++ b/src/Magnum/MultisampleTexture.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,9 +40,9 @@ namespace Magnum { namespace Implementation { template constexpr GLenum multisampleTextureTarget(); - template<> inline constexpr GLenum multisampleTextureTarget<2>() { return GL_TEXTURE_2D_MULTISAMPLE; } + template<> constexpr GLenum multisampleTextureTarget<2>() { return GL_TEXTURE_2D_MULTISAMPLE; } #ifndef MAGNUM_TARGET_GLES - template<> inline constexpr GLenum multisampleTextureTarget<3>() { return GL_TEXTURE_2D_MULTISAMPLE_ARRAY; } + template<> constexpr GLenum multisampleTextureTarget<3>() { return GL_TEXTURE_2D_MULTISAMPLE_ARRAY; } #endif template typename DimensionTraits::VectorType maxMultisampleTextureSize(); @@ -86,7 +86,7 @@ shaders. @see @ref MultisampleTexture2D, @ref MultisampleTexture2DArray, @ref Texture, @ref TextureArray, @ref CubeMapTexture, @ref CubeMapTextureArray, @ref RectangleTexture, @ref BufferTexture -@requires_gl32 %Extension @extension{ARB,texture_multisample} +@requires_gl32 Extension @extension{ARB,texture_multisample} @requires_gles31 Multisample textures are not available in OpenGL ES 3.0 and older. @requires_gl 2D array multisample textures are not available in OpenGL ES, only @@ -94,7 +94,7 @@ shaders. */ template class MultisampleTexture: public AbstractTexture { public: - static const UnsignedInt Dimensions = dimensions; /**< @brief %Texture dimension count */ + static const UnsignedInt Dimensions = dimensions; /**< @brief Texture dimension count */ /** * @brief Max supported multisample texture size @@ -122,45 +122,31 @@ template class MultisampleTexture: public AbstractTextur */ explicit MultisampleTexture(): AbstractTexture(Implementation::multisampleTextureTarget()) {} - /** - * @brief %Image size - * - * The result is not cached in any way. If - * @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or - * @def_gl{TEXTURE_DEPTH} - */ - typename DimensionTraits::VectorType imageSize() { - return DataHelper::imageSize(*this, _target, 0); - } - /** * @brief Set storage * @param samples Sample count * @param internalFormat Internal format - * @param size %Texture size + * @param size Texture size * @param sampleLocations Whether to use fixed sample locations * @return Reference to self (for method chaining) * * After calling this function the texture is immutable and calling * @ref setStorage() again is not allowed. * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. If + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). If * @extension{ARB,texture_storage_multisample} (part of OpenGL 4.3) is - * not available, the feature is emulated using plain - * @extension{ARB,texture_storage} functionality (which unfortunately - * doesn't have any DSA alternative, so the texture must be bound - * to some texture unit before). + * not available, the texture is bound and the feature is emulated + * using plain @extension{ARB,texture_multisample} functionality. * @see @ref maxSize(), @ref maxColorSamples(), @ref maxDepthSamples(), - * @ref maxIntegerSamples(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} - * and @fn_gl{TexStorage2DMultisample}/@fn_gl{TexStorage3DMultisample} - * or @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access}/ - * @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access} - * eventually @fn_gl{TexImage2DMultisample}/@fn_gl{TexImage3DMultisample} + * @ref maxIntegerSamples(), @fn_gl2{TextureStorage2DMultisample,TexStorage2DMultisample} / + * @fn_gl2{TextureStorage3DMultisample,TexStorage3DMultisample}, + * @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access} / + * @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} + * and @fn_gl{TexStorage2DMultisample} / @fn_gl{TexStorage3DMultisample} + * or @fn_gl{TexImage2DMultisample} / @fn_gl{TexImage3DMultisample} * @todoc Remove the workaround when it stops breaking Doxygen layout so badly */ /* The default parameter value was chosen based on discussion in @@ -173,14 +159,35 @@ template class MultisampleTexture: public AbstractTextur NotFixed #endif ) { - DataHelper::setStorageMultisample(*this, _target, samples, internalFormat, size, GLboolean(sampleLocations)); + DataHelper::setStorageMultisample(*this, samples, internalFormat, size, GLboolean(sampleLocations)); return *this; } - /** @copydoc RectangleTexture::invalidateImage() */ + /** + * @brief Texture image size + * + * See @ref Texture::imageSize() for more information. + * @requires_gles31 Texture image size queries are not available in + * OpenGL ES 3.0 and older. + */ + typename DimensionTraits::VectorType imageSize() { + return DataHelper::imageSize(*this, 0); + } + + /** + * @copybrief Texture::invalidateImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::invalidateImage() for more information. + */ void invalidateImage() { AbstractTexture::invalidateImage(0); } - /** @copydoc RectangleTexture::invalidateSubImage() */ + /** + * @copybrief Texture::invalidateSubImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::invalidateSubImage() for more information. + */ void invalidateSubImage(const typename DimensionTraits::VectorType& offset, const typename DimensionTraits::VectorType& size) { DataHelper::invalidateSubImage(*this, 0, offset, size); } @@ -201,7 +208,7 @@ template class MultisampleTexture: public AbstractTextur /** @brief Two-dimensional multisample texture -@requires_gl32 %Extension @extension{ARB,texture_multisample} +@requires_gl32 Extension @extension{ARB,texture_multisample} @requires_gles31 Multisample textures are not available in OpenGL ES 3.0 and older. */ @@ -211,7 +218,7 @@ typedef MultisampleTexture<2> MultisampleTexture2D; /** @brief Two-dimensional multisample texture array -@requires_gl32 %Extension @extension{ARB,texture_multisample} +@requires_gl32 Extension @extension{ARB,texture_multisample} @requires_gl Only @ref Magnum::MultisampleTexture2D "MultisampleTexture2D" is available in OpenGL ES. */ diff --git a/src/Magnum/OpenGL.cpp b/src/Magnum/OpenGL.cpp index da0f1063b..d2570ce83 100644 --- a/src/Magnum/OpenGL.cpp +++ b/src/Magnum/OpenGL.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/OpenGL.h b/src/Magnum/OpenGL.h index aedede4cb..f9ae38f00 100644 --- a/src/Magnum/OpenGL.h +++ b/src/Magnum/OpenGL.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/AbstractXApplication.cpp b/src/Magnum/Platform/AbstractXApplication.cpp index fdb139e98..21cdf9743 100644 --- a/src/Magnum/Platform/AbstractXApplication.cpp +++ b/src/Magnum/Platform/AbstractXApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,9 +37,7 @@ namespace Magnum { namespace Platform { -/** @todo Delegating constructor when support for GCC 4.6 is dropped */ - -AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, const Configuration& configuration): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) { +AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, const Configuration& configuration): _contextHandler(contextHandler), _flags(Flag::Redraw) { createContext(configuration); } @@ -48,7 +46,7 @@ AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandle #else AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, void*) #endif - : contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {} + : _contextHandler(contextHandler), _flags(Flag::Redraw) {} void AbstractXApplication::createContext() { createContext({}); } @@ -57,92 +55,92 @@ void AbstractXApplication::createContext(const Configuration& configuration) { } bool AbstractXApplication::tryCreateContext(const Configuration& configuration) { - CORRADE_ASSERT(!c, "AbstractXApplication::tryCreateContext(): context already created", false); + CORRADE_ASSERT(!_context, "AbstractXApplication::tryCreateContext(): context already created", false); - viewportSize = configuration.size(); + _viewportSize = configuration.size(); /* Get default X display */ - display = XOpenDisplay(nullptr); + _display = XOpenDisplay(nullptr); /* Get visual ID */ - VisualID visualId = contextHandler->getVisualId(display); + VisualID visualId = _contextHandler->getVisualId(_display); /* Get visual info */ XVisualInfo *visInfo, visTemplate; int visualCount; visTemplate.visualid = visualId; - visInfo = XGetVisualInfo(display, VisualIDMask, &visTemplate, &visualCount); + visInfo = XGetVisualInfo(_display, VisualIDMask, &visTemplate, &visualCount); if(!visInfo) { Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot get X visual"; return false; } /* Create X Window */ - Window root = RootWindow(display, DefaultScreen(display)); + Window root = RootWindow(_display, DefaultScreen(_display)); XSetWindowAttributes attr; attr.background_pixel = 0; attr.border_pixel = 0; - attr.colormap = XCreateColormap(display, root, visInfo->visual, AllocNone); + attr.colormap = XCreateColormap(_display, root, visInfo->visual, AllocNone); attr.event_mask = 0; unsigned long mask = CWBackPixel|CWBorderPixel|CWColormap|CWEventMask; - window = XCreateWindow(display, root, 20, 20, configuration.size().x(), configuration.size().y(), 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr); - XSetStandardProperties(display, window, configuration.title().data(), nullptr, 0, nullptr, 0, nullptr); + _window = XCreateWindow(_display, root, 20, 20, configuration.size().x(), configuration.size().y(), 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr); + XSetStandardProperties(_display, _window, configuration.title().data(), nullptr, 0, nullptr, 0, nullptr); XFree(visInfo); /* Be notified about closing the window */ - deleteWindow = XInternAtom(display, "WM_DELETE_WINDOW", True); - XSetWMProtocols(display, window, &deleteWindow, 1); + _deleteWindow = XInternAtom(_display, "WM_DELETE_WINDOW", True); + XSetWMProtocols(_display, _window, &_deleteWindow, 1); /* Create context */ - contextHandler->createContext(configuration, window); + _contextHandler->createContext(configuration, _window); /* Capture exposure, keyboard and mouse button events */ - XSelectInput(display, window, INPUT_MASK); + XSelectInput(_display, _window, INPUT_MASK); /* Set OpenGL context as current */ - contextHandler->makeCurrent(); + _contextHandler->makeCurrent(); - c = new Platform::Context; + _context.reset(new Platform::Context); return true; } AbstractXApplication::~AbstractXApplication() { - delete c; + _context.reset(); /* Shut down context handler */ - delete contextHandler; + _contextHandler.reset(); /* Shut down X */ - XDestroyWindow(display, window); - XCloseDisplay(display); + XDestroyWindow(_display, _window); + XCloseDisplay(_display); } void AbstractXApplication::swapBuffers() { - contextHandler->swapBuffers(); + _contextHandler->swapBuffers(); } int AbstractXApplication::exec() { /* Show window */ - XMapWindow(display, window); + XMapWindow(_display, _window); - while(!(flags & Flag::Exit)) { + while(!(_flags & Flag::Exit)) { XEvent event; /* Closed window */ - if(XCheckTypedWindowEvent(display, window, ClientMessage, &event) && - Atom(event.xclient.data.l[0]) == deleteWindow) { + if(XCheckTypedWindowEvent(_display, _window, ClientMessage, &event) && + Atom(event.xclient.data.l[0]) == _deleteWindow) { return 0; } - while(XCheckWindowEvent(display, window, INPUT_MASK, &event)) { + while(XCheckWindowEvent(_display, _window, INPUT_MASK, &event)) { switch(event.type) { /* Window resizing */ case ConfigureNotify: { Vector2i size(event.xconfigure.width, event.xconfigure.height); - if(size != viewportSize) { - viewportSize = size; + if(size != _viewportSize) { + _viewportSize = size; viewportEvent(size); - flags |= Flag::Redraw; + _flags |= Flag::Redraw; } } break; @@ -166,8 +164,8 @@ int AbstractXApplication::exec() { } } - if(flags & Flag::Redraw) { - flags &= ~Flag::Redraw; + if(_flags & Flag::Redraw) { + _flags &= ~Flag::Redraw; drawEvent(); } else Utility::sleep(5); } diff --git a/src/Magnum/Platform/AbstractXApplication.h b/src/Magnum/Platform/AbstractXApplication.h index 860007f77..a185f4ede 100644 --- a/src/Magnum/Platform/AbstractXApplication.h +++ b/src/Magnum/Platform/AbstractXApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,6 +29,7 @@ * @brief Class @ref Magnum::Platform::AbstractXApplication */ +#include #include #include @@ -47,11 +48,7 @@ #include "Magnum/Version.h" #endif -namespace Magnum { - -class Context; - -namespace Platform { +namespace Magnum { namespace Platform { namespace Implementation { template class AbstractContextHandler; @@ -101,7 +98,7 @@ class AbstractXApplication { int exec(); /** @brief Exit application main loop */ - void exit() { flags |= Flag::Exit; } + void exit() { _flags |= Flag::Exit; } protected: /* Nobody will need to have (and delete) AbstractXApplication*, thus @@ -122,11 +119,15 @@ class AbstractXApplication { /** @{ @name Screen handling */ - /** @copydoc Sdl2Application::swapBuffers() */ + /** + * @brief Swap buffers + * + * Paints currently rendered framebuffer on screen. + */ void swapBuffers(); /** @copydoc Sdl2Application::redraw() */ - void redraw() { flags |= Flag::Redraw; } + void redraw() { _flags |= Flag::Redraw; } #ifdef DOXYGEN_GENERATING_OUTPUT protected: @@ -186,24 +187,23 @@ class AbstractXApplication { typedef Containers::EnumSet Flags; CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) - Display* display; - Window window; - Atom deleteWindow; - - Implementation::AbstractContextHandler* contextHandler; + Display* _display; + Window _window; + Atom _deleteWindow; - Platform::Context* c; + std::unique_ptr> _contextHandler; + std::unique_ptr _context; /** @todo Get this from the created window */ - Vector2i viewportSize; + Vector2i _viewportSize; - Flags flags; + Flags _flags; }; CORRADE_ENUMSET_OPERATORS(AbstractXApplication::Flags) /** -@brief %Configuration +@brief Configuration Double-buffered OpenGL context. @see @ref GlxApplication::GlxApplication(), @ref XEglApplication::XEglApplication(), @@ -263,7 +263,7 @@ class AbstractXApplication::Configuration { class AbstractXApplication::InputEvent { public: /** - * @brief %Modifier + * @brief Modifier * * @see @ref Modifiers, @ref modifiers() */ @@ -354,7 +354,7 @@ CORRADE_ENUMSET_OPERATORS(AbstractXApplication::InputEvent::Buttons) @see @ref keyPressEvent(), @ref keyReleaseEvent() */ class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent { - friend class AbstractXApplication; + friend AbstractXApplication; public: /** @@ -454,7 +454,7 @@ class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent { @see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent { - friend class AbstractXApplication; + friend AbstractXApplication; public: /** @@ -489,7 +489,7 @@ class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent @see @ref MouseEvent, @ref mouseMoveEvent() */ class AbstractXApplication::MouseMoveEvent: public AbstractXApplication::InputEvent { - friend class AbstractXApplication; + friend AbstractXApplication; public: /** @brief Position */ diff --git a/src/Magnum/Platform/AndroidApplication.cpp b/src/Magnum/Platform/AndroidApplication.cpp index 1cea60956..ba94d79a0 100644 --- a/src/Magnum/Platform/AndroidApplication.cpp +++ b/src/Magnum/Platform/AndroidApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -261,4 +261,7 @@ void AndroidApplication::exec(android_app* state, std::unique_ptruserData = nullptr; } +template class BasicScreen; +template class BasicScreenedApplication; + }} diff --git a/src/Magnum/Platform/AndroidApplication.h b/src/Magnum/Platform/AndroidApplication.h index f11ca46ac..85f324933 100644 --- a/src/Magnum/Platform/AndroidApplication.h +++ b/src/Magnum/Platform/AndroidApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -110,9 +110,9 @@ can be then installed directly on the device or emulator using `adb install`. ## General usage For CMake you need to copy `FindEGL.cmake` and `FindOpenGLES2.cmake` (or -`FindOpenGLES3.cmake`) from `modules/` directory in %Magnum source to `modules/` +`FindOpenGLES3.cmake`) from `modules/` directory in Magnum source to `modules/` dir in your project (so it is able to find EGL and OpenGL ES libraries). -Request `%AndroidApplication` component, add +Request `AndroidApplication` component, add `${MAGNUM_ANDROIDAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_ANDROIDAPPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and @@ -239,7 +239,11 @@ class AndroidApplication { /** @{ @name Screen handling */ - /** @copydoc Sdl2Application::swapBuffers() */ + /** + * @brief Swap buffers + * + * Paints currently rendered framebuffer on screen. + */ void swapBuffers(); /** @copydoc Sdl2Application::redraw() */ @@ -319,7 +323,7 @@ class AndroidApplication { CORRADE_ENUMSET_OPERATORS(AndroidApplication::Flags) /** -@brief %Configuration +@brief Configuration Double-buffered RGBA canvas with depth and stencil buffers. @see @ref AndroidApplication(), @ref createContext(), @ref tryCreateContext() @@ -420,7 +424,7 @@ class AndroidApplication::InputEvent { @see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class AndroidApplication::MouseEvent: public InputEvent { - friend class AndroidApplication; + friend AndroidApplication; public: /** @@ -492,7 +496,7 @@ class AndroidApplication::MouseEvent: public InputEvent { @see @ref MouseEvent, @ref mouseMoveEvent() */ class AndroidApplication::MouseMoveEvent: public InputEvent { - friend class AndroidApplication; + friend AndroidApplication; public: /** diff --git a/src/Magnum/Platform/CMakeLists.txt b/src/Magnum/Platform/CMakeLists.txt index 9180cf20c..b6984ba7c 100644 --- a/src/Magnum/Platform/CMakeLists.txt +++ b/src/Magnum/Platform/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -78,6 +78,9 @@ if(WITH_ANDROIDAPPLICATION) ${MagnumAndroidApplication_PRIVATE_HEADERS} ${ANDROID_NATIVE_APP_GLUE_SRC}) set_target_properties(MagnumAndroidApplication PROPERTIES DEBUG_POSTFIX "-d") + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumAndroidApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumAndroidApplication RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -101,6 +104,9 @@ if(WITH_GLUTAPPLICATION) ${MagnumGlutApplication_SRCS} ${MagnumGlutApplication_HEADERS}) set_target_properties(MagnumGlutApplication PROPERTIES DEBUG_POSTFIX "-d") + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumGlutApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumGlutApplication RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -126,6 +132,9 @@ if(WITH_SDL2APPLICATION) ${MagnumSdl2Application_SRCS} ${MagnumSdl2Application_HEADERS}) set_target_properties(MagnumSdl2Application PROPERTIES DEBUG_POSTFIX "-d") + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumSdl2Application_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumSdl2Application RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -146,6 +155,9 @@ if(WITH_NACLAPPLICATION) ${MagnumNaClApplication_SRCS} ${MagnumNaClApplication_HEADERS}) set_target_properties(MagnumNaClApplication PROPERTIES DEBUG_POSTFIX "-d") + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumNaClApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumNaClApplication RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -167,6 +179,9 @@ if(WITH_WINDOWLESSNACLAPPLICATION) ${MagnumWindowlessNaClApplication_HEADERS}) set_target_properties(MagnumWindowlessNaClApplication PROPERTIES DEBUG_POSTFIX "-d") target_link_libraries(MagnumWindowlessNaClApplication Magnum ppapi_cpp ppapi) + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumWindowlessNaClApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumWindowlessNaClApplication RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -209,6 +224,9 @@ if(WITH_GLXAPPLICATION) ${MagnumGlxApplication_SRCS} ${MagnumGlxApplication_HEADERS}) set_target_properties(MagnumGlxApplication PROPERTIES DEBUG_POSTFIX "-d") + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumGlxApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumGlxApplication RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -233,6 +251,9 @@ if(WITH_XEGLAPPLICATION) ${MagnumXEglApplication_SRCS} ${MagnumXEglApplication_HEADERS}) set_target_properties(MagnumXEglApplication PROPERTIES DEBUG_POSTFIX "-d") + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumXEglApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumXEglApplication RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -264,6 +285,9 @@ if(WITH_WINDOWLESSGLXAPPLICATION) COMPILE_FLAGS "-Wno-old-style-cast" DEBUG_POSTFIX "-d") target_link_libraries(MagnumWindowlessGlxApplication Magnum ${X11_LIBRARIES}) + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumWindowlessGlxApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumWindowlessGlxApplication RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -287,6 +311,9 @@ if(WITH_WINDOWLESSWGLAPPLICATION) COMPILE_FLAGS "-DUNICODE" DEBUG_POSTFIX "-d") target_link_libraries(MagnumWindowlessWglApplication Magnum) + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumWindowlessWglApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumWindowlessWglApplication RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -308,6 +335,9 @@ if(WITH_WINDOWLESSCGLAPPLICATION) ${MagnumWindowlessCglApplication_HEADERS}) set_target_properties(MagnumWindowlessCglApplication PROPERTIES DEBUG_POSTFIX "-d") target_link_libraries(MagnumWindowlessCglApplication Magnum) + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumWindowlessGlxApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumWindowlessCglApplication RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} @@ -325,6 +355,9 @@ if(NEED_ABSTRACTXAPPLICATION) ${MagnumAbstractXApplication_HEADERS}) # X11 macros are a mess, disable warnings for C-style casts set_target_properties(MagnumAbstractXApplication PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + install(FILES ${MagnumAbstractXApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) endif() @@ -341,6 +374,9 @@ if(NEED_GLXCONTEXTHANDLER) ${MagnumGlxContextHandler_PRIVATE_HEADERS}) # X11 macros are a mess, disable warnings for C-style casts set_target_properties(MagnumGlxContextHandler PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") + # Assuming that PIC is not needed because this is part of Application lib, + # which is always linked to the executable and not to any intermediate + # shared lib endif() # EGL context handler @@ -363,6 +399,9 @@ if(NEED_EGLCONTEXTHANDLER) ${MagnumEglContextHandler_PRIVATE_HEADERS}) # X11 macros are a mess, disable warnings for C-style casts set_target_properties(MagnumEglContextHandler PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") + # Assuming that PIC is not needed because this is part of Application lib, + # which is always linked to the executable and not to any intermediate + # shared lib endif() # Platform-specific sources for context library @@ -378,6 +417,9 @@ endif() # CGL context if(NEED_CGLCONTEXT OR WITH_CGLCONTEXT) add_library(MagnumCglContextObjects OBJECT ${MagnumContext_SRCS}) + if(BUILD_STATIC_PIC) + set_target_properties(MagnumCglContextObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() # Also create proper static library, if requested if(WITH_CGLCONTEXT) @@ -386,6 +428,10 @@ if(NEED_CGLCONTEXT OR WITH_CGLCONTEXT) # sources again in this case add_library(MagnumCglContext STATIC ${MagnumContext_SRCS}) set_target_properties(MagnumCglContext PROPERTIES DEBUG_POSTFIX "-d") + if(BUILD_STATIC_PIC) + set_target_properties(MagnumCglContext PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() + install(TARGETS MagnumCglContext RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} @@ -397,11 +443,18 @@ endif() if(NEED_EGLCONTEXT OR WITH_EGLCONTEXT) add_library(MagnumEglContextObjects OBJECT ${MagnumContext_SRCS}) set_target_properties(MagnumEglContextObjects PROPERTIES COMPILE_DEFINITIONS "MAGNUM_PLATFORM_USE_EGL") + if(BUILD_STATIC_PIC) + set_target_properties(MagnumEglContextObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() # Also create proper static library, if requested if(WITH_EGLCONTEXT) add_library(MagnumEglContext STATIC $) set_target_properties(MagnumEglContext PROPERTIES DEBUG_POSTFIX "-d") + if(BUILD_STATIC_PIC) + set_target_properties(MagnumEglContext PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() + install(TARGETS MagnumEglContext RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} @@ -413,11 +466,18 @@ endif() if(NEED_GLXCONTEXT OR WITH_GLXCONTEXT) add_library(MagnumGlxContextObjects OBJECT ${MagnumContext_SRCS}) set_target_properties(MagnumGlxContextObjects PROPERTIES COMPILE_DEFINITIONS "MAGNUM_PLATFORM_USE_GLX") + if(BUILD_STATIC_PIC) + set_target_properties(MagnumGlxContextObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() # Also create proper static library, if requested if(WITH_GLXCONTEXT) add_library(MagnumGlxContext STATIC $) set_target_properties(MagnumGlxContext PROPERTIES DEBUG_POSTFIX "-d") + if(BUILD_STATIC_PIC) + set_target_properties(MagnumGlxContext PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() + install(TARGETS MagnumGlxContext RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} @@ -428,11 +488,18 @@ endif() # WGL context if(NEED_WGLCONTEXT OR WITH_WGLCONTEXT) add_library(MagnumWglContextObjects OBJECT ${MagnumContext_SRCS}) + if(BUILD_STATIC_PIC) + set_target_properties(MagnumWglContextObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() # Also create proper static library, if requested if(WITH_GLXCONTEXT) add_library(MagnumWglContext STATIC $) set_target_properties(MagnumWglContext PROPERTIES DEBUG_POSTFIX "-d") + if(BUILD_STATIC_PIC) + set_target_properties(MagnumWglContext PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() + install(TARGETS MagnumWglContext RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} diff --git a/src/Magnum/Platform/Context.h b/src/Magnum/Platform/Context.h index f0503c9c9..32c39c7dd 100644 --- a/src/Magnum/Platform/Context.h +++ b/src/Magnum/Platform/Context.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/GlutApplication.cpp b/src/Magnum/Platform/GlutApplication.cpp index a3d29bcb7..099ff1b5f 100644 --- a/src/Magnum/Platform/GlutApplication.cpp +++ b/src/Magnum/Platform/GlutApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,17 +33,15 @@ namespace Magnum { namespace Platform { -GlutApplication* GlutApplication::instance = nullptr; +GlutApplication* GlutApplication::_instance = nullptr; -/** @todo Delegating constructor when support for GCC 4.6 is dropped */ - -GlutApplication::GlutApplication(const Arguments& arguments, const Configuration& configuration): c(nullptr) { +GlutApplication::GlutApplication(const Arguments& arguments, const Configuration& configuration) { initialize(arguments.argc, arguments.argv); createContext(configuration); } #ifndef DOXYGEN_GENERATING_OUTPUT -GlutApplication::GlutApplication(const Arguments& arguments): c(nullptr) { +GlutApplication::GlutApplication(const Arguments& arguments) { initialize(arguments.argc, arguments.argv); createContext(); } @@ -54,14 +52,13 @@ GlutApplication::GlutApplication(const Arguments& arguments, std::nullptr_t) #else GlutApplication::GlutApplication(const Arguments& arguments, void*) #endif - : c(nullptr) { initialize(arguments.argc, arguments.argv); } void GlutApplication::initialize(int& argc, char** argv) { /* Save global instance */ - instance = this; + _instance = this; /* Init GLUT */ glutInit(&argc, argv); @@ -75,7 +72,7 @@ void GlutApplication::createContext(const Configuration& configuration) { } bool GlutApplication::tryCreateContext(const Configuration& configuration) { - CORRADE_ASSERT(!c, "Platform::GlutApplication::tryCreateContext(): context already created", false); + CORRADE_ASSERT(!_context, "Platform::GlutApplication::tryCreateContext(): context already created", false); unsigned int flags = GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL; @@ -112,45 +109,43 @@ bool GlutApplication::tryCreateContext(const Configuration& configuration) { glutMotionFunc(staticMouseMoveEvent); glutDisplayFunc(staticDrawEvent); - c = new Platform::Context; + _context.reset(new Platform::Context); return true; } -GlutApplication::~GlutApplication() { - delete c; -} +GlutApplication::~GlutApplication() = default; void GlutApplication::staticKeyPressEvent(unsigned char key, int x, int y) { KeyEvent e(static_cast(key), {x, y}); - instance->keyPressEvent(e); + _instance->keyPressEvent(e); } void GlutApplication::staticKeyReleaseEvent(unsigned char key, int x, int y) { KeyEvent e(static_cast(key), {x, y}); - instance->keyReleaseEvent(e); + _instance->keyReleaseEvent(e); } void GlutApplication::staticSpecialKeyPressEvent(int key, int x, int y){ KeyEvent e(static_cast(key << 16), {x, y}); - instance->keyPressEvent(e); + _instance->keyPressEvent(e); } void GlutApplication::staticSpecialKeyReleaseEvent(int key, int x, int y){ KeyEvent e(static_cast(key << 16), {x, y}); - instance->keyReleaseEvent(e); + _instance->keyReleaseEvent(e); } void GlutApplication::staticMouseEvent(int button, int state, int x, int y) { MouseEvent e(static_cast(button), {x, y}); if(state == GLUT_DOWN) - instance->mousePressEvent(e); + _instance->mousePressEvent(e); else - instance->mouseReleaseEvent(e); + _instance->mouseReleaseEvent(e); } void GlutApplication::staticMouseMoveEvent(int x, int y) { MouseMoveEvent e({x, y}, MouseMoveEvent::Button::Left); - instance->mouseMoveEvent(e); + _instance->mouseMoveEvent(e); } void GlutApplication::viewportEvent(const Vector2i&) {} diff --git a/src/Magnum/Platform/GlutApplication.h b/src/Magnum/Platform/GlutApplication.h index 877d4b4b5..9b9d60ec2 100644 --- a/src/Magnum/Platform/GlutApplication.h +++ b/src/Magnum/Platform/GlutApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,6 +29,7 @@ * @brief Class @ref Magnum::Platform::GlutApplication, macro @ref MAGNUM_GLUTAPPLICATION_MAIN() */ +#include #include #include "Magnum/Magnum.h" @@ -43,11 +44,7 @@ #include "Magnum/Version.h" #endif -namespace Magnum { - -class Context; - -namespace Platform { +namespace Magnum { namespace Platform { /** @nosubgrouping @brief GLUT application @@ -78,7 +75,7 @@ See @ref cmake for more information. ## General usage -In CMake you need to request `%GlutApplication` component, add +In CMake you need to request `GlutApplication` component, add `${MAGNUM_GLUTAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_GLUTAPPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and @@ -172,7 +169,11 @@ class GlutApplication { /** @{ @name Screen handling */ - /** @copydoc Sdl2Application::swapBuffers() */ + /** + * @brief Swap buffers + * + * Paints currently rendered framebuffer on screen. + */ void swapBuffers() { glutSwapBuffers(); } /** @copydoc Sdl2Application::redraw() */ @@ -260,7 +261,7 @@ class GlutApplication { void initialize(int& argc, char** argv); static void staticViewportEvent(int x, int y) { - instance->viewportEvent({x, y}); + _instance->viewportEvent({x, y}); } static void staticKeyPressEvent(unsigned char key, int x, int y); @@ -274,16 +275,16 @@ class GlutApplication { static void staticMouseMoveEvent(int x, int y); static void staticDrawEvent() { - instance->drawEvent(); + _instance->drawEvent(); } - static GlutApplication* instance; + static GlutApplication* _instance; - Platform::Context* c; + std::unique_ptr _context; }; /** -@brief %Configuration +@brief Configuration Double-buffered RGBA window with depth and stencil buffers. @see @ref GlutApplication(), @ref createContext(), @ref tryCreateContext() @@ -291,7 +292,7 @@ Double-buffered RGBA window with depth and stencil buffers. class GlutApplication::Configuration { public: /** - * @brief %Context flag + * @brief Context flag * * @see @ref Flags, @ref setFlags() */ @@ -300,7 +301,7 @@ class GlutApplication::Configuration { }; /** - * @brief %Context flags + * @brief Context flags * * @see @ref setFlags() */ @@ -341,7 +342,7 @@ class GlutApplication::Configuration { return *this; } - /** @brief %Context flags */ + /** @brief Context flags */ Flags flags() const { return _flags; } /** @@ -355,7 +356,7 @@ class GlutApplication::Configuration { return *this; } - /** @brief %Context version */ + /** @brief Context version */ Version version() const { return _version; } /** @@ -446,7 +447,7 @@ inline GlutApplication::InputEvent::~InputEvent() = default; @see @ref keyPressEvent() */ class GlutApplication::KeyEvent: public GlutApplication::InputEvent { - friend class GlutApplication; + friend GlutApplication; public: /** @@ -545,7 +546,7 @@ class GlutApplication::KeyEvent: public GlutApplication::InputEvent { @see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class GlutApplication::MouseEvent: public GlutApplication::InputEvent { - friend class GlutApplication; + friend GlutApplication; public: /** @@ -580,7 +581,7 @@ class GlutApplication::MouseEvent: public GlutApplication::InputEvent { @see @ref MouseEvent, @ref mouseMoveEvent() */ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent { - friend class GlutApplication; + friend GlutApplication; public: /** diff --git a/src/Magnum/Platform/GlxApplication.cpp b/src/Magnum/Platform/GlxApplication.cpp index be86288b6..0780257e4 100644 --- a/src/Magnum/Platform/GlxApplication.cpp +++ b/src/Magnum/Platform/GlxApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/GlxApplication.h b/src/Magnum/Platform/GlxApplication.h index d46ed4c5c..bfd3a844c 100644 --- a/src/Magnum/Platform/GlxApplication.h +++ b/src/Magnum/Platform/GlxApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -52,7 +52,7 @@ more information. ## General usage -In CMake you need to request `%GlxApplication` component, add +In CMake you need to request `GlxApplication` component, add `${MAGNUM_GLXAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_GLXAPPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and @@ -79,7 +79,7 @@ class GlxApplication: public AbstractXApplication { /** * @brief Default constructor * @param arguments Application arguments - * @param configuration %Configuration + * @param configuration Configuration * * Creates application with default or user-specified configuration. * See @ref AbstractXApplication::Configuration "Configuration" for diff --git a/src/Magnum/Platform/Implementation/AbstractContextHandler.h b/src/Magnum/Platform/Implementation/AbstractContextHandler.h index 87b18d9b5..83620414f 100644 --- a/src/Magnum/Platform/Implementation/AbstractContextHandler.h +++ b/src/Magnum/Platform/Implementation/AbstractContextHandler.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/Implementation/Egl.cpp b/src/Magnum/Platform/Implementation/Egl.cpp index 35c5fdda1..8857e1d5a 100644 --- a/src/Magnum/Platform/Implementation/Egl.cpp +++ b/src/Magnum/Platform/Implementation/Egl.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/Implementation/Egl.h b/src/Magnum/Platform/Implementation/Egl.h index a84e4fe4c..1828e4c02 100644 --- a/src/Magnum/Platform/Implementation/Egl.h +++ b/src/Magnum/Platform/Implementation/Egl.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/Implementation/EglContextHandler.cpp b/src/Magnum/Platform/Implementation/EglContextHandler.cpp index 153dd7bad..8b3442cca 100644 --- a/src/Magnum/Platform/Implementation/EglContextHandler.cpp +++ b/src/Magnum/Platform/Implementation/EglContextHandler.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/Implementation/EglContextHandler.h b/src/Magnum/Platform/Implementation/EglContextHandler.h index 8c9b7a551..82a5eb711 100644 --- a/src/Magnum/Platform/Implementation/EglContextHandler.h +++ b/src/Magnum/Platform/Implementation/EglContextHandler.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/Implementation/GlxContextHandler.cpp b/src/Magnum/Platform/Implementation/GlxContextHandler.cpp index 40da38307..4ba23bfc7 100644 --- a/src/Magnum/Platform/Implementation/GlxContextHandler.cpp +++ b/src/Magnum/Platform/Implementation/GlxContextHandler.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/Implementation/GlxContextHandler.h b/src/Magnum/Platform/Implementation/GlxContextHandler.h index 7c3805ae1..b851adfb5 100644 --- a/src/Magnum/Platform/Implementation/GlxContextHandler.h +++ b/src/Magnum/Platform/Implementation/GlxContextHandler.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp b/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp index 239f7b545..7a58a698d 100644 --- a/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp +++ b/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h b/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h index 9521b033d..c47ba5587 100644 --- a/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h +++ b/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/NaClApplication.cpp b/src/Magnum/Platform/NaClApplication.cpp index d4e345f97..6359758aa 100644 --- a/src/Magnum/Platform/NaClApplication.cpp +++ b/src/Magnum/Platform/NaClApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/NaClApplication.h b/src/Magnum/Platform/NaClApplication.h index 88a718c2c..4d3115e1b 100644 --- a/src/Magnum/Platform/NaClApplication.h +++ b/src/Magnum/Platform/NaClApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -122,8 +122,8 @@ You can then open `MyApplication` through your webserver in Chrome (e.g. ## General usage For CMake you need to copy `FindOpenGLES2.cmake` from `modules/` directory in -%Magnum source to `modules/` dir in your project (so it is able to find OpenGL -ES). Request `%NaClApplication` component, add +Magnum source to `modules/` dir in your project (so it is able to find OpenGL +ES). Request `NaClApplication` component, add `${MAGNUM_NACLAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_NACLAPPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and @@ -275,7 +275,11 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public bool setFullscreen(bool enabled); protected: - /** @copydoc Sdl2Application::swapBuffers() */ + /** + * @brief Swap buffers + * + * Paints currently rendered framebuffer on screen. + */ void swapBuffers(); /** @copydoc Sdl2Application::redraw() */ @@ -404,7 +408,7 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public }; /** -@brief %Configuration +@brief Configuration Double-buffered RGBA canvas with depth and stencil buffers. @see @ref NaClApplication(), @ref createContext(), @ref tryCreateContext() @@ -478,7 +482,7 @@ propagated to the browser. class NaClApplication::InputEvent { public: /** - * @brief %Modifier + * @brief Modifier * * @see @ref Modifiers, @ref modifiers() * @todo AltGr + PP_INPUTEVENT_MODIFIER_ISKEYPAD, PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT @@ -574,7 +578,7 @@ See also @ref InputEvent for more information. @see @ref keyPressEvent(), @ref keyReleaseEvent() */ class NaClApplication::KeyEvent: public NaClApplication::InputEvent { - friend class NaClApplication; + friend NaClApplication; public: /** @@ -669,7 +673,7 @@ See also @ref InputEvent for more information. @see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class NaClApplication::MouseEvent: public NaClApplication::InputEvent { - friend class NaClApplication; + friend NaClApplication; public: /** @@ -711,7 +715,7 @@ See also @ref InputEvent for more information. @see @ref MouseEvent, @ref mouseMoveEvent() */ class NaClApplication::MouseMoveEvent: public NaClApplication::InputEvent { - friend class NaClApplication; + friend NaClApplication; public: /** @brief Position */ diff --git a/src/Magnum/Platform/Platform.h b/src/Magnum/Platform/Platform.h index 41e25dd0e..ebb547c33 100644 --- a/src/Magnum/Platform/Platform.h +++ b/src/Magnum/Platform/Platform.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,9 +31,11 @@ namespace Magnum { namespace Platform { +#ifndef DOXYGEN_GENERATING_OUTPUT template class BasicScreen; template class BasicScreenedApplication; class Context; +#endif }} diff --git a/src/Magnum/Platform/Screen.h b/src/Magnum/Platform/Screen.h index dafd416e1..51163cb20 100644 --- a/src/Magnum/Platform/Screen.h +++ b/src/Magnum/Platform/Screen.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -67,9 +67,9 @@ The following specialization are explicitly compiled into each particular - @ref XEglApplication "BasicScreen" */ template class BasicScreen: private Containers::LinkedListItem, BasicScreenedApplication> { - friend class Containers::LinkedListItem, BasicScreenedApplication>; - friend class Containers::LinkedList>; - friend class BasicScreenedApplication; + friend Containers::LinkedListItem, BasicScreenedApplication>; + friend Containers::LinkedList>; + friend BasicScreenedApplication; public: #ifdef DOXYGEN_GENERATING_OUTPUT @@ -134,7 +134,7 @@ template class BasicScreen: private Containers::LinkedListIte */ void setPropagatedEvents(PropagatedEvents events) { _propagatedEvents = events; } - /** @brief %Application holding this screen */ + /** @brief Application holding this screen */ template> T* application() { return static_cast(Containers::LinkedListItem, BasicScreenedApplication>::list()); } diff --git a/src/Magnum/Platform/ScreenedApplication.h b/src/Magnum/Platform/ScreenedApplication.h index 0891ed9f3..e0e315218 100644 --- a/src/Magnum/Platform/ScreenedApplication.h +++ b/src/Magnum/Platform/ScreenedApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -62,15 +62,21 @@ application gets an event, they are propagated to the screens: @ref BasicScreen::PropagatedEvent::Input enabled. If any screen sets the event as accepted, it is not propagated further. -Traversing through the list of screens is done like following: +Uses @ref Corrade::Containers::LinkedList for efficient screen management. +Traversing front-to-back through the list of screens can be done using +range-based for: @code -// front-to-back -for(Screen* s = app.frontScreen(); s; s = s->nextFartherScreen()) { +MyApplication app; +for(Screen& screen: app.screens()) { // ... } +@endcode -// back-to-front -for(Screen* s = app.backScreen(); s; s = s->nextNearerScreen()) { +Or, if you need more flexibility, like in the following code. Traversing +back-to-front can be done using @ref Corrade::Containers::LinkedList::last() +and @ref BasicScreen::nextNearerScreen(). +@code +for(Screen* s = app.screens().first(); s; s = s->nextFartherScreen()) { // ... } @endcode @@ -89,15 +95,15 @@ The following specialization are explicitly compiled into each particular - @ref XEglApplication "BasicScreenedApplication" */ template class BasicScreenedApplication: public Application, private Containers::LinkedList> { - friend class Containers::LinkedList>; - friend class Containers::LinkedListItem, BasicScreenedApplication>; - friend class BasicScreen; + friend Containers::LinkedList>; + friend Containers::LinkedListItem, BasicScreenedApplication>; + friend BasicScreen; public: /** * @brief Default constructor * @param arguments Application arguments - * @param configuration %Configuration + * @param configuration Configuration * * Creates application with default or user-specified configuration. * See @ref Sdl2Application::Configuration "Configuration" for more @@ -152,30 +158,46 @@ template class BasicScreenedApplication: public Application, BasicScreenedApplication& focusScreen(BasicScreen& screen); /** - * @brief Front screen + * @brief Application screens * - * @see @ref BasicScreen::nextFartherScreen(), @ref BasicScreen::nextNearerScreen() + * The screens are sorted front-to-back. + * @see @ref BasicScreen::application(), + * @ref BasicScreen::nextFartherScreen(), + * @ref BasicScreen::nextNearerScreen() */ - BasicScreen* frontScreen() { - return Containers::LinkedList>::first(); + Containers::LinkedList>& screens() { + return static_cast>&>(*this); } + /** @overload */ - const BasicScreen* frontScreen() const { - return Containers::LinkedList>::first(); + const Containers::LinkedList>& screens() const { + return static_cast>&>(*this); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Front screen + * @deprecated Use `screens().first()` instead. + */ + CORRADE_DEPRECATED("use screens().first() instead") BasicScreen* frontScreen() { return screens().first(); } + + /** @overload + * @deprecated Use `screens().first()` instead. + */ + CORRADE_DEPRECATED("use screens().first() instead") const BasicScreen* frontScreen() const { return screens().first(); } + /** * @brief Back screen - * - * @see @ref BasicScreen::nextFartherScreen(), @ref BasicScreen::nextNearerScreen() + * @deprecated Use `screens().last()` instead. */ - BasicScreen* backScreen() { - return Containers::LinkedList>::last(); - } - /** @overload */ - const BasicScreen* backScreen() const { - return Containers::LinkedList>::last(); - } + CORRADE_DEPRECATED("use screens().back() instead") BasicScreen* backScreen() { return screens().last(); } + + /** + * @overload + * @deprecated Use `screens().last()` instead. + */ + CORRADE_DEPRECATED("use screens().back() instead") const BasicScreen* backScreen() const { return screens().last(); } + #endif protected: /* Nobody will need to have (and delete) ScreenedApplication*, thus diff --git a/src/Magnum/Platform/ScreenedApplication.hpp b/src/Magnum/Platform/ScreenedApplication.hpp index 93b0995eb..869f5b6ea 100644 --- a/src/Magnum/Platform/ScreenedApplication.hpp +++ b/src/Magnum/Platform/ScreenedApplication.hpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -55,7 +55,7 @@ template BasicScreenedApplication::~BasicScreene template BasicScreenedApplication& BasicScreenedApplication::addScreen(BasicScreen& screen) { Containers::LinkedList>::insert(&screen); - if(frontScreen() == &screen) screen.focusEvent(); + if(screens().first() == &screen) screen.focusEvent(); Application::redraw(); return *this; } @@ -69,10 +69,10 @@ template BasicScreenedApplication& BasicScreened template BasicScreenedApplication& BasicScreenedApplication::focusScreen(BasicScreen& screen) { /* Already focused, nothing to do */ - if(frontScreen() == &screen) return *this; + if(screens().first() == &screen) return *this; - frontScreen()->blurEvent(); - Containers::LinkedList>::move(&screen, frontScreen()); + screens().first()->blurEvent(); + Containers::LinkedList>::move(&screen, screens().first()); screen.focusEvent(); Application::redraw(); return *this; @@ -81,25 +81,24 @@ template BasicScreenedApplication& BasicScreened template void BasicScreenedApplication::globalViewportEvent(const Vector2i&) {} template void BasicScreenedApplication::viewportEvent(const Vector2i& size) { - /* Call viewport event after all other (because of framebuffer resizing) */ + /* Call global event before all other (to resize framebuffer first) */ globalViewportEvent(size); - for(BasicScreen* s = Containers::LinkedList>::first(); s; s = s->next()) - s->viewportEvent(size); + for(BasicScreen& s: *this) s.viewportEvent(size); } template void BasicScreenedApplication::drawEvent() { /* Back-to-front rendering */ - for(BasicScreen* s = backScreen(); s; s = s->nextNearerScreen()) + for(BasicScreen* s = screens().last(); s; s = s->nextNearerScreen()) if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Draw) s->drawEvent(); - /* Call global event after all other (because of buffer swapping) */ + /* Call global event after all other (to swap buffers last) */ globalDrawEvent(); } template void BasicScreenedApplication::keyPressEvent(typename Application::KeyEvent& event) { /* Front-to-back event propagation, stop when the event gets accepted */ - for(BasicScreen* s = frontScreen(); s; s = s->nextFartherScreen()) { + for(BasicScreen* s = screens().first(); s; s = s->nextFartherScreen()) { if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { s->keyPressEvent(event); if(event.isAccepted()) break; @@ -109,7 +108,7 @@ template void BasicScreenedApplication::keyPress template void BasicScreenedApplication::keyReleaseEvent(typename Application::KeyEvent& event) { /* Front-to-back event propagation, stop when the event gets accepted */ - for(BasicScreen* s = frontScreen(); s; s = s->nextFartherScreen()) { + for(BasicScreen* s = screens().first(); s; s = s->nextFartherScreen()) { if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { s->keyReleaseEvent(event); if(event.isAccepted()) break; @@ -119,7 +118,7 @@ template void BasicScreenedApplication::keyRelea template void BasicScreenedApplication::mousePressEvent(typename Application::MouseEvent& event) { /* Front-to-back event propagation, stop when the event gets accepted */ - for(BasicScreen* s = frontScreen(); s; s = s->nextFartherScreen()) { + for(BasicScreen* s = screens().first(); s; s = s->nextFartherScreen()) { if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { s->mousePressEvent(event); if(event.isAccepted()) break; @@ -129,7 +128,7 @@ template void BasicScreenedApplication::mousePre template void BasicScreenedApplication::mouseReleaseEvent(typename Application::MouseEvent& event) { /* Front-to-back event propagation, stop when the event gets accepted */ - for(BasicScreen* s = frontScreen(); s; s = s->nextFartherScreen()) { + for(BasicScreen* s = screens().first(); s; s = s->nextFartherScreen()) { if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { s->mouseReleaseEvent(event); if(event.isAccepted()) break; @@ -139,7 +138,7 @@ template void BasicScreenedApplication::mouseRel template void BasicScreenedApplication::mouseMoveEvent(typename Application::MouseMoveEvent& event) { /* Front-to-back event propagation, stop when the event gets accepted */ - for(BasicScreen* s = frontScreen(); s; s = s->nextFartherScreen()) { + for(BasicScreen* s = screens().first(); s; s = s->nextFartherScreen()) { if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { s->mouseMoveEvent(event); if(event.isAccepted()) break; diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp index 71f3854ed..604a72fed 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -56,21 +56,19 @@ Sdl2Application::InputEvent::Modifiers fixedModifiers(Uint16 mod) { } #ifdef CORRADE_TARGET_EMSCRIPTEN -Sdl2Application* Sdl2Application::instance = nullptr; +Sdl2Application* Sdl2Application::_instance = nullptr; void Sdl2Application::staticMainLoop() { - instance->mainLoop(); + _instance->mainLoop(); } #endif -/** @todo Delegating constructor when support for GCC 4.6 is dropped */ - -Sdl2Application::Sdl2Application(const Arguments&, const Configuration& configuration): context(nullptr), flags(Flag::Redraw) { +Sdl2Application::Sdl2Application(const Arguments&, const Configuration& configuration): _glContext(nullptr), _flags(Flag::Redraw) { initialize(); createContext(configuration); } #ifndef DOXYGEN_GENERATING_OUTPUT -Sdl2Application::Sdl2Application(const Arguments&): context(nullptr), flags(Flag::Redraw) { +Sdl2Application::Sdl2Application(const Arguments&): _glContext(nullptr), _flags(Flag::Redraw) { initialize(); createContext(); } @@ -81,15 +79,15 @@ Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) #else Sdl2Application::Sdl2Application(const Arguments&, void*) #endif - : context(nullptr), flags(Flag::Redraw) + : _glContext(nullptr), _flags(Flag::Redraw) { initialize(); } void Sdl2Application::initialize() { #ifdef CORRADE_TARGET_EMSCRIPTEN - CORRADE_ASSERT(!instance, "Platform::Sdl2Application::Sdl2Application(): the instance is already created", ); - instance = this; + CORRADE_ASSERT(!_instance, "Platform::Sdl2Application::Sdl2Application(): the instance is already created", ); + _instance = this; #endif if(SDL_Init(SDL_INIT_VIDEO) < 0) { @@ -105,7 +103,7 @@ void Sdl2Application::createContext(const Configuration& configuration) { } bool Sdl2Application::tryCreateContext(const Configuration& configuration) { - CORRADE_ASSERT(!context, "Platform::Sdl2Application::tryCreateContext(): context already created", false); + CORRADE_ASSERT(!_glContext, "Platform::Sdl2Application::tryCreateContext(): context already created", false); /* Enable double buffering and 24bt depth buffer */ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); @@ -122,11 +120,12 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { /* Flags: if not hidden, set as shown */ Uint32 windowFlags(configuration.windowFlags()); - if(!(configuration.windowFlags() & Configuration::WindowFlag::Hidden)) windowFlags |= SDL_WINDOW_SHOWN; + if(!(configuration.windowFlags() & Configuration::WindowFlag::Hidden)) + windowFlags |= SDL_WINDOW_SHOWN; /** @todo Remove when Emscripten has proper SDL2 support */ #ifndef CORRADE_TARGET_EMSCRIPTEN - /* Set context version, if requested */ + /* Set context version, if user-specified */ if(configuration.version() != Version::None) { Int major, minor; std::tie(major, minor) = version(configuration.version()); @@ -139,10 +138,25 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { #else SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); #endif - } - #ifdef MAGNUM_TARGET_GLES - else { + /* Request usable version otherwise */ + } else { + #ifndef MAGNUM_TARGET_GLES + /* First try to create core context. This is needed mainly on OS X and + Mesa, as support for recent OpenGL versions isn't implemented in + compatibility contexts (which are the default). At least GL 3.2 is + needed on OSX, at least GL 3.0 is needed on Mesa. Bite the bullet + and try 3.0 also elsewhere. */ + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + #ifdef CORRADE_TARGET_APPLE + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + #else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + #endif + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + + #else + /* For ES the major context version is compile-time constant */ #ifdef MAGNUM_TARGET_GLES3 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); #elif defined(MAGNUM_TARGET_GLES2) @@ -152,22 +166,11 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { #endif SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + #endif } - /* On OS X we need to create 3.2 context, as the default (2.1) contains - compatibility features which are not implemented for newer GL versions - in Apple's GL drivers, thus we would be forever stuck on 2.1 without the - new features. In practice SDL fails to create 2.1 context on recent OS X - versions. */ - #elif defined(CORRADE_TARGET_APPLE) - else { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - } - #endif - - if(!(window = SDL_CreateWindow(configuration.title().data(), + /* Create window */ + if(!(_window = SDL_CreateWindow(configuration.title().data(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, configuration.size().x(), configuration.size().y(), SDL_WINDOW_OPENGL|windowFlags))) @@ -176,17 +179,21 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { return false; } - /* Fall back to GL 2.1, if 3.2 context creation fails on OS X */ - #ifdef CORRADE_TARGET_APPLE - if(!(context = SDL_GL_CreateContext(window))){ + /* Create context */ + _glContext = SDL_GL_CreateContext(_window); + + #ifndef MAGNUM_TARGET_GLES + /* Fall back to (forward compatible) GL 2.1, if core context creation fails + and if version is not user-specified */ + if(configuration.version() == Version::None && !_glContext) { Warning() << "Platform::Sdl2Application::tryCreateContext(): cannot create core context:" << SDL_GetError() << "(falling back to compatibility context)"; - SDL_DestroyWindow(window); + SDL_DestroyWindow(_window); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); - if(!(window = SDL_CreateWindow(configuration.title().data(), + if(!(_window = SDL_CreateWindow(configuration.title().data(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, configuration.size().x(), configuration.size().y(), SDL_WINDOW_OPENGL|windowFlags))) @@ -194,55 +201,69 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); return false; } - - if(!(context = SDL_GL_CreateContext(window))){ - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create compatibility context:" << SDL_GetError(); - SDL_DestroyWindow(window); - window = nullptr; - return false; - } } - #else - if(!(context = SDL_GL_CreateContext(window))) { + #endif + + /* Cannot create context (or fallback compatibility context on desktop) */ + if(!_glContext) { Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create context:" << SDL_GetError(); - SDL_DestroyWindow(window); - window = nullptr; + SDL_DestroyWindow(_window); + _window = nullptr; return false; } - #endif + #else - context = SDL_SetVideoMode(configuration.size().x(), configuration.size().y(), 24, SDL_OPENGL|SDL_HWSURFACE|SDL_DOUBLEBUF); + /* Emscripten-specific initialization */ + _glContext = SDL_SetVideoMode(configuration.size().x(), configuration.size().y(), 24, SDL_OPENGL|SDL_HWSURFACE|SDL_DOUBLEBUF); #endif - c = new Platform::Context; + _context.reset(new Platform::Context); return true; } void Sdl2Application::swapBuffers() { #ifndef CORRADE_TARGET_EMSCRIPTEN - SDL_GL_SwapWindow(window); + SDL_GL_SwapWindow(_window); #else - SDL_Flip(context); + SDL_Flip(_glContext); #endif } +Int Sdl2Application::swapInterval() const { + return SDL_GL_GetSwapInterval(); +} + +bool Sdl2Application::setSwapInterval(const Int interval) { + if(SDL_GL_SetSwapInterval(interval) == -1) { + Error() << "Platform::Sdl2Application::setSwapInterval(): cannot set swap interval:" << SDL_GetError(); + return false; + } + + if(SDL_GL_GetSwapInterval() != interval) { + Error() << "Platform::Sdl2Application::setSwapInterval(): swap interval setting ignored by the driver"; + return false; + } + + return true; +} + Sdl2Application::~Sdl2Application() { - delete c; + _context.reset(); #ifndef CORRADE_TARGET_EMSCRIPTEN - SDL_GL_DeleteContext(context); - SDL_DestroyWindow(window); + SDL_GL_DeleteContext(_glContext); + SDL_DestroyWindow(_window); #else - SDL_FreeSurface(context); - CORRADE_INTERNAL_ASSERT(instance == this); - instance = nullptr; + SDL_FreeSurface(_glContext); + CORRADE_INTERNAL_ASSERT(_instance == this); + _instance = nullptr; #endif SDL_Quit(); } int Sdl2Application::exec() { #ifndef CORRADE_TARGET_EMSCRIPTEN - while(!(flags & Flag::Exit)) mainLoop(); + while(!(_flags & Flag::Exit)) mainLoop(); #else emscripten_set_main_loop(staticMainLoop, 0, true); #endif @@ -251,7 +272,7 @@ int Sdl2Application::exec() { void Sdl2Application::exit() { #ifndef CORRADE_TARGET_EMSCRIPTEN - flags |= Flag::Exit; + _flags |= Flag::Exit; #else emscripten_cancel_main_loop(); #endif @@ -266,10 +287,10 @@ void Sdl2Application::mainLoop() { switch(event.window.event) { case SDL_WINDOWEVENT_RESIZED: viewportEvent({event.window.data1, event.window.data2}); - flags |= Flag::Redraw; + _flags |= Flag::Redraw; break; case SDL_WINDOWEVENT_EXPOSED: - flags |= Flag::Redraw; + _flags |= Flag::Redraw; break; } break; @@ -299,7 +320,7 @@ void Sdl2Application::mainLoop() { case SDL_QUIT: #ifndef CORRADE_TARGET_EMSCRIPTEN - flags |= Flag::Exit; + _flags |= Flag::Exit; #else emscripten_cancel_main_loop(); #endif @@ -307,8 +328,8 @@ void Sdl2Application::mainLoop() { } } - if(flags & Flag::Redraw) { - flags &= ~Flag::Redraw; + if(_flags & Flag::Redraw) { + _flags &= ~Flag::Redraw; drawEvent(); return; } @@ -321,7 +342,7 @@ void Sdl2Application::mainLoop() { void Sdl2Application::setMouseLocked(bool enabled) { /** @todo Implement this in Emscripten */ #ifndef CORRADE_TARGET_EMSCRIPTEN - SDL_SetWindowGrab(window, enabled ? SDL_TRUE : SDL_FALSE); + SDL_SetWindowGrab(_window, enabled ? SDL_TRUE : SDL_FALSE); SDL_SetRelativeMouseMode(enabled ? SDL_TRUE : SDL_FALSE); #else CORRADE_ASSERT(false, "Sdl2Application::setMouseLocked(): not implemented", ); diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index 59584f54b..c66ac1b0f 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,8 +29,9 @@ * @brief Class @ref Magnum::Platform::Sdl2Application, macro @ref MAGNUM_SDL2APPLICATION_MAIN() */ -#include +#include #include +#include #include "Magnum/Magnum.h" #include "Magnum/Math/Vector2.h" @@ -46,11 +47,7 @@ #include "Magnum/Version.h" #endif -namespace Magnum { - -class Context; - -namespace Platform { +namespace Magnum { namespace Platform { /** @nosubgrouping @brief SDL2 application @@ -116,9 +113,9 @@ e.g. `http://localhost/emscripten/MyApplication.html`). ## General usage For CMake you need to copy `FindSDL2.cmake` from `modules/` directory in -%Magnum source to `modules/` dir in your project (so it is able to find SDL2). +Magnum source to `modules/` dir in your project (so it is able to find SDL2). In case of Emscripten you need also `FindOpenGLES2.cmake`. Request -`%Sdl2Application` component, add `${MAGNUM_SDL2APPLICATION_INCLUDE_DIRS}` +`Sdl2Application` component, add `${MAGNUM_SDL2APPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_SDL2APPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and `${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. Again, see @@ -198,7 +195,7 @@ class Sdl2Application { /** * @brief Default constructor * @param arguments Application arguments - * @param configuration %Configuration + * @param configuration Configuration * * Creates application with default or user-specified configuration. * See @ref Configuration for more information. The program exits if @@ -257,8 +254,14 @@ class Sdl2Application { * @brief Create context with given configuration * * Must be called if and only if the context wasn't created by the - * constructor itself. The program exits if the context cannot be - * created, see @ref tryCreateContext() for an alternative. + * constructor itself. Error message is printed and the program exits + * if the context cannot be created, see @ref tryCreateContext() for an + * alternative. + * + * On desktop GL, if version is not specified in @p configuration, the + * application first tries to create core context (OpenGL 3.2+ on OS X, + * OpenGL 3.0+ elsewhere) and if that fails, falls back to + * compatibility OpenGL 2.1 context. */ #ifdef DOXYGEN_GENERATING_OUTPUT void createContext(const Configuration& configuration = Configuration()); @@ -282,9 +285,23 @@ class Sdl2Application { * @brief Swap buffers * * Paints currently rendered framebuffer on screen. + * @see @ref setSwapInterval() */ void swapBuffers(); + /** @brief Swap interval */ + Int swapInterval() const; + + /** + * @brief Set swap interval + * + * Set `0` for no VSync, `1` for enabled VSync. Some platforms support + * `-1` for late swap tearing. Prints error message and returns `false` + * if swap interval cannot be set, `true` otherwise. Default is + * driver-dependent, you can query the value with @ref swapInterval(). + */ + bool setSwapInterval(Int interval); + /** * @brief Redraw immediately * @@ -292,7 +309,7 @@ class Sdl2Application { * in the next iteration. You can call it from @ref drawEvent() itself * to redraw immediately without waiting for user input. */ - void redraw() { flags |= Flag::Redraw; } + void redraw() { _flags |= Flag::Redraw; } #ifdef DOXYGEN_GENERATING_OUTPUT protected: @@ -403,7 +420,7 @@ class Sdl2Application { CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) #ifdef CORRADE_TARGET_EMSCRIPTEN - static Sdl2Application* instance; + static Sdl2Application* _instance; static void staticMainLoop(); #endif @@ -411,21 +428,21 @@ class Sdl2Application { void mainLoop(); #ifndef CORRADE_TARGET_EMSCRIPTEN - SDL_Window* window; - SDL_GLContext context; + SDL_Window* _window; + SDL_GLContext _glContext; #else - SDL_Surface* context; + SDL_Surface* _glContext; #endif - Platform::Context* c; + std::unique_ptr _context; - Flags flags; + Flags _flags; }; CORRADE_ENUMSET_OPERATORS(Sdl2Application::Flags) /** -@brief %Configuration +@brief Configuration Centered non-resizable window with double-buffered OpenGL context and 24bit depth buffer. @@ -435,7 +452,7 @@ class Sdl2Application::Configuration { public: #ifndef CORRADE_TARGET_EMSCRIPTEN /** - * @brief %Context flag + * @brief Context flag * * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". * @see @ref Flags, @ref setFlags() @@ -452,7 +469,7 @@ class Sdl2Application::Configuration { }; /** - * @brief %Context flags + * @brief Context flags * * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". * @see @ref setFlags() @@ -552,7 +569,7 @@ class Sdl2Application::Configuration { #ifndef CORRADE_TARGET_EMSCRIPTEN /** - * @brief %Context flags + * @brief Context flags * * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". */ @@ -571,7 +588,7 @@ class Sdl2Application::Configuration { } /** - * @brief %Context version + * @brief Context version * * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". */ @@ -640,7 +657,7 @@ CORRADE_ENUMSET_OPERATORS(Sdl2Application::Configuration::WindowFlags) class Sdl2Application::InputEvent { public: /** - * @brief %Modifier + * @brief Modifier * * @see @ref Modifiers, @ref KeyEvent::modifiers(), * @ref MouseEvent::modifiers(), @ref MouseMoveEvent::modifiers() @@ -713,7 +730,7 @@ inline Sdl2Application::InputEvent::~InputEvent() = default; @see @ref keyPressEvent(), @ref keyReleaseEvent() */ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent { - friend class Sdl2Application; + friend Sdl2Application; public: /** @@ -813,7 +830,7 @@ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent { @see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent { - friend class Sdl2Application; + friend Sdl2Application; public: /** @@ -857,7 +874,7 @@ class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent { @see @ref MouseEvent, @ref mouseMoveEvent() */ class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent { - friend class Sdl2Application; + friend Sdl2Application; public: /** diff --git a/src/Magnum/Platform/WindowlessCglApplication.cpp b/src/Magnum/Platform/WindowlessCglApplication.cpp index 6225c9f62..0988b18c1 100644 --- a/src/Magnum/Platform/WindowlessCglApplication.cpp +++ b/src/Magnum/Platform/WindowlessCglApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Copyright © 2013 Copyright © 2014 Travis Watkins @@ -31,22 +31,21 @@ #include #include "Magnum/Platform/Context.h" +#include "Magnum/Version.h" namespace Magnum { namespace Platform { -/** @todo Delegating constructor when support for GCC 4.6 is dropped */ - -WindowlessCglApplication::WindowlessCglApplication(const Arguments&, const Configuration& configuration): c(nullptr) { +WindowlessCglApplication::WindowlessCglApplication(const Arguments&, const Configuration& configuration) { createContext(configuration); } #ifndef DOXYGEN_GENERATING_OUTPUT -WindowlessCglApplication::WindowlessCglApplication(const Arguments&): c(nullptr) { +WindowlessCglApplication::WindowlessCglApplication(const Arguments&) { createContext(); } #endif -WindowlessCglApplication::WindowlessCglApplication(const Arguments&, std::nullptr_t): c(nullptr) {} +WindowlessCglApplication::WindowlessCglApplication(const Arguments&, std::nullptr_t) {} void WindowlessCglApplication::createContext() { createContext({}); } @@ -55,77 +54,59 @@ void WindowlessCglApplication::createContext(const Configuration& configuration) } bool WindowlessCglApplication::tryCreateContext(const Configuration&) { - CORRADE_ASSERT(!c, "Platform::WindowlessCglApplication::tryCreateContext(): context already created", false); - - /* Check version */ - int nPix = 0; - GLint major, minor; - CGLGetVersion(&major, &minor); - CGLError cglError; - - if(major == 2 && minor < 1) { - Error() << "Platform::WindowlessCglApplication::tryCreateContext(): OpenGL version 2.1 or greater is required"; - return false; - } - + CORRADE_ASSERT(!_context, "Platform::WindowlessCglApplication::tryCreateContext(): context already created", false); - CGLPixelFormatAttribute pfAttributesGL_3_2[4] = { + int formatCount; + CGLPixelFormatAttribute attributes32[] = { kCGLPFAAccelerated, kCGLPFAOpenGLProfile, - (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core, - (CGLPixelFormatAttribute) 0 + CGLPixelFormatAttribute(kCGLOGLPVersion_3_2_Core), + CGLPixelFormatAttribute(0) }; + if(CGLChoosePixelFormat(attributes32, &_pixelFormat, &formatCount) != kCGLNoError) { + Error() << "Platform::WindowlessCglApplication::tryCreateContext(): cannot choose pixel format for GL 3.2, falling back to 3.0"; - cglError = CGLChoosePixelFormat(pfAttributesGL_3_2,&pixelFormat,&nPix); - - if(cglError == kCGLBadPixelFormat) { - Error() << "Platform::WindowlessCglApplication::tryCreateContext(): OpenGL version 3.2 has failed trying GL version 3.0"; - - CGLPixelFormatAttribute pfAttributesGL3[4] = { + CGLPixelFormatAttribute attributes30[] = { kCGLPFAAccelerated, kCGLPFAOpenGLProfile, - (CGLPixelFormatAttribute) kCGLOGLPVersion_GL3_Core, - (CGLPixelFormatAttribute) 0 + CGLPixelFormatAttribute(kCGLOGLPVersion_GL3_Core), + CGLPixelFormatAttribute(0) }; + if(CGLChoosePixelFormat(attributes30, &_pixelFormat, &formatCount) != kCGLNoError) { + Error() << "Platform::WindowlessCglApplication::tryCreateContext(): cannot choose pixel format for GL 3.0, falling back to 2.1"; - cglError = CGLChoosePixelFormat(pfAttributesGL3,&pixelFormat,&nPix); - - if(cglError == kCGLBadPixelFormat) { - Error() << "Platform::WindowlessCglApplication::tryCreateContext(): OpenGL version 3.0 has failed trying GL version Legacy"; - - CGLPixelFormatAttribute pfAttributesLegacy[4] = { + CGLPixelFormatAttribute attributes21[] = { kCGLPFAAccelerated, kCGLPFAOpenGLProfile, - (CGLPixelFormatAttribute) kCGLOGLPVersion_Legacy, - (CGLPixelFormatAttribute) 0 + CGLPixelFormatAttribute(kCGLOGLPVersion_Legacy), + CGLPixelFormatAttribute(0) }; - - cglError = CGLChoosePixelFormat(pfAttributesLegacy,&pixelFormat,&nPix); - - if(cglError == kCGLBadPixelFormat) - { - Error() << "Platform::WindowlessCglApplication::tryCreateContext(): Context could not be created"; + if(CGLChoosePixelFormat(attributes21, &_pixelFormat, &formatCount) != kCGLNoError) { + Error() << "Platform::WindowlessCglApplication::tryCreateContext(): cannot choose pixel format"; return false; } } } - cglError = CGLCreateContext(pixelFormat, NULL, &context); - if(cglError == kCGLBadContext) { + if(CGLCreateContext(_pixelFormat, nullptr, &_glContext) != kCGLNoError) { Error() << "Platform::WindowlessCglApplication::tryCreateContext(): cannot create context"; return false; } - cglError = CGLSetCurrentContext(context); - c = new Platform::Context; + if(CGLSetCurrentContext(_glContext) != kCGLNoError) { + Error() << "Platform::WindowlessCglApplication::tryCreateContext(): cannot make context current"; + return false; + } + + _context.reset(new Platform::Context); return true; } WindowlessCglApplication::~WindowlessCglApplication() { - delete c; + _context.reset(); - CGLDestroyContext(context); - CGLDestroyPixelFormat(pixelFormat); + CGLDestroyContext(_glContext); + CGLDestroyPixelFormat(_pixelFormat); } }} diff --git a/src/Magnum/Platform/WindowlessCglApplication.h b/src/Magnum/Platform/WindowlessCglApplication.h index 0f751b16c..b994297b8 100644 --- a/src/Magnum/Platform/WindowlessCglApplication.h +++ b/src/Magnum/Platform/WindowlessCglApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Copyright © 2013 Copyright © 2014 Travis Watkins @@ -31,12 +31,15 @@ * @brief Class @ref Magnum::Platform::WindowlessCglApplication, macro @ref MAGNUM_WINDOWLESSCGLAPPLICATION_MAIN() */ +#include + #include "Magnum/OpenGL.h" #include #include #include #include "Magnum/Magnum.h" +#include "Magnum/Platform/Platform.h" namespace Magnum { namespace Platform { @@ -67,7 +70,7 @@ See @ref cmake for more information. ## General usage -In CMake you need to request `%WindowlessCglApplication` component, add +In CMake you need to request `WindowlessCglApplication` component, add `${MAGNUM_WINDOWLESSCGLAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_WINDOWLESSCGLAPPLICATION_LIBRARIES}`. If no other windowless application is requested, you can also use generic @@ -150,14 +153,14 @@ class WindowlessCglApplication { bool tryCreateContext(const Configuration& configuration); private: - CGLContextObj context; - CGLPixelFormatObj pixelFormat; + CGLContextObj _glContext; + CGLPixelFormatObj _pixelFormat; - Platform::Context* c; + std::unique_ptr _context; }; /** -@brief %Configuration +@brief Configuration @see @ref WindowlessCglApplication(), @ref createContext(), @ref tryCreateContext() diff --git a/src/Magnum/Platform/WindowlessGlxApplication.cpp b/src/Magnum/Platform/WindowlessGlxApplication.cpp index a611ada89..49c424a84 100644 --- a/src/Magnum/Platform/WindowlessGlxApplication.cpp +++ b/src/Magnum/Platform/WindowlessGlxApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,24 +34,21 @@ namespace Magnum { namespace Platform { -/** @todo Delegating constructor when support for GCC 4.6 is dropped */ - -WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, const Configuration& configuration): c(nullptr) { +WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, const Configuration& configuration) { createContext(configuration); } #ifndef DOXYGEN_GENERATING_OUTPUT -WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&): c(nullptr) { +WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&) { createContext(); } #endif #ifndef CORRADE_GCC45_COMPATIBILITY -WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, std::nullptr_t) +WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, std::nullptr_t) {} #else -WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, void*) +WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, void*) {} #endif - : c(nullptr) {} void WindowlessGlxApplication::createContext() { createContext({}); } @@ -60,13 +57,13 @@ void WindowlessGlxApplication::createContext(const Configuration& configuration) } bool WindowlessGlxApplication::tryCreateContext(const Configuration&) { - CORRADE_ASSERT(!c, "Platform::WindowlessGlxApplication::tryCreateContext(): context already created", false); + CORRADE_ASSERT(!_context, "Platform::WindowlessGlxApplication::tryCreateContext(): context already created", false); - display = XOpenDisplay(nullptr); + _display = XOpenDisplay(nullptr); /* Check version */ int major, minor; - glXQueryVersion(display, &major, &minor); + glXQueryVersion(_display, &major, &minor); if(major == 1 && minor < 4) { Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): GLX version 1.4 or greater is required"; return false; @@ -75,7 +72,7 @@ bool WindowlessGlxApplication::tryCreateContext(const Configuration&) { /* Choose config */ int configCount = 0; static const int fbAttributes[] = { None }; - GLXFBConfig* configs = glXChooseFBConfig(display, DefaultScreen(display), fbAttributes, &configCount); + GLXFBConfig* configs = glXChooseFBConfig(_display, DefaultScreen(_display), fbAttributes, &configCount); if(!configCount) { Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): no supported framebuffer configuration found"; return false; @@ -98,8 +95,8 @@ bool WindowlessGlxApplication::tryCreateContext(const Configuration&) { /** @todo Use some extension wrangler for this, not GLEW, as it apparently needs context to create context, yo dawg wtf. */ PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); - context = glXCreateContextAttribsARB(display, configs[0], nullptr, True, contextAttributes); - if(!context) { + _glContext = glXCreateContextAttribsARB(_display, configs[0], nullptr, True, contextAttributes); + if(!_glContext) { Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot create context"; return false; } @@ -110,25 +107,25 @@ bool WindowlessGlxApplication::tryCreateContext(const Configuration&) { GLX_PBUFFER_HEIGHT, 32, None }; - pbuffer = glXCreatePbuffer(display, configs[0], pbufferAttributes); + _pbuffer = glXCreatePbuffer(_display, configs[0], pbufferAttributes); XFree(configs); /* Set OpenGL context as current */ - if(!glXMakeContextCurrent(display, pbuffer, pbuffer, context)) { + if(!glXMakeContextCurrent(_display, _pbuffer, _pbuffer, _glContext)) { Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot make context current"; return false; } - c = new Platform::Context; + _context.reset(new Platform::Context); return true; } WindowlessGlxApplication::~WindowlessGlxApplication() { - delete c; + _context.reset(); - glXMakeCurrent(display, None, nullptr); - glXDestroyContext(display, context); + glXMakeCurrent(_display, None, nullptr); + glXDestroyContext(_display, _glContext); } }} diff --git a/src/Magnum/Platform/WindowlessGlxApplication.h b/src/Magnum/Platform/WindowlessGlxApplication.h index d7d2ccac6..06215aa3e 100644 --- a/src/Magnum/Platform/WindowlessGlxApplication.h +++ b/src/Magnum/Platform/WindowlessGlxApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,6 +29,8 @@ * @brief Class @ref Magnum::Platform::WindowlessGlxApplication, macro @ref MAGNUM_WINDOWLESSGLXAPPLICATION_MAIN() */ +#include + #include "Magnum/OpenGL.h" #include #include @@ -73,7 +75,7 @@ See @ref cmake for more information. ## General usage -In CMake you need to request `%WindowlessGlxApplication` component, add +In CMake you need to request `WindowlessGlxApplication` component, add `${MAGNUM_WINDOWLESSGLXAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_WINDOWLESSGLXAPPLICATION_LIBRARIES}`. If no other windowless application is requested, you can also use generic @@ -160,15 +162,15 @@ class WindowlessGlxApplication { bool tryCreateContext(const Configuration& configuration); private: - Display* display; - GLXContext context; - GLXPbuffer pbuffer; + Display* _display; + GLXContext _glContext; + GLXPbuffer _pbuffer; - Platform::Context* c; + std::unique_ptr _context; }; /** -@brief %Configuration +@brief Configuration @see @ref WindowlessGlxApplication(), @ref createContext(), @ref tryCreateContext() diff --git a/src/Magnum/Platform/WindowlessNaClApplication.cpp b/src/Magnum/Platform/WindowlessNaClApplication.cpp index e069fbc1d..0b0174182 100644 --- a/src/Magnum/Platform/WindowlessNaClApplication.cpp +++ b/src/Magnum/Platform/WindowlessNaClApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/WindowlessNaClApplication.h b/src/Magnum/Platform/WindowlessNaClApplication.h index 89123b501..80364c5fc 100644 --- a/src/Magnum/Platform/WindowlessNaClApplication.h +++ b/src/Magnum/Platform/WindowlessNaClApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -70,7 +70,7 @@ more information. ## General Usage -In CMake you need to request `%WindowlessNaClApplication` component, add +In CMake you need to request `WindowlessNaClApplication` component, add `${MAGNUM_WINDOWLESSNACLAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_WINDOWLESSNACLAPPLICATION_LIBRARIES}`. If no other windowless application is requested, you can also use generic @@ -186,7 +186,7 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien }; /** -@brief %Configuration +@brief Configuration @see @ref WindowlessNaClApplication(), @ref createContext(), @ref tryCreateContext() diff --git a/src/Magnum/Platform/WindowlessWglApplication.cpp b/src/Magnum/Platform/WindowlessWglApplication.cpp index 0d7f14e86..4b69a92b5 100644 --- a/src/Magnum/Platform/WindowlessWglApplication.cpp +++ b/src/Magnum/Platform/WindowlessWglApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,7 +25,6 @@ #include "WindowlessWglApplication.h" -#include #include #include @@ -33,8 +32,6 @@ namespace Magnum { namespace Platform { -/** @todo Delegating constructor when support for GCC 4.6 is dropped */ - #ifndef DOXYGEN_GENERATING_OUTPUT int WindowlessWglApplication::create(LRESULT(CALLBACK windowProcedure)(HWND, UINT, WPARAM, LPARAM)) { const WNDCLASS wc{ @@ -58,17 +55,17 @@ int WindowlessWglApplication::create(LRESULT(CALLBACK windowProcedure)(HWND, UIN } #endif -WindowlessWglApplication::WindowlessWglApplication(const Arguments& arguments, const Configuration& configuration): _window(arguments.window), _c(nullptr) { +WindowlessWglApplication::WindowlessWglApplication(const Arguments& arguments, const Configuration& configuration): _window(arguments.window) { createContext(configuration); } #ifndef DOXYGEN_GENERATING_OUTPUT -WindowlessWglApplication::WindowlessWglApplication(const Arguments& arguments): _window(arguments.window), _c(nullptr) { +WindowlessWglApplication::WindowlessWglApplication(const Arguments& arguments): _window(arguments.window) { createContext(); } #endif -WindowlessWglApplication::WindowlessWglApplication(const Arguments& arguments, std::nullptr_t): _window(arguments.window), _c(nullptr) {} +WindowlessWglApplication::WindowlessWglApplication(const Arguments& arguments, std::nullptr_t): _window(arguments.window) {} void WindowlessWglApplication::createContext() { createContext({}); } @@ -77,7 +74,7 @@ void WindowlessWglApplication::createContext(const Configuration& configuration) } bool WindowlessWglApplication::tryCreateContext(const Configuration&) { - CORRADE_ASSERT(!_c, "Platform::WindowlessWglApplication::tryCreateContext(): context already created", false); + CORRADE_ASSERT(!_context, "Platform::WindowlessWglApplication::tryCreateContext(): context already created", false); /* Get device context */ _deviceContext = GetDC(_window); @@ -118,12 +115,12 @@ bool WindowlessWglApplication::tryCreateContext(const Configuration&) { return false; } - _c = new Platform::Context; + _context.reset(new Platform::Context); return true; } WindowlessWglApplication::~WindowlessWglApplication() { - delete _c; + _context.reset(); wglMakeCurrent(_deviceContext, nullptr); wglDeleteContext(_renderingContext); diff --git a/src/Magnum/Platform/WindowlessWglApplication.h b/src/Magnum/Platform/WindowlessWglApplication.h index 3f1ecb623..6a1f22799 100644 --- a/src/Magnum/Platform/WindowlessWglApplication.h +++ b/src/Magnum/Platform/WindowlessWglApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,6 +29,7 @@ * @brief Class @ref Magnum::Platform::WindowlessWglApplication, macro @ref MAGNUM_WINDOWLESSWGLAPPLICATION_MAIN() */ +#include #ifndef DOXYGEN_GENERATING_OUTPUT #define WIN32_LEAN_AND_MEAN 1 #define VC_EXTRALEAN @@ -68,7 +69,7 @@ See @ref cmake for more information. ## General usage -In CMake you need to request `%WindowlessWglApplication` component, add +In CMake you need to request `WindowlessWglApplication` component, add `${MAGNUM_WINDOWLESSWGLAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_WINDOWLESSWGLAPPLICATION_LIBRARIES}`. If no other windowless application is requested, you can also use generic @@ -162,11 +163,11 @@ class WindowlessWglApplication { HDC _deviceContext; HGLRC _renderingContext; - Platform::Context* _c; + std::unique_ptr _context; }; /** -@brief %Configuration +@brief Configuration @see @ref WindowlessWglApplication(), @ref createContext(), @ref tryCreateContext() diff --git a/src/Magnum/Platform/XEglApplication.cpp b/src/Magnum/Platform/XEglApplication.cpp index 61334e87e..d59d444fa 100644 --- a/src/Magnum/Platform/XEglApplication.cpp +++ b/src/Magnum/Platform/XEglApplication.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Platform/XEglApplication.h b/src/Magnum/Platform/XEglApplication.h index a9c756c8c..2c8183c45 100644 --- a/src/Magnum/Platform/XEglApplication.h +++ b/src/Magnum/Platform/XEglApplication.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -51,9 +51,9 @@ more information. ## General usage -For CMake you need to copy `FindEGL.cmake` from `modules/` directory in %Magnum +For CMake you need to copy `FindEGL.cmake` from `modules/` directory in Magnum source to `modules/` dir in your project (so it is able to find EGL), request -`%XEglApplication` component, add `${MAGNUM_XEGLAPPLICATION_INCLUDE_DIRS}` to +`XEglApplication` component, add `${MAGNUM_XEGLAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_XEGLAPPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and `${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See @@ -79,7 +79,7 @@ class XEglApplication: public AbstractXApplication { /** * @brief Default constructor * @param arguments Application arguments - * @param configuration %Configuration + * @param configuration Configuration * * Creates application with default or user-specified configuration. * See @ref AbstractXApplication::Configuration "Configuration" for diff --git a/src/Magnum/Platform/magnum-info.cpp b/src/Magnum/Platform/magnum-info.cpp index 9b6e035d9..68eb70925 100644 --- a/src/Magnum/Platform/magnum-info.cpp +++ b/src/Magnum/Platform/magnum-info.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,10 @@ #include "Magnum/BufferTexture.h" #endif #include "Magnum/Context.h" -#include "Magnum/DebugMessage.h" +#ifndef MAGNUM_TARGET_GLES +#include "Magnum/CubeMapTextureArray.h" +#endif +#include "Magnum/DebugOutput.h" #include "Magnum/Extensions.h" #include "Magnum/Framebuffer.h" #include "Magnum/Mesh.h" @@ -51,6 +54,7 @@ #include "Magnum/Texture.h" #ifndef MAGNUM_TARGET_GLES2 #include "Magnum/TextureArray.h" +#include "Magnum/TransformFeedback.h" #endif #ifdef CORRADE_TARGET_NACL @@ -68,7 +72,7 @@ namespace Magnum { /** @page magnum-info Magnum Info -@brief Displays information about %Magnum engine and OpenGL capabilities +@brief Displays information about Magnum engine and OpenGL capabilities @section magnum-info-usage Usage @@ -188,6 +192,15 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifdef CORRADE_BUILD_STATIC Debug() << " CORRADE_BUILD_STATIC"; #endif + #ifdef CORRADE_TARGET_UNIX + Debug() << " CORRADE_TARGET_UNIX"; + #endif + #ifdef CORRADE_TARGET_APPLE + Debug() << " CORRADE_TARGET_APPLE"; + #endif + #ifdef CORRADE_TARGET_WINDOWS + Debug() << " CORRADE_TARGET_WINDOWS"; + #endif #ifdef CORRADE_TARGET_NACL Debug() << " CORRADE_TARGET_NACL"; #endif @@ -200,6 +213,9 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifdef CORRADE_TARGET_EMSCRIPTEN Debug() << " CORRADE_TARGET_EMSCRIPTEN"; #endif + #ifdef CORRADE_TARGET_ANDROID + Debug() << " CORRADE_TARGET_ANDROID"; + #endif #ifdef MAGNUM_BUILD_DEPRECATED Debug() << " MAGNUM_BUILD_DEPRECATED"; #endif @@ -344,6 +360,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #ifndef MAGNUM_TARGET_GLES2 _lvec(Texture3D::maxSize()) /* Checked ES2 version below */ #endif + _lvec(CubeMapTexture::maxSize()) #ifndef MAGNUM_TARGET_GLES if(c->isExtensionSupported()) { @@ -489,6 +506,12 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat _l(BufferTexture::offsetAlignment()) } + + if(c->isExtensionSupported()) { + _h(ARB::texture_cube_map_array) + + _l(CubeMapTextureArray::maxSize()) + } #endif #ifndef MAGNUM_TARGET_GLES2 @@ -582,12 +605,36 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat _l(Sampler::maxMaxAnisotropy()) } + #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + if(c->isExtensionSupported()) + #endif + { + #ifndef MAGNUM_TARGET_GLES + _h(EXT::transform_feedback) + #endif + + _l(TransformFeedback::maxInterleavedComponents()) + _l(TransformFeedback::maxSeparateAttributes()) + _l(TransformFeedback::maxSeparateComponents()) + } + #endif + + #ifndef MAGNUM_TARGET_GLES + if(c->isExtensionSupported()) { + _h(ARB::transform_feedback3) + + _l(TransformFeedback::maxBuffers()) + } + #endif + if(c->isExtensionSupported()) { _h(KHR::debug) _l(AbstractObject::maxLabelLength()) - _l(DebugMessage::maxLoggedMessages()) - _l(DebugMessage::maxMessageLength()) + _l(DebugOutput::maxLoggedMessages()) + _l(DebugOutput::maxMessageLength()) + _l(DebugGroup::maxStackDepth()) } #ifdef MAGNUM_TARGET_GLES2 diff --git a/src/Magnum/PrimitiveQuery.h b/src/Magnum/PrimitiveQuery.h index c23524ebc..cd2e02321 100644 --- a/src/Magnum/PrimitiveQuery.h +++ b/src/Magnum/PrimitiveQuery.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,6 +33,10 @@ #include "Magnum/AbstractQuery.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif + #ifndef MAGNUM_TARGET_GLES2 namespace Magnum { @@ -55,11 +59,12 @@ if(!q.resultAvailable()) { // ...or block until the result is available UnsignedInt primitiveCount = q.result(); @endcode -@requires_gl30 %Extension @extension{EXT,transform_feedback} +@requires_gl30 Extension @extension{EXT,transform_feedback} @requires_gles30 Only sample queries are available on OpenGL ES 2.0. -@see @ref SampleQuery, @ref TimeQuery +@see @ref SampleQuery, @ref TimeQuery, @ref TransformFeedback @todo glBeginQueryIndexed +@todo @extension{ARB,transform_feedback_overflow_query} */ class PrimitiveQuery: public AbstractQuery { public: diff --git a/src/Magnum/Primitives/CMakeLists.txt b/src/Magnum/Primitives/CMakeLists.txt index 04c2976cf..39b093f13 100644 --- a/src/Magnum/Primitives/CMakeLists.txt +++ b/src/Magnum/Primitives/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -57,15 +57,16 @@ set(MagnumPrimitives_PRIVATE_HEADERS Implementation/Spheroid.h Implementation/WireframeSpheroid.h) +# Primitives library add_library(MagnumPrimitives ${SHARED_OR_STATIC} ${MagnumPrimitives_SRCS} ${MagnumPrimitives_HEADERS} ${MagnumPrimitives_PRIVATE_HEADERS}) set_target_properties(MagnumPrimitives PROPERTIES DEBUG_POSTFIX "-d") if(BUILD_STATIC_PIC) - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumPrimitives PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") + set_target_properties(MagnumPrimitives PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() + target_link_libraries(MagnumPrimitives Magnum) install(TARGETS MagnumPrimitives diff --git a/src/Magnum/Primitives/Capsule.cpp b/src/Magnum/Primitives/Capsule.cpp index 8f2c11da4..0e6bb742d 100644 --- a/src/Magnum/Primitives/Capsule.cpp +++ b/src/Magnum/Primitives/Capsule.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -41,7 +41,7 @@ Trade::MeshData2D Capsule2D::wireframe(UnsignedInt hemisphereRings, UnsignedInt std::vector positions; positions.reserve(hemisphereRings*4+2+(cylinderRings-1)*2); - const Rad angleIncrement(Constants::pi()/(2.0f*hemisphereRings)); + const Rad angleIncrement(Constants::piHalf()/hemisphereRings); const Float cylinderIncrement = 2.0f*halfLength/cylinderRings; /* Bottom cap vertex */ @@ -101,13 +101,13 @@ Trade::MeshData3D Capsule3D::solid(UnsignedInt hemisphereRings, UnsignedInt cyli Float height = 2.0f+2.0f*halfLength; Float hemisphereTextureCoordsVIncrement = 1.0f/(hemisphereRings*height); - Rad hemisphereRingAngleIncrement(Constants::pi()/(2*hemisphereRings)); + Rad hemisphereRingAngleIncrement(Constants::piHalf()/hemisphereRings); /* Bottom cap vertex */ capsule.capVertex(-height/2, -1.0f, 0.0f); /* Rings of bottom hemisphere */ - capsule.hemisphereVertexRings(hemisphereRings-1, -halfLength, -Rad(Constants::pi())/2+hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); + capsule.hemisphereVertexRings(hemisphereRings-1, -halfLength, -Rad(Constants::piHalf())+hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); /* Rings of cylinder */ capsule.cylinderVertexRings(cylinderRings+1, -halfLength, 2.0f*halfLength/cylinderRings, 1.0f/height, 2.0f*halfLength/(cylinderRings*height)); diff --git a/src/Magnum/Primitives/Capsule.h b/src/Magnum/Primitives/Capsule.h index ecaff322f..5558a2191 100644 --- a/src/Magnum/Primitives/Capsule.h +++ b/src/Magnum/Primitives/Capsule.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,7 +37,7 @@ namespace Magnum { namespace Primitives { /** @brief 2D capsule primitive -%Cylinder of radius `1` along Y axis with hemispheres instead of caps. +Cylinder of radius `1` along Y axis with hemispheres instead of caps. */ class MAGNUM_PRIMITIVES_EXPORT Capsule2D { public: @@ -57,7 +57,7 @@ class MAGNUM_PRIMITIVES_EXPORT Capsule2D { /** @brief 3D capsule primitive -%Cylinder of radius `1` along Y axis with hemispheres instead of caps. +Cylinder of radius `1` along Y axis with hemispheres instead of caps. */ class MAGNUM_PRIMITIVES_EXPORT Capsule3D { public: diff --git a/src/Magnum/Primitives/Circle.cpp b/src/Magnum/Primitives/Circle.cpp index 8f951c969..4ca062d5d 100644 --- a/src/Magnum/Primitives/Circle.cpp +++ b/src/Magnum/Primitives/Circle.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -44,7 +44,7 @@ Trade::MeshData2D Circle::solid(UnsignedInt segments) { positions.emplace_back(); /* Points on circle */ - const Rad angleIncrement(2*Constants::pi()/segments); + const Rad angleIncrement(Constants::tau()/segments); for(UnsignedInt i = 0; i != segments; ++i) { const Rad angle(Float(i)*angleIncrement); positions.emplace_back(Math::cos(angle), Math::sin(angle)); @@ -62,7 +62,7 @@ Trade::MeshData2D Circle::wireframe(UnsignedInt segments) { positions.reserve(segments); /* Points on circle */ - const Rad angleIncrement(2*Constants::pi()/segments); + const Rad angleIncrement(Constants::tau()/segments); for(UnsignedInt i = 0; i != segments; ++i) { const Rad angle(Float(i)*angleIncrement); positions.emplace_back(Math::cos(angle), Math::sin(angle)); diff --git a/src/Magnum/Primitives/Circle.h b/src/Magnum/Primitives/Circle.h index d6afd9b34..67038c8f7 100644 --- a/src/Magnum/Primitives/Circle.h +++ b/src/Magnum/Primitives/Circle.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,7 +37,7 @@ namespace Magnum { namespace Primitives { /** @brief 2D circle primitive -%Circle with radius `1`. +Circle with radius `1`. */ class MAGNUM_PRIMITIVES_EXPORT Circle { public: diff --git a/src/Magnum/Primitives/Crosshair.cpp b/src/Magnum/Primitives/Crosshair.cpp index 9434121b7..d748a1dae 100644 --- a/src/Magnum/Primitives/Crosshair.cpp +++ b/src/Magnum/Primitives/Crosshair.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Crosshair.h b/src/Magnum/Primitives/Crosshair.h index 91ff5b6da..91de70d5b 100644 --- a/src/Magnum/Primitives/Crosshair.h +++ b/src/Magnum/Primitives/Crosshair.h @@ -1,9 +1,9 @@ -#ifndef Magnum_Primitives_Cube_h -#define Magnum_Primitives_Cube_h +#ifndef Magnum_Primitives_Crosshair_h +#define Magnum_Primitives_Crosshair_h /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Cube.cpp b/src/Magnum/Primitives/Cube.cpp index 501b201be..4d0259608 100644 --- a/src/Magnum/Primitives/Cube.cpp +++ b/src/Magnum/Primitives/Cube.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -102,6 +102,48 @@ Trade::MeshData3D Cube::solid() { }}, {}); } +Trade::MeshData3D Cube::solidStrip() { + /* Sources: + https://twitter.com/Donzanoid/status/436843034966507520 + http://www.asmcommunity.net/forums/topic/?id=6284#post-45209 + https://gist.github.com/cdwfs/2cab675b333632d940cf + + 0---2---3---1 + |E /|\ A|H /| + | / | \ | / | + |/ D|B \|/ I| + 4---7---6---5 + |C /| + | / | + |/ J| + 4---5 + |\ K| + | \ | + |L \| + 0---1 + |\ G| + | \ | + |F \| + 2---3 + */ + return Trade::MeshData3D(MeshPrimitive::TriangleStrip, {}, {{ + { 1.0f, 1.0f, 1.0f}, /* 3 */ + {-1.0f, 1.0f, 1.0f}, /* 2 */ + { 1.0f, -1.0f, 1.0f}, /* 6 */ + {-1.0f, -1.0f, 1.0f}, /* 7 */ + {-1.0f, -1.0f, -1.0f}, /* 4 */ + {-1.0f, 1.0f, 1.0f}, /* 2 */ + {-1.0f, 1.0f, -1.0f}, /* 0 */ + { 1.0f, 1.0f, 1.0f}, /* 3 */ + { 1.0f, 1.0f, -1.0f}, /* 1 */ + { 1.0f, -1.0f, 1.0f}, /* 6 */ + { 1.0f, -1.0f, -1.0f}, /* 5 */ + {-1.0f, -1.0f, -1.0f}, /* 4 */ + { 1.0f, 1.0f, -1.0f}, /* 1 */ + {-1.0f, 1.0f, -1.0f} /* 0 */ + }}, {}, {}); +} + Trade::MeshData3D Cube::wireframe() { return Trade::MeshData3D(MeshPrimitive::Lines, { 0, 1, 1, 2, 2, 3, 3, 0, /* +Z */ diff --git a/src/Magnum/Primitives/Cube.h b/src/Magnum/Primitives/Cube.h index 25e7bd44e..568eb887f 100644 --- a/src/Magnum/Primitives/Cube.h +++ b/src/Magnum/Primitives/Cube.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -48,6 +48,14 @@ class MAGNUM_PRIMITIVES_EXPORT Cube { */ static Trade::MeshData3D solid(); + /** + * @brief Solid cube as a single strip + * + * Non-indexed @ref MeshPrimitive::TriangleStrip. Just positions, no + * normals or anything else. + */ + static Trade::MeshData3D solidStrip(); + /** * @brief Wireframe cube * diff --git a/src/Magnum/Primitives/Cylinder.cpp b/src/Magnum/Primitives/Cylinder.cpp index 33a9d0e7b..6ae525aa5 100644 --- a/src/Magnum/Primitives/Cylinder.cpp +++ b/src/Magnum/Primitives/Cylinder.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Cylinder.h b/src/Magnum/Primitives/Cylinder.h index dcae34469..07eab3e45 100644 --- a/src/Magnum/Primitives/Cylinder.h +++ b/src/Magnum/Primitives/Cylinder.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,12 +40,12 @@ namespace Magnum { namespace Primitives { /** @brief 3D cylinder primitive -%Cylinder along Y axis of radius `1`. +Cylinder along Y axis of radius `1`. */ class MAGNUM_PRIMITIVES_EXPORT Cylinder { public: /** - * @brief %Flag + * @brief Flag * * @see @ref Flags, @ref solid(), @ref wireframe() */ @@ -55,7 +55,7 @@ class MAGNUM_PRIMITIVES_EXPORT Cylinder { }; /** - * @brief %Flags + * @brief Flags * * @see @ref solid(), @ref wireframe() */ diff --git a/src/Magnum/Primitives/Icosphere.cpp b/src/Magnum/Primitives/Icosphere.cpp index f645bbdb8..498129032 100644 --- a/src/Magnum/Primitives/Icosphere.cpp +++ b/src/Magnum/Primitives/Icosphere.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Icosphere.h b/src/Magnum/Primitives/Icosphere.h index f8e19d469..15af7153c 100644 --- a/src/Magnum/Primitives/Icosphere.h +++ b/src/Magnum/Primitives/Icosphere.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Implementation/Spheroid.cpp b/src/Magnum/Primitives/Implementation/Spheroid.cpp index f8caf4684..fe7c964b2 100644 --- a/src/Magnum/Primitives/Implementation/Spheroid.cpp +++ b/src/Magnum/Primitives/Implementation/Spheroid.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -43,7 +43,7 @@ void Spheroid::capVertex(Float y, Float normalY, Float textureCoordsV) { } void Spheroid::hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { - Rad segmentAngleIncrement(2*Constants::pi()/segments); + Rad segmentAngleIncrement(Constants::tau()/segments); Float x, y, z; for(UnsignedInt i = 0; i != count; ++i) { Rad ringAngle = startRingAngle + Float(i)*ringAngleIncrement; @@ -69,7 +69,7 @@ void Spheroid::hemisphereVertexRings(UnsignedInt count, Float centerY, Rad start } void Spheroid::cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { - Rad segmentAngleIncrement(2*Constants::pi()/segments); + Rad segmentAngleIncrement(Constants::tau()/segments); for(UnsignedInt i = 0; i != count; ++i) { for(UnsignedInt j = 0; j != segments; ++j) { Rad segmentAngle = Float(j)*segmentAngleIncrement; @@ -143,7 +143,7 @@ void Spheroid::topFaceRing() { } void Spheroid::capVertexRing(Float y, Float textureCoordsV, const Vector3& normal) { - Rad segmentAngleIncrement(2*Constants::pi()/segments); + Rad segmentAngleIncrement(Constants::tau()/segments); for(UnsignedInt i = 0; i != segments; ++i) { Rad segmentAngle = Float(i)*segmentAngleIncrement; diff --git a/src/Magnum/Primitives/Implementation/Spheroid.h b/src/Magnum/Primitives/Implementation/Spheroid.h index 2ac669289..0a1b5d6ff 100644 --- a/src/Magnum/Primitives/Implementation/Spheroid.h +++ b/src/Magnum/Primitives/Implementation/Spheroid.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Implementation/WireframeSpheroid.cpp b/src/Magnum/Primitives/Implementation/WireframeSpheroid.cpp index b2f8011e6..2db087a6c 100644 --- a/src/Magnum/Primitives/Implementation/WireframeSpheroid.cpp +++ b/src/Magnum/Primitives/Implementation/WireframeSpheroid.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -45,7 +45,7 @@ void WireframeSpheroid::bottomHemisphere(const Float endY, const UnsignedInt rin _indices.insert(_indices.end(), {0, i+1}); /* Hemisphere vertices and indices */ - const Rad ringAngleIncrement(Constants::pi()/(2*rings)); + const Rad ringAngleIncrement(Constants::piHalf()/rings); for(UnsignedInt j = 0; j != rings-1; ++j) { const Rad angle = Float(j+1)*ringAngleIncrement; @@ -66,7 +66,7 @@ void WireframeSpheroid::topHemisphere(const Float startY, const UnsignedInt ring _indices.insert(_indices.end(), {UnsignedInt(_positions.size())-4*_segments+i, UnsignedInt(_positions.size())+i}); /* Hemisphere vertices and indices */ - const Rad ringAngleIncrement(Constants::pi()/(2*rings)); + const Rad ringAngleIncrement(Constants::piHalf()/rings); for(UnsignedInt j = 0; j != rings-1; ++j) { const Rad angle = Float(j+1)*ringAngleIncrement; @@ -90,10 +90,10 @@ void WireframeSpheroid::topHemisphere(const Float startY, const UnsignedInt ring void WireframeSpheroid::ring(const Float y) { /* Ring vertices and indices */ - const Rad segmentAngleIncrement(Constants::pi()/(2*_segments)); + const Rad segmentAngleIncrement(Constants::piHalf()/_segments); for(UnsignedInt j = 0; j != _segments; ++j) { for(UnsignedInt i = 0; i != 4; ++i) { - const Rad segmentAngle = Rad(Float(i)*Constants::pi()/2) + Float(j)*segmentAngleIncrement; + const Rad segmentAngle = Rad(Float(i)*Constants::piHalf()) + Float(j)*segmentAngleIncrement; if(j != 0) _indices.insert(_indices.end(), {UnsignedInt(_positions.size()-4), UnsignedInt(_positions.size())}); _positions.emplace_back(Math::sin(segmentAngle), y, Math::cos(segmentAngle)); } diff --git a/src/Magnum/Primitives/Implementation/WireframeSpheroid.h b/src/Magnum/Primitives/Implementation/WireframeSpheroid.h index 7a918423e..090451b78 100644 --- a/src/Magnum/Primitives/Implementation/WireframeSpheroid.h +++ b/src/Magnum/Primitives/Implementation/WireframeSpheroid.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Line.cpp b/src/Magnum/Primitives/Line.cpp index bf04c103b..a85af98ba 100644 --- a/src/Magnum/Primitives/Line.cpp +++ b/src/Magnum/Primitives/Line.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Line.h b/src/Magnum/Primitives/Line.h index 9917ce5e6..f928aac98 100644 --- a/src/Magnum/Primitives/Line.h +++ b/src/Magnum/Primitives/Line.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Plane.cpp b/src/Magnum/Primitives/Plane.cpp index dec55458f..5ff866603 100644 --- a/src/Magnum/Primitives/Plane.cpp +++ b/src/Magnum/Primitives/Plane.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Plane.h b/src/Magnum/Primitives/Plane.h index eacd0312e..60840d147 100644 --- a/src/Magnum/Primitives/Plane.h +++ b/src/Magnum/Primitives/Plane.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Square.cpp b/src/Magnum/Primitives/Square.cpp index f8f9a41c3..b27d73235 100644 --- a/src/Magnum/Primitives/Square.cpp +++ b/src/Magnum/Primitives/Square.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Square.h b/src/Magnum/Primitives/Square.h index 3127c4ee6..257fa560f 100644 --- a/src/Magnum/Primitives/Square.h +++ b/src/Magnum/Primitives/Square.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Test/CMakeLists.txt b/src/Magnum/Primitives/Test/CMakeLists.txt index 194a10bce..466de17bd 100644 --- a/src/Magnum/Primitives/Test/CMakeLists.txt +++ b/src/Magnum/Primitives/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/Test/CapsuleTest.cpp b/src/Magnum/Primitives/Test/CapsuleTest.cpp index 81d54e9c8..41d86e5ad 100644 --- a/src/Magnum/Primitives/Test/CapsuleTest.cpp +++ b/src/Magnum/Primitives/Test/CapsuleTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,9 +23,6 @@ DEALINGS IN THE SOFTWARE. */ -/* Less precision */ -#define FLOAT_EQUALITY_PRECISION 1.0e-5 - #include #include @@ -36,15 +33,14 @@ namespace Magnum { namespace Primitives { namespace Test { -class CapsuleTest: public TestSuite::Tester { - public: - CapsuleTest(); +struct CapsuleTest: TestSuite::Tester { + explicit CapsuleTest(); - void wireframe2D(); + void wireframe2D(); - void solid3DWithoutTextureCoords(); - void solid3DWithTextureCoords(); - void wireframe3D(); + void solid3DWithoutTextureCoords(); + void solid3DWithTextureCoords(); + void wireframe3D(); }; CapsuleTest::CapsuleTest() { diff --git a/src/Magnum/Primitives/Test/CircleTest.cpp b/src/Magnum/Primitives/Test/CircleTest.cpp index e8476f0fb..d39544966 100644 --- a/src/Magnum/Primitives/Test/CircleTest.cpp +++ b/src/Magnum/Primitives/Test/CircleTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,12 +31,11 @@ namespace Magnum { namespace Primitives { namespace Test { -class CircleTest: public TestSuite::Tester { - public: - explicit CircleTest(); +struct CircleTest: TestSuite::Tester { + explicit CircleTest(); - void solid(); - void wireframe(); + void solid(); + void wireframe(); }; CircleTest::CircleTest() { diff --git a/src/Magnum/Primitives/Test/CylinderTest.cpp b/src/Magnum/Primitives/Test/CylinderTest.cpp index e86babd16..cba0a56a5 100644 --- a/src/Magnum/Primitives/Test/CylinderTest.cpp +++ b/src/Magnum/Primitives/Test/CylinderTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,13 +32,12 @@ namespace Magnum { namespace Primitives { namespace Test { -class CylinderTest: public TestSuite::Tester { - public: - CylinderTest(); +struct CylinderTest: TestSuite::Tester { + explicit CylinderTest(); - void solidWithoutAnything(); - void solidWithTextureCoordsAndCaps(); - void wireframe(); + void solidWithoutAnything(); + void solidWithTextureCoordsAndCaps(); + void wireframe(); }; CylinderTest::CylinderTest() { diff --git a/src/Magnum/Primitives/Test/IcosphereTest.cpp b/src/Magnum/Primitives/Test/IcosphereTest.cpp index 393330c3c..89caead9e 100644 --- a/src/Magnum/Primitives/Test/IcosphereTest.cpp +++ b/src/Magnum/Primitives/Test/IcosphereTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,11 +31,10 @@ namespace Magnum { namespace Primitives { namespace Test { -class IcosphereTest: public TestSuite::Tester { - public: - explicit IcosphereTest(); +struct IcosphereTest: TestSuite::Tester { + explicit IcosphereTest(); - void count(); + void count(); }; IcosphereTest::IcosphereTest() { diff --git a/src/Magnum/Primitives/Test/UVSphereTest.cpp b/src/Magnum/Primitives/Test/UVSphereTest.cpp index e37993662..43622fbb2 100644 --- a/src/Magnum/Primitives/Test/UVSphereTest.cpp +++ b/src/Magnum/Primitives/Test/UVSphereTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,13 +32,12 @@ namespace Magnum { namespace Primitives { namespace Test { -class UVSphereTest: public TestSuite::Tester { - public: - UVSphereTest(); +struct UVSphereTest: TestSuite::Tester { + explicit UVSphereTest(); - void solidWithoutTextureCoords(); - void solidWithTextureCoords(); - void wireframe(); + void solidWithoutTextureCoords(); + void solidWithTextureCoords(); + void wireframe(); }; UVSphereTest::UVSphereTest() { diff --git a/src/Magnum/Primitives/UVSphere.cpp b/src/Magnum/Primitives/UVSphere.cpp index 1704f26a6..8cbc60913 100644 --- a/src/Magnum/Primitives/UVSphere.cpp +++ b/src/Magnum/Primitives/UVSphere.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -48,7 +48,7 @@ Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, Textu sphere.capVertex(-1.0f, -1.0f, 0.0f); /* Vertex rings */ - sphere.hemisphereVertexRings(rings-1, 0.0f, -Rad(Constants::pi())/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); + sphere.hemisphereVertexRings(rings-1, 0.0f, -Rad(Constants::piHalf())+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); /* Top cap vertex */ sphere.capVertex(1.0f, 1.0f, 1.0f); diff --git a/src/Magnum/Primitives/UVSphere.h b/src/Magnum/Primitives/UVSphere.h index b61cc1874..309322d7f 100644 --- a/src/Magnum/Primitives/UVSphere.h +++ b/src/Magnum/Primitives/UVSphere.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Primitives/visibility.h b/src/Magnum/Primitives/visibility.h index 2e204b4ce..490479881 100644 --- a/src/Magnum/Primitives/visibility.h +++ b/src/Magnum/Primitives/visibility.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Query.h b/src/Magnum/Query.h index 5bde8162e..452a03f09 100644 --- a/src/Magnum/Query.h +++ b/src/Magnum/Query.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/RectangleTexture.cpp b/src/Magnum/RectangleTexture.cpp index 8fcf6ec00..deda0f798 100644 --- a/src/Magnum/RectangleTexture.cpp +++ b/src/Magnum/RectangleTexture.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,8 +26,10 @@ #include "RectangleTexture.h" #ifndef MAGNUM_TARGET_GLES +#include "Magnum/BufferImage.h" #include "Magnum/Context.h" #include "Magnum/Extensions.h" +#include "Magnum/Image.h" #include "Implementation/State.h" #include "Implementation/TextureState.h" @@ -46,5 +48,25 @@ Vector2i RectangleTexture::maxSize() { return Vector2i{value}; } +Image2D RectangleTexture::image(Image2D&& image) { + this->image(image); + return std::move(image); +} + +BufferImage2D RectangleTexture::image(BufferImage2D&& image, const BufferUsage usage) { + this->image(image, usage); + return std::move(image); +} + +Image2D RectangleTexture::subImage(const Range2Di& range, Image2D&& image) { + this->subImage(range, image); + return std::move(image); +} + +BufferImage2D RectangleTexture::subImage(const Range2Di& range, BufferImage2D&& image, const BufferUsage usage) { + this->subImage(range, image, usage); + return std::move(image); +} + } #endif diff --git a/src/Magnum/RectangleTexture.h b/src/Magnum/RectangleTexture.h index 1b61b727b..193e86e36 100644 --- a/src/Magnum/RectangleTexture.h +++ b/src/Magnum/RectangleTexture.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -65,7 +65,7 @@ documentation for more information about usage in shaders. @see @ref Texture, @ref TextureArray, @ref CubeMapTexture, @ref CubeMapTextureArray, @ref BufferTexture, @ref MultisampleTexture -@requires_gl31 %Extension @extension{ARB,texture_rectangle} +@requires_gl31 Extension @extension{ARB,texture_rectangle} @requires_gl Rectangle textures are not available in OpenGL ES. */ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { @@ -92,59 +92,38 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { explicit RectangleTexture(): AbstractTexture(GL_TEXTURE_RECTANGLE) {} /** - * @brief Set minification filter - * @param filter Filter + * @copybrief Texture::setMinificationFilter() * @return Reference to self (for method chaining) * - * Sets filter used when the object pixel size is smaller than the - * texture size. If @extension{EXT,direct_state_access} is not - * available, the texture is bound to some texture unit before the - * operation. Initial value is @ref Sampler::Filter::Linear. - * @see @ref setMagnificationFilter(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_MIN_FILTER} + * See @ref Texture::setMinificationFilter() for more information. + * Initial value is @ref Sampler::Filter::Linear. */ RectangleTexture& setMinificationFilter(Sampler::Filter filter) { AbstractTexture::setMinificationFilter(filter, Sampler::Mipmap::Base); return *this; } - /** @copydoc Texture::setMagnificationFilter() */ + /** + * @copybrief Texture::setMagnificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMagnificationFilter() for more information. + */ RectangleTexture& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); return *this; } /** - * @brief %Image size - * - * The result is not cached in any way. If - * @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. - * @see @ref image(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT} - */ - Vector2i imageSize() { return DataHelper<2>::imageSize(*this, _target, 0); } - - /** - * @brief Set wrapping - * @param wrapping Wrapping type for all texture dimensions + * @copybrief Texture::setWrapping() * @return Reference to self (for method chaining) * * Sets wrapping type for coordinates out of @f$ [ 0, size - 1 ] @f$ - * range. If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. Initial + * range. See @ref Texture::setWrapping() for more information. Initial * value is @ref Sampler::Wrapping::ClampToEdge. * @attention Only @ref Sampler::Wrapping::ClampToEdge and * @ref Sampler::Wrapping::ClampToBorder is supported on this * texture type. - * @see @ref setBorderColor(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T}, - * @def_gl{TEXTURE_WRAP_R} */ RectangleTexture& setWrapping(const Array2D& wrapping) { DataHelper<2>::setWrapping(*this, wrapping); @@ -169,41 +148,38 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * See @ref Texture::setBorderColor(const Vector4ui&) for more * information. + * @requires_gl30 Extension @extension{EXT,texture_integer} */ RectangleTexture& setBorderColor(const Vector4ui& color) { AbstractTexture::setBorderColor(color); return *this; } - /** - * @copybrief Texture::setBorderColor(const Vector4ui&) - * @return Reference to self (for method chaining) - * - * See @ref Texture::setBorderColor(const Vector4i&) for more - * information. + /** @overload + * @requires_gl30 Extension @extension{EXT,texture_integer} */ RectangleTexture& setBorderColor(const Vector4i& color) { AbstractTexture::setBorderColor(color); return *this; } - /** @copydoc Texture::setMaxAnisotropy() */ + /** + * @copybrief Texture::setMaxAnisotropy() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxAnisotropy() for more information. + */ RectangleTexture& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return *this; } /** - * @brief Set sRGB decoding + * @copybrief Texture::setSRGBDecode() * @return Reference to self (for method chaining) * - * Disables or reenables decoding of sRGB values. Initial value is - * `true`. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_SRGB_DECODE_EXT} - * @requires_extension %Extension @extension{EXT,texture_sRGB_decode} + * See @ref Texture::setSRGBDecode() for more information. + * @requires_extension Extension @extension{EXT,texture_sRGB_decode} */ RectangleTexture& setSRGBDecode(bool decode) { AbstractTexture::setSRGBDecode(decode); @@ -215,6 +191,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setSwizzle() for more information. + * @requires_gl33 Extension @extension{ARB,texture_swizzle} */ template RectangleTexture& setSwizzle() { AbstractTexture::setSwizzle(); @@ -248,6 +225,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setDepthStencilMode() for more information. + * @requires_gl43 Extension @extension{ARB,stencil_texturing} */ RectangleTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) { AbstractTexture::setDepthStencilMode(mode); @@ -255,122 +233,149 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { } /** - * @brief Set storage - * @param internalFormat Internal format - * @param size %Texture size + * @copybrief Texture::setStorage() * @return Reference to self (for method chaining) * - * Specifies entire structure of a texture at once, removing the need - * for additional consistency checks and memory reallocations when - * updating the data later. After calling this function the texture - * is immutable and calling @ref setStorage() or @ref setImage() is not - * allowed. - * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. If - * @extension{ARB,texture_storage} (part of OpenGL 4.2), OpenGL ES 3.0 - * or @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not - * available, the feature is emulated with @ref setImage() call. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexStorage2D} or - * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}, - * eventually @fn_gl{TexImage2D} or - * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}. + * See @ref Texture::setStorage() for more information. + * @see @ref maxSize() */ RectangleTexture& setStorage(TextureFormat internalFormat, const Vector2i& size) { - DataHelper<2>::setStorage(*this, _target, 1, internalFormat, size); + DataHelper<2>::setStorage(*this, 1, internalFormat, size); return *this; } /** - * @brief Read texture to image - * @param image %Image where to put the data + * @brief Texture image size * - * %Image parameters like format and type of pixel data are taken from - * given image, image size is taken from the texture using - * @ref imageSize(). + * See @ref Texture::imageSize() for more information. + */ + Vector2i imageSize() { return DataHelper<2>::imageSize(*this, 0); } + + /** + * @brief Read texture to image * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. If - * @extension{ARB,robustness} is available, the operation is protected - * from buffer overflow. However, if both @extension{EXT,direct_state_access} - * and @extension{ARB,robustness} are available, the DSA version is - * used, because it is better for performance and there isn't any - * function combining both features. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT}, then - * @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access} - * or @fn_gl_extension{GetnTexImage,ARB,robustness} + * See @ref Texture::image(Int, Image&) for more information. */ void image(Image2D& image) { - AbstractTexture::image<2>(_target, 0, image); + AbstractTexture::image<2>(0, image); } + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image2D image = texture.image({ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image2D image(Image2D&& image); + /** - * @brief Read given mip level of texture to buffer image - * @param image %Buffer image where to put the data - * @param usage %Buffer usage + * @brief Read texture to buffer image * - * See @ref image(Image2D&) for more information. + * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more + * information. */ void image(BufferImage2D& image, BufferUsage usage) { - AbstractTexture::image<2>(_target, 0, image, usage); + AbstractTexture::image<2>(0, image, usage); } + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage2D image = texture.image({ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage2D image(BufferImage2D&& image, BufferUsage usage); + /** - * @brief Set image data - * @param internalFormat Internal format - * @param image @ref Image2D, @ref ImageReference2D or - * @ref Trade::ImageData2D - * @return Reference to self (for method chaining) + * @copybrief Texture::subImage(Int, const RangeTypeFor&, Image&) * - * For better performance when calling @ref setImage() more than once - * use @ref setStorage() and @ref setSubImage() instead. + * See @ref Texture::subImage(Int, const RangeTypeFor&, Image&) + * for more information. + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + */ + void subImage(const Range2Di& range, Image2D& image) { + AbstractTexture::subImage<2>(0, range, image); + } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image2D image = texture.subImage(range, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image2D subImage(const Range2Di& range, Image2D&& image); + + /** + * @copybrief Texture::subImage(Int, const RangeTypeFor&, BufferImage&, BufferUsage) * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexImage2D} or - * @fn_gl_extension{TextureImage2D,EXT,direct_state_access} + * See @ref Texture::subImage(Int, const RangeTypeFor&, BufferImage&, BufferUsage) + * for more information. + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + */ + void subImage(const Range2Di& range, BufferImage2D& image, BufferUsage usage) { + AbstractTexture::subImage<2>(0, range, image, usage); + } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage2D image = texture.subImage(range, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage2D subImage(const Range2Di& range, BufferImage2D&& image, BufferUsage usage); + + /** + * @copybrief Texture::setImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setImage() for more information. + * @see @ref maxSize() + * @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()" + * and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()" + * instead. */ RectangleTexture& setImage(TextureFormat internalFormat, const ImageReference2D& image) { - DataHelper<2>::setImage(*this, _target, 0, internalFormat, image); + DataHelper<2>::setImage(*this, 0, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()" + * and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()" + * instead. + */ RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D& image) { - DataHelper<2>::setImage(*this, _target, 0, internalFormat, image); + DataHelper<2>::setImage(*this, 0, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()" + * and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()" + * instead. + */ RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D&& image) { return setImage(internalFormat, image); } /** - * @brief Set image subdata - * @param offset Offset where to put data in the texture - * @param image @ref Image2D, @ref ImageReference2D or - * @ref Trade::ImageData2D + * @copybrief Texture::setSubImage() * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. - * @see @ref setStorage(), @ref setImage(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexSubImage2D} or - * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access} + * See @ref Texture::setSubImage() for more information. */ RectangleTexture& setSubImage(const Vector2i& offset, const ImageReference2D& image) { - DataHelper<2>::setSubImage(*this, _target, 0, offset, image); + DataHelper<2>::setSubImage(*this, 0, offset, image); return *this; } /** @overload */ RectangleTexture& setSubImage(const Vector2i& offset, BufferImage2D& image) { - DataHelper<2>::setSubImage(*this, _target, 0, offset, image); + DataHelper<2>::setSubImage(*this, 0, offset, image); return *this; } @@ -380,22 +385,18 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { } /** - * @brief Invalidate texture image + * @brief Invalidate texture * - * If extension @extension{ARB,invalidate_subdata} (part of OpenGL 4.3) - * is not available, this function does nothing. - * @see @ref invalidateSubImage(), @fn_gl{InvalidateTexImage} + * See @ref Texture::invalidateImage() for more information. */ void invalidateImage() { AbstractTexture::invalidateImage(0); } /** - * @brief Invalidate texture subimage + * @brief Invalidate subtexture * @param offset Offset into the texture * @param size Size of invalidated data * - * If extension @extension{ARB,invalidate_subdata} (part of OpenGL 4.3) - * is not available, this function does nothing. - * @see @ref invalidateImage(), @fn_gl{InvalidateTexSubImage} + * See @ref Texture::invalidateSubImage() for more information. */ void invalidateSubImage(const Vector2i& offset, const Vector2i& size) { DataHelper<2>::invalidateSubImage(*this, 0, offset, size); diff --git a/src/Magnum/Renderbuffer.cpp b/src/Magnum/Renderbuffer.cpp index 298cb63ed..7d23bb205 100644 --- a/src/Magnum/Renderbuffer.cpp +++ b/src/Magnum/Renderbuffer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -138,6 +138,10 @@ void Renderbuffer::storageImplementationDefault(RenderbufferFormat internalForma } #ifndef MAGNUM_TARGET_GLES +void Renderbuffer::storageImplementationDSA(const RenderbufferFormat internalFormat, const Vector2i& size) { + glNamedRenderbufferStorage(_id, GLenum(internalFormat), size.x(), size.y()); +} + void Renderbuffer::storageImplementationDSAEXT(RenderbufferFormat internalFormat, const Vector2i& size) { _created = true; glNamedRenderbufferStorageEXT(_id, GLenum(internalFormat), size.x(), size.y()); @@ -176,6 +180,10 @@ void Renderbuffer::storageMultisampleImplementationNV(const GLsizei samples, con #endif #ifndef MAGNUM_TARGET_GLES +void Renderbuffer::storageMultisampleImplementationDSA(const GLsizei samples, const RenderbufferFormat internalFormat, const Vector2i& size) { + glNamedRenderbufferStorageMultisample(_id, samples, GLenum(internalFormat), size.x(), size.y()); +} + void Renderbuffer::storageMultisampleImplementationDSAEXT(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size) { _created = true; glNamedRenderbufferStorageMultisampleEXT(_id, samples, GLenum(internalFormat), size.x(), size.y()); diff --git a/src/Magnum/Renderbuffer.h b/src/Magnum/Renderbuffer.h index 5f97f8b49..c3c7ab930 100644 --- a/src/Magnum/Renderbuffer.h +++ b/src/Magnum/Renderbuffer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -43,7 +43,7 @@ namespace Magnum { namespace Implementation { struct FramebufferState; } /** -@brief %Renderbuffer +@brief Renderbuffer Attachable to framebuffer as render target, see @ref Framebuffer documentation for more information. @@ -51,18 +51,20 @@ for more information. ## Performance optimizations The engine tracks currently bound renderbuffer to avoid unnecessary calls to -@fn_gl{BindRenderbuffer} in @ref setStorage(). %Renderbuffer limits and +@fn_gl{BindRenderbuffer} in @ref setStorage(). Renderbuffer limits and implementation-defined values (such as @ref maxSize()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. -If extension @extension{EXT,direct_state_access} is available, function -@ref setStorage() uses DSA to avoid unnecessary calls to @fn_gl{BindRenderbuffer}. -See its documentation for more information. +If not on OpenGL ES and either @extension{ARB,direct_state_access} (part of +OpenGL 4.5) or @extension{EXT,direct_state_access} is available, functions +@ref setStorage() and @ref setStorageMultisample() use DSA to avoid unnecessary +calls to @fn_gl{BindRenderbuffer}. See their respective documentation for more +information. -@requires_gl30 %Extension @extension{ARB,framebuffer_object} +@requires_gl30 Extension @extension{ARB,framebuffer_object} */ class MAGNUM_EXPORT Renderbuffer: public AbstractObject { - friend struct Implementation::FramebufferState; + friend Implementation::FramebufferState; public: /** @@ -120,7 +122,7 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject { GLuint id() const { return _id; } /** - * @brief %Renderbuffer label + * @brief Renderbuffer label * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. If OpenGL 4.3 is not supported and neither @@ -149,19 +151,20 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject { /** @overload */ template Renderbuffer& setLabel(const char(&label)[size]) { - return setLabelInternal(label); + return setLabelInternal({label, size - 1}); } /** * @brief Set renderbuffer storage * @param internalFormat Internal format - * @param size %Renderbuffer size + * @param size Renderbuffer size * - * If @extension{EXT,direct_state_access} is not available and the - * framebufferbuffer is not currently bound, it is bound before the - * operation. - * @see @ref maxSize(), @fn_gl{BindRenderbuffer}, @fn_gl{RenderbufferStorage} - * or @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the renderbuffer is bound before the operation (if not already). + * @see @ref maxSize(), @fn_gl2{NamedRenderbufferStorage,RenderbufferStorage}, + * @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access}, + * eventually @fn_gl{BindRenderbuffer} and @fn_gl{RenderbufferStorage} */ void setStorage(RenderbufferFormat internalFormat, const Vector2i& size); @@ -169,14 +172,16 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject { * @brief Set multisample renderbuffer storage * @param samples Sample count * @param internalFormat Internal format - * @param size %Renderbuffer size + * @param size Renderbuffer size * - * If @extension{EXT,direct_state_access} is not available and the - * framebufferbuffer is not currently bound, it is bound before the - * operation. - * @see @ref maxSize(), @ref maxSamples(), @fn_gl{BindRenderbuffer}, - * @fn_gl{RenderbufferStorageMultisample} or @fn_gl_extension{NamedRenderbufferStorageMultisample,EXT,direct_state_access} - * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_multisample} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the renderbuffer is bound before the operation (if not already). + * @see @ref maxSize(), @ref maxSamples(), + * @fn_gl2{NamedRenderbufferStorageMultisample,RenderbufferStorageMultisample}, + * @fn_gl_extension{NamedRenderbufferStorageMultisample,EXT,direct_state_access}, + * eventually @fn_gl{BindRenderbuffer} and @fn_gl{RenderbufferStorageMultisample} + * @requires_gles30 Extension @es_extension{ANGLE,framebuffer_multisample} * or @es_extension{NV,framebuffer_multisample} in OpenGL ES 2.0 * @todo How about @es_extension{APPLE,framebuffer_multisample}? * @todo NaCl has @fn_gl_extension{RenderbufferStorageMultisample,EXT,multisampled_render_to_texture} @@ -195,12 +200,14 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject { void MAGNUM_LOCAL storageImplementationDefault(RenderbufferFormat internalFormat, const Vector2i& size); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL storageImplementationDSA(RenderbufferFormat internalFormat, const Vector2i& size); void MAGNUM_LOCAL storageImplementationDSAEXT(RenderbufferFormat internalFormat, const Vector2i& size); #endif #ifndef MAGNUM_TARGET_GLES2 void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size); void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size); #endif #else @@ -219,8 +226,9 @@ inline Renderbuffer::Renderbuffer(Renderbuffer&& other) noexcept: _id{other._id} } inline Renderbuffer& Renderbuffer::operator=(Renderbuffer&& other) noexcept { - std::swap(_id, other._id); - std::swap(_created, other._created); + using std::swap; + swap(_id, other._id); + swap(_created, other._created); return *this; } diff --git a/src/Magnum/RenderbufferFormat.h b/src/Magnum/RenderbufferFormat.h index 1c57a29e4..d9cbcdea9 100644 --- a/src/Magnum/RenderbufferFormat.h +++ b/src/Magnum/RenderbufferFormat.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,14 +37,14 @@ namespace Magnum { @brief Internal renderbuffer format @see @ref Renderbuffer -@requires_gl30 %Extension @extension{ARB,framebuffer_object} +@requires_gl30 Extension @extension{ARB,framebuffer_object} @todo RGB, RGB8 ES only (ES3 + @es_extension{OES,rgb8_rgba8}) */ enum class RenderbufferFormat: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Red component, normalized unsigned, size implementation-dependent. - * @requires_gl30 %Extension @extension{ARB,texture_rg} + * @requires_gl30 Extension @extension{ARB,texture_rg} * @requires_gl Use exactly specified format in OpenGL ES instead. * @deprecated_gl Prefer to use the exactly specified version of this * format, e.g. @ref Magnum::RenderbufferFormat "RenderbufferFormat::R8". @@ -54,8 +54,8 @@ enum class RenderbufferFormat: GLenum { /** * Red component, normalized unsigned byte. - * @requires_gl30 %Extension @extension{ARB,texture_rg} - * @requires_gles30 %Extension @es_extension{EXT,texture_rg} in OpenGL ES + * @requires_gl30 Extension @extension{ARB,texture_rg} + * @requires_gles30 Extension @es_extension{EXT,texture_rg} in OpenGL ES * 2.0 */ #ifndef MAGNUM_TARGET_GLES2 @@ -68,7 +68,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, normalized unsigned, size * implementation-dependent. - * @requires_gl30 %Extension @extension{ARB,texture_rg} + * @requires_gl30 Extension @extension{ARB,texture_rg} * @requires_gl Use exactly specified format in OpenGL ES instead. * @deprecated_gl Prefer to use the exactly specified version of this * format, e.g. @ref Magnum::RenderbufferFormat "RenderbufferFormat::RG8". @@ -78,8 +78,8 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each normalized unsigned byte. - * @requires_gl30 %Extension @extension{ARB,texture_rg} - * @requires_gles30 %Extension @es_extension{EXT,texture_rg} in OpenGL ES + * @requires_gl30 Extension @extension{ARB,texture_rg} + * @requires_gles30 Extension @es_extension{EXT,texture_rg} in OpenGL ES * 2.0 */ #ifndef MAGNUM_TARGET_GLES2 @@ -100,7 +100,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, each component normalized unsigned byte. - * @requires_gles30 %Extension @es_extension{ARM,rgba8} or @es_extension{OES,rgb8_rgba8} + * @requires_gles30 Extension @es_extension{ARM,rgba8} or @es_extension{OES,rgb8_rgba8} * in OpenGL ES 2.0 */ #ifndef MAGNUM_TARGET_GLES2 @@ -112,7 +112,7 @@ enum class RenderbufferFormat: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Red component, normalized unsigned short. - * @requires_gl30 %Extension @extension{ARB,texture_rg} + * @requires_gl30 Extension @extension{ARB,texture_rg} * @requires_gl Only byte-sized normalized formats are available in OpenGL * ES. */ @@ -120,7 +120,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each normalized unsigned short. - * @requires_gl30 %Extension @extension{ARB,texture_rg} + * @requires_gl30 Extension @extension{ARB,texture_rg} * @requires_gl Only byte-sized normalized formats are available in OpenGL * ES. */ @@ -144,7 +144,7 @@ enum class RenderbufferFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * Red component, non-normalized unsigned byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -152,7 +152,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each non-normalized unsigned byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -160,7 +160,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, each component non-normalized unsigned byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -168,7 +168,7 @@ enum class RenderbufferFormat: GLenum { /** * Red component, non-normalized signed byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -176,7 +176,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each non-normalized signed byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -184,7 +184,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, each component non-normalized signed byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -192,7 +192,7 @@ enum class RenderbufferFormat: GLenum { /** * Red component, non-normalized unsigned short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -200,7 +200,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each non-normalized unsigned short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -208,7 +208,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, each component non-normalized unsigned short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -216,7 +216,7 @@ enum class RenderbufferFormat: GLenum { /** * Red component, non-normalized signed short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -224,7 +224,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each non-normalized signed short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -232,7 +232,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, each component non-normalized signed short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -240,7 +240,7 @@ enum class RenderbufferFormat: GLenum { /** * Red component, non-normalized unsigned int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -248,7 +248,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each non-normalized unsigned int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -256,7 +256,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, each component non-normalized unsigned int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -264,7 +264,7 @@ enum class RenderbufferFormat: GLenum { /** * Red component, non-normalized signed int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -272,7 +272,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each non-normalized signed int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -280,7 +280,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, each component non-normalized signed int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -290,7 +290,7 @@ enum class RenderbufferFormat: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Red component, half float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gl Only (non)normalized integral formats are available in * OpenGL ES. */ @@ -298,7 +298,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each half float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gl Only (non)normalized integral formats are available in * OpenGL ES. */ @@ -306,7 +306,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, each component half float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gl Only (non)normalized integral formats are available in * OpenGL ES. */ @@ -314,7 +314,7 @@ enum class RenderbufferFormat: GLenum { /** * Red component, float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gl Only (non)normalized integral formats are available in * OpenGL ES. */ @@ -322,7 +322,7 @@ enum class RenderbufferFormat: GLenum { /** * Red and green component, each float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gl Only (non)normalized integral formats are available in * OpenGL ES. */ @@ -330,7 +330,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, each component float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gl Only (non)normalized integral formats are available in * OpenGL ES. */ @@ -347,7 +347,7 @@ enum class RenderbufferFormat: GLenum { /** * RGBA, non-normalized unsigned, each RGB component 10bit, alpha 2bit. - * @requires_gl33 %Extension @extension{ARB,texture_rgb10_a2ui} + * @requires_gl33 Extension @extension{ARB,texture_rgb10_a2ui} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -363,7 +363,7 @@ enum class RenderbufferFormat: GLenum { #ifndef MAGNUM_TARGET_GLES /** * RGB, float, red and green 11bit, blue 10bit. - * @requires_gl30 %Extension @extension{EXT,packed_float} + * @requires_gl30 Extension @extension{EXT,packed_float} * @requires_gl Usable only as internal texture format in OpenGL ES, see * @ref Magnum::TextureFormat "TextureFormat::R11FG11FB10F". */ @@ -375,7 +375,7 @@ enum class RenderbufferFormat: GLenum { /** * sRGBA, each component normalized unsigned byte. - * @requires_gles30 %Extension @es_extension{EXT,sRGB} in OpenGL ES 2.0 + * @requires_gles30 Extension @es_extension{EXT,sRGB} in OpenGL ES 2.0 */ #ifndef MAGNUM_TARGET_GLES2 SRGB8Alpha8 = GL_SRGB8_ALPHA8, @@ -399,7 +399,7 @@ enum class RenderbufferFormat: GLenum { /** * Depth component, 24bit. - * @requires_gles30 %Extension @es_extension{OES,depth24} in OpenGL ES 2.0 + * @requires_gles30 Extension @es_extension{OES,depth24} in OpenGL ES 2.0 */ #ifndef MAGNUM_TARGET_GLES2 DepthComponent24 = GL_DEPTH_COMPONENT24, @@ -409,7 +409,7 @@ enum class RenderbufferFormat: GLenum { /** * Depth component, 32bit. - * @requires_es_extension %Extension @es_extension{OES,depth32} + * @requires_es_extension Extension @es_extension{OES,depth32} */ #ifndef MAGNUM_TARGET_GLES DepthComponent32 = GL_DEPTH_COMPONENT32, @@ -420,7 +420,7 @@ enum class RenderbufferFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * Depth component, 32bit float. - * @requires_gl30 %Extension @extension{ARB,depth_buffer_float} + * @requires_gl30 Extension @extension{ARB,depth_buffer_float} * @requires_gles30 Only integral depth textures are available in OpenGL ES * 2.0. */ @@ -439,7 +439,7 @@ enum class RenderbufferFormat: GLenum { /** * 1-bit stencil index. - * @requires_es_extension %Extension @es_extension{OES,stencil1} + * @requires_es_extension Extension @es_extension{OES,stencil1} */ #ifndef MAGNUM_TARGET_GLES StencilIndex1 = GL_STENCIL_INDEX1, @@ -449,7 +449,7 @@ enum class RenderbufferFormat: GLenum { /** * 4-bit stencil index. - * @requires_es_extension %Extension @es_extension{OES,stencil4} + * @requires_es_extension Extension @es_extension{OES,stencil4} */ #ifndef MAGNUM_TARGET_GLES StencilIndex4 = GL_STENCIL_INDEX4, @@ -478,7 +478,7 @@ enum class RenderbufferFormat: GLenum { /** * 24bit depth and 8bit stencil component. - * @requires_gles30 %Extension @es_extension{OES,packed_depth_stencil} in + * @requires_gles30 Extension @es_extension{OES,packed_depth_stencil} in * OpenGL ES 2.0 */ #ifdef MAGNUM_TARGET_GLES2 @@ -488,7 +488,7 @@ enum class RenderbufferFormat: GLenum { /** * 32bit float depth component and 8bit stencil component. - * @requires_gl30 %Extension @extension{ARB,depth_buffer_float} + * @requires_gl30 Extension @extension{ARB,depth_buffer_float} * @requires_gles30 Only integral depth textures are available in OpenGL ES * 2.0. */ diff --git a/src/Magnum/Renderer.cpp b/src/Magnum/Renderer.cpp index 83d642589..1a4a82cc8 100644 --- a/src/Magnum/Renderer.cpp +++ b/src/Magnum/Renderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Renderer.h b/src/Magnum/Renderer.h index aaf574f4c..dc09ab92b 100644 --- a/src/Magnum/Renderer.h +++ b/src/Magnum/Renderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -48,8 +48,8 @@ namespace Implementation { struct RendererState; } @todo `GL_MAX_CLIP_DISTANCES`... */ class MAGNUM_EXPORT Renderer { - friend class Context; - friend struct Implementation::RendererState; + friend Context; + friend Implementation::RendererState; public: Renderer() = delete; @@ -85,11 +85,12 @@ class MAGNUM_EXPORT Renderer { Blending = GL_BLEND, /** - * Debug output - * @see @ref DebugMessage, @ref DebugMessage::setEnabled(), - * @ref Feature::DebugOutputSynchronous - * @requires_gl43 %Extension @extension{KHR,debug} - * @requires_es_extension %Extension @es_extension{KHR,debug} + * Debug output. Disabled by default unless the GL context was + * created with debug output enabled. + * @see @ref DebugOutput, @ref Feature::DebugOutputSynchronous, + * @ref Platform::Sdl2Application::Configuration::Flag::Debug "Platform::*Application::Configuration::Flag::Debug" + * @requires_gl43 Extension @extension{KHR,debug} + * @requires_es_extension Extension @es_extension{KHR,debug} */ #ifndef MAGNUM_TARGET_GLES DebugOutput = GL_DEBUG_OUTPUT, @@ -101,8 +102,8 @@ class MAGNUM_EXPORT Renderer { * Synchronous debug output. Has effect only if * @ref Feature::DebugOutput is enabled. * @see @ref DebugMessage - * @requires_gl43 %Extension @extension{KHR,debug} - * @requires_es_extension %Extension @es_extension{KHR,debug} + * @requires_gl43 Extension @extension{KHR,debug} + * @requires_es_extension Extension @es_extension{KHR,debug} */ #ifndef MAGNUM_TARGET_GLES DebugOutputSynchronous = GL_DEBUG_OUTPUT_SYNCHRONOUS, @@ -113,7 +114,7 @@ class MAGNUM_EXPORT Renderer { #ifndef MAGNUM_TARGET_GLES /** * Depth clamping. If enabled, ignores near and far clipping plane. - * @requires_gl32 %Extension @extension{ARB,depth_clamp} + * @requires_gl32 Extension @extension{ARB,depth_clamp} * @requires_gl Depth clamping is not available in OpenGL ES. */ DepthClamp = GL_DEPTH_CLAMP, @@ -137,7 +138,7 @@ class MAGNUM_EXPORT Renderer { #ifndef MAGNUM_TARGET_GLES /** * sRGB encoding of the default framebuffer - * @requires_gl30 %Extension @extension{ARB,framebuffer_sRGB} + * @requires_gl30 Extension @extension{ARB,framebuffer_sRGB} * @requires_gl sRGB encoding of the default framebuffer is * implementation-defined in OpenGL ES. */ @@ -205,7 +206,7 @@ class MAGNUM_EXPORT Renderer { #ifndef MAGNUM_TARGET_GLES2 /** * Discard primitives before rasterization. - * @requires_gl30 %Extension @extension{EXT,transform_feedback} + * @requires_gl30 Extension @extension{EXT,transform_feedback} * @requires_gles30 Transform feedback is not available in OpenGL * ES 2.0. */ @@ -222,7 +223,7 @@ class MAGNUM_EXPORT Renderer { /** * Seamless cube map texture. * @see @ref CubeMapTexture, @ref CubeMapTextureArray - * @requires_gl32 %Extension @extension{ARB,seamless_cube_map} + * @requires_gl32 Extension @extension{ARB,seamless_cube_map} * @requires_gl Not available in OpenGL ES 2.0, always enabled in * OpenGL ES 3.0. */ @@ -272,7 +273,7 @@ class MAGNUM_EXPORT Renderer { enum class Hint: GLenum { /** * Accuracy of derivative calculation in fragment shader. - * @requires_gles30 %Extension @es_extension{OES,standard_derivatives} + * @requires_gles30 Extension @es_extension{OES,standard_derivatives} * in OpenGL ES 2.0 */ #ifndef MAGNUM_TARGET_GLES2 @@ -308,7 +309,7 @@ class MAGNUM_EXPORT Renderer { /** * @brief Set clear color * - * Initial value is {0.125f, 0.125f, 0.125f, 1.0f}. + * Initial value is `{0.125f, 0.125f, 0.125f, 1.0f}`. * @see @fn_gl{ClearColor} */ static void setClearColor(const Color4& color); @@ -363,7 +364,7 @@ class MAGNUM_EXPORT Renderer { /** * @brief Set front-facing polygon winding * - * Initial value is `FrontFace::%CounterClockWise`. + * Initial value is @ref FrontFace::CounterClockWise. * @see @ref setFaceCullingMode(), @fn_gl{FrontFace} */ static void setFrontFace(FrontFace mode); @@ -383,7 +384,7 @@ class MAGNUM_EXPORT Renderer { * @brief Provoking vertex * * @see @ref setProvokingVertex() - * @requires_gl32 %Extension @extension{ARB,provoking_vertex}. Older + * @requires_gl32 Extension @extension{ARB,provoking_vertex}. Older * versions behave always like * @ref Magnum::Renderer::ProvokingVertex "ProvokingVertex::LastVertexConvention". * @requires_gl OpenGL ES behaves always like @@ -402,7 +403,7 @@ class MAGNUM_EXPORT Renderer { * * Initial value is @ref ProvokingVertex::LastVertexConvention. * @see @fn_gl{ProvokingVertex} - * @requires_gl32 %Extension @extension{ARB,provoking_vertex}. Older + * @requires_gl32 Extension @extension{ARB,provoking_vertex}. Older * versions behave always like the default. * @requires_gl OpenGL ES behaves always like the default. */ @@ -483,6 +484,7 @@ class MAGNUM_EXPORT Renderer { /** * @brief Set scissor rectangle * + * Initial value is set to cover whole window. * @see @ref Feature::ScissorTest, @fn_gl{Scissor} */ static void setScissor(const Range2Di& rectangle); @@ -673,7 +675,7 @@ class MAGNUM_EXPORT Renderer { /** * @{ @name Blending * - * You have to enable blending with setFeature() first. + * You have to enable blending with @ref enable() first. * @todo Blending for given draw buffer */ @@ -691,14 +693,14 @@ class MAGNUM_EXPORT Renderer { , /** * `min(source, destination)` - * @requires_gles30 %Extension @es_extension2{EXT,blend_minmax,blend_minmax} + * @requires_gles30 Extension @es_extension2{EXT,blend_minmax,blend_minmax} * in OpenGL ES 2.0 */ Min = GL_MIN, /** * `max(source, destination)` - * @requires_gles30 %Extension @es_extension2{EXT,blend_minmax,blend_minmax} + * @requires_gles30 Extension @es_extension2{EXT,blend_minmax,blend_minmax} * in OpenGL ES 2.0 */ Max = GL_MAX @@ -753,7 +755,7 @@ class MAGNUM_EXPORT Renderer { * Second source color (@f$ RGB = (R_{s1}, G_{s1}, B_{s1}); A = A_{s1} @f$) * * @see @ref AbstractShaderProgram::bindFragmentDataLocationIndexed() - * @requires_gl33 %Extension @extension{ARB,blend_func_extended} + * @requires_gl33 Extension @extension{ARB,blend_func_extended} * @requires_gl Multiple blending inputs are not available in * OpenGL ES. */ @@ -770,7 +772,7 @@ class MAGNUM_EXPORT Renderer { * One minus second source color (@f$ RGB = (1.0 - R_{s1}, 1.0 - G_{s1}, 1.0 - B_{s1}); A = 1.0 - A_{s1} @f$) * * @see @ref AbstractShaderProgram::bindFragmentDataLocationIndexed() - * @requires_gl33 %Extension @extension{ARB,blend_func_extended} + * @requires_gl33 Extension @extension{ARB,blend_func_extended} * @requires_gl Multiple blending inputs are not available in * OpenGL ES. */ @@ -792,7 +794,7 @@ class MAGNUM_EXPORT Renderer { * Second source alpha (@f$ RGB = (A_{s1}, A_{s1}, A_{s1}); A = A_{s1} @f$) * * @see @ref AbstractShaderProgram::bindFragmentDataLocationIndexed() - * @requires_gl33 %Extension @extension{ARB,blend_func_extended} + * @requires_gl33 Extension @extension{ARB,blend_func_extended} * @requires_gl Multiple blending inputs are not available in * OpenGL ES. */ @@ -809,7 +811,7 @@ class MAGNUM_EXPORT Renderer { * One minus second source alpha (@f$ RGB = (1.0 - A_{s1}, 1.0 - A_{s1}, 1.0 - A_{s1}); A = 1.0 - A_{s1} @f$) * * @see @ref AbstractShaderProgram::bindFragmentDataLocationIndexed() - * @requires_gl33 %Extension @extension{ARB,blend_func_extended} + * @requires_gl33 Extension @extension{ARB,blend_func_extended} * @requires_gl Multiple blending inputs are not available in * OpenGL ES. */ @@ -971,7 +973,7 @@ class MAGNUM_EXPORT Renderer { /** * The framebuffer object is not complete. * @see AbstractFramebuffer::checkStatus() - * @requires_gl30 %Extension @extension{ARB,framebuffer_object} + * @requires_gl30 Extension @extension{ARB,framebuffer_object} */ InvalidFramebufferOperation = GL_INVALID_FRAMEBUFFER_OPERATION, @@ -980,8 +982,9 @@ class MAGNUM_EXPORT Renderer { /** * Given operation would cause an internal stack to underflow. - * @requires_gl43 %Extension @extension{KHR,debug} - * @requires_es_extension %Extension @es_extension2{KHR,debug,debug} + * @see @ref DebugGroup + * @requires_gl43 Extension @extension{KHR,debug} + * @requires_es_extension Extension @es_extension2{KHR,debug,debug} */ #ifndef MAGNUM_TARGET_GLES StackUnderflow = GL_STACK_UNDERFLOW, @@ -991,8 +994,9 @@ class MAGNUM_EXPORT Renderer { /** * Given operation would cause an internal stack to overflow. - * @requires_gl43 %Extension @extension{KHR,debug} - * @requires_es_extension %Extension @es_extension2{KHR,debug,debug} + * @see @ref DebugGroup + * @requires_gl43 Extension @extension{KHR,debug} + * @requires_es_extension Extension @es_extension2{KHR,debug,debug} */ #ifndef MAGNUM_TARGET_GLES StackOverflow = GL_STACK_OVERFLOW @@ -1015,8 +1019,8 @@ class MAGNUM_EXPORT Renderer { * @brief Graphics reset notification strategy * * @see @ref resetNotificationStrategy() - * @requires_extension %Extension @extension{ARB,robustness} - * @requires_es_extension %Extension @es_extension{EXT,robustness} + * @requires_extension Extension @extension{ARB,robustness} + * @requires_es_extension Extension @es_extension{EXT,robustness} */ enum class ResetNotificationStrategy: GLint { /** @@ -1063,8 +1067,8 @@ class MAGNUM_EXPORT Renderer { * @brief Graphics reset status * * @see @ref resetNotificationStrategy(), @ref graphicsResetStatus() - * @requires_extension %Extension @extension{ARB,robustness} - * @requires_es_extension %Extension @es_extension{EXT,robustness} + * @requires_extension Extension @extension{ARB,robustness} + * @requires_es_extension Extension @es_extension{EXT,robustness} */ enum class GraphicsResetStatus: GLenum { /** No reset occured since last call. */ diff --git a/src/Magnum/Resource.cpp b/src/Magnum/Resource.cpp index d59fd55da..fea4895e3 100644 --- a/src/Magnum/Resource.cpp +++ b/src/Magnum/Resource.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Resource.h b/src/Magnum/Resource.h index 750eb1fb7..ad05e5755 100644 --- a/src/Magnum/Resource.h +++ b/src/Magnum/Resource.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,10 +37,14 @@ #include "Magnum/Magnum.h" #include "Magnum/visibility.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif + namespace Magnum { /** -@brief %Resource state +@brief Resource state @see @ref Resource::state(), @ref ResourceManager::state() */ @@ -108,7 +112,7 @@ namespace Implementation { } /** -@brief %Resource reference +@brief Resource reference See @ref ResourceManager for more information. */ @@ -118,7 +122,7 @@ template template #endif class Resource { - friend class Implementation::ResourceManagerData; + friend Implementation::ResourceManagerData; public: /** @@ -151,14 +155,13 @@ class Resource { /** @brief Move assignment */ Resource& operator=(Resource&& other); - /** @brief %Resource key */ + /** @brief Resource key */ ResourceKey key() const { return _key; } /** - * @brief %Resource state + * @brief Resource state * - * @see operator bool(), @ref ResourceManager::state() - * @todoc Explicit reference when Doxygen can handle conversion operators + * @see @ref operator bool(), @ref ResourceManager::state() */ ResourceState state() { acquire(); @@ -204,10 +207,10 @@ class Resource { #ifdef MAGNUM_BUILD_DEPRECATED /** * @overload - * @deprecated Use the explicit @ref operator*() or operator->() - * instead. Implicit conversion is no longer allowed if it might - * throw an assertion. - * @todoc Explicit reference when Doxygen can handle operator->() + * @deprecated Use the explicit @ref Magnum::Resource::operator*() "operator*()" + * or @ref Magnum::Resource::operator->() "operator->()" instead. + * Implicit conversion is no longer allowed if it might throw an + * assertion. */ CORRADE_DEPRECATED("use operator*() or operator->() instead") operator U&() { return **this; } #endif diff --git a/src/Magnum/ResourceManager.h b/src/Magnum/ResourceManager.h index 389c61798..db2e42d05 100644 --- a/src/Magnum/ResourceManager.h +++ b/src/Magnum/ResourceManager.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,7 @@ namespace Magnum { /** -@brief %Resource data state +@brief Resource data state @see @ref ResourceManager::set(), @ref ResourceState */ @@ -70,7 +70,7 @@ enum class ResourceDataState: UnsignedByte { }; /** -@brief %Resource policy +@brief Resource policy @see @ref ResourceManager::set(), @ref ResourceManager::free() */ @@ -96,7 +96,7 @@ namespace Implementation { template class ResourceManagerData { template friend class Magnum::Resource; - friend class AbstractResourceLoader; + friend AbstractResourceLoader; public: ResourceManagerData(const ResourceManagerData&) = delete; @@ -155,10 +155,33 @@ template class ResourceManagerData { std::size_t _lastChange; }; +/* Helper class for defining which real types are in the type pack */ +template struct ResourceTypePack {}; + +/* Common resource manager implementation with inline internal instance (for + use in user code), definition of internalInstance() is in this header */ +template struct ResourceManagerInlineInstanceImplementation { + static ResourceManager*& internalInstance(); +}; +template struct ResourceManagerImplementation: ResourceManagerInlineInstanceImplementation, ResourceManagerData... { + typedef ResourceTypePack TypePack; +}; + +/* Resource manager implementation with file-local internal instance (for use + in code where the manager is used across library boundaries), definition + of internalInstance() is in ResourceManager.hpp, see it for usage details */ +template struct ResourceManagerLocalInstanceImplementation { + static ResourceManager*& internalInstance(); +}; +struct ResourceManagerLocalInstance; +template struct ResourceManagerImplementation: ResourceManagerLocalInstanceImplementation, ResourceManagerData... { + typedef ResourceTypePack TypePack; +}; + } /** -@brief %Resource manager +@brief Resource manager Provides storage for arbitrary set of types, accessible globally using @ref instance(). @@ -184,7 +207,7 @@ can be deleted by calling @ref free() if nothing references them anymore, and reference counted resources, which are deleted as soon as the last reference to them is removed. -%Resource state and policy is configured when setting the resource data in +Resource state and policy is configured when setting the resource data in @ref set() and can be changed each time the data are updated, although already final resources cannot obviously be set as mutable again. @@ -224,7 +247,7 @@ cube->draw(*shader); /* Due to too much work involved with explicit template instantiation (all Resource combinations, all ResourceManagerData...), this class doesn't have template implementation file. */ -template class ResourceManager: private Implementation::ResourceManagerData... { +template class ResourceManager: private Implementation::ResourceManagerImplementation... { public: /** * @brief Global instance @@ -282,7 +305,7 @@ template class ResourceManager: private Implementation::Resource } /** - * @brief %Resource state + * @brief Resource state * * @see @ref set(), @ref Resource::state() */ @@ -294,17 +317,10 @@ template class ResourceManager: private Implementation::Resource * @brief Set resource data * @return Reference to self (for method chaining) * - * If @p policy is set to @ref ResourcePolicy::ReferenceCounted, there - * must be already at least one reference to given resource, otherwise - * the data will be deleted immediately and no resource will be added. - * To avoid spending unnecessary loading time, add reference-counted - * resources only if they are already referenced: - * @code - * if(manager.referenceCount("myresource")) { - * // load data... - * manager.set("myresource", data, state, ResourcePolicy::ReferenceCounted); - * } - * @endcode + * Resources with @ref ResourcePolicy::ReferenceCounted are added with + * zero reference count. It means that all reference counted resources + * which were only loaded but not used will stay loaded and you need to + * explicitly call @ref free() to delete them. * @attention Subsequent updates are not possible if resource state is * already @ref ResourceState::Final. * @see @ref referenceCount(), @ref state() @@ -373,7 +389,7 @@ template class ResourceManager: private Implementation::Resource * @return Reference to self (for method chaining) */ ResourceManager& free() { - freeInternal(); + freeInternal(typename Implementation::ResourceManagerImplementation::TypePack{}); return *this; } @@ -397,7 +413,7 @@ template class ResourceManager: private Implementation::Resource * referenced. */ ResourceManager& clear() { - clearInternal(); + clearInternal(typename Implementation::ResourceManagerImplementation::TypePack{}); return *this; } @@ -426,35 +442,31 @@ template class ResourceManager: private Implementation::Resource } private: - template void freeInternal() { + template void freeInternal(Implementation::ResourceTypePack) { free(); - freeInternal(); + freeInternal(Implementation::ResourceTypePack{}); } - template void freeInternal() const {} + void freeInternal(Implementation::ResourceTypePack<>) const {} - template void clearInternal() { + template void clearInternal(Implementation::ResourceTypePack) { clear(); - clearInternal(); + clearInternal(Implementation::ResourceTypePack{}); } - template void clearInternal() const {} + void clearInternal(Implementation::ResourceTypePack<>) const {} - template void freeLoaders() { + template void freeLoaders(Implementation::ResourceTypePack) { Implementation::ResourceManagerData::freeLoader(); - freeLoaders(); + freeLoaders(Implementation::ResourceTypePack{}); } - template void freeLoaders() const {} - - static ResourceManager*& internalInstance(); + void freeLoaders(Implementation::ResourceTypePack<>) const {} }; -#ifndef MAGNUM_RESOURCEMANAGER_DONT_DEFINE_INTERNALINSTANCE -template ResourceManager*& ResourceManager::internalInstance() { +namespace Implementation { + +template ResourceManager*& ResourceManagerInlineInstanceImplementation::internalInstance() { static ResourceManager* _instance(nullptr); return _instance; } -#endif - -namespace Implementation { template void safeDelete(T* data) { static_assert(sizeof(T) > 0, "Cannot delete pointer to incomplete type"); @@ -514,28 +526,17 @@ template void ResourceManagerData::set(const ResourceKey key, T* con CORRADE_ASSERT(it == _data.end() || it->second.state != ResourceDataState::Final, "ResourceManager::set(): cannot change already final resource" << key, ); - /* If nothing is referencing reference-counted resource, we're done */ - if(policy == ResourcePolicy::ReferenceCounted && (it == _data.end() || it->second.referenceCount == 0)) { - Warning() << "ResourceManager: Reference-counted resource with key" << key << "isn't referenced from anywhere, deleting it immediately"; - safeDelete(data); - - /* Delete also already present resource (it could be here - because previous policy could be other than - ReferenceCounted) */ - if(it != _data.end()) _data.erase(it); - - return; - - /* Insert it, if not already here */ - } else if(it == _data.end()) + /* Insert the resource, if not already there */ + if(it == _data.end()) #ifndef CORRADE_GCC46_COMPATIBILITY it = _data.emplace(key, Data()).first; #else it = _data.insert({key, Data()}).first; #endif - /* Replace previous data */ - safeDelete(it->second.data); + /* Otherwise delete previous data */ + else safeDelete(it->second.data); + it->second.data = data; it->second.state = state; it->second.policy = policy; @@ -618,19 +619,22 @@ template inline ResourceManagerData::Data::~Data() { } template ResourceManager& ResourceManager::instance() { - CORRADE_ASSERT(internalInstance(), "ResourceManager::instance(): no instance exists", *internalInstance()); - return *internalInstance(); + CORRADE_ASSERT(Implementation::ResourceManagerImplementation::internalInstance(), + "ResourceManager::instance(): no instance exists", + static_cast&>(*Implementation::ResourceManagerImplementation::internalInstance())); + return static_cast&>(*Implementation::ResourceManagerImplementation::internalInstance()); } template ResourceManager::ResourceManager() { - CORRADE_ASSERT(!internalInstance(), "ResourceManager::ResourceManager(): another instance is already created", ); - internalInstance() = this; + CORRADE_ASSERT(!Implementation::ResourceManagerImplementation::internalInstance(), + "ResourceManager::ResourceManager(): another instance is already created", ); + Implementation::ResourceManagerImplementation::internalInstance() = this; } template ResourceManager::~ResourceManager() { - freeLoaders(); - CORRADE_INTERNAL_ASSERT(internalInstance() == this); - internalInstance() = nullptr; + freeLoaders(typename Implementation::ResourceManagerImplementation::TypePack{}); + CORRADE_INTERNAL_ASSERT(Implementation::ResourceManagerImplementation::internalInstance() == this); + Implementation::ResourceManagerImplementation::internalInstance() = nullptr; } } diff --git a/src/Magnum/ResourceManager.hpp b/src/Magnum/ResourceManager.hpp new file mode 100644 index 000000000..44ffc3d02 --- /dev/null +++ b/src/Magnum/ResourceManager.hpp @@ -0,0 +1,46 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "ResourceManager.h" + +/* + File-local definition of ResourceManager instance holder for use in cases + where the class is used across library boundaries, in which case additional + care must be done to ensure a single static instance. + + Usage: typedef the resource manager with Implementation::ResourceManagerLocalInstance + as a first type and then include this file in a _single_ *.cpp file. + + This symbol is always exported. +*/ + +namespace Magnum { namespace Implementation { + +template CORRADE_VISIBILITY_EXPORT ResourceManager*& ResourceManagerLocalInstanceImplementation::internalInstance() { + static ResourceManager* _instance(nullptr); + return _instance; +} + +}} diff --git a/src/Magnum/SampleQuery.h b/src/Magnum/SampleQuery.h index 53018a8fe..d5ee092a1 100644 --- a/src/Magnum/SampleQuery.h +++ b/src/Magnum/SampleQuery.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,6 +31,10 @@ #include "Magnum/AbstractQuery.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif + namespace Magnum { /** @@ -69,7 +73,7 @@ q.endConditionalRender(); @endcode @see @ref PrimitiveQuery, @ref TimeQuery -@requires_gles30 %Extension @es_extension{EXT,occlusion_query_boolean} in +@requires_gles30 Extension @es_extension{EXT,occlusion_query_boolean} in OpenGL ES 2.0 */ class SampleQuery: public AbstractQuery { @@ -86,7 +90,7 @@ class SampleQuery: public AbstractQuery { /** * Whether any samples passed from fragment shader - * @requires_gl33 %Extension @extension{ARB,occlusion_query2} + * @requires_gl33 Extension @extension{ARB,occlusion_query2} */ #ifndef MAGNUM_TARGET_GLES2 AnySamplesPassed = GL_ANY_SAMPLES_PASSED, @@ -99,7 +103,7 @@ class SampleQuery: public AbstractQuery { * * An implementation may choose a less precise version of the * test at the expense of some false positives. - * @requires_gl43 %Extension @extension{ARB,ES3_compatibility} + * @requires_gl43 Extension @extension{ARB,ES3_compatibility} */ #ifndef MAGNUM_TARGET_GLES2 AnySamplesPassedConservative = GL_ANY_SAMPLES_PASSED_CONSERVATIVE @@ -112,7 +116,7 @@ class SampleQuery: public AbstractQuery { /** * @brief Conditional render mode * - * @requires_gl30 %Extension @extension{NV,conditional_render} + * @requires_gl30 Extension @extension{NV,conditional_render} * @requires_gl Conditional rendering is not available in OpenGL ES. */ enum class ConditionalRenderMode: GLenum { @@ -125,7 +129,7 @@ class SampleQuery: public AbstractQuery { /** * If query result is not yet available, waits for it and then * begins rendering only if result is zero. - * @requires_gl45 %Extension @extension{ARB,conditional_render_inverted} + * @requires_gl45 Extension @extension{ARB,conditional_render_inverted} */ WaitInverted = GL_QUERY_WAIT_INVERTED, @@ -138,7 +142,7 @@ class SampleQuery: public AbstractQuery { /** * If query result is not yet available, begins rendering like if * the result was zero. - * @requires_gl45 %Extension @extension{ARB,conditional_render_inverted} + * @requires_gl45 Extension @extension{ARB,conditional_render_inverted} */ NoWaitInverted = GL_QUERY_NO_WAIT_INVERTED, @@ -152,7 +156,7 @@ class SampleQuery: public AbstractQuery { * The same as @ref ConditionalRenderMode::WaitInverted, but * regions untouched by the sample query may not be rendered at * all. - * @requires_gl45 %Extension @extension{ARB,conditional_render_inverted} + * @requires_gl45 Extension @extension{ARB,conditional_render_inverted} */ ByRegionWaitInverted = GL_QUERY_BY_REGION_WAIT_INVERTED, @@ -166,7 +170,7 @@ class SampleQuery: public AbstractQuery { * The same as @ref ConditionalRenderMode::NoWaitInverted, but * regions untouched by the sample query may not be rendered at * all. - * @requires_gl45 %Extension @extension{ARB,conditional_render_inverted} + * @requires_gl45 Extension @extension{ARB,conditional_render_inverted} */ ByRegionNoWaitInverted = GL_QUERY_BY_REGION_NO_WAIT_INVERTED }; @@ -221,7 +225,7 @@ class SampleQuery: public AbstractQuery { * @brief Begin conditional rendering based on result value * * @see @fn_gl{BeginConditionalRender} - * @requires_gl30 %Extension @extension{NV,conditional_render} + * @requires_gl30 Extension @extension{NV,conditional_render} * @requires_gl Conditional rendering is not available in OpenGL ES. */ void beginConditionalRender(ConditionalRenderMode mode) { @@ -232,7 +236,7 @@ class SampleQuery: public AbstractQuery { * @brief End conditional render * * @see @fn_gl{EndConditionalRender} - * @requires_gl30 %Extension @extension{NV,conditional_render} + * @requires_gl30 Extension @extension{NV,conditional_render} * @requires_gl Conditional rendering is not available in OpenGL ES. */ void endConditionalRender() { diff --git a/src/Magnum/Sampler.cpp b/src/Magnum/Sampler.cpp index 7a886575b..de494480b 100644 --- a/src/Magnum/Sampler.cpp +++ b/src/Magnum/Sampler.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Sampler.h b/src/Magnum/Sampler.h index 94dd23b6e..6a50aec84 100644 --- a/src/Magnum/Sampler.h +++ b/src/Magnum/Sampler.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,7 @@ namespace Magnum { /** -@brief %Texture sampler +@brief Texture sampler @see @ref Texture, @ref TextureArray, @ref CubeMapTexture, @ref CubeMapTextureArray, @ref RectangleTexture @@ -44,7 +44,7 @@ namespace Magnum { class MAGNUM_EXPORT Sampler { public: /** - * @brief %Texture filtering + * @brief Texture filtering * * @see @ref Texture::setMinificationFilter() "*Texture::setMinificationFilter()", * @ref Texture::setMagnificationFilter() "*Texture::setMagnificationFilter()" @@ -54,7 +54,7 @@ class MAGNUM_EXPORT Sampler { /** * Linear interpolation filtering. - * @requires_gles30 %Extension @es_extension{OES,texture_float_linear} / + * @requires_gles30 Extension @es_extension{OES,texture_float_linear} / * @es_extension2{OES,texture_half_float_linear,OES_texture_float_linear} * for linear interpolation of textures with * @ref Magnum::TextureFormat "TextureFormat::HalfFloat" / @@ -80,7 +80,7 @@ class MAGNUM_EXPORT Sampler { /** * Linear interpolation of nearest mip levels. **Unavailable on * rectangle textures.** - * @requires_gles30 %Extension @es_extension{OES,texture_float_linear} / + * @requires_gles30 Extension @es_extension{OES,texture_float_linear} / * @es_extension2{OES,texture_half_float_linear,OES_texture_float_linear} * for linear interpolation of textures with * @ref Magnum::TextureFormat "TextureFormat::HalfFloat" / @@ -91,7 +91,7 @@ class MAGNUM_EXPORT Sampler { }; /** - * @brief %Texture wrapping + * @brief Texture wrapping * * @see @ref Texture::setWrapping() "*Texture::setWrapping()" */ @@ -114,7 +114,7 @@ class MAGNUM_EXPORT Sampler { * Clamp to border color. Coordinates out of range will be clamped * to border color (set with * @ref Texture::setBorderColor() "*Texture::setBorderColor()"). - * @requires_es_extension %Extension @es_extension{NV,texture_border_clamp} + * @requires_es_extension Extension @es_extension{NV,texture_border_clamp} */ #ifndef MAGNUM_TARGET_GLES ClampToBorder = GL_CLAMP_TO_BORDER, @@ -126,7 +126,7 @@ class MAGNUM_EXPORT Sampler { /** * Mirror the texture once in negative coordinates and clamp to * edge after that. **Unavailable on rectangle textures.** - * @requires_gl44 %Extension @extension{ARB,texture_mirror_clamp_to_edge}, + * @requires_gl44 Extension @extension{ARB,texture_mirror_clamp_to_edge}, * @extension{ATI,texture_mirror_once} or @extension{EXT,texture_mirror_clamp} * @requires_gl Only separate @ref Magnum::Sampler::Wrapping "Wrapping::MirroredRepeat" * or @ref Magnum::Sampler::Wrapping "Wrapping::ClampToEdge" @@ -141,7 +141,7 @@ class MAGNUM_EXPORT Sampler { * * @see @ref CompareFunction, * @ref Texture::setCompareMode() "*Texture::setCompareMode()" - * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} + * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} */ enum class CompareMode: GLenum { /** Directly output the depth value */ @@ -163,7 +163,7 @@ class MAGNUM_EXPORT Sampler { * @ref CompareMode::CompareRefToTexture. * @see @ref Texture::setCompareFunction() "*Texture::setCompareFunction()", * @ref Texture::setCompareMode() "*Texture::setCompareMode()" - * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} + * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} */ enum class CompareFunction: GLenum { Never = GL_NEVER, /**< Always `0.0` */ @@ -211,7 +211,7 @@ class MAGNUM_EXPORT Sampler { * @brief Depth/stencil texture mode * * @see @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()" - * @requires_gl43 %Extension @extension{ARB,stencil_texturing} + * @requires_gl43 Extension @extension{ARB,stencil_texturing} * @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0 * and older */ @@ -233,15 +233,6 @@ class MAGNUM_EXPORT Sampler { * @see @fn_gl{Get} with @def_gl{MAX_TEXTURE_MAX_ANISOTROPY_EXT} */ static Float maxMaxAnisotropy(); - - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @copybrief maxMaxAnisotropy() - * @deprecated Use @ref Magnum::Sampler::maxMaxAnisotropy() "maxMaxAnisotropy()" - * instead. - */ - static CORRADE_DEPRECATED("use maxMaxAnisotropy() instead") Float maxAnisotropy() { return maxMaxAnisotropy(); } - #endif }; /** @debugoperatorclassenum{Magnum::Sampler,Magnum::Sampler::Filter} */ diff --git a/src/Magnum/SceneGraph/AbstractCamera.h b/src/Magnum/SceneGraph/AbstractCamera.h index 1c0e67eb9..b4651b0ca 100644 --- a/src/Magnum/SceneGraph/AbstractCamera.h +++ b/src/Magnum/SceneGraph/AbstractCamera.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -62,9 +62,9 @@ instead. ## Explicit template specializations The following specializations are explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type) you have to -use @ref AbstractCamera.hpp implementation file to avoid linker errors. See -also relevant sections in @ref SceneGraph-Camera2D-explicit-specializations "Camera2D" +library. For other specializations (e.g. using @ref Magnum::Double "Double" +type) you have to use @ref AbstractCamera.hpp implementation file to avoid +linker errors. See also relevant sections in @ref SceneGraph-Camera2D-explicit-specializations "Camera2D" and @ref SceneGraph-Camera3D-explicit-specializations "Camera3D" class documentation or @ref compilation-speedup-hpp for more information. @@ -89,7 +89,8 @@ template class AbstractCamera: public AbstractF * @brief Camera matrix * * Camera matrix describes world position relative to the camera and is - * applied as first. + * applied after object transformation matrix and before projection + * matrix. */ typename DimensionTraits::MatrixType cameraMatrix() { AbstractFeature::object().setClean(); @@ -100,7 +101,7 @@ template class AbstractCamera: public AbstractF * @brief Projection matrix * * Projection matrix handles e.g. perspective distortion and is applied - * as last. + * as last, after @ref cameraMatrix() and object transformation matrix. * @see @ref projectionSize() */ typename DimensionTraits::MatrixType projectionMatrix() const { return _projectionMatrix; } @@ -137,7 +138,7 @@ template class AbstractCamera: public AbstractF protected: /** * @brief Constructor - * @param object %Object holding the camera + * @param object Object holding the camera */ explicit AbstractCamera(AbstractObject& object); @@ -149,9 +150,7 @@ template class AbstractCamera: public AbstractF } #ifndef DOXYGEN_GENERATING_OUTPUT - void fixAspectRatio() { - _projectionMatrix = Implementation::aspectRatioFix(_aspectRatioPolicy, {rawProjectionMatrix[0].x(), rawProjectionMatrix[1].y()}, _viewport)*rawProjectionMatrix; - } + void fixAspectRatio(); typename DimensionTraits::MatrixType rawProjectionMatrix; AspectRatioPolicy _aspectRatioPolicy; @@ -168,7 +167,7 @@ template class AbstractCamera: public AbstractF /** @brief Base camera for two-dimensional scenes -Convenience alternative to %AbstractCamera<2, T>. See +Convenience alternative to `AbstractCamera<2, T>`. See @ref AbstractCamera for more information. @note Not available on GCC < 4.7. Use %AbstractCamera<2, T> instead. @see @ref AbstractCamera2D, @ref AbstractBasicCamera3D @@ -195,7 +194,7 @@ typedef AbstractCamera<2, Float> AbstractCamera2D; /** @brief Base camera for three-dimensional scenes -Convenience alternative to %AbstractCamera<3, T>. See +Convenience alternative to `AbstractCamera<3, T>`. See @ref AbstractCamera for more information. @note Not available on GCC < 4.7. Use %AbstractCamera<3, T> instead. @see @ref AbstractCamera3D, @ref AbstractBasicCamera2D diff --git a/src/Magnum/SceneGraph/AbstractCamera.hpp b/src/Magnum/SceneGraph/AbstractCamera.hpp index 6987390de..126431bfb 100644 --- a/src/Magnum/SceneGraph/AbstractCamera.hpp +++ b/src/Magnum/SceneGraph/AbstractCamera.hpp @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,6 +29,7 @@ * @brief @ref compilation-speedup-hpp "Template implementation" for @ref AbstractCamera.h */ +#include "Magnum/Math/Functions.h" #include "Magnum/SceneGraph/AbstractCamera.h" #include "Magnum/SceneGraph/Drawable.h" @@ -36,34 +37,20 @@ namespace Magnum { namespace SceneGraph { namespace Implementation { -template class Camera {}; - -template class Camera<2, T> { - public: - constexpr static Math::Matrix3 aspectRatioScale(const Math::Vector2& scale) { - return Math::Matrix3::scaling({scale.x(), scale.y()}); - } -}; -template class Camera<3, T> { - public: - constexpr static Math::Matrix4 aspectRatioScale(const Math::Vector2& scale) { - return Math::Matrix4::scaling({scale.x(), scale.y(), 1.0f}); - } -}; - template typename DimensionTraits::MatrixType aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& projectionScale, const Vector2i& viewport) { /* Don't divide by zero / don't preserve anything */ if(projectionScale.x() == 0 || projectionScale.y() == 0 || viewport.x() == 0 || viewport.y() == 0 || aspectRatioPolicy == AspectRatioPolicy::NotPreserved) return {}; + CORRADE_INTERNAL_ASSERT((projectionScale > Math::Vector2(0)).all() && (viewport > Vector2i(0)).all()); Math::Vector2 relativeAspectRatio = Math::Vector2(viewport)*projectionScale; /* Extend on larger side = scale larger side down Clip on smaller side = scale smaller side up */ - return Camera::aspectRatioScale( + return MatrixTypeFor::scaling(Math::Vector::pad( (relativeAspectRatio.x() > relativeAspectRatio.y()) == (aspectRatioPolicy == AspectRatioPolicy::Extend) ? - Vector2(relativeAspectRatio.y()/relativeAspectRatio.x(), T(1.0)) : - Vector2(T(1.0), relativeAspectRatio.x()/relativeAspectRatio.y())); + Vector2(relativeAspectRatio.y()/relativeAspectRatio.x(), T(1)) : + Vector2(T(1), relativeAspectRatio.x()/relativeAspectRatio.y()), T(1))); } } @@ -75,6 +62,10 @@ template AbstractCamera::Abstrac /* `= default` causes linker errors in GCC 4.4 */ template AbstractCamera::~AbstractCamera() {} +template void AbstractCamera::fixAspectRatio() { + _projectionMatrix = Implementation::aspectRatioFix(_aspectRatioPolicy, {Math::abs(rawProjectionMatrix[0].x()), Math::abs(rawProjectionMatrix[1].y())}, _viewport)*rawProjectionMatrix; +} + template AbstractCamera& AbstractCamera::setAspectRatioPolicy(AspectRatioPolicy policy) { _aspectRatioPolicy = policy; fixAspectRatio(); diff --git a/src/Magnum/SceneGraph/AbstractFeature.h b/src/Magnum/SceneGraph/AbstractFeature.h index 2a6b68077..289a3183e 100644 --- a/src/Magnum/SceneGraph/AbstractFeature.h +++ b/src/Magnum/SceneGraph/AbstractFeature.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,7 +40,7 @@ namespace Magnum { namespace SceneGraph { /** @brief Which transformation to cache in given feature -@see @ref scenegraph-caching, @ref CachedTransformations, +@see @ref scenegraph-features-caching, @ref CachedTransformations, @ref AbstractFeature::setCachedTransformations(), @ref AbstractFeature::clean(), @ref AbstractFeature::cleanInverted() @todo Provide also simpler representations from which could benefit @@ -68,7 +68,7 @@ enum class CachedTransformation: UnsignedByte { /** @brief Which transformations to cache in this feature -@see @ref scenegraph-caching, @ref AbstractFeature::setCachedTransformations(), +@see @ref scenegraph-features-caching, @ref AbstractFeature::setCachedTransformations(), @ref AbstractFeature::clean(), @ref AbstractFeature::cleanInverted() */ typedef Containers::EnumSet CachedTransformations; @@ -90,12 +90,11 @@ Feature is templated on dimension count and underlying transformation type, so it can be used only on object having transformation with the same dimension count and type. -@anchor SceneGraph-AbstractFeature-subclassing-caching ### Caching transformations in features Features can cache absolute transformation of the object instead of computing it from scratch every time to achieve better performance. See -@ref scenegraph-caching for introduction. +@ref scenegraph-features-caching for introduction. In order to have caching, you must enable it first, because by default the caching is disabled. You can enable it using @ref setCachedTransformations() @@ -104,17 +103,16 @@ and then implement corresponding cleaning function(s) -- either @ref clean(), @code class CachingFeature: public SceneGraph::AbstractFeature3D { public: - CachingFeature(SceneGraph::AbstractObject3D& object): SceneGraph::AbstractFeature3D(object) { + explicit CachingFeature(SceneGraph::AbstractObject3D& object): SceneGraph::AbstractFeature3D{object} { setCachedTransformations(CachedTransformation::Absolute); } - protected: + private: void clean(const Matrix4& absoluteTransformationMatrix) override { - absolutePosition = absoluteTransformationMatrix.translation(); + _absolutePosition = absoluteTransformationMatrix.translation(); } - private: - Vector3 absolutePosition; + Vector3 _absolutePosition; }; @endcode @@ -123,40 +121,29 @@ Before using the cached value explicitly request object cleaning by calling ### Accessing object transformation -Features has by default access only to @ref AbstractObject, which is base of -@ref Object not depending on any particular transformation implementation. This -has the advantage that features doesn't have to be implemented for all possible -transformation implementations, thus preventing code duplication. However it -is impossible to transform the object using only pointer to @ref AbstractObject. - -The transformations have interfaces for common functionality, so the feature -can use that interface instead of being specialized for all relevant -transformation implementations. Using small trick we are able to get pointer -to both @ref AbstractObject and needed transformation from one constructor -parameter: +The feature has by default only access to @ref AbstractObject, which doesn't +know about any used transformation. By using small template trick in the +constructor it is possible to gain access to transformation interface in the +constructor: @code class TransformingFeature: public SceneGraph::AbstractFeature3D { public: - template TransformingFeature(SceneGraph::Object& object): - SceneGraph::AbstractFeature3D(object), transformation(object) {} + template explicit TransformingFeature(SceneGraph::Object& object): + SceneGraph::AbstractFeature3D{object}, _transformation{object} {} private: - SceneGraph::AbstractTranslationRotation3D& transformation; + SceneGraph::AbstractTranslationRotation3D& _transformation; }; @endcode -If we take for example @ref Object "Object", it is -derived from @ref AbstractObject "AbstractObject3D" and -@ref BasicMatrixTransformation3D "MatrixTransformation3D", which is derived -from @ref AbstractBasicTranslationRotationScaling3D "AbstractTranslationRotationScaling3D", -which is derived from @ref AbstractBasicTranslationRotation3D "AbstractTranslationRotation3D", -which is automatically extracted from the reference in our constructor. + +See @ref scenegraph-features-transformation for more detailed information. ## Explicit template specializations The following specializations are explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type) you have to -use @ref AbstractFeature.hpp implementation file to avoid linker errors. See -also @ref compilation-speedup-hpp for more information. +library. For other specializations (e.g. using @ref Magnum::Double "Double" type) +you have to use @ref AbstractFeature.hpp implementation file to avoid linker +errors. See also @ref compilation-speedup-hpp for more information. - @ref AbstractFeature2D - @ref AbstractFeature3D @@ -169,14 +156,14 @@ template class AbstractFeature : private Containers::LinkedListItem, AbstractObject> #endif { - friend class Containers::LinkedList>; - friend class Containers::LinkedListItem, AbstractObject>; - template friend class Object; + friend Containers::LinkedList>; + friend Containers::LinkedListItem, AbstractObject>; + template friend class Object; public: /** * @brief Constructor - * @param object %Object holding this feature + * @param object Object holding this feature */ explicit AbstractFeature(AbstractObject& object); @@ -196,7 +183,7 @@ template class AbstractFeature virtual ~AbstractFeature() = 0; - /** @brief %Object holding this feature */ + /** @brief Object holding this feature */ AbstractObject& object() { return *Containers::LinkedListItem, AbstractObject>::list(); } @@ -229,13 +216,14 @@ template class AbstractFeature /** * @{ @name Transformation caching * - * See @ref scenegraph-caching for more information. + * See @ref scenegraph-features-caching for more information. */ /** * @brief Which transformations are cached * - * @see @ref scenegraph-caching, @ref clean(), @ref cleanInverted() + * @see @ref scenegraph-features-caching, @ref clean(), + * @ref cleanInverted() */ CachedTransformations cachedTransformations() const { return _cachedTransformations; @@ -250,7 +238,7 @@ template class AbstractFeature * transformation. * * Nothing is enabled by default. - * @see @ref scenegraph-caching + * @see @ref scenegraph-features-caching */ void setCachedTransformations(CachedTransformations transformations) { _cachedTransformations = transformations; @@ -264,7 +252,7 @@ template class AbstractFeature * done in @ref clean() and @ref cleanInverted(). * * Default implementation does nothing. - * @see @ref scenegraph-caching + * @see @ref scenegraph-features-caching */ virtual void markDirty(); @@ -276,7 +264,7 @@ template class AbstractFeature * to recalculate data based on absolute object transformation. * * Default implementation does nothing. - * @see @ref scenegraph-caching, @ref cleanInverted() + * @see @ref scenegraph-features-caching, @ref cleanInverted() */ virtual void clean(const typename DimensionTraits::MatrixType& absoluteTransformationMatrix); @@ -289,7 +277,7 @@ template class AbstractFeature * transformation. * * Default implementation does nothing. - * @see @ref scenegraph-caching, @ref clean() + * @see @ref scenegraph-features-caching, @ref clean() */ virtual void cleanInverted(const typename DimensionTraits::MatrixType& invertedAbsoluteTransformationMatrix); @@ -303,7 +291,7 @@ template class AbstractFeature /** @brief Base feature for two-dimensional scenes -Convenience alternative to %AbstractFeature<2, T>. See +Convenience alternative to `AbstractFeature<2, T>`. See @ref AbstractFeature for more information. @note Not available on GCC < 4.7. Use %AbstractFeature<2, T> instead. @see @ref AbstractFeature2D, @ref AbstractBasicFeature3D @@ -330,7 +318,7 @@ typedef AbstractFeature<2, Float> AbstractFeature2D; /** @brief Base feature for three-dimensional scenes -Convenience alternative to %AbstractFeature<3, T>. See +Convenience alternative to `AbstractFeature<3, T>`. See @ref AbstractFeature for more information. @note Not available on GCC < 4.7. Use %AbstractFeature<3, T> instead. @see @ref AbstractFeature3D, @ref AbstractBasicFeature2D diff --git a/src/Magnum/SceneGraph/AbstractFeature.hpp b/src/Magnum/SceneGraph/AbstractFeature.hpp index 75f00da25..bf75487e4 100644 --- a/src/Magnum/SceneGraph/AbstractFeature.hpp +++ b/src/Magnum/SceneGraph/AbstractFeature.hpp @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/SceneGraph/AbstractGroupedFeature.h b/src/Magnum/SceneGraph/AbstractGroupedFeature.h index f79f32f35..4e7ecd46a 100644 --- a/src/Magnum/SceneGraph/AbstractGroupedFeature.h +++ b/src/Magnum/SceneGraph/AbstractGroupedFeature.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -56,9 +56,9 @@ typedef SceneGraph::FeatureGroup3D DrawableGroup; ## Explicit template specializations The following specializations are explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type) you have to -use @ref FeatureGroup.hpp implementation file to avoid linker errors. See also -@ref compilation-speedup-hpp for more information. +library. For other specializations (e.g. using @ref Magnum::Double "Double" type) +you have to use @ref FeatureGroup.hpp implementation file to avoid linker +errors. See also @ref compilation-speedup-hpp for more information. - @ref FeatureGroup2D - @ref FeatureGroup3D @@ -68,12 +68,12 @@ use @ref FeatureGroup.hpp implementation file to avoid linker errors. See also @ref AbstractGroupedFeature3D, @ref FeatureGroup */ template class AbstractGroupedFeature: public AbstractFeature { - friend class FeatureGroup; + friend FeatureGroup; public: /** * @brief Constructor - * @param object %Object this feature belongs to + * @param object Object this feature belongs to * @param group Group this feature belongs to * * Adds the feature to the object and to group, if specified. @@ -111,7 +111,7 @@ template class AbstractGroupedFe /** @brief Base grouped feature for two-dimensional scenes -Convenience alternative to %AbstractGroupedFeature<2, Derived, T>. See +Convenience alternative to `AbstractGroupedFeature<2, Derived, T>`. See @ref AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use %AbstractGroupedFeature<2, Derived, T> instead. @@ -124,7 +124,7 @@ template using AbstractBasicGroupedFeature2D = AbstractG /** @brief Base grouped feature for two-dimensional float scenes -Convenience alternative to %AbstractBasicGroupedFeature2D. +Convenience alternative to `AbstractBasicGroupedFeature2D`. See @ref AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use %AbstractGroupedFeature<2, Derived, Float> instead. @@ -137,7 +137,7 @@ template using AbstractGroupedFeature2D = AbstractBasicGroupedFea /** @brief Base grouped feature for three-dimensional scenes -Convenience alternative to %AbstractGroupedFeature<3, Derived, T>. See +Convenience alternative to `AbstractGroupedFeature<3, Derived, T>`. See @ref AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use %AbstractGroupedFeature<3, Derived, T> instead. @@ -150,7 +150,7 @@ template using AbstractBasicGroupedFeature3D = AbstractG /** @brief Base grouped feature for three-dimensional float scenes -Convenience alternative to %AbstractBasicGroupedFeature3D. +Convenience alternative to `AbstractBasicGroupedFeature3D`. See @ref AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use %AbstractGroupedFeature<3, Derived, Float> instead. diff --git a/src/Magnum/SceneGraph/AbstractObject.h b/src/Magnum/SceneGraph/AbstractObject.h index 74bd9a722..6608223eb 100644 --- a/src/Magnum/SceneGraph/AbstractObject.h +++ b/src/Magnum/SceneGraph/AbstractObject.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,6 +37,10 @@ #include "Magnum/SceneGraph/SceneGraph.h" #include "Magnum/SceneGraph/visibility.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif + namespace Magnum { namespace SceneGraph { /** @@ -46,11 +50,20 @@ Provides minimal interface for features, not depending on object transformation implementation. This class is not directly instantiatable, use @ref Object subclass instead. See also @ref scenegraph for more information. -Uses @ref Corrade::Containers::LinkedList for storing features. Traversing -through the list is done like in the following code. It is also possible to go -in reverse order using @ref lastFeature() and @ref AbstractFeature::previousFeature(). +Uses @ref Corrade::Containers::LinkedList for efficient feature management. +Traversing through the feature list can be done using range-based for: +@code +AbstractObject3D object; +for(AbstractFeature3D& feature: object.features()) { + // ... +} +@endcode + +Or, if you need more flexibility, like in the following code. It is also +possible to go in reverse order using @ref Corrade::Containers::LinkedList::last() +and @ref AbstractFeature::previousFeature(). @code -for(AbstractFeature* feature = o->firstFeature(); feature; feature = feature->nextFeature()) { +for(AbstractFeature3D* feature = object.features().first(); feature; feature = feature->nextFeature()) { // ... } @endcode @@ -59,10 +72,10 @@ for(AbstractFeature* feature = o->firstFeature(); feature; feature = feature->ne ## Explicit template specializations The following specializations are explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type) you have to -use @ref Object.hpp implementation file to avoid linker errors. See also -relevant sections in @ref SceneGraph-Object-explicit-specializations "Object" and -@ref SceneGraph-AbstractTransformation-explicit-specializations "AbstractTransformation" +library. For other specializations (e.g. using @ref Magnum::Double "Double" +type) you have to use @ref Object.hpp implementation file to avoid linker +errors. See also relevant sections in @ref SceneGraph-Object-explicit-specializations "Object" +and @ref SceneGraph-AbstractTransformation-explicit-specializations "AbstractTransformation" class documentation or @ref compilation-speedup-hpp for more information. - @ref AbstractObject2D @@ -76,9 +89,9 @@ template class AbstractObject : private Containers::LinkedList> #endif { - friend class Containers::LinkedList>; - friend class Containers::LinkedListItem, AbstractObject>; - friend class AbstractFeature; + friend Containers::LinkedList>; + friend Containers::LinkedListItem, AbstractObject>; + friend AbstractFeature; public: /** @brief Matrix type */ @@ -92,34 +105,65 @@ template class AbstractObject explicit AbstractObject(); virtual ~AbstractObject(); - /** @brief Whether this object has features */ - bool hasFeatures() const { - return !Containers::LinkedList>::isEmpty(); - } - - /** @brief First object feature or `nullptr`, if this object has no features */ - FeatureType* firstFeature() { - return Containers::LinkedList>::first(); + /** + * @brief Object features + * + * @see @ref AbstractFeature::object(), + * @ref AbstractFeature::previousFeature(), + * @ref AbstractFeature::nextFeature() + */ + Containers::LinkedList>& features() { + return static_cast>&>(*this); } /** @overload */ - const FeatureType* firstFeature() const { - return Containers::LinkedList>::first(); + const Containers::LinkedList>& features() const { + return static_cast>&>(*this); } - /** @brief Last object feature or `nullptr`, if this object has no features */ - FeatureType* lastFeature() { - return Containers::LinkedList>::last(); - } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Whether this object has features + * @deprecated Use `features().isEmpty()` instead. + */ + CORRADE_DEPRECATED("use features().isEmpty() instead") bool hasFeatures() const { return !features().isEmpty(); } - /** @overload */ - const FeatureType* lastFeature() const { - return Containers::LinkedList>::last(); + /** + * @brief First object feature or `nullptr`, if this object has no features + * @deprecated Use `features().first()` instead. + */ + CORRADE_DEPRECATED("use features().first() instead") FeatureType* firstFeature() { return features().first(); } + + /** @overload + * @deprecated Use `features().first()` instead. + */ + CORRADE_DEPRECATED("use features().first() instead") const FeatureType* firstFeature() const { return features().first(); } + + /** + * @brief Last object feature or `nullptr`, if this object has no features + * @deprecated Use `features().last()` instead.` + */ + CORRADE_DEPRECATED("use features().last() instead") FeatureType* lastFeature() { return features().last(); } + + /** @overload + * @deprecated Use `features().last()` instead. + */ + CORRADE_DEPRECATED("use features().last() instead") const FeatureType* lastFeature() const { return features().last(); } + #endif + + /** + * @brief Add a feature + * + * Calling `object.addFeature(args...)` is equivalent to + * `new MyFeature{object, args...}`. + */ + template U& addFeature(Args... args) { + return *(new U{*this, std::forward(args)...}); } /** - * @brief %Scene - * @return %Scene or `nullptr`, if the object is not part of any scene. + * @brief Scene + * @return Scene or `nullptr`, if the object is not part of any scene. */ AbstractObject* scene() { return doScene(); } @@ -183,7 +227,7 @@ template class AbstractObject /** * @{ @name Transformation caching * - * See @ref scenegraph-caching for more information. + * See @ref scenegraph-features-caching for more information. */ /** @@ -223,7 +267,7 @@ template class AbstractObject * Returns `true` if transformation of the object or any parent has * changed since last call to @ref setClean(), `false` otherwise. All * objects are dirty by default. - * @see @ref scenegraph-caching + * @see @ref scenegraph-features-caching */ bool isDirty() const { return doIsDirty(); } @@ -234,7 +278,8 @@ template class AbstractObject * recursively calls @ref setDirty() on every child object which is not * already dirty. If the object is already marked as dirty, the * function does nothing. - * @see @ref scenegraph-caching, @ref setClean(), @ref isDirty() + * @see @ref scenegraph-features-caching, @ref setClean(), + * @ref isDirty() */ void setDirty() { doSetDirty(); } @@ -249,7 +294,8 @@ template class AbstractObject * See also @ref setClean(const std::vector*>&), * which cleans given set of objects more efficiently than when calling * @ref setClean() on each object individually. - * @see @ref scenegraph-caching, @ref setDirty(), @ref isDirty() + * @see @ref scenegraph-features-caching, @ref setDirty(), + * @ref isDirty() */ void setClean() { doSetClean(); } @@ -273,7 +319,7 @@ template class AbstractObject /** @brief Base object for two-dimensional scenes -Convenience alternative to %AbstractObject<2, T>. See +Convenience alternative to `AbstractObject<2, T>`. See @ref AbstractObject for more information. @note Not available on GCC < 4.7. Use %AbstractObject<2, T> instead. @see @ref AbstractObject2D, @ref AbstractBasicObject3D @@ -300,7 +346,7 @@ typedef AbstractObject<2, Float> AbstractObject2D; /** @brief Base object for three-dimensional scenes -Convenience alternative to %AbstractObject<3, T>. See +Convenience alternative to `AbstractObject<3, T>`. See @ref AbstractObject for more information. @note Not available on GCC < 4.7. Use %AbstractObject<3, T> instead. @see @ref AbstractObject3D, @ref AbstractBasicObject2D diff --git a/src/Magnum/SceneGraph/AbstractTransformation.h b/src/Magnum/SceneGraph/AbstractTransformation.h index 609ecb82c..88e8ee607 100644 --- a/src/Magnum/SceneGraph/AbstractTransformation.h +++ b/src/Magnum/SceneGraph/AbstractTransformation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,6 +29,8 @@ * @brief Class @ref Magnum::SceneGraph::AbstractTransformation, alias @ref Magnum::SceneGraph::AbstractBasicTransformation2D, @ref Magnum::SceneGraph::AbstractBasicTransformation3D, typedef @ref Magnum::SceneGraph::AbstractTransformation2D, @ref Magnum::SceneGraph::AbstractTransformation3D, enum @ref Magnum::SceneGraph::TransformationType */ +#include + #include "Magnum/SceneGraph/SceneGraph.h" #include "Magnum/SceneGraph/visibility.h" @@ -37,15 +39,16 @@ namespace Magnum { namespace SceneGraph { /** @brief Base for transformations -Provides transformation implementation for @ref Object instances. +Provides transformation implementation for @ref Object instances. See +@ref scenegraph-features-transformation for more information. @anchor SceneGraph-AbstractTransformation-explicit-specializations ## Explicit template specializations The following specializations are explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type) you have to -use @ref Object.hpp implementation file to avoid linker errors. See -@ref compilation-speedup-hpp for more information. +library. For other specializations (e.g. using @ref Magnum::Double "Double" +type) you have to use @ref Object.hpp implementation file to avoid linker +errors. See @ref compilation-speedup-hpp for more information. - @ref AbstractTransformation2D - @ref AbstractTransformation3D @@ -87,24 +90,26 @@ template class AbstractTransformation { template inline AbstractTransformation::~AbstractTransformation() = default; +#ifdef MAGNUM_BUILD_DEPRECATED /** @brief Transformation type - -@todo Get rid of this in favor of separate function for each type (less branching) +@deprecated Use `*Transformation*::*()` and `*Transformation::*Local*()` + overloads instead. */ -enum class TransformationType: UnsignedByte { +enum class CORRADE_DEPRECATED_ENUM("use *() and *Local() overloads instead") TransformationType: UnsignedByte { /** Global transformation, applied after all other transformations. */ Global = 0x00, /** Local transformation, applied before all other transformations. */ Local = 0x01 }; +#endif #ifndef CORRADE_GCC46_COMPATIBILITY /** @brief Base transformation for two-dimensional scenes -Convenience alternative to %AbstractTransformation<2, T>. See +Convenience alternative to `AbstractTransformation<2, T>`. See @ref AbstractTransformation for more information. @note Not available on GCC < 4.7. Use %AbstractTransformation<2, T> instead. @@ -130,7 +135,7 @@ typedef AbstractTransformation<2, Float> AbstractTransformation2D; /** @brief Base transformation for three-dimensional scenes -Convenience alternative to %AbstractTransformation<3, T>. See +Convenience alternative to `AbstractTransformation<3, T>`. See @ref AbstractTransformation for more information. @note Not available on GCC < 4.7. Use %AbstractTransformation<3, T> instead. diff --git a/src/Magnum/SceneGraph/AbstractTranslation.h b/src/Magnum/SceneGraph/AbstractTranslation.h index 8b327c918..75441b522 100644 --- a/src/Magnum/SceneGraph/AbstractTranslation.h +++ b/src/Magnum/SceneGraph/AbstractTranslation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,13 +38,15 @@ namespace Magnum { namespace SceneGraph { /** @brief Base transformation for two-dimensional scenes supporting translation +See @ref scenegraph-features-transformation for more information. + By default the translation is stored with the same underlying type as resulting transformation matrix, but it's possible to store translation in e.g. integral coordinates while having floating-point transformation matrix. -@see @ref AbstractBasicTranslation2D, @ref AbstractBasicTranslation3D, - @ref AbstractTranslation2D, @ref AbstractTranslation3D, @ref scenegraph, - @ref TranslationTransformation +@see @ref scenegraph, @ref AbstractBasicTranslation2D, + @ref AbstractBasicTranslation3D, @ref AbstractTranslation2D, + @ref AbstractTranslation3D, @ref TranslationTransformation */ #ifdef DOXYGEN_GENERATING_OUTPUT template @@ -57,19 +59,48 @@ class AbstractTranslation: public AbstractTransformation { /** * @brief Translate object - * @param vector Translation vector - * @param type Transformation type * @return Reference to self (for method chaining) * - * @see @ref Math::Vector2::xAxis(), @ref Math::Vector2::yAxis(), - * @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(), - * @ref Math::Vector3::zAxis() + * @see @ref translateLocal(), @ref Math::Vector2::xAxis(), + * @ref Math::Vector2::yAxis(), @ref Math::Vector3::xAxis(), + * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() + */ + AbstractTranslation& translate(const typename DimensionTraits::VectorType& vector) { + doTranslate(vector); + return *this; + } + + /** + * @brief Translate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. */ - AbstractTranslation& translate(const typename DimensionTraits::VectorType& vector, TransformationType type = TransformationType::Global) { - doTranslate(vector, type); + AbstractTranslation& translateLocal(const typename DimensionTraits::VectorType& vector) { + doTranslateLocal(vector); return *this; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief translate() + * @deprecated Use @ref Magnum::SceneGraph::AbstractTranslation::translate() "translate()" + * or @ref Magnum::SceneGraph::AbstractTranslation::translateLocal() "translateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use translate() or translateLocal() instead") AbstractTranslation& translate(const VectorTypeFor& vector, TransformationType type) { + return type == TransformationType::Global ? translate(vector) : translateLocal(vector); + } + #endif + + /* Overloads to remove WTF-factor from method chaining order */ + #ifndef DOXYGEN_GENERATING_OUTPUT + AbstractTranslation& resetTransformation() { + AbstractTransformation::resetTransformation(); + return *this; + } + #endif + protected: ~AbstractTranslation(); @@ -79,7 +110,10 @@ class AbstractTranslation: public AbstractTransformation { private: #endif /** @brief Polymorphic implementation for @ref translate() */ - virtual void doTranslate(const typename DimensionTraits::VectorType& vector, TransformationType type) = 0; + virtual void doTranslate(const typename DimensionTraits::VectorType& vector) = 0; + + /** @brief Polymorphic implementation for @ref translateLocal() */ + virtual void doTranslateLocal(const typename DimensionTraits::VectorType& vector) = 0; }; template inline AbstractTranslation::AbstractTranslation() = default; @@ -90,7 +124,7 @@ template inline Abstract /** @brief Base transformation for two-dimensional scenes supporting translation -Convenience alternative to %AbstractTranslation<2, T, TranslationType>. +Convenience alternative to `AbstractTranslation<2, T, TranslationType>`. See @ref AbstractTranslation for more information. @note Not available on GCC < 4.7. Use %AbstractTranslation<2, T, TranslationType> instead. @@ -121,7 +155,7 @@ typedef AbstractTranslation<2, Float> AbstractTranslation2D; /** @brief Base transformation for three-dimensional scenes supporting translation -Convenience alternative to %AbstractTranslation<3, T, TranslationType>. +Convenience alternative to `AbstractTranslation<3, T, TranslationType>`. See @ref AbstractTranslation for more information. @note Not available on GCC < 4.7. Use %AbstractTranslation<3, T, TranslationType> instead. diff --git a/src/Magnum/SceneGraph/AbstractTranslationRotation2D.h b/src/Magnum/SceneGraph/AbstractTranslationRotation2D.h index 655d9b18e..a12ac67e9 100644 --- a/src/Magnum/SceneGraph/AbstractTranslationRotation2D.h +++ b/src/Magnum/SceneGraph/AbstractTranslationRotation2D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,9 @@ namespace Magnum { namespace SceneGraph { /** @brief Base transformation for two-dimensional scenes supporting translation and rotation -@see @ref AbstractTranslationRotation2D, @ref scenegraph, +See @ref scenegraph-features-transformation for more information. + +@see @ref scenegraph, @ref AbstractTranslationRotation2D, @ref AbstractBasicTranslationRotation3D, @ref BasicRigidMatrixTransformation2D, @ref BasicDualComplexTransformation @todo Use AbstractBasicTransformation2D when support for GCC 4.6 is dropped @@ -48,20 +50,58 @@ template class AbstractBasicTranslationRotation2D: public AbstractTrans /** * @brief Rotate object * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) + * + * @see @ref rotateLocal() + */ + AbstractBasicTranslationRotation2D& rotate(Math::Rad angle) { + doRotate(angle); + return *this; + } + + /** + * @brief Rotate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. */ - AbstractBasicTranslationRotation2D& rotate(Math::Rad angle, TransformationType type = TransformationType::Global) { - doRotate(angle, type); + AbstractBasicTranslationRotation2D& rotateLocal(Math::Rad angle) { + doRotateLocal(angle); return *this; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotate() + * @deprecated Use @ref Magnum::SceneGraph::AbstractTranslationRotation2D::rotate() "rotate()" + * or @ref Magnum::SceneGraph::AbstractTranslationRotation2D::rotateLocal() "rotateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotate() or rotateLocal() instead") AbstractBasicTranslationRotation2D& rotate(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotate(angle, type) : rotateLocal(angle, type); + } + #endif + /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT AbstractBasicTranslationRotation2D& resetTransformation() { AbstractTransformation<2, T>::resetTransformation(); return *this; } + AbstractBasicTranslationRotation2D& translate(const Math::Vector2& vector) { + AbstractBasicTranslation2D::translate(vector); + return *this; + } + AbstractBasicTranslationRotation2D& translateLocal(const Math::Vector2& vector) { + AbstractBasicTranslation2D::translateLocal(vector); + return *this; + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use translate() or translateLocal() instead") AbstractBasicTranslationRotation2D& translate(const Math::Vector2& vector, TransformationType type) { + AbstractBasicTranslation2D::translate(vector, type); + return *this; + } + #endif #endif protected: @@ -73,7 +113,10 @@ template class AbstractBasicTranslationRotation2D: public AbstractTrans private: #endif /** @brief Polymorphic implementation for @ref rotate() */ - virtual void doRotate(Math::Rad angle, TransformationType type) = 0; + virtual void doRotate(Math::Rad angle) = 0; + + /** @brief Polymorphic implementation for @ref rotateLocal() */ + virtual void doRotateLocal(Math::Rad angle) = 0; }; template inline AbstractBasicTranslationRotation2D::AbstractBasicTranslationRotation2D() = default; diff --git a/src/Magnum/SceneGraph/AbstractTranslationRotation3D.h b/src/Magnum/SceneGraph/AbstractTranslationRotation3D.h index 5f85da808..8ff622330 100644 --- a/src/Magnum/SceneGraph/AbstractTranslationRotation3D.h +++ b/src/Magnum/SceneGraph/AbstractTranslationRotation3D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,9 @@ namespace Magnum { namespace SceneGraph { /** @brief Base transformation for three-dimensional scenes supporting translation and rotation -@see @ref AbstractTranslationRotation3D @ref scenegraph, +See @ref scenegraph-features-transformation for more information. + +@see @ref scenegraph, @ref AbstractTranslationRotation3D, @ref AbstractBasicTranslationRotation2D, @ref BasicRigidMatrixTransformation3D, @ref BasicDualQuaternionTransformation @@ -50,69 +52,180 @@ template class AbstractBasicTranslationRotation3D: public AbstractTrans * @brief Rotate object * @param angle Angle (counterclockwise) * @param normalizedAxis Normalized rotation axis - * @param type Transformation type * @return Reference to self (for method chaining) * - * @see @ref rotateX(), @ref rotateY(), @ref rotateZ(), - * @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(), - * @ref Math::Vector3::zAxis() + * @see @ref rotateLocal(), @ref rotateX(), @ref rotateY(), + * @ref rotateZ(), @ref Math::Vector3::xAxis(), + * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() + */ + AbstractBasicTranslationRotation3D& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { + doRotate(angle, normalizedAxis); + return *this; + } + + /** + * @brief Rotate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. */ - AbstractBasicTranslationRotation3D& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type = TransformationType::Global) { - doRotate(angle, normalizedAxis, type); + AbstractBasicTranslationRotation3D& rotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) { + doRotateLocal(angle, normalizedAxis); return *this; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotate() + * @deprecated Use @ref Magnum::SceneGraph::AbstractTranslationRotation3D::rotate() "rotate()" + * or @ref Magnum::SceneGraph::AbstractTranslationRotation3D::rotateLocal() "rotateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotate() or rotateLocal() instead") AbstractBasicTranslationRotation3D& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type) { + return type == TransformationType::Global ? rotate(angle, normalizedAxis) : rotateLocal(angle, normalizedAxis); + } + #endif + /** * @brief Rotate object around X axis * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * * In some implementations faster than calling - * `rotate(angle, %Vector3::xAxis())`, see subclasses for more + * `rotate(angle, Vector3::xAxis())`, see subclasses for more + * information. + * @see @ref rotateXLocal() + */ + AbstractBasicTranslationRotation3D& rotateX(Math::Rad angle) { + doRotateX(angle); + return *this; + } + + /** + * @brief Rotate object around X axis as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. In some implementations faster than calling + * `rotateLocal(angle, Vector3::xAxis())`, see subclasses for more * information. */ - AbstractBasicTranslationRotation3D& rotateX(Math::Rad angle, TransformationType type = TransformationType::Global) { - doRotateX(angle, type); + AbstractBasicTranslationRotation3D& rotateXLocal(Math::Rad angle) { + doRotateXLocal(angle); return *this; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotateX() + * @deprecated Use @ref Magnum::SceneGraph::AbstractTranslationRotation3D::rotateX() "rotateX()" + * or @ref Magnum::SceneGraph::AbstractTranslationRotation3D::rotateXLocal() "rotateXLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotateX() or rotateXLocal() instead") AbstractBasicTranslationRotation3D& rotateX(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotateX(angle) : rotateXLocal(angle); + } + #endif + /** * @brief Rotate object around Y axis * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * * In some implementations faster than calling - * `rotate(angle, %Vector3::yAxis())`, see subclasses for more + * `rotate(angle, Vector3::yAxis())`, see subclasses for more + * information. + * @see @ref rotateYLocal() + */ + AbstractBasicTranslationRotation3D& rotateY(Math::Rad angle) { + doRotateY(angle); + return *this; + } + + /** + * @brief Rotate object around Y axis as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. In some implementations faster than calling + * `rotateLocal(angle, Vector3::yAxis())`, see subclasses for more * information. */ - AbstractBasicTranslationRotation3D& rotateY(Math::Rad angle, TransformationType type = TransformationType::Global) { - doRotateX(angle, type); + AbstractBasicTranslationRotation3D& rotateYLocal(Math::Rad angle) { + doRotateY(angle); return *this; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotateY() + * @deprecated Use @ref Magnum::SceneGraph::AbstractTranslationRotation3D::rotateY() "rotateY()" + * or @ref Magnum::SceneGraph::AbstractTranslationRotation3D::rotateYLocal() "rotateYLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotateY() or rotateYLocal() instead") AbstractBasicTranslationRotation3D& rotateY(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotateY(angle) : rotateYLocal(angle); + } + #endif + /** * @brief Rotate object around Z axis * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * * In some implementations faster than calling - * `rotate(angle, %Vector3::zAxis())`, see subclasses for more + * `rotate(angle, Vector3::zAxis())`, see subclasses for more + * information. + * @see @ref rotateZLocal() + */ + AbstractBasicTranslationRotation3D& rotateZ(Math::Rad angle) { + doRotateZ(angle); + return *this; + } + + /** + * @brief Rotate object around Z axis as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. In some implementations faster than calling + * `rotateLocal(angle, Vector3::zAxis())`, see subclasses for more * information. */ - AbstractBasicTranslationRotation3D& rotateZ(Math::Rad angle, TransformationType type = TransformationType::Global) { - doRotateZ(angle, type); + AbstractBasicTranslationRotation3D& rotateZLocal(Math::Rad angle) { + doRotateZLocal(angle); return *this; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotateZ() + * @deprecated Use @ref Magnum::SceneGraph::AbstractTranslationRotation3D::rotateZ() "rotateZ()" + * or @ref Magnum::SceneGraph::AbstractTranslationRotation3D::rotateZLocal() "rotateZLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotateZ() or rotateZLocal() instead") AbstractBasicTranslationRotation3D& rotateZ(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotateZ(angle) : rotateZLocal(); + } + #endif + /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT AbstractBasicTranslationRotation3D& resetTransformation() { AbstractTransformation<3, T>::resetTransformation(); return *this; } + AbstractBasicTranslationRotation3D& translate(const Math::Vector3& vector) { + AbstractBasicTranslation3D::translate(vector); + return *this; + } + AbstractBasicTranslationRotation3D& translateLocal(const Math::Vector3& vector) { + AbstractBasicTranslation3D::translateLocal(vector); + return *this; + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use translate() or translateLocal() instead") AbstractBasicTranslationRotation3D& translate(const Math::Vector2& vector, TransformationType type) { + AbstractBasicTranslation3D::translate(vector, type); + return *this; + } + #endif #endif protected: @@ -124,7 +237,10 @@ template class AbstractBasicTranslationRotation3D: public AbstractTrans private: #endif /** @brief Polymorphic implementation for @ref rotate() */ - virtual void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type) = 0; + virtual void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis) = 0; + + /** @brief Polymorphic implementation for @ref rotateLocal() */ + virtual void doRotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) = 0; /** * @brief Polymorphic implementation for @ref rotateX() @@ -132,8 +248,18 @@ template class AbstractBasicTranslationRotation3D: public AbstractTrans * Default implementation calls @ref rotate() with * @ref Math::Vector3::xAxis(). */ - virtual void doRotateX(Math::Rad angle, TransformationType type) { - rotate(angle, Math::Vector3::xAxis(), type); + virtual void doRotateX(Math::Rad angle) { + rotate(angle, Math::Vector3::xAxis()); + } + + /** + * @brief Polymorphic implementation for @ref rotateXLocal() + * + * Default implementation calls @ref rotateLocal() with + * @ref Math::Vector3::xAxis(). + */ + virtual void doRotateXLocal(Math::Rad angle) { + rotateLocal(angle, Math::Vector3::xAxis()); } /** @@ -142,8 +268,18 @@ template class AbstractBasicTranslationRotation3D: public AbstractTrans * Default implementation calls @ref rotate() with * @ref Math::Vector3::yAxis(). */ - virtual void doRotateY(Math::Rad angle, TransformationType type) { - rotate(angle, Math::Vector3::yAxis(), type); + virtual void doRotateY(Math::Rad angle) { + rotate(angle, Math::Vector3::yAxis()); + } + + /** + * @brief Polymorphic implementation for @ref rotateYLocal() + * + * Default implementation calls @ref rotateLocal() with + * @ref Math::Vector3::yAxis(). + */ + virtual void doRotateYLocal(Math::Rad angle) { + rotateLocal(angle, Math::Vector3::yAxis()); } /** @@ -152,8 +288,18 @@ template class AbstractBasicTranslationRotation3D: public AbstractTrans * Default implementation calls @ref rotate() with * @ref Math::Vector3::zAxis(). */ - virtual void doRotateZ(Math::Rad angle, TransformationType type) { - rotate(angle, Math::Vector3::zAxis(), type); + virtual void doRotateZ(Math::Rad angle) { + rotate(angle, Math::Vector3::zAxis()); + } + + /** + * @brief Polymorphic implementation for @ref rotateZLocal() + * + * Default implementation calls @ref rotateLocal() with + * @ref Math::Vector3::zAxis(). + */ + virtual void doRotateZLocal(Math::Rad angle) { + rotateLocal(angle, Math::Vector3::zAxis()); } }; diff --git a/src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h b/src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h index fca6283ae..b5ae8f47a 100644 --- a/src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h +++ b/src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,9 @@ namespace Magnum { namespace SceneGraph { /** @brief Base transformation for two-dimensional scenes supporting translation, rotation and scaling -@see @ref AbstractTranslationRotationScaling2D, @ref scenegraph, +See @ref scenegraph-features-transformation for more information. + +@see @ref scenegraph, @ref AbstractTranslationRotationScaling2D, @ref AbstractBasicTranslationRotationScaling2D, @ref BasicMatrixTransformation2D */ @@ -46,32 +48,74 @@ template class AbstractBasicTranslationRotationScaling2D: public Abstra /** * @brief Scale object - * @param vector Scaling vector - * @param type Transformation type * @return Reference to self (for method chaining) * - * @see @ref Math::Vector2::xScale(), @ref Math::Vector2::yScale() + * @see @ref scaleLocal(), @ref Math::Vector2::xScale(), + * @ref Math::Vector2::yScale() + */ + AbstractBasicTranslationRotationScaling2D& scale(const Math::Vector2& vector) { + doScale(vector); + return *this; + } + + /** + * @brief Scale object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. */ - AbstractBasicTranslationRotationScaling2D& scale(const Math::Vector2& vector, TransformationType type = TransformationType::Global) { - doScale(vector, type); + AbstractBasicTranslationRotationScaling2D& scaleLocal(const Math::Vector2& vector) { + doScaleLocal(vector); return *this; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief scale() + * @deprecated Use @ref Magnum::SceneGraph::AbstractTranslationRotationScaling2D::scale() "scale()" + * or @ref Magnum::SceneGraph::AbstractTranslationRotationScaling2D::scaleLocal() "scaleLocal()" + * instead. + */ + CORRADE_DEPRECATED("use scale() or scaleLocal() instead") AbstractBasicTranslationRotationScaling2D& scale(const Math::Vector2& vector, TransformationType type) { + return type == TransformationType::Global ? scale(vector) : scaleLocal(vector); + } + #endif + /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT AbstractBasicTranslationRotationScaling2D& resetTransformation() { AbstractBasicTranslationRotation2D::resetTransformation(); return *this; } - AbstractBasicTranslationRotationScaling2D& translate(const Math::Vector2& vector, TransformationType type = TransformationType::Global) { + AbstractBasicTranslationRotationScaling2D& translate(const Math::Vector2& vector) { + AbstractBasicTranslationRotation2D::translate(vector); + return *this; + } + AbstractBasicTranslationRotationScaling2D& translateLocal(const Math::Vector2& vector) { + AbstractBasicTranslationRotation2D::translateLocal(vector); + return *this; + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use translate() or translateLocal() instead") AbstractBasicTranslationRotationScaling2D& translate(const Math::Vector2& vector, TransformationType type) { AbstractBasicTranslationRotation2D::translate(vector, type); return *this; } - AbstractBasicTranslationRotationScaling2D& rotate(Math::Rad angle, TransformationType type = TransformationType::Global) { + #endif + AbstractBasicTranslationRotationScaling2D& rotate(Math::Rad angle) { + AbstractBasicTranslationRotation2D::rotate(angle); + return *this; + } + AbstractBasicTranslationRotationScaling2D& rotateLocal(Math::Rad angle) { + AbstractBasicTranslationRotation2D::rotateLocal(angle); + return *this; + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use rotate() or rotateLocal() instead") AbstractBasicTranslationRotationScaling2D& rotate(Math::Rad angle, TransformationType type) { AbstractBasicTranslationRotation2D::rotate(angle, type); return *this; } #endif + #endif protected: ~AbstractBasicTranslationRotationScaling2D(); @@ -82,7 +126,10 @@ template class AbstractBasicTranslationRotationScaling2D: public Abstra private: #endif /** @brief Polymorphic implementation for @ref scale() */ - virtual void doScale(const Math::Vector2& vector, TransformationType type) = 0; + virtual void doScale(const Math::Vector2& vector) = 0; + + /** @brief Polymorphic implementation for @ref scaleLocal() */ + virtual void doScaleLocal(const Math::Vector2& vector) = 0; }; template inline AbstractBasicTranslationRotationScaling2D::AbstractBasicTranslationRotationScaling2D() = default; diff --git a/src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h b/src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h index 05691ecb0..0339055ac 100644 --- a/src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h +++ b/src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,9 @@ namespace Magnum { namespace SceneGraph { /** @brief Base transformation for three-dimensional scenes supporting translation, rotation and scaling -@see @ref AbstractTranslationRotationScaling3D, @ref scenegraph, +See @ref scenegraph-features-transformation for more information. + +@see @ref scenegraph, @ref AbstractTranslationRotationScaling3D, @ref AbstractBasicTranslationRotationScaling2D, @ref BasicMatrixTransformation3D */ @@ -46,45 +48,116 @@ template class AbstractBasicTranslationRotationScaling3D: public Abstra /** * @brief Scale object - * @param vector Scaling vector - * @param type Transformation type * @return Reference to self (for method chaining) * - * @see @ref Math::Vector3::xScale(), @ref Math::Vector3::yScale(), - * @ref Math::Vector3::zScale() + * @see @ref scaleLocal(), @ref Math::Vector3::xScale(), + * @ref Math::Vector3::yScale(), @ref Math::Vector3::zScale() + */ + AbstractBasicTranslationRotationScaling3D& scale(const Math::Vector3& vector) { + doScale(vector); + return *this; + } + + /** + * @brief Scale object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. */ - AbstractBasicTranslationRotationScaling3D& scale(const Math::Vector3& vector, TransformationType type = TransformationType::Global) { - doScale(vector, type); + AbstractBasicTranslationRotationScaling3D& scaleLocal(const Math::Vector3& vector) { + doScaleLocal(vector); return *this; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief scale() + * @deprecated Use @ref Magnum::SceneGraph::AbstractTranslationRotationScaling3D::scale() "scale()" + * or @ref Magnum::SceneGraph::AbstractTranslationRotationScaling3D::scaleLocal() "scaleLocal()" + * instead. + */ + CORRADE_DEPRECATED("use scale() or scaleLocal() instead") AbstractBasicTranslationRotationScaling3D& scale(const Math::Vector3& vector, TransformationType type) { + return type == TransformationType::Global ? scale(vector) : scaleLocal(vector); + } + #endif + /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT AbstractBasicTranslationRotationScaling3D& resetTransformation() { AbstractBasicTranslationRotation3D::resetTransformation(); return *this; } - AbstractBasicTranslationRotationScaling3D& translate(const Math::Vector3& vector, TransformationType type = TransformationType::Global) { + AbstractBasicTranslationRotationScaling3D& translate(const Math::Vector3& vector) { + AbstractBasicTranslationRotation3D::translate(vector); + return *this; + } + AbstractBasicTranslationRotationScaling3D& translateLocal(const Math::Vector3& vector) { + AbstractBasicTranslationRotation3D::translateLocal(vector); + return *this; + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use translate() or translateLocal() instead") AbstractBasicTranslationRotationScaling3D& translate(const Math::Vector3& vector, TransformationType type) { AbstractBasicTranslationRotation3D::translate(vector, type); return *this; } - AbstractBasicTranslationRotationScaling3D& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type = TransformationType::Global) { + #endif + AbstractBasicTranslationRotationScaling3D& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { + AbstractBasicTranslationRotation3D::rotate(angle, normalizedAxis); + return *this; + } + AbstractBasicTranslationRotationScaling3D& rotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) { + AbstractBasicTranslationRotation3D::rotateLocal(angle, normalizedAxis); + return *this; + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use rotate() or rotateLocal() instead") AbstractBasicTranslationRotationScaling3D& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type) { AbstractBasicTranslationRotation3D::rotate(angle, normalizedAxis, type); return *this; } - AbstractBasicTranslationRotationScaling3D& rotateX(Math::Rad angle, TransformationType type = TransformationType::Global) { + #endif + AbstractBasicTranslationRotationScaling3D& rotateX(Math::Rad angle) { + AbstractBasicTranslationRotation3D::rotateX(angle); + return *this; + } + AbstractBasicTranslationRotationScaling3D& rotateXLocal(Math::Rad angle) { + AbstractBasicTranslationRotation3D::rotateXLocal(angle); + return *this; + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use rotateX() or rotateXLocal() instead") AbstractBasicTranslationRotationScaling3D& rotateX(Math::Rad angle, TransformationType type) { AbstractBasicTranslationRotation3D::rotateX(angle, type); return *this; } - AbstractBasicTranslationRotationScaling3D& rotateY(Math::Rad angle, TransformationType type = TransformationType::Global) { + #endif + AbstractBasicTranslationRotationScaling3D& rotateY(Math::Rad angle) { + AbstractBasicTranslationRotation3D::rotateY(angle); + return *this; + } + AbstractBasicTranslationRotationScaling3D& rotateYLocal(Math::Rad angle) { + AbstractBasicTranslationRotation3D::rotateYLocal(angle); + return *this; + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use rotateY() or rotateYLocal() instead") AbstractBasicTranslationRotationScaling3D& rotateY(Math::Rad angle, TransformationType type) { AbstractBasicTranslationRotation3D::rotateY(angle, type); return *this; } - AbstractBasicTranslationRotationScaling3D& rotateZ(Math::Rad angle, TransformationType type = TransformationType::Global) { + #endif + AbstractBasicTranslationRotationScaling3D& rotateZ(Math::Rad angle) { + AbstractBasicTranslationRotation3D::rotateZ(angle); + return *this; + } + AbstractBasicTranslationRotationScaling3D& rotateZLocal(Math::Rad angle) { + AbstractBasicTranslationRotation3D::rotateZLocal(angle); + return *this; + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use rotateZ() or rotateZLocal() instead") AbstractBasicTranslationRotationScaling3D& rotateZ(Math::Rad angle, TransformationType type) { AbstractBasicTranslationRotation3D::rotateZ(angle, type); return *this; } #endif + #endif protected: ~AbstractBasicTranslationRotationScaling3D(); @@ -95,7 +168,10 @@ template class AbstractBasicTranslationRotationScaling3D: public Abstra private: #endif /** @brief Polymorphic implementation for @ref scale() */ - virtual void doScale(const Math::Vector3& vector, TransformationType type) = 0; + virtual void doScale(const Math::Vector3& vector) = 0; + + /** @brief Polymorphic implementation for @ref scaleLocal() */ + virtual void doScaleLocal(const Math::Vector3& vector) = 0; }; template inline AbstractBasicTranslationRotationScaling3D::AbstractBasicTranslationRotationScaling3D() = default; diff --git a/src/Magnum/SceneGraph/Animable.cpp b/src/Magnum/SceneGraph/Animable.cpp index c9a55293c..bdf7be945 100644 --- a/src/Magnum/SceneGraph/Animable.cpp +++ b/src/Magnum/SceneGraph/Animable.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/SceneGraph/Animable.h b/src/Magnum/SceneGraph/Animable.h index 74d7f7acf..c0131e792 100644 --- a/src/Magnum/SceneGraph/Animable.h +++ b/src/Magnum/SceneGraph/Animable.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -60,9 +60,9 @@ enum class AnimationState: UnsignedByte { Debug MAGNUM_SCENEGRAPH_EXPORT operator<<(Debug debug, AnimationState value); /** -@brief %Animable +@brief Animable -Adds animation feature to object. Each %Animable is part of some +Adds animation feature to object. Each Animable is part of some @ref AnimableGroup, which takes care of running the animations. ## Usage @@ -78,22 +78,25 @@ typedef SceneGraph::Scene Scene3D; class AnimableObject: public Object3D, SceneGraph::Animable3D { public: - AnimableObject(Object* parent = nullptr, SceneGraph::DrawableGroup3D* group = nullptr): Object3D(parent), SceneGraph::Animable3D(*this, group) { + AnimableObject(Object3D* parent = nullptr, SceneGraph::DrawableGroup3D* group = nullptr): Object3D{parent}, SceneGraph::Animable3D{*this, group} { setDuration(10.0f); // ... } + private: void animationStep(Float time, Float delta) override { rotateX(15.0_degf*delta); // rotate at 15 degrees per second } } @endcode -Then add the object to your scene and some animation group. You can also use -@ref AnimableGroup::add() and @ref AnimableGroup::remove() instead of passing -the group in the constructor. The animation is initially in stopped state and -without repeat, see @ref setState(), @ref setRepeated() and -@ref setRepeatCount() for more information. +Similarly to @ref Drawable feature, there is no way to just animate all the +objects in the scene. You need to create animable group and use it to control +given set of animations. You can also use @ref AnimableGroup::add() and +@ref AnimableGroup::remove() instead of passing the group in the constructor. +The animation is initially in stopped state and without repeat, see +@ref setState(), @ref setRepeated() and @ref setRepeatCount() for more +information. @code Scene3D scene; SceneGraph::AnimableGroup3D animables; @@ -120,20 +123,20 @@ void MyApplication::drawEvent() { } @endcode -## Using animable groups to improve performance +## Using multiple animable groups to improve performance @ref AnimableGroup is optimized for case when no animation is running -- it just puts itself to rest and waits until some animation changes its state to @ref AnimationState::Running again. If you put animations which are not -pernamently running to separate group, they will not be always traversed when -calling @ref AnimableGroup::step(), saving precious frame time. +pernamently running into separate group, they will not be traversed every time +the @ref AnimableGroup::step() gets called, saving precious frame time. ## Explicit template specializations The following specializations are explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type) you have to -use @ref Animable.hpp implementation file to avoid linker errors. See also -@ref compilation-speedup-hpp for more information. +library. For other specializations (e.g. using @ref Magnum::Double "Double" +type) you have to use @ref Animable.hpp implementation file to avoid linker +errors. See also @ref compilation-speedup-hpp for more information. - @ref Animable2D, @ref AnimableGroup2D - @ref Animable3D, @ref AnimableGroup3D @@ -142,12 +145,12 @@ use @ref Animable.hpp implementation file to avoid linker errors. See also @ref Animable2D, @ref Animable3D, @ref AnimableGroup */ template class Animable: public AbstractGroupedFeature, T> { - friend class AnimableGroup; + friend AnimableGroup; public: /** * @brief Constructor - * @param object %Object this animable belongs to + * @param object Object this animable belongs to * @param group Group this animable belongs to * * Creates stopped non-repeating animation with infinite duration, @@ -225,22 +228,6 @@ template class Animable: public AbstractGrouped AnimableGroup* animables(); const AnimableGroup* animables() const; /**< @overload */ - #ifdef MAGNUM_BUILD_DEPRECATED - /** - * @copydoc animables() - * @deprecated Use @ref Magnum::SceneGraph::Animable::animables() "animables()" - * instead. - */ - CORRADE_DEPRECATED("use animables() instead") AnimableGroup* group() { return animables(); } - - /** - * @copydoc animables() - * @deprecated Use @ref Magnum::SceneGraph::Animable::animables() "animables()" - * instead. - */ - CORRADE_DEPRECATED("use animables() instead") const AnimableGroup* group() const { return animables(); } - #endif - protected: /** * @brief Set animation duration @@ -338,9 +325,9 @@ template class Animable: public AbstractGrouped #ifndef CORRADE_GCC46_COMPATIBILITY /** -@brief %Animable for two-dimensional scenes +@brief Animable for two-dimensional scenes -Convenience alternative to %Animable<2, T>. See @ref Animable for more +Convenience alternative to `Animable<2, T>`. See @ref Animable for more information. @note Not available on GCC < 4.7. Use %Animable<2, T> instead. @see @ref Animable2D, @ref BasicAnimable3D @@ -351,7 +338,7 @@ template using BasicAnimable2D = Animable<2, T>; #endif /** -@brief %Animable for two-dimensional float scenes +@brief Animable for two-dimensional float scenes @see @ref Animable3D */ @@ -365,9 +352,9 @@ typedef Animable<2, Float> Animable2D; #ifndef CORRADE_GCC46_COMPATIBILITY /** -@brief %Animable for three-dimensional scenes +@brief Animable for three-dimensional scenes -Convenience alternative to %Animable<3, T>. See @ref Animable for more +Convenience alternative to `Animable<3, T>`. See @ref Animable for more information. @note Not available on GCC < 4.7. Use %Animable<3, T> instead. @see @ref Animable3D, @ref BasicAnimable2D @@ -378,7 +365,7 @@ template using BasicAnimable3D = Animable<3, T>; #endif /** -@brief %Animable for three-dimensional float scenes +@brief Animable for three-dimensional float scenes @see @ref Animable2D */ diff --git a/src/Magnum/SceneGraph/Animable.hpp b/src/Magnum/SceneGraph/Animable.hpp index e23bb40cf..f714d32a6 100644 --- a/src/Magnum/SceneGraph/Animable.hpp +++ b/src/Magnum/SceneGraph/Animable.hpp @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,12 +30,13 @@ */ #include "Magnum/Timeline.h" +#include "Magnum/Math/Constants.h" #include "Magnum/SceneGraph/AnimableGroup.h" #include "Magnum/SceneGraph/Animable.h" namespace Magnum { namespace SceneGraph { -template Animable::Animable(AbstractObject& object, AnimableGroup* group): AbstractGroupedFeature, T>(object, group), _duration(0.0f), startTime(std::numeric_limits::infinity()), pauseTime(-std::numeric_limits::infinity()), previousState(AnimationState::Stopped), currentState(AnimationState::Stopped), _repeated(false), _repeatCount(0), repeats(0) {} +template Animable::Animable(AbstractObject& object, AnimableGroup* group): AbstractGroupedFeature, T>(object, group), _duration(0.0f), startTime(Constants::inf()), pauseTime(-Constants::inf()), previousState(AnimationState::Stopped), currentState(AnimationState::Stopped), _repeated(false), _repeatCount(0), repeats(0) {} template Animable::~Animable() {} diff --git a/src/Magnum/SceneGraph/AnimableGroup.h b/src/Magnum/SceneGraph/AnimableGroup.h index 47d7b8663..084f5b4b8 100644 --- a/src/Magnum/SceneGraph/AnimableGroup.h +++ b/src/Magnum/SceneGraph/AnimableGroup.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -42,7 +42,7 @@ See @ref Animable for more information. @ref AnimableGroup2D, @ref AnimableGroup3D */ template class AnimableGroup: public FeatureGroup, T> { - friend class Animable; + friend Animable; public: /** @@ -74,9 +74,9 @@ template class AnimableGroup: public FeatureGro #ifndef CORRADE_GCC46_COMPATIBILITY /** -@brief %Animable group for two-dimensional scenes +@brief Animable group for two-dimensional scenes -Convenience alternative to %AnimableGroup<2, T>. See Animable for +Convenience alternative to `AnimableGroup<2, T>`. See Animable for more information. @note Not available on GCC < 4.7. Use %AnimableGroup<2, T> instead. @see @ref AnimableGroup2D, @ref BasicAnimableGroup3D @@ -87,7 +87,7 @@ template using BasicAnimableGroup2D = AnimableGroup<2, T>; #endif /** -@brief %Animable group for two-dimensional float scenes +@brief Animable group for two-dimensional float scenes @see @ref AnimableGroup3D */ @@ -101,9 +101,9 @@ typedef AnimableGroup<2, Float> AnimableGroup2D; #ifndef CORRADE_GCC46_COMPATIBILITY /** -@brief %Animable group for three-dimensional scenes +@brief Animable group for three-dimensional scenes -Convenience alternative to %AnimableGroup<3, T>. See Animable for +Convenience alternative to `AnimableGroup<3, T>`. See Animable for more information. @note Not available on GCC < 4.7. Use %AnimableGroup<3, T> instead. @see @ref AnimableGroup3D, @ref BasicAnimableGroup2D @@ -114,7 +114,7 @@ template using BasicAnimableGroup3D = AnimableGroup<3, T>; #endif /** -@brief %Animable group for three-dimensional float scenes +@brief Animable group for three-dimensional float scenes @see @ref AnimableGroup2D */ diff --git a/src/Magnum/SceneGraph/CMakeLists.txt b/src/Magnum/SceneGraph/CMakeLists.txt index 3ec9ca2e2..db9ec6027 100644 --- a/src/Magnum/SceneGraph/CMakeLists.txt +++ b/src/Magnum/SceneGraph/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -69,23 +69,26 @@ set(MagnumSceneGraph_HEADERS visibility.h) -# Set shared library flags for the objects, as they will be part of shared lib -# TODO: fix when CMake sets target_EXPORTS for OBJECT targets as well +# Objects shared between main and test library add_library(MagnumSceneGraphObjects OBJECT ${MagnumSceneGraph_SRCS} ${MagnumSceneGraph_HEADERS}) -if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumSceneGraphObjects PROPERTIES COMPILE_FLAGS "-DMagnumSceneGraphObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") -else() +if(NOT BUILD_STATIC) set_target_properties(MagnumSceneGraphObjects PROPERTIES COMPILE_FLAGS "-DMagnumSceneGraphObjects_EXPORTS") endif() +if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) + set_target_properties(MagnumSceneGraphObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() -# SceneGraph library +# Main SceneGraph library add_library(MagnumSceneGraph ${SHARED_OR_STATIC} $ ${MagnumSceneGraph_GracefulAssert_SRCS}) set_target_properties(MagnumSceneGraph PROPERTIES DEBUG_POSTFIX "-d") +if(BUILD_STATIC_PIC) + set_target_properties(MagnumSceneGraph PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() + target_link_libraries(MagnumSceneGraph Magnum) install(TARGETS MagnumSceneGraph @@ -106,7 +109,7 @@ if(BUILD_TESTS) # On Windows we need to install first and then run the tests to avoid "DLL # not found" hell, thus we need to install this too - if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING) + if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING AND NOT BUILD_STATIC) install(TARGETS MagnumSceneGraphTestLib RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} diff --git a/src/Magnum/SceneGraph/Camera2D.h b/src/Magnum/SceneGraph/Camera2D.h index 9ff2466ec..b9daa89af 100644 --- a/src/Magnum/SceneGraph/Camera2D.h +++ b/src/Magnum/SceneGraph/Camera2D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,11 +36,11 @@ namespace Magnum { namespace SceneGraph { /** @brief Camera for two-dimensional scenes -See Drawable documentation for introduction. The camera by default displays -OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` and doesn't do any aspect ratio -correction. Common setup example: +See @ref Drawable documentation for complete introduction. The camera by +default displays OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` and doesn't do +any aspect ratio correction. Common setup example: @code -SceneGraph::Camera2D camera(&cameraObject); +SceneGraph::Camera2D camera{&cameraObject}; camera.setProjection({4.0f/3.0f, 1.0f}) .setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend); @endcode @@ -49,9 +49,9 @@ camera.setProjection({4.0f/3.0f, 1.0f}) ## Explicit template specializations The following specialization is explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type) you have to -use @ref Camera2D.hpp implementation file to avoid linker errors. See also -relevant section in @ref SceneGraph-AbstractCamera-explicit-specializations "AbstractCamera" +library. For other specializations (e.g. using @ref Magnum::Double "Double" +type) you have to use @ref Camera2D.hpp implementation file to avoid linker +errors. See also relevant section in @ref SceneGraph-AbstractCamera-explicit-specializations "AbstractCamera" class documentation or @ref compilation-speedup-hpp for more information. - @ref Camera2D @@ -63,7 +63,7 @@ template class BasicCamera2D: public AbstractCamera<2, T> { public: /** * @brief Constructor - * @param object %Object holding this feature + * @param object Object holding this feature * * Sets orthographic projection to the default OpenGL cube (range @f$ [-1; 1] @f$ in all directions). * @see @ref setProjection() diff --git a/src/Magnum/SceneGraph/Camera2D.hpp b/src/Magnum/SceneGraph/Camera2D.hpp index c399c0964..c8efabbc8 100644 --- a/src/Magnum/SceneGraph/Camera2D.hpp +++ b/src/Magnum/SceneGraph/Camera2D.hpp @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/SceneGraph/Camera3D.h b/src/Magnum/SceneGraph/Camera3D.h index 5990b68fc..202c33ec3 100644 --- a/src/Magnum/SceneGraph/Camera3D.h +++ b/src/Magnum/SceneGraph/Camera3D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -41,12 +41,12 @@ namespace Magnum { namespace SceneGraph { /** @brief Camera for three-dimensional scenes -See Drawable documentation for introduction. The camera by default displays -OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` with orthographic projection and -doesn't do any aspect ratio correction. Common setup example: +See @ref Drawable documentation for complete introduction. The camera by +default displays OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` with orthographic +projection and doesn't do any aspect ratio correction. Common setup example: @code -SceneGraph::Camera3D camera(&cameraObject); -camera.setPerspective({}, 0.001f, 100.0f) +SceneGraph::Camera3D camera{&cameraObject}; +camera.setPerspective(35.0_degf, 1.0f, 0.001f, 100.0f) .setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend); @endcode @@ -54,9 +54,9 @@ camera.setPerspective({}, 0.001f, 100.0f) ## Explicit template specializations The following specialization is explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type) you have to -use @ref Camera3D.hpp implementation file to avoid linker errors. See also -relevant section in @ref SceneGraph-AbstractCamera-explicit-specializations "AbstractCamera" +library. For other specializations (e.g. using @ref Magnum::Double "Double" +type) you have to use @ref Camera3D.hpp implementation file to avoid linker +errors. See also relevant section in @ref SceneGraph-AbstractCamera-explicit-specializations "AbstractCamera" class documentation or @ref compilation-speedup-hpp for more information. - @ref Camera3D @@ -68,7 +68,7 @@ template class BasicCamera3D: public AbstractCamera<3, T> { public: /** * @brief Constructor - * @param object %Object holding this feature + * @param object Object holding this feature */ explicit BasicCamera3D(AbstractObject<3, T>& object); diff --git a/src/Magnum/SceneGraph/Camera3D.hpp b/src/Magnum/SceneGraph/Camera3D.hpp index d4a385104..7c0e760aa 100644 --- a/src/Magnum/SceneGraph/Camera3D.hpp +++ b/src/Magnum/SceneGraph/Camera3D.hpp @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/SceneGraph/Drawable.h b/src/Magnum/SceneGraph/Drawable.h index 599a02f47..7ba70aac4 100644 --- a/src/Magnum/SceneGraph/Drawable.h +++ b/src/Magnum/SceneGraph/Drawable.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,64 +34,96 @@ namespace Magnum { namespace SceneGraph { /** -@brief %Drawable +@brief Drawable -Adds drawing function to the object. Each %Drawable is part of some -@ref DrawableGroup and the whole group is drawn with particular camera using -@ref AbstractCamera::draw(). +Adds drawing functionality to the object. Each Drawable is part of some +@ref DrawableGroup and the whole group can be drawn with particular camera +using @ref AbstractCamera::draw(). ## Usage First thing is to add @ref Drawable feature to some object and implement -@ref draw(). You can do it conveniently using multiple inheritance (see -@ref scenegraph-features for introduction). Example: +@ref draw() function. You can do it conveniently using multiple inheritance +(see @ref scenegraph-features for introduction). Example drawable object that +draws blue sphere: @code typedef SceneGraph::Object Object3D; typedef SceneGraph::Scene Scene3D; -class DrawableObject: public Object3D, SceneGraph::Drawable3D { +class RedCube: public Object3D, public SceneGraph::Drawable3D { public: - DrawableObject(Object* parent = nullptr, SceneGraph::DrawableGroup3D* group = nullptr): Object3D(parent), SceneGraph::Drawable3D(*this, group) { - // ... + explicit RedCube(Object3D* parent, SceneGraph::DrawableGroup3D* group): Object3D{parent}, SceneGraph::Drawable3D{*this, group} { + std::tie(_mesh, _vertices, _indices) = MeshTools::compile(Primitives::UVSphere::solid(16, 32), BufferUsage::StaticDraw); } + private: void draw(const Matrix4& transformationMatrix, AbstractCamera3D& camera) override { - // ... + _shader.setDiffuseColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) + .setLightPosition(camera.cameraMatrix().transformPoint({5.0f, 5.0f, 7.0f})) + .setTransformationMatrix(transformationMatrix) + .setNormalMatrix(transformationMatrix.rotation()) + .setProjectionMatrix(camera.projectionMatrix()); + _mesh.draw(_shader); } + + Mesh _mesh; + std::unique_ptr _vertices, _indices; + Shaders::Phong _shader; } @endcode -Then you add these objects to your scene and some drawable group and transform -them as you like. You can also use @ref DrawableGroup::add() and -@ref DrawableGroup::remove(). +The @p transformationMatrix parameter in @ref draw() function contains +transformation of the object (to which the drawable is attached) relative to +@p camera. The camera contains projection matrix. Some shaders (like the +@ref Shaders::Phong used in the example) have separate functions for setting +transformation and projection matrix, but some (such as @ref Shaders::Flat) +have single function to set composite transformation and projection matrix. In +that case you need to combine the two matrices manually like in the following +code. Some shaders have additional requirements for various transformation +matrices, see their respective documentation for details. +@code +Shaders::Flat3D shader; +shader.setTransformationProjectionMatrix(camera.projectionMatrix()*transformationMatrix); +@endcode + +There is no way to just draw all the drawables in the scene, you need to create +some drawable group and add the drawable objects to both the scene and the +group. You can also use @ref DrawableGroup::add() and +@ref DrawableGroup::remove() instead of passing the group in the constructor. @code Scene3D scene; SceneGraph::DrawableGroup3D drawables; -(new DrawableObject(&scene, &drawables)) +(new RedCube(&scene, &drawables)) ->translate(Vector3::yAxis(-0.3f)) .rotateX(30.0_degf); -(new AnotherDrawableObject(&scene, &drawables)) - ->translate(Vector3::zAxis(0.5f)); + // ... @endcode The last thing you need is camera attached to some object (thus using its -transformation) and with it you can perform drawing in your draw event +transformation). Using the camera and the drawable group you can perform +drawing in your @ref Platform::Sdl2Application::drawEvent() "drawEvent()" implementation. See @ref Camera2D and @ref Camera3D documentation for more information. @code -Camera3D camera(&cameraObject); +auto cameraObject = new Object3D(&scene); +cameraObject->translate(Vector3::zAxis(5.0f)); +auto camera = new SceneGraph::Camera3D(&cameraObject); +camera->setPerspective(35.0_degf, 1.0f, 0.001f, 100.0f); + +// ... void MyApplication::drawEvent() { - camera.draw(drawables); + camera->draw(drawables); - swapBuffers(); // ... + + swapBuffers(); } @endcode -## Using drawable groups to improve performance +## Using multiple drawable groups to improve performance You can organize your drawables to multiple groups to minimize OpenGL state changes -- for example put all objects using the same shader, the same light @@ -104,13 +136,19 @@ SceneGraph::DrawableGroup3D phongObjects, transparentObjects; void MyApplication::drawEvent() { shader.setProjectionMatrix(camera->projectionMatrix()) - .setLightPosition(lightPosition) + .setLightPosition(lightPositionRelativeToCamera) .setLightColor(lightColor) .setAmbientColor(ambientColor); + + // Each drawable sets only unique properties such as transformation matrix + // and diffuse color camera.draw(phongObjects); Renderer::enable(Renderer::Feature::Blending); + + // Also here camera.draw(transparentObjects); + Renderer::disable(Renderer::Feature::Blending); // ... @@ -120,9 +158,9 @@ void MyApplication::drawEvent() { ## Explicit template specializations The following specializations are explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type) you have to -use @ref Drawable.hpp implementation file to avoid linker errors. See also -@ref compilation-speedup-hpp for more information. +library. For other specializations (e.g. using @ref Magnum::Double "Double" +type) you have to use @ref Drawable.hpp implementation file to avoid linker +errors. See also @ref compilation-speedup-hpp for more information. - @ref Drawable2D - @ref Drawable3D @@ -134,7 +172,7 @@ template class Drawable: public AbstractGrouped public: /** * @brief Constructor - * @param object %Object this drawable belongs to + * @param object Object this drawable belongs to * @param drawables Group this drawable belongs to * * Adds the feature to the object and also to the group, if specified. @@ -166,9 +204,8 @@ template class Drawable: public AbstractGrouped /** * @brief Draw the object using given camera - * @param transformationMatrix %Object transformation relative - * to camera - * @param camera Camera + * @param transformationMatrix Object transformation relative to camera + * @param camera Camera * * Projection matrix can be retrieved from * @ref SceneGraph::AbstractCamera::projectionMatrix() "AbstractCamera::projectionMatrix()". @@ -178,9 +215,9 @@ template class Drawable: public AbstractGrouped #ifndef CORRADE_GCC46_COMPATIBILITY /** -@brief %Drawable for two-dimensional scenes +@brief Drawable for two-dimensional scenes -Convenience alternative to %Drawable<2, T>. See @ref Drawable for more +Convenience alternative to `Drawable<2, T>`. See @ref Drawable for more information. @note Not available on GCC < 4.7. Use %Drawable<2, T> instead. @see @ref Drawable2D, @ref BasicDrawable3D @@ -191,7 +228,7 @@ template using BasicDrawable2D = Drawable<2, T>; #endif /** -@brief %Drawable for two-dimensional float scenes +@brief Drawable for two-dimensional float scenes @see @ref Drawable3D */ @@ -203,9 +240,9 @@ typedef Drawable<2, Float> Drawable2D; #ifndef CORRADE_GCC46_COMPATIBILITY /** -@brief %Drawable for three-dimensional scenes +@brief Drawable for three-dimensional scenes -Convenience alternative to %Drawable<3, T>. See @ref Drawable for more +Convenience alternative to `Drawable<3, T>`. See @ref Drawable for more information. @note Not available on GCC < 4.7. Use %Drawable<3, T> instead. @see @ref Drawable3D, @ref BasicDrawable3D @@ -216,7 +253,7 @@ template using BasicDrawable3D = Drawable<3, T>; #endif /** -@brief %Drawable for three-dimensional float scenes +@brief Drawable for three-dimensional float scenes @see @ref Drawable2D */ @@ -245,7 +282,7 @@ template class DrawableGroup: public FeatureGro /** @brief Group of drawables for two-dimensional scenes -Convenience alternative to %DrawableGroup<2, T>. See @ref Drawable for +Convenience alternative to `DrawableGroup<2, T>`. See @ref Drawable for more information. @note Not available on GCC < 4.7. Use %DrawableGroup<2, T> instead. @see @ref DrawableGroup2D, @ref BasicDrawableGroup3D @@ -270,7 +307,7 @@ typedef DrawableGroup<2, Float> DrawableGroup2D; /** @brief Group of drawables for three-dimensional scenes -Convenience alternative to %DrawableGroup<3, T>. See @ref Drawable for +Convenience alternative to `DrawableGroup<3, T>`. See @ref Drawable for more information. @note Not available on GCC < 4.7. Use %DrawableGroup<3, T> instead. @see @ref DrawableGroup3D, @ref BasicDrawableGroup2D diff --git a/src/Magnum/SceneGraph/Drawable.hpp b/src/Magnum/SceneGraph/Drawable.hpp index 658af6cb6..1800c80c5 100644 --- a/src/Magnum/SceneGraph/Drawable.hpp +++ b/src/Magnum/SceneGraph/Drawable.hpp @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/SceneGraph/DualComplexTransformation.h b/src/Magnum/SceneGraph/DualComplexTransformation.h index 6610a8f0a..177286c6c 100644 --- a/src/Magnum/SceneGraph/DualComplexTransformation.h +++ b/src/Magnum/SceneGraph/DualComplexTransformation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,7 +40,7 @@ namespace Magnum { namespace SceneGraph { This class allows only rigid transformation (i.e. only rotation and translation). Uses @ref Math::DualComplex as underlying transformation type. -@see @ref DualComplexTransformation, @ref scenegraph, +@see @ref scenegraph, @ref DualComplexTransformation, @ref BasicDualQuaternionTransformation */ template class BasicDualComplexTransformation: public AbstractBasicTranslationRotation2D { @@ -48,7 +48,7 @@ template class BasicDualComplexTransformation: public AbstractBasicTran /** @brief Underlying transformation type */ typedef Math::DualComplex DataType; - /** @brief %Object transformation */ + /** @brief Object transformation */ Math::DualComplex transformation() const { return _transformation; } /** @@ -84,41 +84,112 @@ template class BasicDualComplexTransformation: public AbstractBasicTran /** * @brief Transform object - * @param transformation Transformation - * @param type Transformation type * @return Reference to self (for method chaining) * * Expects that the dual complex number is normalized. - * @see @ref Math::DualComplex::isNormalized() + * @see @ref transformLocal(), @ref Math::DualComplex::isNormalized() */ - Object>& transform(const Math::DualComplex& transformation, TransformationType type = TransformationType::Global) { + Object>& transform(const Math::DualComplex& transformation) { CORRADE_ASSERT(transformation.isNormalized(), "SceneGraph::DualComplexTransformation::transform(): the dual complex number is not normalized", static_cast>&>(*this)); - return transformInternal(transformation, type); + return transformInternal(transformation); + } + + /** + * @brief Transform object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& transformLocal(const Math::DualComplex& transformation) { + CORRADE_ASSERT(transformation.isNormalized(), + "SceneGraph::DualComplexTransformation::transformLocal(): the dual complex number is not normalized", + static_cast>&>(*this)); + return transformLocalInternal(transformation); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief transform() + * @deprecated Use @ref Magnum::SceneGraph::DualComplexTransformation::transform() "transform()" + * or @ref Magnum::SceneGraph::DualComplexTransformation::transformLocal() "transformLocal()" + * instead. + */ + CORRADE_DEPRECATED("use transform() or transformLocal() instead") Object>& transform(const Math::DualComplex& transformation, TransformationType type) { + return type == TransformationType::Global ? transform(transformation) : transformLocal(transformation); } + #endif /** - * @copydoc AbstractTranslationRotationScaling2D::translate() + * @brief Translate object + * @return Reference to self (for method chaining) + * * Same as calling @ref transform() with @ref Math::DualComplex::translation(). + * @see @ref translateLocal(), @ref Math::Vector2::xAxis(), + * @ref Math::Vector2::yAxis() */ - Object>& translate(const Math::Vector2& vector, TransformationType type = TransformationType::Global) { - return transformInternal(Math::DualComplex::translation(vector), type); + Object>& translate(const Math::Vector2& vector) { + return transformInternal(Math::DualComplex::translation(vector)); } + /** + * @brief Translate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::DualComplex::translation(). + */ + Object>& translateLocal(const Math::Vector2& vector) { + return transformLocalInternal(Math::DualComplex::translation(vector)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief translate() + * @deprecated Use @ref Magnum::SceneGraph::DualComplexTransformation::translate() "translate()" + * or @ref Magnum::SceneGraph::DualComplexTransformation::translateLocal() "translateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use translate() or translateLocal() instead") Object>& translate(const Math::Vector2& vector, TransformationType type) { + return type == TransformationType::Global ? translate(vector) : translateLocal(vector); + } + #endif + /** * @brief Rotate object * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::DualComplex::rotation(). - * @see @ref normalizeRotation() + * @see @ref rotateLocal(), @ref normalizeRotation() */ - Object>& rotate(Math::Rad angle, TransformationType type = TransformationType::Global) { - return transformInternal(Math::DualComplex::rotation(angle), type); + Object>& rotate(Math::Rad angle) { + return transformInternal(Math::DualComplex::rotation(angle)); } + /** + * @brief Rotate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& rotateLocal(Math::Rad angle) { + return transformLocalInternal(Math::DualComplex::rotation(angle)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotate() + * @deprecated Use @ref Magnum::SceneGraph::DualComplexTransformation::rotate() "rotate()" + * or @ref Magnum::SceneGraph::DualComplexTransformation::rotateLocal() "rotateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotate() or rotateLocal() instead") Object>& rotate(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotate(angle) : rotateLocal(angle); + } + #endif + protected: /* Allow construction only from Object */ explicit BasicDualComplexTransformation(); @@ -126,14 +197,16 @@ template class BasicDualComplexTransformation: public AbstractBasicTran private: void doResetTransformation() override final { resetTransformation(); } - void doTranslate(const Math::Vector2& vector, TransformationType type) override final { - translate(vector, type); + void doTranslate(const Math::Vector2& vector) override final { + translate(vector); } - - void doRotate(Math::Rad angle, TransformationType type) override final { - rotate(angle, type); + void doTranslateLocal(const Math::Vector2& vector) override final { + translateLocal(vector); } + void doRotate(Math::Rad angle) override final { rotate(angle); } + void doRotateLocal(Math::Rad angle) override final { rotateLocal(angle); } + /* No assertions fired, for internal use */ Object>& setTransformationInternal(const Math::DualComplex& transformation) { /* Setting transformation is forbidden for the scene */ @@ -148,9 +221,11 @@ template class BasicDualComplexTransformation: public AbstractBasicTran } /* No assertions fired, for internal use */ - Object>& transformInternal(const Math::DualComplex& transformation, TransformationType type) { - return setTransformationInternal(type == TransformationType::Global ? - transformation*_transformation : _transformation*transformation); + Object>& transformInternal(const Math::DualComplex& transformation) { + return setTransformationInternal(transformation*_transformation); + } + Object>& transformLocalInternal(const Math::DualComplex& transformation) { + return setTransformationInternal(_transformation*transformation); } Math::DualComplex _transformation; diff --git a/src/Magnum/SceneGraph/DualQuaternionTransformation.h b/src/Magnum/SceneGraph/DualQuaternionTransformation.h index 8c7d907b7..9d8290e75 100644 --- a/src/Magnum/SceneGraph/DualQuaternionTransformation.h +++ b/src/Magnum/SceneGraph/DualQuaternionTransformation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -40,7 +40,7 @@ namespace Magnum { namespace SceneGraph { This class allows only rigid transformation (i.e. only rotation and translation). Uses @ref Math::DualQuaternion as underlying transformation type. -@see @ref DualQuaternionTransformation @ref scenegraph, +@see @ref scenegraph, @ref DualQuaternionTransformation, @ref BasicDualComplexTransformation */ template class BasicDualQuaternionTransformation: public AbstractBasicTranslationRotation3D { @@ -48,7 +48,7 @@ template class BasicDualQuaternionTransformation: public AbstractBasicT /** @brief Underlying transformation type */ typedef Math::DualQuaternion DataType; - /** @brief %Object transformation */ + /** @brief Object transformation */ Math::DualQuaternion transformation() const { return _transformation; } /** @@ -83,56 +83,151 @@ template class BasicDualQuaternionTransformation: public AbstractBasicT } /** - * @brief Multiply transformation - * @param transformation Transformation - * @param type Transformation type + * @brief Transform object * @return Reference to self (for method chaining) * * Expects that the dual quaternion is normalized. - * @see @ref Math::DualQuaternion::isNormalized() + * @see @ref transformLocal(), @ref Math::DualQuaternion::isNormalized() */ - Object>& transform(const Math::DualQuaternion& transformation, TransformationType type = TransformationType::Global) { + Object>& transform(const Math::DualQuaternion& transformation) { CORRADE_ASSERT(transformation.isNormalized(), "SceneGraph::DualQuaternionTransformation::transform(): the dual quaternion is not normalized", static_cast>&>(*this)); - return transformInternal(transformation, type); + return transformInternal(transformation); + } + + /** + * @brief Transform object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& transformLocal(const Math::DualQuaternion& transformation) { + CORRADE_ASSERT(transformation.isNormalized(), + "SceneGraph::DualQuaternionTransformation::transformLocal(): the dual quaternion is not normalized", + static_cast>&>(*this)); + return transformLocalInternal(transformation); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief transform() + * @deprecated Use @ref Magnum::SceneGraph::DualQuaternionTransformation::transform() "transform()" + * or @ref Magnum::SceneGraph::DualQuaternionTransformation::transformLocal() "transformLocal()" + * instead. + */ + CORRADE_DEPRECATED("use transform() or transformLocal() instead") Object>& transform(const Math::DualQuaternion& transformation, TransformationType type) { + return type == TransformationType::Global ? transform(transformation) : transformLocal(transformation); } + #endif /** - * @copydoc AbstractTranslationRotationScaling3D::translate() + * @brief Translate object + * @return Reference to self (for method chaining) + * * Same as calling @ref transform() with @ref Math::DualQuaternion::translation(). + * @see @ref translateLocal(), @ref Math::Vector3::xAxis(), + * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() + */ + Object>& translate(const Math::Vector3& vector) { + return transformInternal(Math::DualQuaternion::translation(vector)); + } + + /** + * @brief Translate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. */ - Object>& translate(const Math::Vector3& vector, TransformationType type = TransformationType::Global) { - return transformInternal(Math::DualQuaternion::translation(vector), type); + Object>& translateLocal(const Math::Vector3& vector) { + return transformLocalInternal(Math::DualQuaternion::translation(vector)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief translate() + * @deprecated Use @ref Magnum::SceneGraph::DualQuaternionTransformation::translate() "translate()" + * or @ref Magnum::SceneGraph::DualQuaternionTransformation::translateLocal() "translateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use translate() or translateLocal() instead") Object>& translate(const Math::Vector3& vector, TransformationType type) { + return type == TransformationType::Global ? translate(vector) : translateLocal(vector); + } + #endif + /** * @brief Rotate object * @param angle Angle (counterclockwise) * @param normalizedAxis Normalized rotation axis - * @param type Transformation type * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::DualQuaternion::rotation(). - * @see @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(), - * @ref Math::Vector3::zAxis(), @ref normalizeRotation() + * @see @ref rotateLocal(), @ref Math::Vector3::xAxis(), + * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis(), + * @ref normalizeRotation() + */ + Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { + return transformInternal(Math::DualQuaternion::rotation(angle, normalizedAxis)); + } + + /** + * @brief Rotate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. */ - Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type = TransformationType::Global) { - return transformInternal(Math::DualQuaternion::rotation(angle, normalizedAxis), type); + Object>& rotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) { + return transformLocalInternal(Math::DualQuaternion::rotation(angle, normalizedAxis)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotate() + * @deprecated Use @ref Magnum::SceneGraph::DualQuaternionTransformation::rotate() "rotate()" + * or @ref Magnum::SceneGraph::DualQuaternionTransformation::rotateLocal() "rotateLocal()" + * instead. + */ + CORRADE_DEPRECATED("usr rotate() or rotateLocal() instead") Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type) { + return type == TransformationType::Global ? rotate(angle, normalizedAxis) : rotateLocal(angle, normalizedAxis); + } + #endif + /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT - Object>& rotateX(Math::Rad angle, TransformationType type = TransformationType::Global) { + Object>& rotateX(Math::Rad angle) { + return rotate(angle, Math::Vector3::xAxis()); + } + Object>& rotateXLocal(Math::Rad angle) { + return rotateLocal(angle, Math::Vector3::xAxis()); + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use rotateX() or rotateXLocal() instead") Object>& rotateX(Math::Rad angle, TransformationType type) { return rotate(angle, Math::Vector3::xAxis(), type); } - Object>& rotateY(Math::Rad angle, TransformationType type = TransformationType::Global) { + #endif + Object>& rotateY(Math::Rad angle) { + return rotate(angle, Math::Vector3::yAxis()); + } + Object>& rotateYLocal(Math::Rad angle) { + return rotateLocal(angle, Math::Vector3::yAxis()); + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use rotateY() or rotateYLocal() instead") Object>& rotateY(Math::Rad angle, TransformationType type) { return rotate(angle, Math::Vector3::yAxis(), type); } - Object>& rotateZ(Math::Rad angle, TransformationType type = TransformationType::Global) { + #endif + Object>& rotateZ(Math::Rad angle) { + return rotate(angle, Math::Vector3::zAxis()); + } + Object>& rotateZLocal(Math::Rad angle) { + return rotateLocal(angle, Math::Vector3::zAxis()); + } + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_DEPRECATED("use rotateZ() or rotateZLocal() instead") Object>& rotateZ(Math::Rad angle, TransformationType type) { return rotate(angle, Math::Vector3::zAxis(), type); } #endif + #endif protected: /* Allow construction only from Object */ @@ -141,12 +236,18 @@ template class BasicDualQuaternionTransformation: public AbstractBasicT private: void doResetTransformation() override final { resetTransformation(); } - void doTranslate(const Math::Vector3& vector, TransformationType type) override final { - translate(vector, type); + void doTranslate(const Math::Vector3& vector) override final { + translate(vector); + } + void doTranslateLocal(const Math::Vector3& vector) override final { + translateLocal(vector); } - void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type) override final { - rotate(angle, normalizedAxis, type); + void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { + rotate(angle, normalizedAxis); + } + void doRotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { + rotateLocal(angle, normalizedAxis); } /* No assertions fired, for internal use */ @@ -163,9 +264,11 @@ template class BasicDualQuaternionTransformation: public AbstractBasicT } /* No assertions fired, for internal use */ - Object>& transformInternal(const Math::DualQuaternion& transformation, TransformationType type) { - return setTransformationInternal(type == TransformationType::Global ? - transformation*_transformation : _transformation*transformation); + Object>& transformInternal(const Math::DualQuaternion& transformation) { + return setTransformationInternal(transformation*_transformation); + } + Object>& transformLocalInternal(const Math::DualQuaternion& transformation) { + return setTransformationInternal(_transformation*transformation); } Math::DualQuaternion _transformation; diff --git a/src/Magnum/SceneGraph/FeatureGroup.h b/src/Magnum/SceneGraph/FeatureGroup.h index e95f6f829..cc3d4298c 100644 --- a/src/Magnum/SceneGraph/FeatureGroup.h +++ b/src/Magnum/SceneGraph/FeatureGroup.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -62,7 +62,7 @@ See @ref AbstractGroupedFeature for more information. @ref FeatureGroup2D, @ref FeatureGroup3D */ template class FeatureGroup: public AbstractFeatureGroup { - friend class AbstractGroupedFeature; + friend AbstractGroupedFeature; public: explicit FeatureGroup(); @@ -119,7 +119,7 @@ template inline FeatureGroup%FeatureGroup<2, Feature, T>. See +Convenience alternative to `FeatureGroup<2, Feature, T>`. See @ref AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use %FeatureGroup<2, Feature, T> instead. @@ -132,7 +132,7 @@ template using BasicFeatureGroup2D = FeatureGroup<2, Fea /** @brief Base feature group for two-dimensional float scenes -Convenience alternative to %BasicFeatureGroup2D. See +Convenience alternative to `BasicFeatureGroup2D`. See @ref AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use %FeatureGroup<2, Feature, Float> instead. @@ -145,7 +145,7 @@ template using FeatureGroup2D = BasicFeatureGroup2D%FeatureGroup<3, Feature, T>. See +Convenience alternative to `FeatureGroup<3, Feature, T>`. See @ref AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use %FeatureGroup<3, Feature, T> instead. @@ -158,7 +158,7 @@ template using BasicFeatureGroup3D = FeatureGroup<3, Fea /** @brief Base feature group for three-dimensional float scenes -Convenience alternative to %BasicFeatureGroup3D. See +Convenience alternative to `BasicFeatureGroup3D`. See @ref AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use %FeatureGroup<3, Feature, Float> instead. diff --git a/src/Magnum/SceneGraph/FeatureGroup.hpp b/src/Magnum/SceneGraph/FeatureGroup.hpp index 0477d50d9..d0e63a77e 100644 --- a/src/Magnum/SceneGraph/FeatureGroup.hpp +++ b/src/Magnum/SceneGraph/FeatureGroup.hpp @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/SceneGraph/MatrixTransformation2D.h b/src/Magnum/SceneGraph/MatrixTransformation2D.h index f7e6bb262..d0da29bfd 100644 --- a/src/Magnum/SceneGraph/MatrixTransformation2D.h +++ b/src/Magnum/SceneGraph/MatrixTransformation2D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,7 +39,7 @@ namespace Magnum { namespace SceneGraph { @brief Two-dimensional transformation implemented using matrices Uses @ref Math::Matrix3 as underlying transformation type. -@see @ref MatrixTransformation2D, @ref scenegraph, +@see @ref scenegraph, @ref MatrixTransformation2D, @ref BasicRigidMatrixTransformation2D, @ref BasicMatrixTransformation3D */ template class BasicMatrixTransformation2D: public AbstractBasicTranslationRotationScaling2D { @@ -47,7 +47,7 @@ template class BasicMatrixTransformation2D: public AbstractBasicTransla /** @brief Underlying transformation type */ typedef Math::Matrix3 DataType; - /** @brief %Object transformation */ + /** @brief Object transformation */ Math::Matrix3 transformation() const { return _transformation; } /** @@ -68,14 +68,35 @@ template class BasicMatrixTransformation2D: public AbstractBasicTransla /** * @brief Transform object - * @param transformation Transformation - * @param type Transformation type * @return Reference to self (for method chaining) + * + * @see @ref transformLocal() + */ + Object>& transform(const Math::Matrix3& transformation) { + return setTransformation(transformation*_transformation); + } + + /** + * @brief Transform object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& transformLocal(const Math::Matrix3& transformation) { + return setTransformation(_transformation*transformation); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief transform() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation2D::transform() "transform()" + * or @ref Magnum::SceneGraph::MatrixTransformation2D::transformLocal() "transformLocal()" + * instead. */ - Object>& transform(const Math::Matrix3& transformation, TransformationType type = TransformationType::Global) { - return setTransformation(type == TransformationType::Global ? - transformation*_transformation : _transformation*transformation); + CORRADE_DEPRECATED("use transform() or transformLocal() instead") Object>& transform(const Math::Matrix3& transformation, TransformationType type) { + return type == TransformationType::Global ? transform(transformation) : transformLocal(transformation); } + #endif /** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */ Object>& resetTransformation() { @@ -83,42 +104,147 @@ template class BasicMatrixTransformation2D: public AbstractBasicTransla } /** - * @copydoc AbstractTranslationRotationScaling2D::translate() + * Translate object + * @return Reference to self (for method chaining) + * * Same as calling @ref transform() with @ref Math::Matrix3::translation(). + * @see @ref translateLocal(), @ref Math::Vector2::xAxis(), + * @ref Math::Vector2::yAxis() + */ + Object>& translate(const Math::Vector2& vector) { + return transform(Math::Matrix3::translation(vector)); + } + + /** + * @brief Translate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix3::translation(). + */ + Object>& translateLocal(const Math::Vector2& vector) { + return transformLocal(Math::Matrix3::translation(vector)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief translate() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation2D::translate() "translate()" + * or @ref Magnum::SceneGraph::MatrixTransformation2D::translateLocal() "translateLocal()" + * instead. */ - Object>& translate(const Math::Vector2& vector, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix3::translation(vector), type); + CORRADE_DEPRECATED("use translate() or translateLocal() instead") Object>& translate(const Math::Vector2& vector, TransformationType type) { + return type == TransformationType::Global ? translate(vector) : translateLocal(vector); } + #endif /** - * @copydoc AbstractTranslationRotationScaling2D::rotate() + * @brief Rotate object + * @param angle Angle (counterclockwise) + * @return Reference to self (for method chaining) + * * Same as calling @ref transform() with @ref Math::Matrix3::rotation(). + * @see @ref rotateLocal() + */ + Object>& rotate(Math::Rad angle) { + return transform(Math::Matrix3::rotation(angle)); + } + + /** + * @brief Rotate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix3::rotation(). */ - Object>& rotate(Math::Rad angle, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix3::rotation(angle), type); + Object>& rotateLocal(Math::Rad angle) { + return transformLocal(Math::Matrix3::rotation(angle)); } + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @copydoc AbstractTranslationRotationScaling2D::scale() + * @copybrief rotate() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation2D::rotate() "rotate()" + * or @ref Magnum::SceneGraph::MatrixTransformation2D::rotateLocal() "rotateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotate() or rotateLocal() instead") Object>& rotate(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotate(angle) : rotateLocal(angle); + } + #endif + + /** + * @brief Scale object + * @return Reference to self (for method chaining) + * * Same as calling @ref transform() with @ref Math::Matrix3::scaling(). + * @see @ref scaleLocal(), @ref Math::Vector2::xScale(), + * @ref Math::Vector2::yScale() + */ + Object>& scale(const Math::Vector2& vector) { + return transform(Math::Matrix3::scaling(vector)); + } + + /** + * @brief Scale object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix3::scaling(). */ - Object>& scale(const Math::Vector2& vector, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix3::scaling(vector), type); + Object>& scaleLocal(const Math::Vector2& vector) { + return transformLocal(Math::Matrix3::scaling(vector)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief scale() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation2D::scale() "scale()" + * or @ref Magnum::SceneGraph::MatrixTransformation2D::scaleLocal() "scaleLocal()" + * instead. + */ + CORRADE_DEPRECATED("use scale() or scaleLocal() instead") Object>& scale(const Math::Vector2& vector, TransformationType type) { + return type == TransformationType::Global ? scale(vector) : scaleLocal(vector); + } + #endif + /** * @brief Reflect object * @param normal Normal of the line through which to reflect * (normalized) - * @param type Transformation type * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::Matrix3::reflection(). + * @see @ref reflectLocal(), @ref Math::Vector2::xAxis(), + * @ref Math::Vector2::yAxis() */ - Object>& reflect(const Math::Vector2& normal, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix3::reflection(normal), type); + Object>& reflect(const Math::Vector2& normal) { + return transform(Math::Matrix3::reflection(normal)); } + /** + * @brief Reflect object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix3::reflection(). + */ + Object>& reflectLocal(const Math::Vector2& normal) { + return transformLocal(Math::Matrix3::reflection(normal)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief reflect() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation2D::reflect() "reflect()" + * or @ref Magnum::SceneGraph::MatrixTransformation2D::reflectLocal() "reflectLocal()" + * instead. + */ + CORRADE_DEPRECATED("use reflect() or reflectLocal() instead") Object>& reflect(const Math::Vector2& normal, TransformationType type) { + return type == TransformationType::Global ? reflect(normal) : reflectLocal(normal); + } + #endif + protected: /* Allow construction only from Object */ explicit BasicMatrixTransformation2D(); @@ -126,17 +252,14 @@ template class BasicMatrixTransformation2D: public AbstractBasicTransla private: void doResetTransformation() override final { resetTransformation(); } - void doTranslate(const Math::Vector2& vector, TransformationType type) override final { - translate(vector, type); - } + void doTranslate(const Math::Vector2& vector) override final { translate(vector); } + void doTranslateLocal(const Math::Vector2& vector) override final { translateLocal(vector); } - void doRotate(Math::Rad angle, TransformationType type) override final { - rotate(angle, type); - } + void doRotate(Math::Rad angle) override final { rotate(angle); } + void doRotateLocal(Math::Rad angle) override final { rotateLocal(angle); } - void doScale(const Math::Vector2& vector, TransformationType type) override final { - scale(vector, type); - } + void doScale(const Math::Vector2& vector) override final { scale(vector); } + void doScaleLocal(const Math::Vector2& vector) override final { scaleLocal(vector); } Math::Matrix3 _transformation; }; diff --git a/src/Magnum/SceneGraph/MatrixTransformation3D.h b/src/Magnum/SceneGraph/MatrixTransformation3D.h index 2eb19af05..da9b5d6e0 100644 --- a/src/Magnum/SceneGraph/MatrixTransformation3D.h +++ b/src/Magnum/SceneGraph/MatrixTransformation3D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,14 +39,15 @@ namespace Magnum { namespace SceneGraph { @brief Three-dimensional transformation implemented using matrices Uses @ref Math::Matrix4 as underlying transformation type. -@see @ref MatrixTransformation3D, @ref scenegraph, @ref BasicRigidMatrixTransformation3D, @ref BasicMatrixTransformation2D +@see @ref scenegraph, @ref MatrixTransformation3D, + @ref BasicRigidMatrixTransformation3D, @ref BasicMatrixTransformation2D */ template class BasicMatrixTransformation3D: public AbstractBasicTranslationRotationScaling3D { public: /** @brief Underlying transformation type */ typedef Math::Matrix4 DataType; - /** @brief %Object transformation */ + /** @brief Object transformation */ Math::Matrix4 transformation() const { return _transformation; } /** @@ -71,89 +72,286 @@ template class BasicMatrixTransformation3D: public AbstractBasicTransla } /** - * @brief Multiply transformation - * @param transformation Transformation - * @param type Transformation type + * @brief Transform object * @return Reference to self (for method chaining) + * + * @see @ref transformLocal() + */ + Object>& transform(const Math::Matrix4& transformation) { + return setTransformation(transformation*_transformation); + } + + /** + * @brief Transform object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. */ - Object>& transform(const Math::Matrix4& transformation, TransformationType type = TransformationType::Global) { - return setTransformation(type == TransformationType::Global ? - transformation*_transformation : _transformation*transformation); + Object>& transformLocal(const Math::Matrix4& transformation) { + return setTransformation(_transformation*transformation); } + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @copydoc AbstractTranslationRotationScaling3D::translate() + * @copybrief transform() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation3D::transform() "transform()" + * or @ref Magnum::SceneGraph::MatrixTransformation3D::transformLocal() "transformLocal()" + * instead. + */ + CORRADE_DEPRECATED("use transform() or transformLocal() instead") Object>& transform(const Math::Matrix4& transformation, TransformationType type) { + return type == TransformationType::Global ? transform(transformation) : transformLocal(transformation); + } + #endif + + /** + * @brief Translate object + * @return Reference to self (for method chaining) + * * Same as calling @ref transform() with @ref Math::Matrix4::translation(). + * @see @ref translateLocal(), @ref Math::Vector3::xAxis(), + * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() + */ + Object>& translate(const Math::Vector3& vector) { + return transform(Math::Matrix4::translation(vector)); + } + + /** + * @brief Translate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix4::translation(). */ - Object>& translate(const Math::Vector3& vector, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix4::translation(vector), type); + Object>& translateLocal(const Math::Vector3& vector) { + return transformLocal(Math::Matrix4::translation(vector)); } + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @copydoc AbstractTranslationRotationScaling3D::rotate() + * @copybrief translate() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation3D::translate() "translate()" + * or @ref Magnum::SceneGraph::MatrixTransformation3D::translateLocal() "translateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use translate() or translateLocal() instead") Object>& translate(const Math::Vector3& vector, TransformationType type) { + return type == TransformationType::Global ? translate(vector) : translateLocal(vector); + } + #endif + + /** + * @brief Rotate object + * @param angle Angle (counterclockwise) + * @param normalizedAxis Normalized rotation axis + * @return Reference to self (for method chaining) + * * Same as calling @ref transform() with @ref Math::Matrix4::rotation(). + * @see @ref rotateLocal(), @ref rotateX(), @ref rotateY(), + * @ref rotateZ(), @ref Math::Vector3::xAxis(), + * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() + */ + Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { + return transform(Math::Matrix4::rotation(angle, normalizedAxis)); + } + + /** + * @brief Rotate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix4::rotation(). + */ + Object>& rotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) { + return transformLocal(Math::Matrix4::rotation(angle, normalizedAxis)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotate() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation3D::rotate() "rotate()" + * or @ref Magnum::SceneGraph::MatrixTransformation3D::rotateLocal() "rotateLocal()" + * instead. */ - Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix4::rotation(angle, normalizedAxis), type); + CORRADE_DEPRECATED("use rotate() or rotateLocal() instead") Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type) { + return type == TransformationType::Global ? rotate(angle, normalizedAxis) : rotateLocal(angle, normalizedAxis); } + #endif /** * @brief Rotate object around X axis * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::Matrix4::rotationX(). + * @see @ref rotateXLocal() */ - Object>& rotateX(Math::Rad angle, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix4::rotationX(angle), type); + Object>& rotateX(Math::Rad angle) { + return transform(Math::Matrix4::rotationX(angle)); } + /** + * @brief Rotate object around X axis as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix4::rotationX(). + */ + Object>& rotateXLocal(Math::Rad angle) { + return transformLocal(Math::Matrix4::rotationX(angle)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotateX() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation3D::rotateX() "rotateX()" + * or @ref Magnum::SceneGraph::MatrixTransformation3D::rotateXLocal() "rotateXLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotateX() or rotateXLocal() instead") Object>& rotateX(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotateX(angle) : rotateXLocal(angle); + } + #endif + /** * @brief Rotate object around Y axis * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::Matrix4::rotationY(). + * @see @ref rotateYLocal() + */ + Object>& rotateY(Math::Rad angle) { + return transform(Math::Matrix4::rotationY(angle)); + } + + /** + * @brief Rotate object around Y axis as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix4::rotationY(). */ - Object>& rotateY(Math::Rad angle, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix4::rotationY(angle), type); + Object>& rotateYLocal(Math::Rad angle) { + return transformLocal(Math::Matrix4::rotationY(angle)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotateY() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation3D::rotateY() "rotateY()" + * or @ref Magnum::SceneGraph::MatrixTransformation3D::rotateYLocal() "rotateYLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotateY() or rotateYLocal() instead") Object>& rotateY(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotateY(angle) : rotateYLocal(angle); + } + #endif + /** * @brief Rotate object around Z axis * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::Matrix4::rotationZ(). + * @see @ref rotateZLocal() + */ + Object>& rotateZ(Math::Rad angle) { + return transform(Math::Matrix4::rotationZ(angle)); + } + + /** + * @brief Rotate object around Z axis as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix4::rotationZ(). + */ + Object>& rotateZLocal(Math::Rad angle) { + return transformLocal(Math::Matrix4::rotationZ(angle)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotateZ() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation3D::rotateZ() "rotateZ()" + * or @ref Magnum::SceneGraph::MatrixTransformation3D::rotateZLocal() "rotateZLocal()" + * instead. */ - Object>& rotateZ(Math::Rad angle, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix4::rotationZ(angle), type); + CORRADE_DEPRECATED("use rotateZ() or rotateZLocal() instead") Object>& rotateZ(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotateZ(angle) : rotateZLocal(angle); } + #endif /** - * @copydoc AbstractTranslationRotationScaling3D::scale() + * @brief Scale object + * @return Reference to self (for method chaining) + * * Same as calling @ref transform() with @ref Math::Matrix4::scaling(). + * @see @ref scaleLocal(), @ref Math::Vector3::xScale(), + * @ref Math::Vector3::yScale(), @ref Math::Vector3::zScale() */ - Object>& scale(const Math::Vector3& vector, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix4::scaling(vector), type); + Object>& scale(const Math::Vector3& vector) { + return transform(Math::Matrix4::scaling(vector)); } + /** + * @brief Scale object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix4::scaling(). + */ + Object>& scaleLocal(const Math::Vector3& vector) { + return transformLocal(Math::Matrix4::scaling(vector)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief scale() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation3D::scale() "scale()" + * or @ref Magnum::SceneGraph::MatrixTransformation3D::scaleLocal() "scaleLocal()" + * instead. + */ + CORRADE_DEPRECATED("use scale() or scaleLocal() instead") Object>& scale(const Math::Vector3& vector, TransformationType type) { + return type == TransformationType::Global ? scale(vector) : scaleLocal(vector); + } + #endif + /** * @brief Reflect object * @param normal Normal of the plane through which to reflect * (normalized) - * @param type Transformation type * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::Matrix4::reflection(). + * @see @ref reflectLocal() + */ + Object>& reflect(const Math::Vector3& normal) { + return transform(Math::Matrix4::reflection(normal)); + } + + /** + * @brief Reflect object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix4::reflection(). */ - Object>& reflect(const Math::Vector3& normal, TransformationType type = TransformationType::Global) { - return transform(Math::Matrix4::reflection(normal), type); + Object>& reflectLocal(const Math::Vector3& normal) { + return transformLocal(Math::Matrix4::reflection(normal)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief reflect() + * @deprecated Use @ref Magnum::SceneGraph::MatrixTransformation3D::reflect() "reflect()" + * or @ref Magnum::SceneGraph::MatrixTransformation3D::reflectLocal() "reflectLocal()" + * instead. + */ + CORRADE_DEPRECATED("use reflect() or reflectLocal() instead") Object>& reflect(const Math::Vector3& normal, TransformationType type) { + return type == TransformationType::Global ? reflect(normal) : reflectLocal(normal); + } + #endif + protected: /* Allow construction only from Object */ explicit BasicMatrixTransformation3D(); @@ -161,29 +359,27 @@ template class BasicMatrixTransformation3D: public AbstractBasicTransla private: void doResetTransformation() override final { resetTransformation(); } - void doTranslate(const Math::Vector3& vector, TransformationType type) override final { - translate(vector, type); - } + void doTranslate(const Math::Vector3& vector) override final { translate(vector); } + void doTranslateLocal(const Math::Vector3& vector) override final { translateLocal(vector); } - void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type) override final { - rotate(angle, normalizedAxis, type); + void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { + rotate(angle, normalizedAxis); } - - void doRotateX(Math::Rad angle, TransformationType type) override final { - rotateX(angle, type); + void doRotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { + rotateLocal(angle, normalizedAxis); } - void doRotateY(Math::Rad angle, TransformationType type) override final { - rotateY(angle, type); - } + void doRotateX(Math::Rad angle) override final { rotateX(angle); } + void doRotateXLocal(Math::Rad angle) override final { rotateXLocal(angle); } - void doRotateZ(Math::Rad angle, TransformationType type) override final { - rotateZ(angle, type); - } + void doRotateY(Math::Rad angle) override final { rotateY(angle); } + void doRotateYLocal(Math::Rad angle) override final { rotateYLocal(angle); } - void doScale(const Math::Vector3& vector, TransformationType type) override final { - scale(vector, type); - } + void doRotateZ(Math::Rad angle) override final { rotateZ(angle); } + void doRotateZLocal(Math::Rad angle) override final { rotateZLocal(angle); } + + void doScale(const Math::Vector3& vector) override final { scale(vector); } + void doScaleLocal(const Math::Vector3& vector) override final { scaleLocal(vector); } Math::Matrix4 _transformation; }; diff --git a/src/Magnum/SceneGraph/Object.h b/src/Magnum/SceneGraph/Object.h index de6ce7964..b31f12a3c 100644 --- a/src/Magnum/SceneGraph/Object.h +++ b/src/Magnum/SceneGraph/Object.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -50,7 +50,7 @@ namespace Implementation { } /** -@brief %Object +@brief Object Base of scene graph. Contains specific transformation implementation, takes care of parent/children relationship and contains features. See @ref scenegraph @@ -63,11 +63,20 @@ typedef SceneGraph::Scene Scene3D; typedef SceneGraph::Object Object3D; @endcode -Uses @ref Corrade::Containers::LinkedList for parent/children relationship. -Traversing through the list is done like in the following code. It is also -possible to go in reverse order using @ref lastChild() and @ref previousSibling(). +Uses @ref Corrade::Containers::LinkedList for efficient hierarchy management. +Traversing through the list of child objects can be done using range-based for: @code -for(Object* child = o->firstChild(); child; child = child->nextSibling()) { +Object3D o; +for(AbstractFeature3D& feature: o.features()) { + // ... +} +@endcode + +Or, if you need more flexibility, like in the following code. It is also +possible to go in reverse order using @ref Corrade::Containers::LinkedList::last() +and @ref previousSibling(). +@code +for(Object3D* child = o->children().first(); child; child = child->nextSibling()) { // ... } @endcode @@ -76,9 +85,9 @@ for(Object* child = o->firstChild(); child; child = child->nextSibling()) { ## Explicit template specializations The following specializations are explicitly compiled into @ref SceneGraph -library. For other specializations (e.g. using @ref Double type or special -transformation class) you have to use @ref Object.hpp implementation file to -avoid linker errors. See also relevant sections in +library. For other specializations (e.g. using @ref Magnum::Double "Double" +type or special transformation class) you have to use @ref Object.hpp +implementation file to avoid linker errors. See also relevant sections in @ref SceneGraph-AbstractObject-explicit-specializations "AbstractObject" and @ref SceneGraph-AbstractTransformation-explicit-specializations "AbstractTransformation" class documentation or @ref compilation-speedup-hpp for more information. @@ -102,8 +111,8 @@ template class Object: public AbstractObject>, private Containers::LinkedListItem, Object> #endif { - friend class Containers::LinkedList>; - friend class Containers::LinkedListItem, Object>; + friend Containers::LinkedList>; + friend Containers::LinkedListItem, Object>; public: /** @brief Matrix type */ @@ -175,29 +184,58 @@ template class Object: public AbstractObject, Object>::next(); } - /** @brief Whether this object has children */ - bool hasChildren() const { - return !Containers::LinkedList>::isEmpty(); - } - - /** @brief First child object or `nullptr`, if this object has no children */ - Object* firstChild() { - return Containers::LinkedList>::first(); + /** + * @brief Child objects + * + * @see @ref parent(), @ref previousSibling(), @ref nextSibling() + */ + Containers::LinkedList>& children() { + return static_cast>&>(*this); } /** @overload */ - const Object* firstChild() const { - return Containers::LinkedList>::first(); + const Containers::LinkedList>& children() const { + return static_cast>&>(*this); } - /** @brief Last child object or `nullptr`, if this object has no children */ - Object* lastChild() { - return Containers::LinkedList>::last(); - } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Whether this object has children + * @deprecated Use `children().isEmpty()` instead. + */ + CORRADE_DEPRECATED("use children().isEmpty()") bool hasChildren() const { return !children().isEmpty(); } - /** @overload */ - const Object* lastChild() const { - return Containers::LinkedList>::last(); + /** + * @brief First child object or `nullptr`, if this object has no children + * @deprecated Use `children().first()` instead. + */ + CORRADE_DEPRECATED("use children().first()") Object* firstChild() { return children().first(); } + + /** @overload + * @deprecated Use `children.first()` instead. + */ + CORRADE_DEPRECATED("use children().first()") const Object* firstChild() const { return children().first(); } + + /** + * @brief Last child object or `nullptr`, if this object has no children + * @deprecated Use `children().last()` instead. + */ + CORRADE_DEPRECATED("use children().last()") Object* lastChild() { return children().last(); } + + /** @overload + * @deprecated Use `children().last()` instead. + */ + CORRADE_DEPRECATED("use children().last()") const Object* lastChild() const { return children().last(); } + #endif + + /** + * @brief Add a child + * + * Calling `object.addChild(args...)` is equivalent to + * `new MyObject{args..., &object}`. + */ + template T& addChild(Args... args) { + return *(new T{std::forward(args)..., this}); } /** @@ -335,7 +373,7 @@ template class Object: public AbstractObject class Object: public AbstractObject>>), * which cleans given set of objects more efficiently than when calling * @ref setClean() on each object individually. - * @see @ref scenegraph-caching, @ref setDirty(), @ref isDirty() + * @see @ref scenegraph-features-caching, @ref setDirty(), + * @ref isDirty() */ /* note: doc verbatim copied from AbstractObject::setClean() */ void setClean(); diff --git a/src/Magnum/SceneGraph/Object.hpp b/src/Magnum/SceneGraph/Object.hpp index d5882e762..5fcc56475 100644 --- a/src/Magnum/SceneGraph/Object.hpp +++ b/src/Magnum/SceneGraph/Object.hpp @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -170,15 +170,13 @@ template void Object::setDirty() { nothing to do */ if(flags & Flag::Dirty) return; - Object* self = static_cast*>(this); - /* Make all features dirty */ - for(AbstractFeature* i = self->firstFeature(); i; i = i->nextFeature()) - i->markDirty(); + for(AbstractFeature& feature: this->features()) + feature.markDirty(); /* Make all children dirty */ - for(Object* i = self->firstChild(); i; i = i->nextSibling()) - i->setDirty(); + for(Object& child: children()) + child.setDirty(); /* Mark object as dirty */ flags |= Flag::Dirty; @@ -549,28 +547,28 @@ template void Object::setCleanInternal(con MatrixType matrix, invertedMatrix; /* Clean all features */ - for(AbstractFeature* i = this->firstFeature(); i; i = i->nextFeature()) { + for(AbstractFeature& feature: this->features()) { /* Cached absolute transformation, compute it if it wasn't computed already */ - if(i->cachedTransformations() & CachedTransformation::Absolute) { + if(feature.cachedTransformations() & CachedTransformation::Absolute) { if(!(cached & CachedTransformation::Absolute)) { cached |= CachedTransformation::Absolute; matrix = Implementation::Transformation::toMatrix(absoluteTransformation); } - i->clean(matrix); + feature.clean(matrix); } /* Cached inverse absolute transformation, compute it if it wasn't computed already */ - if(i->cachedTransformations() & CachedTransformation::InvertedAbsolute) { + if(feature.cachedTransformations() & CachedTransformation::InvertedAbsolute) { if(!(cached & CachedTransformation::InvertedAbsolute)) { cached |= CachedTransformation::InvertedAbsolute; invertedMatrix = Implementation::Transformation::toMatrix( Implementation::Transformation::inverted(absoluteTransformation)); } - i->cleanInverted(invertedMatrix); + feature.cleanInverted(invertedMatrix); } } diff --git a/src/Magnum/SceneGraph/RigidMatrixTransformation2D.h b/src/Magnum/SceneGraph/RigidMatrixTransformation2D.h index b3aa635cd..8a9b4d844 100644 --- a/src/Magnum/SceneGraph/RigidMatrixTransformation2D.h +++ b/src/Magnum/SceneGraph/RigidMatrixTransformation2D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -43,7 +43,7 @@ Unlike @ref BasicMatrixTransformation2D this class allows only rotation, reflection and translation (no scaling or setting arbitrary transformations). This allows to use @ref Math::Matrix3::invertedRigid() for faster computation of inverse transformations. -@see @ref RigidMatrixTransformation2D, @ref scenegraph, +@see @ref scenegraph, @ref RigidMatrixTransformation2D, @ref BasicRigidMatrixTransformation3D */ template class BasicRigidMatrixTransformation2D: public AbstractBasicTranslationRotation2D { @@ -51,7 +51,7 @@ template class BasicRigidMatrixTransformation2D: public AbstractBasicTr /** @brief Underlying transformation type */ typedef Math::Matrix3 DataType; - /** @brief %Object transformation */ + /** @brief Object transformation */ Math::Matrix3 transformation() const { return _transformation; } /** @@ -89,57 +89,150 @@ template class BasicRigidMatrixTransformation2D: public AbstractBasicTr /** * @brief Transform object - * @param transformation Transformation - * @param type Transformation type * @return Reference to self (for method chaining) * * Expects that the matrix represents rigid transformation. - * @see @ref Math::Matrix3::isRigidTransformation() + * @see @ref transformLocal(), @ref Math::Matrix3::isRigidTransformation() */ - Object>& transform(const Math::Matrix3& transformation, TransformationType type = TransformationType::Global) { + Object>& transform(const Math::Matrix3& transformation) { CORRADE_ASSERT(transformation.isRigidTransformation(), "SceneGraph::RigidMatrixTransformation2D::transform(): the matrix doesn't represent rigid transformation", static_cast>&>(*this)); - return transformInternal(transformation, type); + return transformInternal(transformation); + } + + /** + * @brief Transform object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& transformLocal(const Math::Matrix3& transformation) { + CORRADE_ASSERT(transformation.isRigidTransformation(), + "SceneGraph::RigidMatrixTransformation2D::transformLocal(): the matrix doesn't represent rigid transformation", + static_cast>&>(*this)); + return transformLocalInternal(transformation); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief transform() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation2D::transform() "transform()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation2D::transformLocal() "transformLocal()" + * instead. + */ + CORRADE_DEPRECATED("use transform() or transformLocal() instead") Object>& transform(const Math::Matrix3& transformation, TransformationType type) { + return type == TransformationType::Global ? transform(transformation) : transformLocal(transformation); } + #endif /** - * @copydoc AbstractTranslationRotationScaling2D::translate() - * Same as calling @ref transform() with + * Translate object + * @return Reference to self (for method chaining) + * + * Same as calling @ref transform() with @ref Math::Matrix3::translation(). + * @see @ref translateLocal(), @ref Math::Vector2::xAxis(), + * @ref Math::Vector2::yAxis() + */ + Object>& translate(const Math::Vector2& vector) { + return transformInternal(Math::Matrix3::translation(vector)); + } + + /** + * @brief Translate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with * @ref Math::Matrix3::translation(). */ - Object>& translate(const Math::Vector2& vector, TransformationType type = TransformationType::Global) { - return transformInternal(Math::Matrix3::translation(vector), type); + Object>& translateLocal(const Math::Vector2& vector) { + return transformLocalInternal(Math::Matrix3::translation(vector)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief translate() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation2D::translate() "translate()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation2D::translateLocal() "translateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use translate() or translateLocal() instead") Object>& translate(const Math::Vector2& vector, TransformationType type) { + return type == TransformationType::Global ? translate(vector) : translateLocal(vector); } + #endif /** * @brief Rotate object * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * - * Same as calling @ref transform() with + * Same as calling @ref transform() with @ref Math::Matrix3::rotation(). + * @see @ref rotateLocal(), @ref normalizeRotation() + */ + Object>& rotate(Math::Rad angle) { + return transformInternal(Math::Matrix3::rotation(angle)); + } + + /** + * @brief Rotate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with * @ref Math::Matrix3::rotation(). * @see @ref normalizeRotation() */ - Object>& rotate(Math::Rad angle, TransformationType type = TransformationType::Global) { - return transformInternal(Math::Matrix3::rotation(angle), type); + Object>& rotateLocal(Math::Rad angle) { + return transformLocalInternal(Math::Matrix3::rotation(angle)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotate() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation2D::rotate() "rotate()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation2D::rotateLocal() "rotateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotate() or rotateLocal() instead") Object>& rotate(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotate(angle) : rotateLocal(angle); + } + #endif + /** * @brief Reflect object * @param normal Normal of the line through which to reflect * (normalized) - * @param type Transformation type * @return Reference to self (for method chaining) * - * Same as calling @ref transform() with + * Same as calling @ref transform() with @ref Math::Matrix3::reflection(). + * @see @ref reflectLocal() + */ + Object>& reflect(const Math::Vector2& normal) { + return transformInternal(Math::Matrix3::reflection(normal)); + } + + /** + * @brief Reflect object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with * @ref Math::Matrix3::reflection(). */ - Object>& reflect(const Math::Vector2& normal, TransformationType type = TransformationType::Global) { - return transformInternal(Math::Matrix3::reflection(normal), type); + Object>& reflectLocal(const Math::Vector2& normal) { + return transformLocalInternal(Math::Matrix3::reflection(normal)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief reflect() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation2D::reflect() "reflect()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation2D::reflectLocal() "reflectLocal()" + * instead. + */ + CORRADE_DEPRECATED("use reflect() or reflectInternal() instead") Object>& reflect(const Math::Vector2& normal, TransformationType type) { + return type == TransformationType::Global ? reflect(normal) : reflectLocal(normal); + } + #endif + protected: /* Allow construction only from Object */ explicit BasicRigidMatrixTransformation2D(); @@ -147,13 +240,11 @@ template class BasicRigidMatrixTransformation2D: public AbstractBasicTr private: void doResetTransformation() override final { resetTransformation(); } - void doTranslate(const Math::Vector2& vector, TransformationType type) override final { - translate(vector, type); - } + void doTranslate(const Math::Vector2& vector) override final { translate(vector); } + void doTranslateLocal(const Math::Vector2& vector) override final { translateLocal(vector); } - void doRotate(Math::Rad angle, TransformationType type) override final { - rotate(angle, type); - } + void doRotate(Math::Rad angle) override final { rotate(angle); } + void doRotateLocal(Math::Rad angle) override final { rotateLocal(angle); } /* No assertions fired, for internal use */ Object>& setTransformationInternal(const Math::Matrix3& transformation) { @@ -169,9 +260,11 @@ template class BasicRigidMatrixTransformation2D: public AbstractBasicTr } /* No assertions fired, for internal use */ - Object>& transformInternal(const Math::Matrix3& transformation, TransformationType type) { - return setTransformationInternal(type == TransformationType::Global ? - transformation*_transformation : _transformation*transformation); + Object>& transformInternal(const Math::Matrix3& transformation) { + return setTransformationInternal(transformation*_transformation); + } + Object>& transformLocalInternal(const Math::Matrix3& transformation) { + return setTransformationInternal(_transformation*transformation); } Math::Matrix3 _transformation; diff --git a/src/Magnum/SceneGraph/RigidMatrixTransformation3D.h b/src/Magnum/SceneGraph/RigidMatrixTransformation3D.h index 04af62cf3..cb2997537 100644 --- a/src/Magnum/SceneGraph/RigidMatrixTransformation3D.h +++ b/src/Magnum/SceneGraph/RigidMatrixTransformation3D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -43,14 +43,15 @@ Unlike @ref BasicMatrixTransformation3D this class allows only rotation, reflection and translation (no scaling or setting arbitrary transformations). This allows to use @ref Math::Matrix4::invertedRigid() for faster computation of inverse transformations. -@see @ref RigidMatrixTransformation3D, @ref scenegraph, @ref BasicRigidMatrixTransformation2D +@see @ref scenegraph, @ref RigidMatrixTransformation3D, + @ref BasicRigidMatrixTransformation2D */ template class BasicRigidMatrixTransformation3D: public AbstractBasicTranslationRotation3D { public: /** @brief Underlying transformation type */ typedef Math::Matrix4 DataType; - /** @brief %Object transformation */ + /** @brief Object transformation */ Math::Matrix4 transformation() const { return _transformation; } /** @@ -86,101 +87,259 @@ template class BasicRigidMatrixTransformation3D: public AbstractBasicTr } /** - * @brief Multiply transformation - * @param transformation Transformation - * @param type Transformation type + * @brief Transform object * @return Reference to self (for method chaining) * * Expects that the matrix represents rigid transformation. - * @see @ref Math::Matrix4::isRigidTransformation() + * @see @ref transformLocal(), @ref Math::Matrix4::isRigidTransformation() */ - Object>& transform(const Math::Matrix4& transformation, TransformationType type = TransformationType::Global) { + Object>& transform(const Math::Matrix4& transformation) { CORRADE_ASSERT(transformation.isRigidTransformation(), "SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation", static_cast>&>(*this)); - return transformInternal(transformation, type); + return transformInternal(transformation); } /** - * @copydoc AbstractTranslationRotationScaling3D::translate() + * @brief Transform object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& transformLocal(const Math::Matrix4& transformation) { + CORRADE_ASSERT(transformation.isRigidTransformation(), + "SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation", + static_cast>&>(*this)); + return transformLocalInternal(transformation); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief transform() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation3D::transform() "transform()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation3D::transformLocal() "transformLocal()" + * instead. + */ + CORRADE_DEPRECATED("use transform() or transformLocal() instead") Object>& transform(const Math::Matrix4& transformation, TransformationType type) { + return type == TransformationType::Global ? transform(transformation) : transformLocal(transformation); + } + #endif + + /** + * @brief Translate object + * @return Reference to self (for method chaining) + * * Same as calling @ref transform() with @ref Math::Matrix4::translation(). + * @see @ref translateLocal(), @ref Math::Vector3::xAxis(), + * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() + */ + Object>& translate(const Math::Vector3& vector) { + return transformInternal(Math::Matrix4::translation(vector)); + } + + /** + * @brief Translate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix4::translation(). + */ + Object>& translateLocal(const Math::Vector3& vector) { + return transformLocalInternal(Math::Matrix4::translation(vector)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief translate() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation3D::translate() "translate()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation3D::translateLocal() "translateLocal()" + * instead. */ - Object>& translate(const Math::Vector3& vector, TransformationType type = TransformationType::Global) { - return transformInternal(Math::Matrix4::translation(vector), type); + CORRADE_DEPRECATED("use translate() or translateLocal() instead") Object>& translate(const Math::Vector3& vector, TransformationType type) { + return type == TransformationType::Global ? translate(vector) : translateLocal(vector); } + #endif /** * @brief Rotate object * @param angle Angle (counterclockwise) * @param normalizedAxis Normalized rotation axis - * @param type Transformation type * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::Matrix4::rotation(). - * @see @ref rotateX(), @ref rotateY(), @ref rotateZ(), - * @ref normalizeRotation(), @ref Math::Vector3::xAxis(), - * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() + * @see @ref rotateLocal(), @ref rotateX(), @ref rotateY(), + * @ref rotateZ(), @ref normalizeRotation(), + * @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(), + * @ref Math::Vector3::zAxis() */ - Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type = TransformationType::Global) { - return transformInternal(Math::Matrix4::rotation(angle, normalizedAxis), type); + Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { + return transformInternal(Math::Matrix4::rotation(angle, normalizedAxis)); } + /** + * @brief Rotate object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with + * @ref Math::Matrix4::rotation(). + */ + Object>& rotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) { + return transformLocalInternal(Math::Matrix4::rotation(angle, normalizedAxis)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotate() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation3D::rotate() "rotate()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation3D::rotateLocal() "rotateLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotate() or rotateLocal() instead") Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type) { + return type == TransformationType::Global ? rotate(angle, normalizedAxis) : rotateLocal(angle, normalizedAxis); + } + #endif + /** * @brief Rotate object around X axis * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * - * Same as calling @ref transform() with + * Same as calling @ref transform() with @ref Math::Matrix4::rotationX(). + * @see @ref rotateXLocal(), @ref normalizeRotation() + */ + Object>& rotateX(Math::Rad angle) { + return transformInternal(Math::Matrix4::rotationX(angle)); + } + + /** + * @brief Rotate object around X axis as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with * @ref Math::Matrix4::rotationX(). - * @see @ref normalizeRotation() */ - Object>& rotateX(Math::Rad angle, TransformationType type = TransformationType::Global) { - return transformInternal(Math::Matrix4::rotationX(angle), type); + Object>& rotateXLocal(Math::Rad angle) { + return transformLocalInternal(Math::Matrix4::rotationX(angle)); + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotateX() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation3D::rotateX() "rotateX()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation3D::rotateXLocal() "rotateXLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotateX() or rotateXLocal() instead") Object>& rotateX(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotateX(angle) : rotateXLocal(angle); } + #endif /** * @brief Rotate object around Y axis * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * - * Same as calling @ref transform() with + * Same as calling @ref transform() with @ref Math::Matrix4::rotationY(). + * @see @ref rotateYLocal(), @ref normalizeRotation() + */ + Object>& rotateY(Math::Rad angle) { + return transformInternal(Math::Matrix4::rotationY(angle)); + } + + /** + * @brief Rotate object around Y axis as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with * @ref Math::Matrix4::rotationY(). - * @see @ref normalizeRotation() */ - Object>& rotateY(Math::Rad angle, TransformationType type = TransformationType::Global) { - return transformInternal(Math::Matrix4::rotationY(angle), type); + Object>& rotateYLocal(Math::Rad angle) { + return transformLocalInternal(Math::Matrix4::rotationY(angle)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotateY() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation3D::rotateY() "rotateY()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation3D::rotateYLocal() "rotateYLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotateY() or rotateYLocal() instead") Object>& rotateY(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotateY(angle) : rotateYLocal(angle); + } + #endif + /** * @brief Rotate object around Z axis * @param angle Angle (counterclockwise) - * @param type Transformation type * @return Reference to self (for method chaining) * - * Same as calling @ref transform() with + * Same as calling @ref transform() with @ref Math::Matrix4::rotationZ(). + * @see @ref rotateZLocal(), @ref normalizeRotation() + */ + Object>& rotateZ(Math::Rad angle) { + return transformInternal(Math::Matrix4::rotationZ(angle)); + } + + /** + * @brief Rotate object around Z axis as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with * @ref Math::Matrix4::rotationZ(). - * @see @ref normalizeRotation() */ - Object>& rotateZ(Math::Rad angle, TransformationType type = TransformationType::Global) { - return transformInternal(Math::Matrix4::rotationZ(angle), type); + Object>& rotateZLocal(Math::Rad angle) { + return transformLocalInternal(Math::Matrix4::rotationZ(angle)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief rotateZ() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation3D::rotateZ() "rotateZ()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation3D::rotateZLocal() "rotateZLocal()" + * instead. + */ + CORRADE_DEPRECATED("use rotateZ() or rotateZLocal() instead") Object>& rotateZ(Math::Rad angle, TransformationType type) { + return type == TransformationType::Global ? rotateZ(angle) : rotateZLocal(angle); + } + #endif + /** * @brief Reflect object * @param normal Normal of the plane through which to reflect * (normalized) - * @param type Transformation type * @return Reference to self (for method chaining) * - * Same as calling @ref transform() with + * Same as calling @ref transform() with @ref Math::Matrix4::reflection(). + * @see @ref reflectLocal() + */ + Object>& reflect(const Math::Vector3& normal) { + return transformInternal(Math::Matrix4::reflection(normal)); + } + + /** + * @brief Reflect object as a local transformation + * + * Similar to the above, except that the transformation is applied + * before all others. Same as calling @ref transformLocal() with * @ref Math::Matrix4::reflection(). */ - Object>& reflect(const Math::Vector3& normal, TransformationType type = TransformationType::Global) { - return transformInternal(Math::Matrix4::reflection(normal), type); + Object>& reflectLocal(const Math::Vector3& normal) { + return transformLocalInternal(Math::Matrix4::reflection(normal)); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief reflect() + * @deprecated Use @ref Magnum::SceneGraph::RigidMatrixTransformation3D::reflect() "reflect()" + * or @ref Magnum::SceneGraph::RigidMatrixTransformation3D::reflectLocal() "reflectLocal()" + * instead. + */ + CORRADE_DEPRECATED("use reflect() or reflectLocal() instead") Object>& reflect(const Math::Vector3& normal, TransformationType type) { + return type == TransformationType::Global ? reflect(normal) : reflectLocal(normal); + } + #endif + protected: /* Allow construction only from Object */ explicit BasicRigidMatrixTransformation3D(); @@ -188,25 +347,24 @@ template class BasicRigidMatrixTransformation3D: public AbstractBasicTr private: void doResetTransformation() override final { resetTransformation(); } - void doTranslate(const Math::Vector3& vector, TransformationType type) override final { - translate(vector, type); - } + void doTranslate(const Math::Vector3& vector) override final { translate(vector); } + void doTranslateLocal(const Math::Vector3& vector) override final { translateLocal(vector); } - void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis, TransformationType type) override final { - rotate(angle, normalizedAxis, type); + void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { + rotate(angle, normalizedAxis); } - - void doRotateX(Math::Rad angle, TransformationType type) override final { - rotateX(angle, type); + void doRotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { + rotateLocal(angle, normalizedAxis); } - void doRotateY(Math::Rad angle, TransformationType type) override final { - rotateY(angle, type); - } + void doRotateX(Math::Rad angle) override final { rotateX(angle); } + void doRotateXLocal(Math::Rad angle) override final { rotateXLocal(angle); } - void doRotateZ(Math::Rad angle, TransformationType type) override final { - rotateZ(angle, type); - } + void doRotateY(Math::Rad angle) override final { rotateY(angle); } + void doRotateYLocal(Math::Rad angle) override final { rotateYLocal(angle); } + + void doRotateZ(Math::Rad angle) override final { rotateZ(angle); } + void doRotateZLocal(Math::Rad angle) override final { rotateZLocal(angle); } /* No assertions fired, for internal use */ Object>& setTransformationInternal(const Math::Matrix4& transformation) { @@ -222,9 +380,11 @@ template class BasicRigidMatrixTransformation3D: public AbstractBasicTr } /* No assertions fired, for internal use */ - Object>& transformInternal(const Math::Matrix4& transformation, TransformationType type) { - return setTransformationInternal(type == TransformationType::Global ? - transformation*_transformation : _transformation*transformation); + Object>& transformInternal(const Math::Matrix4& transformation) { + return setTransformationInternal(transformation*_transformation); + } + Object>& transformLocalInternal(const Math::Matrix4& transformation) { + return setTransformationInternal(_transformation*transformation); } Math::Matrix4 _transformation; diff --git a/src/Magnum/SceneGraph/Scene.h b/src/Magnum/SceneGraph/Scene.h index be945ab07..aa9050d96 100644 --- a/src/Magnum/SceneGraph/Scene.h +++ b/src/Magnum/SceneGraph/Scene.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,7 +34,7 @@ namespace Magnum { namespace SceneGraph { /** -@brief %Scene +@brief Scene Basically @ref Object which cannot have parent or non-default transformation. See @ref scenegraph for introduction. diff --git a/src/Magnum/SceneGraph/SceneGraph.h b/src/Magnum/SceneGraph/SceneGraph.h index 7acc96543..40a47c27b 100644 --- a/src/Magnum/SceneGraph/SceneGraph.h +++ b/src/Magnum/SceneGraph/SceneGraph.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -35,6 +35,7 @@ namespace Magnum { namespace SceneGraph { +#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef CORRADE_GCC45_COMPATIBILITY enum class AspectRatioPolicy: UnsignedByte; #endif @@ -84,10 +85,6 @@ typedef AbstractObject<2, Float> AbstractObject2D; typedef AbstractObject<3, Float> AbstractObject3D; #endif -#ifndef CORRADE_GCC45_COMPATIBILITY -enum class TransformationType: UnsignedByte; -#endif - template class AbstractTransformation; #ifndef CORRADE_GCC46_COMPATIBILITY template using AbstractBasicTransformation2D = AbstractTransformation<2, T>; @@ -215,6 +212,7 @@ typedef TranslationTransformation<3, Float> TranslationTransformation3D; namespace Implementation { template struct Transformation; } +#endif }} diff --git a/src/Magnum/SceneGraph/Test/AnimableTest.cpp b/src/Magnum/SceneGraph/Test/AnimableTest.cpp index 5f0f2a51a..39e67b5e5 100644 --- a/src/Magnum/SceneGraph/Test/AnimableTest.cpp +++ b/src/Magnum/SceneGraph/Test/AnimableTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,18 +32,17 @@ namespace Magnum { namespace SceneGraph { namespace Test { -class AnimableTest: public TestSuite::Tester { - public: - AnimableTest(); +struct AnimableTest: TestSuite::Tester { + explicit AnimableTest(); - void state(); - void step(); - void duration(); - void repeat(); - void stop(); - void pause(); + void state(); + void step(); + void duration(); + void repeat(); + void stop(); + void pause(); - void debug(); + void debug(); }; typedef SceneGraph::Object Object3D; diff --git a/src/Magnum/SceneGraph/Test/CMakeLists.txt b/src/Magnum/SceneGraph/Test/CMakeLists.txt index c6600a537..fa2e0934f 100644 --- a/src/Magnum/SceneGraph/Test/CMakeLists.txt +++ b/src/Magnum/SceneGraph/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/SceneGraph/Test/CameraTest.cpp b/src/Magnum/SceneGraph/Test/CameraTest.cpp index 44fb994af..991cbd0cb 100644 --- a/src/Magnum/SceneGraph/Test/CameraTest.cpp +++ b/src/Magnum/SceneGraph/Test/CameraTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -35,18 +35,18 @@ namespace Magnum { namespace SceneGraph { namespace Test { -class CameraTest: public TestSuite::Tester { - public: - CameraTest(); - - void fixAspectRatio(); - void defaultProjection2D(); - void defaultProjection3D(); - void projectionSize2D(); - void projectionSizeOrthographic(); - void projectionSizePerspective(); - void projectionSizeViewport(); - void draw(); +struct CameraTest: TestSuite::Tester { + explicit CameraTest(); + + void fixAspectRatio(); + void defaultProjection2D(); + void defaultProjection3D(); + void projectionCorrectedInvertedY(); + void projectionSize2D(); + void projectionSizeOrthographic(); + void projectionSizePerspective(); + void projectionSizeViewport(); + void draw(); }; typedef SceneGraph::Object Object2D; @@ -57,6 +57,7 @@ CameraTest::CameraTest() { addTests({&CameraTest::fixAspectRatio, &CameraTest::defaultProjection2D, &CameraTest::defaultProjection3D, + &CameraTest::projectionCorrectedInvertedY, &CameraTest::projectionSize2D, &CameraTest::projectionSizeOrthographic, &CameraTest::projectionSizePerspective, @@ -120,6 +121,20 @@ void CameraTest::defaultProjection3D() { CORRADE_COMPARE(camera.projectionSize(), Vector2(2.0f)); } +void CameraTest::projectionCorrectedInvertedY() { + Object2D o; + Camera2D camera(o); + camera.setProjection({4.0f, -2.0f}) + .setAspectRatioPolicy(AspectRatioPolicy::Extend) + .setViewport({4, 4}); + + /* Resulting matrix should have Y coordinate inverted */ + Matrix3 expected{{0.5f, 0.0f, 0.0f}, + {0.0f, -0.5f, 0.0f}, + {0.0f, 0.0f, 1.0f}}; + CORRADE_COMPARE(camera.projectionMatrix(), expected); +} + void CameraTest::projectionSize2D() { Vector2 projectionSize(4.0f, 3.0f); Object2D o; diff --git a/src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp b/src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp index 89bc7bc48..23c169e43 100644 --- a/src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp +++ b/src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,21 +34,20 @@ namespace Magnum { namespace SceneGraph { namespace Test { typedef Object Object2D; typedef Scene Scene2D; -class DualComplexTransformationTest: public TestSuite::Tester { - public: - explicit DualComplexTransformationTest(); - - void fromMatrix(); - void toMatrix(); - void compose(); - void inverted(); - - void setTransformation(); - void resetTransformation(); - void transform(); - void translate(); - void rotate(); - void normalizeRotation(); +struct DualComplexTransformationTest: TestSuite::Tester { + explicit DualComplexTransformationTest(); + + void fromMatrix(); + void toMatrix(); + void compose(); + void inverted(); + + void setTransformation(); + void resetTransformation(); + void transform(); + void translate(); + void rotate(); + void normalizeRotation(); }; DualComplexTransformationTest::DualComplexTransformationTest() { @@ -136,7 +135,7 @@ void DualComplexTransformationTest::transform() { } { Object2D o; o.setTransformation(DualComplex::rotation(Deg(17.0f))); - o.transform(DualComplex::translation({1.0f, -0.3f}), TransformationType::Local); + o.transformLocal(DualComplex::translation({1.0f, -0.3f})); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f})); } } @@ -150,7 +149,7 @@ void DualComplexTransformationTest::translate() { } { Object2D o; o.setTransformation(DualComplex::rotation(Deg(17.0f))); - o.translate({1.0f, -0.3f}, TransformationType::Local); + o.translateLocal({1.0f, -0.3f}); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f})); } } @@ -164,7 +163,7 @@ void DualComplexTransformationTest::rotate() { } { Object2D o; o.setTransformation(DualComplex::translation({1.0f, -0.3f})); - o.rotate(Deg(17.0f), TransformationType::Local); + o.rotateLocal(Deg(17.0f)); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f))); } } diff --git a/src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp b/src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp index 088930ef6..ce9797da5 100644 --- a/src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp +++ b/src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,21 +34,20 @@ namespace Magnum { namespace SceneGraph { namespace Test { typedef Object Object3D; typedef Scene Scene3D; -class DualQuaternionTransformationTest: public TestSuite::Tester { - public: - explicit DualQuaternionTransformationTest(); - - void fromMatrix(); - void toMatrix(); - void compose(); - void inverted(); - - void setTransformation(); - void resetTransformation(); - void transform(); - void translate(); - void rotate(); - void normalizeRotation(); +struct DualQuaternionTransformationTest: TestSuite::Tester { + explicit DualQuaternionTransformationTest(); + + void fromMatrix(); + void toMatrix(); + void compose(); + void inverted(); + + void setTransformation(); + void resetTransformation(); + void transform(); + void translate(); + void rotate(); + void normalizeRotation(); }; DualQuaternionTransformationTest::DualQuaternionTransformationTest() { @@ -142,7 +141,7 @@ void DualQuaternionTransformationTest::transform() { } { Object3D o; o.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())); - o.transform(DualQuaternion::translation({1.0f, -0.3f, 2.3f}), TransformationType::Local); + o.transformLocal(DualQuaternion::translation({1.0f, -0.3f, 2.3f})); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})); } } @@ -156,7 +155,7 @@ void DualQuaternionTransformationTest::translate() { } { Object3D o; o.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())); - o.translate({1.0f, -0.3f, 2.3f}, TransformationType::Local); + o.translateLocal({1.0f, -0.3f, 2.3f}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})); } } @@ -178,10 +177,10 @@ void DualQuaternionTransformationTest::rotate() { } { Object3D o; o.transform(DualQuaternion::translation({1.0f, -0.3f, 2.3f})); - o.rotateX(Deg(17.0f), TransformationType::Local) - .rotateY(Deg(25.0f), TransformationType::Local) - .rotateZ(Deg(-23.0f), TransformationType::Local) - .rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()), TransformationType::Local); + o.rotateXLocal(Deg(17.0f)) + .rotateYLocal(Deg(25.0f)) + .rotateZLocal(Deg(-23.0f)) + .rotateLocal(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})* Matrix4::rotationX(Deg(17.0f))* diff --git a/src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp b/src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp index 4b85c9698..11963f800 100644 --- a/src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp +++ b/src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,22 +33,21 @@ namespace Magnum { namespace SceneGraph { namespace Test { typedef Object Object2D; typedef Scene Scene2D; -class MatrixTransformation2DTest: public TestSuite::Tester { - public: - explicit MatrixTransformation2DTest(); - - void fromMatrix(); - void toMatrix(); - void compose(); - void inverted(); - - void setTransformation(); - void resetTransformation(); - void transform(); - void translate(); - void rotate(); - void scale(); - void reflect(); +struct MatrixTransformation2DTest: TestSuite::Tester { + explicit MatrixTransformation2DTest(); + + void fromMatrix(); + void toMatrix(); + void compose(); + void inverted(); + + void setTransformation(); + void resetTransformation(); + void transform(); + void translate(); + void rotate(); + void scale(); + void reflect(); }; MatrixTransformation2DTest::MatrixTransformation2DTest() { @@ -122,7 +121,7 @@ void MatrixTransformation2DTest::transform() { } { Object2D o; o.setTransformation(Matrix3::rotation(Deg(17.0f))); - o.transform(Matrix3::translation({1.0f, -0.3f}), TransformationType::Local); + o.transformLocal(Matrix3::translation({1.0f, -0.3f})); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f})); } } @@ -136,7 +135,7 @@ void MatrixTransformation2DTest::translate() { } { Object2D o; o.setTransformation(Matrix3::rotation(Deg(17.0f))); - o.translate({1.0f, -0.3f}, TransformationType::Local); + o.translateLocal({1.0f, -0.3f}); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f})); } } @@ -150,7 +149,7 @@ void MatrixTransformation2DTest::rotate() { } { Object2D o; o.setTransformation(Matrix3::translation({1.0f, -0.3f})); - o.rotate(Deg(17.0f), TransformationType::Local); + o.rotateLocal(Deg(17.0f)); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f))); } } @@ -164,7 +163,7 @@ void MatrixTransformation2DTest::scale() { } { Object2D o; o.setTransformation(Matrix3::rotation(Deg(17.0f))); - o.scale({1.0f, -0.3f}, TransformationType::Local); + o.scaleLocal({1.0f, -0.3f}); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::scaling({1.0f, -0.3f})); } } @@ -178,7 +177,7 @@ void MatrixTransformation2DTest::reflect() { } { Object2D o; o.setTransformation(Matrix3::rotation(Deg(17.0f))); - o.reflect(Vector2(-1.0f/Constants::sqrt2()), TransformationType::Local); + o.reflectLocal(Vector2(-1.0f/Constants::sqrt2())); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::reflection(Vector2(-1.0f/Constants::sqrt2()))); } } diff --git a/src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp b/src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp index fc1f998b7..29af9dfc1 100644 --- a/src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp +++ b/src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,22 +33,21 @@ namespace Magnum { namespace SceneGraph { namespace Test { typedef Object Object3D; typedef Scene Scene3D; -class MatrixTransformation3DTest: public TestSuite::Tester { - public: - explicit MatrixTransformation3DTest(); - - void fromMatrix(); - void toMatrix(); - void compose(); - void inverted(); - - void setTransformation(); - void resetTransformation(); - void transform(); - void translate(); - void rotate(); - void scale(); - void reflect(); +struct MatrixTransformation3DTest: TestSuite::Tester { + explicit MatrixTransformation3DTest(); + + void fromMatrix(); + void toMatrix(); + void compose(); + void inverted(); + + void setTransformation(); + void resetTransformation(); + void transform(); + void translate(); + void rotate(); + void scale(); + void reflect(); }; MatrixTransformation3DTest::MatrixTransformation3DTest() { @@ -122,7 +121,7 @@ void MatrixTransformation3DTest::transform() { } { Object3D o; o.setTransformation(Matrix4::rotationX(Deg(17.0f))); - o.transform(Matrix4::translation({1.0f, -0.3f, 2.3f}), TransformationType::Local); + o.transformLocal(Matrix4::translation({1.0f, -0.3f, 2.3f})); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})); } } @@ -136,7 +135,7 @@ void MatrixTransformation3DTest::translate() { } { Object3D o; o.setTransformation(Matrix4::rotationX(Deg(17.0f))); - o.translate({1.0f, -0.3f, 2.3f}, TransformationType::Local); + o.translateLocal({1.0f, -0.3f, 2.3f}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})); } } @@ -158,10 +157,10 @@ void MatrixTransformation3DTest::rotate() { } { Object3D o; o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})); - o.rotateX(Deg(17.0f), TransformationType::Local) - .rotateY(Deg(25.0f), TransformationType::Local) - .rotateZ(Deg(-23.0f), TransformationType::Local) - .rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()), TransformationType::Local); + o.rotateXLocal(Deg(17.0f)) + .rotateYLocal(Deg(25.0f)) + .rotateZLocal(Deg(-23.0f)) + .rotateLocal(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})* Matrix4::rotationX(Deg(17.0f))* @@ -180,7 +179,7 @@ void MatrixTransformation3DTest::scale() { } { Object3D o; o.setTransformation(Matrix4::rotationX(Deg(17.0f))); - o.scale({1.0f, -0.3f, 2.3f}, TransformationType::Local); + o.scaleLocal({1.0f, -0.3f, 2.3f}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::scaling({1.0f, -0.3f, 2.3f})); } } @@ -194,7 +193,7 @@ void MatrixTransformation3DTest::reflect() { } { Object3D o; o.setTransformation(Matrix4::rotationX(Deg(17.0f))); - o.reflect(Vector3(-1.0f/Constants::sqrt3()), TransformationType::Local); + o.reflectLocal(Vector3(-1.0f/Constants::sqrt3())); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::reflection(Vector3(-1.0f/Constants::sqrt3()))); } } diff --git a/src/Magnum/SceneGraph/Test/ObjectTest.cpp b/src/Magnum/SceneGraph/Test/ObjectTest.cpp index e585dd47a..d6b10655b 100644 --- a/src/Magnum/SceneGraph/Test/ObjectTest.cpp +++ b/src/Magnum/SceneGraph/Test/ObjectTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,21 +31,26 @@ namespace Magnum { namespace SceneGraph { namespace Test { -class ObjectTest: public TestSuite::Tester { - public: - ObjectTest(); - - void parenting(); - void scene(); - void setParentKeepTransformation(); - void absoluteTransformation(); - void transformations(); - void transformationsRelative(); - void transformationsOrphan(); - void transformationsDuplicate(); - void setClean(); - void setCleanListHierarchy(); - void setCleanListBulk(); +struct ObjectTest: TestSuite::Tester { + explicit ObjectTest(); + + void addFeature(); + + void parenting(); + void addChild(); + void scene(); + void setParentKeepTransformation(); + void absoluteTransformation(); + void transformations(); + void transformationsRelative(); + void transformationsOrphan(); + void transformationsDuplicate(); + void setClean(); + void setCleanListHierarchy(); + void setCleanListBulk(); + + void rangeBasedForChildren(); + void rangeBasedForFeatures(); }; typedef SceneGraph::Object Object3D; @@ -66,7 +71,10 @@ class CachingObject: public Object3D, AbstractFeature3D { }; ObjectTest::ObjectTest() { - addTests({&ObjectTest::parenting, + addTests({&ObjectTest::addFeature, + + &ObjectTest::parenting, + &ObjectTest::addChild, &ObjectTest::scene, &ObjectTest::setParentKeepTransformation, &ObjectTest::absoluteTransformation, @@ -76,7 +84,23 @@ ObjectTest::ObjectTest() { &ObjectTest::transformationsDuplicate, &ObjectTest::setClean, &ObjectTest::setCleanListHierarchy, - &ObjectTest::setCleanListBulk}); + &ObjectTest::setCleanListBulk, + + &ObjectTest::rangeBasedForChildren, + &ObjectTest::rangeBasedForFeatures}); +} + +void ObjectTest::addFeature() { + class MyFeature: public AbstractFeature3D { + public: + explicit MyFeature(AbstractObject3D& object, Int, std::string&&): AbstractFeature3D{object} {} + }; + + Object3D o; + CORRADE_VERIFY(o.features().isEmpty()); + MyFeature& f = o.addFeature(0, "hello"); + CORRADE_VERIFY(!o.features().isEmpty()); + CORRADE_COMPARE(&f.object(), &o); } void ObjectTest::parenting() { @@ -87,9 +111,9 @@ void ObjectTest::parenting() { CORRADE_VERIFY(childOne->parent() == &root); CORRADE_VERIFY(childTwo->parent() == &root); - CORRADE_VERIFY(root.firstChild() == childOne); - CORRADE_VERIFY(root.lastChild() == childTwo); - CORRADE_VERIFY(root.firstChild()->nextSibling() == root.lastChild()); + CORRADE_VERIFY(root.children().first() == childOne); + CORRADE_VERIFY(root.children().last() == childTwo); + CORRADE_VERIFY(root.children().first()->nextSibling() == root.children().last()); /* A object cannot be parent of itself */ childOne->setParent(childOne); @@ -101,12 +125,25 @@ void ObjectTest::parenting() { /* Reparent to another */ childTwo->setParent(childOne); - CORRADE_VERIFY(root.firstChild() == childOne && root.firstChild()->nextSibling() == nullptr); - CORRADE_VERIFY(childOne->firstChild() == childTwo && childOne->firstChild()->nextSibling() == nullptr); + CORRADE_VERIFY(root.children().first() == childOne && root.children().first()->nextSibling() == nullptr); + CORRADE_VERIFY(childOne->children().first() == childTwo && childOne->children().first()->nextSibling() == nullptr); /* Delete child */ delete childTwo; - CORRADE_VERIFY(!childOne->hasChildren()); + CORRADE_VERIFY(childOne->children().isEmpty()); +} + +void ObjectTest::addChild() { + class MyObject: public Object3D { + public: + explicit MyObject(Int, std::string&&, Object3D* parent = nullptr): Object3D{parent} {} + }; + + Object3D o; + CORRADE_VERIFY(o.children().isEmpty()); + MyObject& p = o.addChild(0, "hello"); + CORRADE_VERIFY(!o.children().isEmpty()); + CORRADE_COMPARE(p.parent(), &o); } void ObjectTest::scene() { @@ -285,7 +322,7 @@ void ObjectTest::setClean() { class CachingFeature: public AbstractFeature3D { public: - CachingFeature(AbstractObject3D& object): AbstractFeature3D(object) { + explicit CachingFeature(AbstractObject3D& object): AbstractFeature3D{object} { setCachedTransformations(CachedTransformation::Absolute); } @@ -298,7 +335,7 @@ void ObjectTest::setClean() { class CachingInvertedFeature: public AbstractFeature3D { public: - CachingInvertedFeature(AbstractObject3D& object): AbstractFeature3D(object) { + explicit CachingInvertedFeature(AbstractObject3D& object): AbstractFeature3D{object} { setCachedTransformations(CachedTransformation::InvertedAbsolute); } @@ -383,7 +420,7 @@ void ObjectTest::setCleanListHierarchy() { class CachingFeature: public AbstractFeature3D { public: - CachingFeature(AbstractObject3D& object): AbstractFeature3D(object) { + explicit CachingFeature(AbstractObject3D& object): AbstractFeature3D{object} { setCachedTransformations(CachedTransformation::Absolute); } @@ -468,6 +505,32 @@ void ObjectTest::setCleanListBulk() { CORRADE_COMPARE(d.cleanedAbsoluteTransformation, Matrix4::translation(Vector3::zAxis(3.0f))*Matrix4::scaling(Vector3(-2.0f))); } +void ObjectTest::rangeBasedForChildren() { + Scene3D scene; + Object3D a(&scene); + Object3D b(&scene); + Object3D c(&scene); + + std::vector objects; + for(auto&& i: scene.children()) objects.push_back(&i); + CORRADE_COMPARE(objects, (std::vector{&a, &b, &c})); +} + +void ObjectTest::rangeBasedForFeatures() { + struct Feature: AbstractFeature3D { + explicit Feature(AbstractObject3D& object): AbstractFeature3D{object} {} + }; + + Object3D object; + Feature a(object); + Feature b(object); + Feature c(object); + + std::vector features; + for(auto&& i: object.features()) features.push_back(&i); + CORRADE_COMPARE(features, (std::vector{&a, &b, &c})); +} + }}} CORRADE_TEST_MAIN(Magnum::SceneGraph::Test::ObjectTest) diff --git a/src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp b/src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp index 51f6c9c00..2e465dfd0 100644 --- a/src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp +++ b/src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,22 +34,21 @@ namespace Magnum { namespace SceneGraph { namespace Test { typedef Object Object2D; typedef Scene Scene2D; -class RigidMatrixTransformation2DTest: public TestSuite::Tester { - public: - explicit RigidMatrixTransformation2DTest(); - - void fromMatrix(); - void toMatrix(); - void compose(); - void inverted(); - - void setTransformation(); - void resetTransformation(); - void transform(); - void translate(); - void rotate(); - void reflect(); - void normalizeRotation(); +struct RigidMatrixTransformation2DTest: TestSuite::Tester { + explicit RigidMatrixTransformation2DTest(); + + void fromMatrix(); + void toMatrix(); + void compose(); + void inverted(); + + void setTransformation(); + void resetTransformation(); + void transform(); + void translate(); + void rotate(); + void reflect(); + void normalizeRotation(); }; RigidMatrixTransformation2DTest::RigidMatrixTransformation2DTest() { @@ -141,7 +140,7 @@ void RigidMatrixTransformation2DTest::transform() { } { Object2D o; o.setTransformation(Matrix3::rotation(Deg(17.0f))); - o.transform(Matrix3::translation({1.0f, -0.3f}), TransformationType::Local); + o.transformLocal(Matrix3::translation({1.0f, -0.3f})); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f})); } } @@ -155,7 +154,7 @@ void RigidMatrixTransformation2DTest::translate() { } { Object2D o; o.setTransformation(Matrix3::rotation(Deg(17.0f))); - o.translate({1.0f, -0.3f}, TransformationType::Local); + o.translateLocal({1.0f, -0.3f}); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f})); } } @@ -169,7 +168,7 @@ void RigidMatrixTransformation2DTest::rotate() { } { Object2D o; o.setTransformation(Matrix3::translation({1.0f, -0.3f})); - o.rotate(Deg(17.0f), TransformationType::Local); + o.rotateLocal(Deg(17.0f)); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f))); } } @@ -183,7 +182,7 @@ void RigidMatrixTransformation2DTest::reflect() { } { Object2D o; o.setTransformation(Matrix3::rotation(Deg(17.0f))); - o.reflect(Vector2(-1.0f/Constants::sqrt2()), TransformationType::Local); + o.reflectLocal(Vector2(-1.0f/Constants::sqrt2())); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::reflection(Vector2(-1.0f/Constants::sqrt2()))); } } diff --git a/src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp b/src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp index 80e00a24d..ffd226eca 100644 --- a/src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp +++ b/src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,22 +34,21 @@ namespace Magnum { namespace SceneGraph { namespace Test { typedef Object Object3D; typedef Scene Scene3D; -class RigidMatrixTransformation3DTest: public TestSuite::Tester { - public: - explicit RigidMatrixTransformation3DTest(); - - void fromMatrix(); - void toMatrix(); - void compose(); - void inverted(); - - void setTransformation(); - void resetTransformation(); - void transform(); - void translate(); - void rotate(); - void reflect(); - void normalizeRotation(); +struct RigidMatrixTransformation3DTest: TestSuite::Tester { + explicit RigidMatrixTransformation3DTest(); + + void fromMatrix(); + void toMatrix(); + void compose(); + void inverted(); + + void setTransformation(); + void resetTransformation(); + void transform(); + void translate(); + void rotate(); + void reflect(); + void normalizeRotation(); }; RigidMatrixTransformation3DTest::RigidMatrixTransformation3DTest() { @@ -142,7 +141,7 @@ void RigidMatrixTransformation3DTest::transform() { } { Object3D o; o.setTransformation(Matrix4::rotationX(Deg(17.0f))); - o.transform(Matrix4::translation({1.0f, -0.3f, 2.3f}), TransformationType::Local); + o.transformLocal(Matrix4::translation({1.0f, -0.3f, 2.3f})); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})); } } @@ -156,7 +155,7 @@ void RigidMatrixTransformation3DTest::translate() { } { Object3D o; o.setTransformation(Matrix4::rotationX(Deg(17.0f))); - o.translate({1.0f, -0.3f, 2.3f}, TransformationType::Local); + o.translateLocal({1.0f, -0.3f, 2.3f}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})); } } @@ -178,10 +177,10 @@ void RigidMatrixTransformation3DTest::rotate() { } { Object3D o; o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})); - o.rotateX(Deg(17.0f), TransformationType::Local) - .rotateY(Deg(25.0f), TransformationType::Local) - .rotateZ(Deg(-23.0f), TransformationType::Local) - .rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()), TransformationType::Local); + o.rotateXLocal(Deg(17.0f)) + .rotateYLocal(Deg(25.0f)) + .rotateZLocal(Deg(-23.0f)) + .rotateLocal(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})* Matrix4::rotationX(Deg(17.0f))* @@ -200,7 +199,7 @@ void RigidMatrixTransformation3DTest::reflect() { } { Object3D o; o.setTransformation(Matrix4::rotationX(Deg(17.0f))); - o.reflect(Vector3(-1.0f/Constants::sqrt3()), TransformationType::Local); + o.reflectLocal(Vector3(-1.0f/Constants::sqrt3())); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::reflection(Vector3(-1.0f/Constants::sqrt3()))); } } diff --git a/src/Magnum/SceneGraph/Test/SceneTest.cpp b/src/Magnum/SceneGraph/Test/SceneTest.cpp index bb36a49cb..238fcf04f 100644 --- a/src/Magnum/SceneGraph/Test/SceneTest.cpp +++ b/src/Magnum/SceneGraph/Test/SceneTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,12 +30,11 @@ namespace Magnum { namespace SceneGraph { namespace Test { -class SceneTest: public TestSuite::Tester { - public: - SceneTest(); +struct SceneTest: TestSuite::Tester { + explicit SceneTest(); - void transformation(); - void parent(); + void transformation(); + void parent(); }; typedef SceneGraph::Scene Scene3D; @@ -62,8 +61,8 @@ void SceneTest::parent() { Object3D object; scenePointer->setParent(&object); CORRADE_VERIFY(scene.parent() == nullptr); - CORRADE_VERIFY(!scene.hasChildren()); - CORRADE_VERIFY(!object.hasChildren()); + CORRADE_VERIFY(scene.children().isEmpty()); + CORRADE_VERIFY(object.children().isEmpty()); } }}} diff --git a/src/Magnum/SceneGraph/Test/TranslationTransformationTest.cpp b/src/Magnum/SceneGraph/Test/TranslationTransformationTest.cpp index 2890600e0..c9911e21d 100644 --- a/src/Magnum/SceneGraph/Test/TranslationTransformationTest.cpp +++ b/src/Magnum/SceneGraph/Test/TranslationTransformationTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -35,21 +35,20 @@ namespace Magnum { namespace SceneGraph { namespace Test { typedef Object Object2D; typedef Scene Scene2D; -class TranslationTransformationTest: public TestSuite::Tester { - public: - explicit TranslationTransformationTest(); +struct TranslationTransformationTest: TestSuite::Tester { + explicit TranslationTransformationTest(); - void fromMatrix(); - void toMatrix(); - void compose(); - void inverted(); + void fromMatrix(); + void toMatrix(); + void compose(); + void inverted(); - void setTransformation(); - void resetTransformation(); - void transform(); - void translate(); + void setTransformation(); + void resetTransformation(); + void transform(); + void translate(); - void integral(); + void integral(); }; TranslationTransformationTest::TranslationTransformationTest() { diff --git a/src/Magnum/SceneGraph/TranslationTransformation.h b/src/Magnum/SceneGraph/TranslationTransformation.h index d4de0d0f0..0e377ed47 100644 --- a/src/Magnum/SceneGraph/TranslationTransformation.h +++ b/src/Magnum/SceneGraph/TranslationTransformation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -44,13 +44,9 @@ the translation is stored with the same underlying type as resulting transformation matrix, but it's possible to store translation in e.g. integral coordinates while having floating-point transformation matrix. -Note that translation is commutative, so all @ref TransformationType parameters -have no effect and are included only for compatibility with other -transformation implementations. - -@see @ref BasicTranslationTransformation2D, @ref BasicTranslationTransformation3D, - @ref TranslationTransformation2D, @ref TranslationTransformation3D, - @ref scenegraph +@see @ref scenegraph, @ref BasicTranslationTransformation2D, + @ref BasicTranslationTransformation3D, @ref TranslationTransformation2D, + @ref TranslationTransformation3D */ #ifdef DOXYGEN_GENERATING_OUTPUT template @@ -62,7 +58,7 @@ class TranslationTransformation: public AbstractTranslation::VectorType DataType; - /** @brief %Object transformation */ + /** @brief Object transformation */ typename DimensionTraits::VectorType transformation() const { return _transformation; } /** @@ -87,31 +83,53 @@ class TranslationTransformation: public AbstractTranslation>& transform(const typename DimensionTraits::VectorType& transformation, TransformationType = TransformationType::Global) { + Object>& transform(const typename DimensionTraits::VectorType& transformation) { return translate(transformation); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief transform() + * @deprecated Use @ref Magnum::SceneGraph::TranslationTransformation::transform() "transform()" + * instead. + */ + CORRADE_DEPRECATED("use transform() instead") Object>& transform(const typename DimensionTraits::VectorType& transformation, TransformationType) { + return transform(transformation); + } + #endif + /** * @brief Translate object - * @param vector Translation vector * @return Reference to self (for method chaining) * + * There is no difference between global and local translation. * @see @ref Math::Vector2::xAxis(), @ref Math::Vector2::yAxis(), * @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(), * @ref Math::Vector3::zAxis() */ - Object>& translate(const typename DimensionTraits::VectorType& vector, TransformationType = TransformationType::Global) { + Object>& translate(const typename DimensionTraits::VectorType& vector) { _transformation += vector; return static_cast>&>(*this); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief translate() + * @deprecated Use @ref Magnum::SceneGraph::TranslationTransformation::translate() "translate()" + * instead. + */ + CORRADE_DEPRECATED("use translate() instead") Object>& translate(const typename DimensionTraits::VectorType& vector, TransformationType) { + return translate(vector); + } + #endif + protected: /* Allow construction only from Object */ explicit TranslationTransformation(); @@ -119,7 +137,10 @@ class TranslationTransformation: public AbstractTranslation::VectorType& vector, TransformationType) override final { + void doTranslate(const typename DimensionTraits::VectorType& vector) override final { + translate(vector); + } + void doTranslateLocal(const typename DimensionTraits::VectorType& vector) override final { translate(vector); } @@ -132,7 +153,7 @@ template inline Translat /** @brief Base transformation for two-dimensional scenes supporting translation -Convenience alternative to %TranslationTransformation<2, T, TranslationType>. +Convenience alternative to `TranslationTransformation<2, T, TranslationType>`. See @ref TranslationTransformation for more information. @note Not available on GCC < 4.7. Use %TranslationTransformation<2, T, TranslationType> instead. @@ -163,7 +184,7 @@ typedef TranslationTransformation<2, Float> TranslationTransformation2D; /** @brief Base transformation for three-dimensional scenes supporting translation -Convenience alternative to %TranslationTransformation<3, T, TranslationType>. +Convenience alternative to `TranslationTransformation<3, T, TranslationType>`. See @ref TranslationTransformation for more information. @note Not available on GCC < 4.7. Use %TranslationTransformation<3, T, TranslationType> instead. diff --git a/src/Magnum/SceneGraph/instantiation.cpp b/src/Magnum/SceneGraph/instantiation.cpp index c8f40fb3f..08ba7aab7 100644 --- a/src/Magnum/SceneGraph/instantiation.cpp +++ b/src/Magnum/SceneGraph/instantiation.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/SceneGraph/visibility.h b/src/Magnum/SceneGraph/visibility.h index 51699fce0..ffe2e0cef 100644 --- a/src/Magnum/SceneGraph/visibility.h +++ b/src/Magnum/SceneGraph/visibility.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shader.cpp b/src/Magnum/Shader.cpp index e839c19a8..c32d2e94f 100644 --- a/src/Magnum/Shader.cpp +++ b/src/Magnum/Shader.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shader.h b/src/Magnum/Shader.h index 749174434..67e027c4b 100644 --- a/src/Magnum/Shader.h +++ b/src/Magnum/Shader.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -44,19 +44,19 @@ namespace Magnum { /** -@brief %Shader +@brief Shader See @ref AbstractShaderProgram for usage information. ## Performance optimizations -%Shader limits and implementation-defined values (such as @ref maxUniformComponents()) +Shader limits and implementation-defined values (such as @ref maxUniformComponents()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. */ class MAGNUM_EXPORT Shader: public AbstractObject { public: /** - * @brief %Shader type + * @brief Shader type * * @see @ref Shader(Version, Type), * @ref maxAtomicCounterBuffers(), @@ -74,21 +74,21 @@ class MAGNUM_EXPORT Shader: public AbstractObject { #ifndef MAGNUM_TARGET_GLES /** * Tessellation control shader - * @requires_gl40 %Extension @extension{ARB,tessellation_shader} + * @requires_gl40 Extension @extension{ARB,tessellation_shader} * @requires_gl Tessellation shaders are not available in OpenGL ES. */ TessellationControl = GL_TESS_CONTROL_SHADER, /** * Tessellation evaluation shader - * @requires_gl40 %Extension @extension{ARB,tessellation_shader} + * @requires_gl40 Extension @extension{ARB,tessellation_shader} * @requires_gl Tessellation shaders are not available in OpenGL ES. */ TessellationEvaluation = GL_TESS_EVALUATION_SHADER, /** * Geometry shader - * @requires_gl32 %Extension @extension{ARB,geometry_shader4} + * @requires_gl32 Extension @extension{ARB,geometry_shader4} * @requires_gl Geometry shaders are not available in OpenGL ES. */ Geometry = GL_GEOMETRY_SHADER, @@ -97,7 +97,7 @@ class MAGNUM_EXPORT Shader: public AbstractObject { #ifndef MAGNUM_TARGET_GLES2 /** * Compute shader - * @requires_gl43 %Extension @extension{ARB,compute_shader} + * @requires_gl43 Extension @extension{ARB,compute_shader} * @requires_gles31 Compute shaders are not available in OpenGL ES * 3.0 and older */ @@ -459,7 +459,7 @@ class MAGNUM_EXPORT Shader: public AbstractObject { /** * @brief Constructor * @param version Target version - * @param type %Shader type + * @param type Shader type * * Creates empty OpenGL shader and adds @c \#version directive * corresponding to @p version parameter at the beginning. If @@ -493,7 +493,7 @@ class MAGNUM_EXPORT Shader: public AbstractObject { GLuint id() const { return _id; } /** - * @brief %Shader label + * @brief Shader label * * The result is *not* cached, repeated queries will result in repeated * OpenGL calls. If OpenGL 4.3 is not supported and neither @@ -522,13 +522,13 @@ class MAGNUM_EXPORT Shader: public AbstractObject { /** @overload */ template Shader& setLabel(const char(&label)[size]) { - return setLabelInternal(label); + return setLabelInternal({label, size - 1}); } - /** @brief %Shader type */ + /** @brief Shader type */ Type type() const { return _type; } - /** @brief %Shader sources */ + /** @brief Shader sources */ std::vector sources() const; /** @@ -583,9 +583,10 @@ inline Shader::Shader(Shader&& other) noexcept: _type(other._type), _id(other._i } inline Shader& Shader::operator=(Shader&& other) noexcept { - std::swap(_type, other._type); - std::swap(_id, other._id); - std::swap(_sources, other._sources); + using std::swap; + swap(_type, other._type); + swap(_id, other._id); + swap(_sources, other._sources); return *this; } diff --git a/src/Magnum/Shaders/AbstractVector.cpp b/src/Magnum/Shaders/AbstractVector.cpp index e06d09cc9..6ff6104bc 100644 --- a/src/Magnum/Shaders/AbstractVector.cpp +++ b/src/Magnum/Shaders/AbstractVector.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/AbstractVector.h b/src/Magnum/Shaders/AbstractVector.h index ec184d87b..145e2474d 100644 --- a/src/Magnum/Shaders/AbstractVector.h +++ b/src/Magnum/Shaders/AbstractVector.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,23 +36,33 @@ namespace Magnum { namespace Shaders { /** @brief Base for vector shaders -@see @ref AbstractVector2D, @ref AbstractVector3D +See @ref DistanceFieldVector and @ref Vector for more information. +@see @ref shaders, @ref AbstractVector2D, @ref AbstractVector3D */ template class AbstractVector: public AbstractShaderProgram { public: - /** @brief Vertex position */ + /** + * @brief Vertex position + * + * @ref shaders-generic "Generic attribute", @ref Vector2 in 2D, + * @ref Vector3 in 3D. + */ typedef typename Generic::Position Position; - /** @brief %Texture coordinates */ + /** + * @brief 2D texture coordinates + * + * @ref shaders-generic "Generic attribute", @ref Vector2. + */ typedef typename Generic::TextureCoordinates TextureCoordinates; #ifdef MAGNUM_BUILD_DEPRECATED enum: Int { /** - * %Vector texture binding unit + * Vector texture binding unit * @deprecated Use @ref Magnum::Shaders::AbstractVector::setVectorTexture() "setVectorTexture()" instead. */ - VectorTextureLayer = 16 + VectorTextureLayer = 15 }; #endif @@ -67,7 +77,7 @@ template class AbstractVector: public AbstractShaderProg ~AbstractVector(); #ifndef MAGNUM_BUILD_DEPRECATED - enum: Int { VectorTextureLayer = 16 }; + enum: Int { VectorTextureLayer = 15 }; #endif }; diff --git a/src/Magnum/Shaders/AbstractVector2D.vert b/src/Magnum/Shaders/AbstractVector2D.vert index bb6a4b2ea..eaaf6e806 100644 --- a/src/Magnum/Shaders/AbstractVector2D.vert +++ b/src/Magnum/Shaders/AbstractVector2D.vert @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/AbstractVector3D.vert b/src/Magnum/Shaders/AbstractVector3D.vert index 06c041694..c5c76b159 100644 --- a/src/Magnum/Shaders/AbstractVector3D.vert +++ b/src/Magnum/Shaders/AbstractVector3D.vert @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/CMakeLists.txt b/src/Magnum/Shaders/CMakeLists.txt index 04a0a0db9..18a12277f 100644 --- a/src/Magnum/Shaders/CMakeLists.txt +++ b/src/Magnum/Shaders/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -54,21 +54,18 @@ set(MagnumShaders_PRIVATE_HEADERS Implementation/CreateCompatibilityShader.h) if(BUILD_STATIC) set(MagnumShaders_HEADERS ${MagnumShaders_HEADERS} resourceImport.hpp) - - if(BUILD_DEPRECATED) - set(MagnumShaders_HEADERS ${MagnumShaders_HEADERS} magnumShadersResourceImport.hpp) - endif() endif() +# Shaders library add_library(MagnumShaders ${SHARED_OR_STATIC} ${MagnumShaders_SRCS} ${MagnumShaders_HEADERS} ${MagnumShaders_PRIVATE_HEADERS}) set_target_properties(MagnumShaders PROPERTIES DEBUG_POSTFIX "-d") if(BUILD_STATIC_PIC) - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumShaders PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") + set_target_properties(MagnumShaders PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() + target_link_libraries(MagnumShaders Magnum) install(TARGETS MagnumShaders diff --git a/src/Magnum/Shaders/DistanceFieldVector.cpp b/src/Magnum/Shaders/DistanceFieldVector.cpp index 8241b2a7d..dd9e64ba3 100644 --- a/src/Magnum/Shaders/DistanceFieldVector.cpp +++ b/src/Magnum/Shaders/DistanceFieldVector.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/DistanceFieldVector.frag b/src/Magnum/Shaders/DistanceFieldVector.frag index 15b48a976..23a67a6fb 100644 --- a/src/Magnum/Shaders/DistanceFieldVector.frag +++ b/src/Magnum/Shaders/DistanceFieldVector.frag @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -49,7 +49,7 @@ uniform lowp float smoothness; #endif #ifdef EXPLICIT_TEXTURE_LAYER -layout(binding = 16) uniform sampler2D vectorTexture; +layout(binding = 15) uniform sampler2D vectorTexture; #else uniform lowp sampler2D vectorTexture; #endif diff --git a/src/Magnum/Shaders/DistanceFieldVector.h b/src/Magnum/Shaders/DistanceFieldVector.h index 9512c212b..7a94c034d 100644 --- a/src/Magnum/Shaders/DistanceFieldVector.h +++ b/src/Magnum/Shaders/DistanceFieldVector.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -41,10 +41,52 @@ namespace Magnum { namespace Shaders { /** @brief Distance field vector shader -Renders vector art in form of signed distance field. See @ref TextureTools::distanceField() -for more information. Note that the final rendered outlook will greatly depend -on radius of input distance field and value passed to @ref setSmoothness(). -@see @ref DistanceFieldVector2D, @ref DistanceFieldVector3D +Renders vector graphics in form of signed distance field. See +@ref TextureTools::distanceField() for more information. Note that the final +rendered outlook will greatly depend on radius of input distance field and +value passed to @ref setSmoothness(). You need to provide @ref Position and +@ref TextureCoordinates attributes in your triangle mesh and call at least +@ref setTransformationProjectionMatrix(), @ref setColor() and +@ref setVectorTexture(). + +@image html shaders-distancefieldvector.png +@image latex shaders-distancefieldvector.png + +## Example usage + +Common mesh setup: +@code +struct Vertex { + Vector2 position; + Vector2 textureCoordinates; +}; +Vertex data[] = { ... }; + +Buffer vertices; +vertices.setData(data, BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, + Shaders::DistanceFieldVector2D::Position{}, + Shaders::DistanceFieldVector2D::TextureCoordinates{}); +@endcode + +Common rendering setup: +@code +Matrix3 transformationMatrix, projectionMatrix; +Texture2D texture; + +Shaders::DistanceFieldVector2D shader; +shader.setColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) + .setOutlineColor(Color3{0.95f}) + .setOutlineRange(0.6f, 0.4f) + .setVectorTexture(texture) + .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix); + +mesh.draw(shader); +@endcode + +@see @ref shaders, @ref DistanceFieldVector2D, @ref DistanceFieldVector3D @todo Use fragment shader derivations to have proper smoothness in perspective/ large zoom levels, make it optional as it might have negative performance impact diff --git a/src/Magnum/Shaders/Flat.cpp b/src/Magnum/Shaders/Flat.cpp index ee07d8d39..973868cbc 100644 --- a/src/Magnum/Shaders/Flat.cpp +++ b/src/Magnum/Shaders/Flat.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Flat.frag b/src/Magnum/Shaders/Flat.frag index db41ea0c3..d98543db2 100644 --- a/src/Magnum/Shaders/Flat.frag +++ b/src/Magnum/Shaders/Flat.frag @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Flat.h b/src/Magnum/Shaders/Flat.h index 8b1c687e3..407f99920 100644 --- a/src/Magnum/Shaders/Flat.h +++ b/src/Magnum/Shaders/Flat.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -44,7 +44,7 @@ namespace Implementation { } /** -@brief %Flat shader +@brief Flat shader Draws whole mesh with given unshaded color or texture. For colored mesh you need to provide @ref Position attribute in your triangle mesh and call at least @@ -57,17 +57,88 @@ The texture will be multiplied with the color (which is white by default, thus it doesn't change texture color). For coloring the texture based on intensity you can use the @ref Vector shader. -@see @ref Flat2D, @ref Flat3D + +@image html shaders-flat.png +@image latex shaders-flat.png + +## Example usage + +### Colored mesh + +Common mesh setup: +@code +struct Vertex { + Vector3 position; +}; +Vertex data[] = { ... }; + +Buffer vertices; +vertices.setData(data, BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, Shaders::Flat3D::Position{}); +@endcode + +Common rendering setup: +@code +Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f)); +Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); + +Shaders::Flat3D shader; +shader.setColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) + .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix); + +mesh.draw(shader); +@endcode + +### Textured mesh + +Common mesh setup: +@code +struct Vertex { + Vector3 position; + Vector2 textureCoordinates; +}; +Vertex data[] = { ... }; + +Buffer vertices; +vertices.setData(data, BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, + Shaders::Flat3D::Position{}, + Shaders::Flat3D::TextureCoordinates{}); +@endcode + +Common rendering setup: +@code +Matrix4 transformationMatrix, projectionMatrix; +Texture2D texture; + +Shaders::Flat3D shader{Shaders::Flat3D::Textured}; +shader.setTransformationProjectionMatrix(projectionMatrix*transformationMatrix) + .setTexture(texture); + +mesh.draw(shader); +@endcode + +@see @ref shaders, @ref Flat2D, @ref Flat3D */ template class MAGNUM_SHADERS_EXPORT Flat: public AbstractShaderProgram { public: - /** @brief Vertex position */ + /** + * @brief Vertex position + * + * @ref shaders-generic "Generic attribute", @ref Vector2 in 2D, + * @ref Vector3 in 3D. + */ typedef typename Generic::Position Position; /** - * @brief %Texture coordinates + * @brief 2D texture coordinates * - * Used only if @ref Flag::Textured is set. + * @ref shaders-generic "Generic attribute", @ref Vector2. Used only if + * @ref Flag::Textured is set. */ typedef typename Generic::TextureCoordinates TextureCoordinates; @@ -84,7 +155,7 @@ template class MAGNUM_SHADERS_EXPORT Flat: public Abstra #ifdef DOXYGEN_GENERATING_OUTPUT /** - * @brief %Flag + * @brief Flag * * @see @ref Flags, @ref flags() */ @@ -93,7 +164,7 @@ template class MAGNUM_SHADERS_EXPORT Flat: public Abstra }; /** - * @brief %Flags + * @brief Flags * * @see @ref flags() */ @@ -105,11 +176,11 @@ template class MAGNUM_SHADERS_EXPORT Flat: public Abstra /** * @brief Constructor - * @param flags %Flags + * @param flags Flags */ explicit Flat(Flags flags = Flags()); - /** @brief %Flags */ + /** @brief Flags */ Flags flags() const { return _flags; } /** diff --git a/src/Magnum/Shaders/Flat2D.vert b/src/Magnum/Shaders/Flat2D.vert index b1b7dfc62..43544cf3b 100644 --- a/src/Magnum/Shaders/Flat2D.vert +++ b/src/Magnum/Shaders/Flat2D.vert @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Flat3D.vert b/src/Magnum/Shaders/Flat3D.vert index ecb85c005..8e0163683 100644 --- a/src/Magnum/Shaders/Flat3D.vert +++ b/src/Magnum/Shaders/Flat3D.vert @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/FullScreenTriangle.glsl b/src/Magnum/Shaders/FullScreenTriangle.glsl index 268329de2..45ed802f7 100644 --- a/src/Magnum/Shaders/FullScreenTriangle.glsl +++ b/src/Magnum/Shaders/FullScreenTriangle.glsl @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Generic.h b/src/Magnum/Shaders/Generic.h index 567fa6ab1..267465ed3 100644 --- a/src/Magnum/Shaders/Generic.h +++ b/src/Magnum/Shaders/Generic.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,30 +34,13 @@ namespace Magnum { namespace Shaders { /** -@brief %Generic shader definition +@brief Generic shader definition Definitions common for majority of shaders in @ref Shaders namespace, allowing -mesh configured for the generic shader to be used with any of them. +mesh configured for the generic shader to be used with any of them. See +@ref shaders-generic for more information. -Example usage (configuring the mesh for generic shader, then using it with -@ref Shaders::Phong): -@code -Mesh mesh; -Buffer vertexBuffer; - -// ... - -mesh.addVertexBuffer(vertexBuffer, 0, - Shaders::Generic3D::Position(), - Shaders::Generic3D::Normal(), - Shaders::Generic3D::TextureCoordinates()); - -Shaders::Phong phong; -// ... -mesh.draw(phong); -@endcode - -@see @ref Generic2D, @ref Generic3D +@see @ref shaders, @ref Generic2D, @ref Generic3D */ #ifndef DOXYGEN_GENERATING_OUTPUT template struct Generic; @@ -66,40 +49,44 @@ template struct Generic { /** * @brief Vertex position * - * Defined as @ref Vector2 in 2D and @ref Vector3 in 3D. + * @ref Vector2 in 2D and @ref Vector3 in 3D. */ - typedef AbstractShaderProgram::Attribute<0, T> Position; + typedef Attribute<0, T> Position; - /** @brief 2D texture coordinates */ - typedef AbstractShaderProgram::Attribute<1, Vector2> TextureCoordinates; + /** + * @brief 2D texture coordinates + * + * @ref Vector2. + */ + typedef Attribute<1, Vector2> TextureCoordinates; /** * @brief Vertex normal * - * Defined only in 3D. + * @ref Vector3, defined only in 3D. */ - typedef AbstractShaderProgram::Attribute<2, Vector3> Normal; + typedef Attribute<2, Vector3> Normal; }; #endif -/** @brief %Generic 2D shader definition */ +/** @brief Generic 2D shader definition */ typedef Generic<2> Generic2D; -/** @brief %Generic 3D shader definition */ +/** @brief Generic 3D shader definition */ typedef Generic<3> Generic3D; #ifndef DOXYGEN_GENERATING_OUTPUT struct BaseGeneric { - typedef AbstractShaderProgram::Attribute<1, Vector2> TextureCoordinates; + typedef Attribute<1, Vector2> TextureCoordinates; }; template<> struct Generic<2>: BaseGeneric { - typedef AbstractShaderProgram::Attribute<0, Vector2> Position; + typedef Attribute<0, Vector2> Position; }; template<> struct Generic<3>: BaseGeneric { - typedef AbstractShaderProgram::Attribute<0, Vector3> Position; - typedef AbstractShaderProgram::Attribute<2, Vector3> Normal; + typedef Attribute<0, Vector3> Position; + typedef Attribute<2, Vector3> Normal; }; #endif diff --git a/src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h b/src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h index 5fa3fabd2..353358f8d 100644 --- a/src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h +++ b/src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/MeshVisualizer.cpp b/src/Magnum/Shaders/MeshVisualizer.cpp index 4c1b70abf..a1144a599 100644 --- a/src/Magnum/Shaders/MeshVisualizer.cpp +++ b/src/Magnum/Shaders/MeshVisualizer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/MeshVisualizer.frag b/src/Magnum/Shaders/MeshVisualizer.frag index cb011cdf0..ce613fb14 100644 --- a/src/Magnum/Shaders/MeshVisualizer.frag +++ b/src/Magnum/Shaders/MeshVisualizer.frag @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/MeshVisualizer.geom b/src/Magnum/Shaders/MeshVisualizer.geom index 6e51b930e..e2825989e 100644 --- a/src/Magnum/Shaders/MeshVisualizer.geom +++ b/src/Magnum/Shaders/MeshVisualizer.geom @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/MeshVisualizer.h b/src/Magnum/Shaders/MeshVisualizer.h index 8b9805173..a413c7f60 100644 --- a/src/Magnum/Shaders/MeshVisualizer.h +++ b/src/Magnum/Shaders/MeshVisualizer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,11 +38,14 @@ namespace Magnum { namespace Shaders { /** -@brief %Mesh visualization shader +@brief Mesh visualization shader -Uses geometry shader to visualize wireframe. You need to provide @ref Position -attribute in your triangle mesh and call at least @ref setTransformationProjectionMatrix() -to be able to render. +Uses geometry shader to visualize wireframe of 3D meshes. You need to provide +@ref Position attribute in your triangle mesh and call at least +@ref setTransformationProjectionMatrix() to be able to render. + +@image html shaders-meshvisualizer.png +@image latex shaders-meshvisualizer.png ## Wireframe visualization @@ -51,7 +54,7 @@ either using geometry shaders or with help of additional vertex information. If you have geometry shaders available, you don't need to do anything else. -@requires_gl32 %Extension @extension{ARB,geometry_shader4} for wireframe +@requires_gl32 Extension @extension{ARB,geometry_shader4} for wireframe rendering using geometry shaders. If you don't have geometry shaders, you need to set @ref Flag::NoGeometryShader @@ -60,28 +63,112 @@ meshes (see @ref MeshTools::duplicate() for possible solution). Additionaly, if you have OpenGL < 3.1 or OpenGL ES 2.0, you need to provide also @ref VertexIndex attribute. -@requires_es_extension %Extension @extension{OES,standard_derivatives} for +@requires_es_extension Extension @extension{OES,standard_derivatives} for wireframe rendering. +## Example usage + +### Wireframe visualization with geometry shader (desktop GL) + +Common mesh setup: +@code +struct Vertex { + Vector3 position; +}; +Vertex data[] = { ... }; + +Buffer vertices; +vertices.setData(data, BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, Shaders::MeshVisualizer::Position{}); +@endcode + +Common rendering setup: +@code +Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f)); +Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); + +Shaders::MeshVisualizer shader{Shaders::MeshVisualizer::Wireframe}; +shader.setColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) + .setWireframeColor(Color3{0.95f}) + .setViewportSize(defaultFramebuffer.viewport().size()) + .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix); + +mesh.draw(shader); +@endcode + +### Wireframe visualization without geometry shader on older hardware + +You need to provide also the @ref VertexIndex attribute. Mesh setup *in +addition to the above*: +@code +constexpr std::size_t vertexCount = std::extent::value; +Float vertexIndex[vertexCount]; +std::iota(vertexIndex, vertexIndex + vertexCount, 0.0f); + +Buffer vertexIndices; +vertexIndices.setData(vertexIndex, BufferUsage::StaticDraw); + +mesh.addVertexBuffer(vertexIndices, 0, Shaders::MeshVisualizer::VertexIndex{}); +@endcode + +Rendering setup: +@code +Matrix4 transformationMatrix, projectionMatrix; + +Shaders::MeshVisualizer shader{Shaders::MeshVisualizer::Wireframe| + Shaders::MeshVisualizer::NoGeometryShader}; +shader.setColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) + .setWireframeColor(Color3{0.95f}) + .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix); + +mesh.draw(shader); +@endcode + +### Wireframe visualization of indexed meshes without geometry shader + +The vertices must be converted to non-indexed array. Mesh setup: +@code +std::vector indices{ ... }; +std::vector indexedPositions{ ... }; + +// De-indexing the position array +Buffer vertices; +vertices.setData(MeshTools::duplicate(indices, indexedPositions), BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, Shaders::MeshVisualizer::Position{}); +@endcode + +Rendering setup the same as above. + +@see @ref shaders @todo Understand and add support wireframe width/smoothness without GS */ class MAGNUM_SHADERS_EXPORT MeshVisualizer: public AbstractShaderProgram { public: - typedef Attribute<0, Vector3> Position; /**< @brief Vertex position */ + /** + * @brief Vertex position + * + * @ref shaders-generic "Generic attribute", @ref Vector3. + */ + typedef Attribute<0, Vector3> Position; /** * @brief Vertex index * - * Used only in OpenGL < 3.1 and OpenGL ES 2.0 if @ref Flag::Wireframe - * is enabled. This attribute specifies index of given vertex in - * triangle, i.e. `0` for first, `1` for second, `2` for third. In - * OpenGL 3.1, OpenGL ES 3.0 and newer this value is provided by the - * shader itself, so the attribute is not needed. + * @ref Magnum::Float "Float", used only in OpenGL < 3.1 and OpenGL ES + * 2.0 if @ref Flag::Wireframe is enabled. This attribute (modulo 3) + * specifies index of given vertex in triangle, i.e. `0` for first, `1` + * for second, `2` for third. In OpenGL 3.1, OpenGL ES 3.0 and newer + * this value is provided by the shader itself, so the attribute is not + * needed. */ typedef Attribute<3, Float> VertexIndex; /** - * @brief %Flag + * @brief Flag * * @see @ref Flags, @ref MeshVisualizer() */ @@ -105,12 +192,12 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer: public AbstractShaderProgram { NoGeometryShader = 1 << 1 }; - /** @brief %Flags */ + /** @brief Flags */ typedef Containers::EnumSet Flags; /** * @brief Constructor - * @param flags %Flags + * @param flags Flags */ explicit MeshVisualizer(Flags flags = Flags()); diff --git a/src/Magnum/Shaders/MeshVisualizer.vert b/src/Magnum/Shaders/MeshVisualizer.vert index b8adcb1ba..7a105aed2 100644 --- a/src/Magnum/Shaders/MeshVisualizer.vert +++ b/src/Magnum/Shaders/MeshVisualizer.vert @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Phong.cpp b/src/Magnum/Shaders/Phong.cpp index fd52a0d2f..0cee1f213 100644 --- a/src/Magnum/Shaders/Phong.cpp +++ b/src/Magnum/Shaders/Phong.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Phong.frag b/src/Magnum/Shaders/Phong.frag index 9b9a96bfc..30c70d195 100644 --- a/src/Magnum/Shaders/Phong.frag +++ b/src/Magnum/Shaders/Phong.frag @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Phong.h b/src/Magnum/Shaders/Phong.h index 44a2799ac..600c1aaf3 100644 --- a/src/Magnum/Shaders/Phong.h +++ b/src/Magnum/Shaders/Phong.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,7 +37,7 @@ namespace Magnum { namespace Shaders { /** -@brief %Phong shader +@brief Phong shader Uses ambient, diffuse and specular color or texture. For colored mesh you need to provide @ref Position and @ref Normal attributes in your triangle mesh and @@ -48,17 +48,108 @@ If you want to use texture instead of color, you need to provide also @ref TextureCoordinates attribute. Pass appropriate flags to constructor and then at render time don't forget to also call appropriate subset of @ref setAmbientTexture(), @ref setDiffuseTexture() and @ref setSpecularTexture(). + +@image html shaders-phong.png +@image latex shaders-phong.png + +## Example usage + +### Colored mesh + +Common mesh setup: +@code +struct Vertex { + Vector3 position; + Vector3 normal; +}; +Vertex data[] = { ... }; + +Buffer vertices; +vertices.setData(data, BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, + Shaders::Phong::Position{}, + Shaders::Phong::Normal{}); +@endcode + +Common rendering setup: +@code +Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f)); +Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); + +Shaders::Phong shader; +shader.setDiffuseColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) + .setShininess(200.0f) + .setLightPosition({5.0f, 5.0f, 7.0f}) + .setTransformationMatrix(transformationMatrix) + .setNormalMatrix(transformationMatrix.rotation()) + .setProjectionMatrix(projectionMatrix); + +mesh.draw(shader); +@endcode + +### Diffuse and specular texture + +Common mesh setup: +@code +struct Vertex { + Vector3 position; + Vector3 normal; + Vector2 textureCoordinates; +}; +Vertex data[] = { ... }; + +Buffer vertices; +vertices.setData(data, BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, + Shaders::Phong::Position{}, + Shaders::Phong::Normal{}, + Shaders::Phong::TextureCoordinates{}); +@endcode + +Common rendering setup: +@code +Matrix4 transformationMatrix, projectionMatrix; +Texture2D diffuseTexture, specularTexture; + +Shaders::Phong shader{Shaders::Phong::DiffuseTexture| + Shaders::Phong::SpecularTexture}; +shader.setTextures(nullptr, &diffuseTexture, &specularTexture) + .setLightPosition({5.0f, 5.0f, 7.0f}) + .setTransformationMatrix(transformationMatrix) + .setNormalMatrix(transformationMatrix.rotation()) + .setProjectionMatrix(projectionMatrix); + +mesh.draw(shader); +@endcode + +@see @ref shaders */ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { public: - typedef Generic3D::Position Position; /**< @brief Vertex position */ - typedef Generic3D::Normal Normal; /**< @brief Normal direction */ + /** + * @brief Vertex position + * + * @ref shaders-generic "Generic attribute", @ref Vector3. + */ + typedef Generic3D::Position Position; + + /** + * @brief Normal direction + * + * @ref shaders-generic "Generic attribute", @ref Vector3. + */ + typedef Generic3D::Normal Normal; /** - * @brief %Texture coordinates + * @brief 2D texture coordinates * - * Used only if one of @ref Flag::AmbientTexture, @ref Flag::DiffuseTexture - * or @ref Flag::SpecularTexture is set. + * @ref shaders-generic "Generic attribute", @ref Vector2, used only if + * at least one of @ref Flag::AmbientTexture, @ref Flag::DiffuseTexture + * and @ref Flag::SpecularTexture is set. */ typedef Generic3D::TextureCoordinates TextureCoordinates; @@ -91,7 +182,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { #endif /** - * @brief %Flag + * @brief Flag * * @see @ref Flags, @ref flags() */ @@ -102,7 +193,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { }; /** - * @brief %Flags + * @brief Flags * * @see @ref flags() */ @@ -110,18 +201,18 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { /** * @brief Constructor - * @param flags %Flags + * @param flags Flags */ explicit Phong(Flags flags = Flags()); - /** @brief %Flags */ + /** @brief Flags */ Flags flags() const { return _flags; } /** * @brief Set ambient color * @return Reference to self (for method chaining) * - * If not set, default value is `(0.0f, 0.0f, 0.0f)`. Has no effect if + * If not set, default value is `{0.0f, 0.0f, 0.0f}`. Has no effect if * @ref Flag::AmbientTexture is set. * @see @ref setAmbientTexture() */ @@ -158,7 +249,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * @brief Set specular color * @return Reference to self (for method chaining) * - * If not set, default value is `(1.0f, 1.0f, 1.0f)`. Has no effect if + * If not set, default value is `{1.0f, 1.0f, 1.0f}`. Has no effect if * @ref Flag::SpecularTexture is set. * @see @ref setSpecularTexture() */ @@ -240,7 +331,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * @brief Set light color * @return Reference to self (for method chaining) * - * If not set, default value is `(1.0f, 1.0f, 1.0f)`. + * If not set, default value is `{1.0f, 1.0f, 1.0f}`. */ Phong& setLightColor(const Color3& color) { setUniform(lightColorUniform, color); diff --git a/src/Magnum/Shaders/Phong.vert b/src/Magnum/Shaders/Phong.vert index 2f04b482e..8e93565f0 100644 --- a/src/Magnum/Shaders/Phong.vert +++ b/src/Magnum/Shaders/Phong.vert @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Shaders.h b/src/Magnum/Shaders/Shaders.h index d3fd54b2f..d213b3844 100644 --- a/src/Magnum/Shaders/Shaders.h +++ b/src/Magnum/Shaders/Shaders.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,6 +33,7 @@ namespace Magnum { namespace Shaders { +#ifndef DOXYGEN_GENERATING_OUTPUT template class DistanceFieldVector; typedef DistanceFieldVector<2> DistanceFieldVector2D; typedef DistanceFieldVector<3> DistanceFieldVector3D; @@ -57,6 +58,7 @@ typedef Vector<3> Vector3D; template class VertexColor; typedef VertexColor<2> VertexColor2D; typedef VertexColor<3> VertexColor3D; +#endif }} diff --git a/src/Magnum/Shaders/Test/CMakeLists.txt b/src/Magnum/Shaders/Test/CMakeLists.txt index e2bb8b56d..bcabd8117 100644 --- a/src/Magnum/Shaders/Test/CMakeLists.txt +++ b/src/Magnum/Shaders/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp b/src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp index a2976e152..f658b4835 100644 --- a/src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp +++ b/src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,12 +32,11 @@ namespace Magnum { namespace Shaders { namespace Test { -class DistanceFieldVectorGLTest: public Magnum::Test::AbstractOpenGLTester { - public: - explicit DistanceFieldVectorGLTest(); +struct DistanceFieldVectorGLTest: Magnum::Test::AbstractOpenGLTester { + explicit DistanceFieldVectorGLTest(); - void compile2D(); - void compile3D(); + void compile2D(); + void compile3D(); }; DistanceFieldVectorGLTest::DistanceFieldVectorGLTest() { diff --git a/src/Magnum/Shaders/Test/FlatGLTest.cpp b/src/Magnum/Shaders/Test/FlatGLTest.cpp index 5554938fe..6b89dfea7 100644 --- a/src/Magnum/Shaders/Test/FlatGLTest.cpp +++ b/src/Magnum/Shaders/Test/FlatGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,14 +32,13 @@ namespace Magnum { namespace Shaders { namespace Test { -class FlatGLTest: public Magnum::Test::AbstractOpenGLTester { - public: - explicit FlatGLTest(); +struct FlatGLTest: Magnum::Test::AbstractOpenGLTester { + explicit FlatGLTest(); - void compile2D(); - void compile3D(); - void compile2DTextured(); - void compile3DTextured(); + void compile2D(); + void compile3D(); + void compile2DTextured(); + void compile3DTextured(); }; FlatGLTest::FlatGLTest() { diff --git a/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp b/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp index b00e9186e..0ce071067 100644 --- a/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp +++ b/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,13 +34,12 @@ namespace Magnum { namespace Shaders { namespace Test { -class MeshVisualizerGLTest: public Magnum::Test::AbstractOpenGLTester { - public: - explicit MeshVisualizerGLTest(); +struct MeshVisualizerGLTest: Magnum::Test::AbstractOpenGLTester { + explicit MeshVisualizerGLTest(); - void compile(); - void compileWireframeGeometryShader(); - void compileWireframeNoGeometryShader(); + void compile(); + void compileWireframeGeometryShader(); + void compileWireframeNoGeometryShader(); }; MeshVisualizerGLTest::MeshVisualizerGLTest() { diff --git a/src/Magnum/Shaders/Test/PhongGLTest.cpp b/src/Magnum/Shaders/Test/PhongGLTest.cpp index 4482962a3..516c69ad7 100644 --- a/src/Magnum/Shaders/Test/PhongGLTest.cpp +++ b/src/Magnum/Shaders/Test/PhongGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,18 +32,17 @@ namespace Magnum { namespace Shaders { namespace Test { -class PhongGLTest: public Magnum::Test::AbstractOpenGLTester { - public: - explicit PhongGLTest(); - - void compile(); - void compileAmbientTexture(); - void compileDiffuseTexture(); - void compileSpecularTexture(); - void compileAmbientDiffuseTexture(); - void compileAmbientSpecularTexture(); - void compileDiffuseSpecularTexture(); - void compileAmbientDiffuseSpecularTexture(); +struct PhongGLTest: Magnum::Test::AbstractOpenGLTester { + explicit PhongGLTest(); + + void compile(); + void compileAmbientTexture(); + void compileDiffuseTexture(); + void compileSpecularTexture(); + void compileAmbientDiffuseTexture(); + void compileAmbientSpecularTexture(); + void compileDiffuseSpecularTexture(); + void compileAmbientDiffuseSpecularTexture(); }; PhongGLTest::PhongGLTest() { diff --git a/src/Magnum/Shaders/Test/VectorGLTest.cpp b/src/Magnum/Shaders/Test/VectorGLTest.cpp index 7098912c4..0ca53fd77 100644 --- a/src/Magnum/Shaders/Test/VectorGLTest.cpp +++ b/src/Magnum/Shaders/Test/VectorGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,12 +32,11 @@ namespace Magnum { namespace Shaders { namespace Test { -class VectorGLTest: public Magnum::Test::AbstractOpenGLTester { - public: - explicit VectorGLTest(); +struct VectorGLTest: Magnum::Test::AbstractOpenGLTester { + explicit VectorGLTest(); - void compile2D(); - void compile3D(); + void compile2D(); + void compile3D(); }; VectorGLTest::VectorGLTest() { diff --git a/src/Magnum/Shaders/Test/VertexColorGLTest.cpp b/src/Magnum/Shaders/Test/VertexColorGLTest.cpp index fbce51cf5..02e0baae0 100644 --- a/src/Magnum/Shaders/Test/VertexColorGLTest.cpp +++ b/src/Magnum/Shaders/Test/VertexColorGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,12 +32,11 @@ namespace Magnum { namespace Shaders { namespace Test { -class VertexColorGLTest: public Magnum::Test::AbstractOpenGLTester { - public: - explicit VertexColorGLTest(); +struct VertexColorGLTest: Magnum::Test::AbstractOpenGLTester { + explicit VertexColorGLTest(); - void compile2D(); - void compile3D(); + void compile2D(); + void compile3D(); }; VertexColorGLTest::VertexColorGLTest() { diff --git a/src/Magnum/Shaders/Vector.cpp b/src/Magnum/Shaders/Vector.cpp index fdb4c6109..9a7f7b6cd 100644 --- a/src/Magnum/Shaders/Vector.cpp +++ b/src/Magnum/Shaders/Vector.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/Vector.frag b/src/Magnum/Shaders/Vector.frag index a1fe76039..40c46af82 100644 --- a/src/Magnum/Shaders/Vector.frag +++ b/src/Magnum/Shaders/Vector.frag @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,7 +38,7 @@ uniform lowp vec4 color; #endif #ifdef EXPLICIT_TEXTURE_LAYER -layout(binding = 16) uniform sampler2D vectorTexture; +layout(binding = 15) uniform sampler2D vectorTexture; #else uniform lowp sampler2D vectorTexture; #endif diff --git a/src/Magnum/Shaders/Vector.h b/src/Magnum/Shaders/Vector.h index ae73cf8d0..e6288c3ad 100644 --- a/src/Magnum/Shaders/Vector.h +++ b/src/Magnum/Shaders/Vector.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -39,12 +39,51 @@ namespace Magnum { namespace Shaders { /** -@brief %Vector shader +@brief Vector shader Renders vector art in plain grayscale form. See also @ref DistanceFieldVector for more advanced effects. For rendering unchanged texture you can use the -@ref Flat shader. -@see @ref Vector2D, @ref Vector3D +@ref Flat shader. You need to provide @ref Position and @ref TextureCoordinates +attributes in your triangle mesh and call at least +@ref setTransformationProjectionMatrix(), @ref setColor() and +@ref setVectorTexture(). + +@image html shaders-vector.png +@image latex shaders-vector.png + +## Example usage + +Common mesh setup: +@code +struct Vertex { + Vector2 position; + Vector2 textureCoordinates; +}; +Vertex data[] = { ... }; + +Buffer vertices; +vertices.setData(data, BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, + Shaders::Vector2D::Position{}, + Shaders::Vector2D::TextureCoordinates{}); +@endcode + +Common rendering setup: +@code +Matrix3 transformationMatrix, projectionMatrix; +Texture2D texture; + +Shaders::Vector2D shader; +shader.setColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) + .setVectorTexture(texture) + .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix); + +mesh.draw(shader); +@endcode + +@see @ref shaders, @ref Vector2D, @ref Vector3D */ template class MAGNUM_SHADERS_EXPORT Vector: public AbstractVector { public: diff --git a/src/Magnum/Shaders/VertexColor.cpp b/src/Magnum/Shaders/VertexColor.cpp index 539f25289..bed259c89 100644 --- a/src/Magnum/Shaders/VertexColor.cpp +++ b/src/Magnum/Shaders/VertexColor.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/VertexColor.frag b/src/Magnum/Shaders/VertexColor.frag index 889a5c0be..9456d219b 100644 --- a/src/Magnum/Shaders/VertexColor.frag +++ b/src/Magnum/Shaders/VertexColor.frag @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/VertexColor.h b/src/Magnum/Shaders/VertexColor.h index 4cb7cc865..bb5c221c6 100644 --- a/src/Magnum/Shaders/VertexColor.h +++ b/src/Magnum/Shaders/VertexColor.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -41,15 +41,60 @@ namespace Magnum { namespace Shaders { /** @brief Vertex color shader -Draws vertex-colored mesh. -@see @ref VertexColor2D, @ref VertexColor3D +Draws vertex-colored mesh. You need to provide @ref Position and @ref Color +attributes in your triangle mesh and call at least +@ref setTransformationProjectionMatrix(). + +@image html shaders-vertexcolor.png +@image latex shaders-vertexcolor.png + +## Example usage + +Common mesh setup: +@code +struct Vertex { + Vector3 position; + Color3 color; +}; +Vertex data[] = { ... }; + +Buffer vertices; +vertices.setData(data, BufferUsage::StaticDraw); + +Mesh mesh; +mesh.addVertexBuffer(vertices, 0, + Shaders::VertexColor3D::Position{}, + Shaders::VertexColor3D::Color{}); +@endcode + +Common rendering setup: +@code +Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f)); +Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); + +Shaders::VertexColor3D shader; +shader.setTransformationProjectionMatrix(projectionMatrix*transformationMatrix); + +mesh.draw(shader); +@endcode + +@see @ref shaders, @ref VertexColor2D, @ref VertexColor3D */ template class MAGNUM_SHADERS_EXPORT VertexColor: public AbstractShaderProgram { public: - /** @brief Vertex position */ + /** + * @brief Vertex position + * + * @ref shaders-generic "Generic attribute", @ref Vector2 in 2D, + * @ref Vector3 in 3D. + */ typedef typename Generic::Position Position; - /** @brief Vertex color */ + /** + * @brief Vertex color + * + * @ref shaders-generic "Generic attribute", @ref Vector3. + */ typedef Attribute<3, Color3> Color; explicit VertexColor(); diff --git a/src/Magnum/Shaders/VertexColor2D.vert b/src/Magnum/Shaders/VertexColor2D.vert index b3e0a242e..e3c5de102 100644 --- a/src/Magnum/Shaders/VertexColor2D.vert +++ b/src/Magnum/Shaders/VertexColor2D.vert @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/VertexColor3D.vert b/src/Magnum/Shaders/VertexColor3D.vert index 2fc4ebd5a..faae0e333 100644 --- a/src/Magnum/Shaders/VertexColor3D.vert +++ b/src/Magnum/Shaders/VertexColor3D.vert @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/compatibility.glsl b/src/Magnum/Shaders/compatibility.glsl index e041903d6..7fd075b63 100644 --- a/src/Magnum/Shaders/compatibility.glsl +++ b/src/Magnum/Shaders/compatibility.glsl @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/generic.glsl b/src/Magnum/Shaders/generic.glsl index c4fd0c914..066359be8 100644 --- a/src/Magnum/Shaders/generic.glsl +++ b/src/Magnum/Shaders/generic.glsl @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/resourceImport.hpp b/src/Magnum/Shaders/resourceImport.hpp index 7ce0a164d..2962a373d 100644 --- a/src/Magnum/Shaders/resourceImport.hpp +++ b/src/Magnum/Shaders/resourceImport.hpp @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shaders/visibility.h b/src/Magnum/Shaders/visibility.h index 5ed4db950..0c14bdb36 100644 --- a/src/Magnum/Shaders/visibility.h +++ b/src/Magnum/Shaders/visibility.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/AbstractShape.cpp b/src/Magnum/Shapes/AbstractShape.cpp index 8bb10797a..322c53aac 100644 --- a/src/Magnum/Shapes/AbstractShape.cpp +++ b/src/Magnum/Shapes/AbstractShape.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/AbstractShape.h b/src/Magnum/Shapes/AbstractShape.h index 4250651ac..17a1e5003 100644 --- a/src/Magnum/Shapes/AbstractShape.h +++ b/src/Magnum/Shapes/AbstractShape.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -67,7 +67,7 @@ template class MAGNUM_SHAPES_EXPORT AbstractShape: publi Dimensions = dimensions /**< Dimension count */ }; - /** @brief %Shape type */ + /** @brief Shape type */ #ifdef DOXYGEN_GENERATING_OUTPUT enum class Type { Point, /**< Point */ @@ -92,14 +92,14 @@ template class MAGNUM_SHAPES_EXPORT AbstractShape: publi explicit AbstractShape(SceneGraph::AbstractObject& object, ShapeGroup* group = nullptr); /** - * @brief %Shape group containing this shape + * @brief Shape group containing this shape * * If the shape doesn't belong to any group, returns `nullptr`. */ ShapeGroup* group(); const ShapeGroup* group() const; /**< @overload */ - /** @brief %Shape type */ + /** @brief Shape type */ Type type() const; /** @@ -110,7 +110,7 @@ template class MAGNUM_SHAPES_EXPORT AbstractShape: publi bool collides(const AbstractShape& other) const; /** - * @brief %Collision with other shape + * @brief Collision with other shape * * Default implementation returns empty collision. */ diff --git a/src/Magnum/Shapes/AxisAlignedBox.cpp b/src/Magnum/Shapes/AxisAlignedBox.cpp index d75d3695d..6b5a65a39 100644 --- a/src/Magnum/Shapes/AxisAlignedBox.cpp +++ b/src/Magnum/Shapes/AxisAlignedBox.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/AxisAlignedBox.h b/src/Magnum/Shapes/AxisAlignedBox.h index bb2d1076e..d6f95041a 100644 --- a/src/Magnum/Shapes/AxisAlignedBox.h +++ b/src/Magnum/Shapes/AxisAlignedBox.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -82,7 +82,7 @@ template class MAGNUM_SHAPES_EXPORT AxisAlignedBox { _max = max; } - /** @brief %Collision occurence with point */ + /** @brief Collision occurence with point */ bool operator%(const Point& other) const; private: diff --git a/src/Magnum/Shapes/Box.cpp b/src/Magnum/Shapes/Box.cpp index 13dbaecf2..a271176f3 100644 --- a/src/Magnum/Shapes/Box.cpp +++ b/src/Magnum/Shapes/Box.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Box.h b/src/Magnum/Shapes/Box.h index e6b785cd6..a9a863692 100644 --- a/src/Magnum/Shapes/Box.h +++ b/src/Magnum/Shapes/Box.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/CMakeLists.txt b/src/Magnum/Shapes/CMakeLists.txt index 42f90ba38..4e2a5af48 100644 --- a/src/Magnum/Shapes/CMakeLists.txt +++ b/src/Magnum/Shapes/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -64,15 +64,16 @@ set(MagnumShapes_HEADERS # Header files to display in project view of IDEs only set(MagnumShapes_PRIVATE_HEADERS Implementation/CollisionDispatch.h) +# Shapes library add_library(MagnumShapes ${SHARED_OR_STATIC} ${MagnumShapes_SRCS} ${MagnumShapes_HEADERS} ${MagnumShapes_PRIVATE_HEADERS}) set_target_properties(MagnumShapes PROPERTIES DEBUG_POSTFIX "-d") if(BUILD_STATIC_PIC) - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumShapes PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") + set_target_properties(MagnumShapes PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() + target_link_libraries(MagnumShapes Magnum MagnumSceneGraph) install(TARGETS MagnumShapes diff --git a/src/Magnum/Shapes/Capsule.cpp b/src/Magnum/Shapes/Capsule.cpp index 0e95e1843..6bb654e4f 100644 --- a/src/Magnum/Shapes/Capsule.cpp +++ b/src/Magnum/Shapes/Capsule.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Capsule.h b/src/Magnum/Shapes/Capsule.h index e760327fc..5419807f0 100644 --- a/src/Magnum/Shapes/Capsule.h +++ b/src/Magnum/Shapes/Capsule.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -37,7 +37,7 @@ namespace Magnum { namespace Shapes { /** -@brief %Capsule defined by cylinder start and end point and radius +@brief Capsule defined by cylinder start and end point and radius Unlike other elements the capsule expects uniform scaling. See @ref shapes for brief introduction. @@ -90,10 +90,10 @@ template class MAGNUM_SHAPES_EXPORT Capsule { /** @brief Set radius */ void setRadius(Float radius) { _radius = radius; } - /** @brief %Collision occurence with point */ + /** @brief Collision occurence with point */ bool operator%(const Point& other) const; - /** @brief %Collision occurence with sphere */ + /** @brief Collision occurence with sphere */ bool operator%(const Sphere& other) const; private: diff --git a/src/Magnum/Shapes/Collision.h b/src/Magnum/Shapes/Collision.h index 71687ccf0..69c85106c 100644 --- a/src/Magnum/Shapes/Collision.h +++ b/src/Magnum/Shapes/Collision.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,7 @@ namespace Magnum { namespace Shapes { /** -@brief %Collision data +@brief Collision data Contains information about collision between objects A and B, described by contact position, separation normal and separation distance. @@ -80,7 +80,7 @@ template class Collision { */ operator bool() const { return _separationDistance > 0.0f; } - /** @brief %Collision position */ + /** @brief Collision position */ typename DimensionTraits::VectorType position() const { return _position; } @@ -97,8 +97,7 @@ template class Collision { /** * @brief Separation distance * - * @see @ref separationNormal(), operator bool() - * @todoc Explicit reference when Doxygen can handle conversion operators + * @see @ref separationNormal(), @ref operator bool() */ Float separationDistance() const { return _separationDistance; diff --git a/src/Magnum/Shapes/Composition.cpp b/src/Magnum/Shapes/Composition.cpp index 09a0bbabc..511e47f4f 100644 --- a/src/Magnum/Shapes/Composition.cpp +++ b/src/Magnum/Shapes/Composition.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -96,8 +96,9 @@ template Composition& Composition Composition& Composition::operator=(Composition&& other) { - std::swap(other._shapes, _shapes); - std::swap(other._nodes, _nodes); + using std::swap; + swap(other._shapes, _shapes); + swap(other._nodes, _nodes); return *this; } diff --git a/src/Magnum/Shapes/Composition.h b/src/Magnum/Shapes/Composition.h index 593a81458..30545f8d5 100644 --- a/src/Magnum/Shapes/Composition.h +++ b/src/Magnum/Shapes/Composition.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -52,7 +52,7 @@ namespace Implementation { } } -/** @brief %Shape operation */ +/** @brief Shape operation */ enum class CompositionOperation: UnsignedByte { Not, /**< Boolean NOT */ And, /**< Boolean AND */ @@ -60,7 +60,7 @@ enum class CompositionOperation: UnsignedByte { }; /** -@brief %Composition of shapes +@brief Composition of shapes Result of logical operations on shapes. See @ref shapes for brief introduction. */ @@ -73,14 +73,14 @@ template class MAGNUM_SHAPES_EXPORT Composition { template friend Implementation::AbstractShape& Implementation::getAbstractShape(Composition&, std::size_t); template friend const Implementation::AbstractShape& Implementation::getAbstractShape(const Composition&, std::size_t); #endif - friend struct Implementation::ShapeHelper>; + friend Implementation::ShapeHelper>; public: enum: UnsignedInt { Dimensions = dimensions /**< Dimension count */ }; - /** @brief %Shape type */ + /** @brief Shape type */ #ifdef DOXYGEN_GENERATING_OUTPUT enum class Type { Point, /**< Point */ @@ -143,10 +143,10 @@ template class MAGNUM_SHAPES_EXPORT Composition { /** @brief Type of shape at given position */ Type type(std::size_t i) const { return _shapes[i]->type(); } - /** @brief %Shape at given position */ + /** @brief Shape at given position */ template const T& get(std::size_t i) const; - /** @brief %Collision with another shape */ + /** @brief Collision with another shape */ #ifdef DOXYGEN_GENERATING_OUTPUT template bool operator%(const T& other) const { #else @@ -205,7 +205,7 @@ template Debug operator<<(Debug debug, typename Composit #endif /** @relates Composition -@brief %Collision occurence of shape with %Composition +@brief Collision occurence of shape with Composition */ #ifdef DOXYGEN_GENERATING_OUTPUT template inline bool operator%(const T& a, const Composition& b) { diff --git a/src/Magnum/Shapes/Cylinder.cpp b/src/Magnum/Shapes/Cylinder.cpp index aeb4ab640..451a0f206 100644 --- a/src/Magnum/Shapes/Cylinder.cpp +++ b/src/Magnum/Shapes/Cylinder.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Cylinder.h b/src/Magnum/Shapes/Cylinder.h index 04a311a71..91a08b579 100644 --- a/src/Magnum/Shapes/Cylinder.h +++ b/src/Magnum/Shapes/Cylinder.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -90,10 +90,10 @@ template class MAGNUM_SHAPES_EXPORT Cylinder { /** @brief Set radius */ void setRadius(Float radius) { _radius = radius; } - /** @brief %Collision occurence with point */ + /** @brief Collision occurence with point */ bool operator%(const Point& other) const; - /** @brief %Collision occurence with sphere */ + /** @brief Collision occurence with sphere */ bool operator%(const Sphere& other) const; private: diff --git a/src/Magnum/Shapes/Implementation/CollisionDispatch.cpp b/src/Magnum/Shapes/Implementation/CollisionDispatch.cpp index 7a57a0282..b12d60f66 100644 --- a/src/Magnum/Shapes/Implementation/CollisionDispatch.cpp +++ b/src/Magnum/Shapes/Implementation/CollisionDispatch.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Implementation/CollisionDispatch.h b/src/Magnum/Shapes/Implementation/CollisionDispatch.h index 84d79aa2f..938645d38 100644 --- a/src/Magnum/Shapes/Implementation/CollisionDispatch.h +++ b/src/Magnum/Shapes/Implementation/CollisionDispatch.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Line.cpp b/src/Magnum/Shapes/Line.cpp index d492ec8b0..e0a7ce944 100644 --- a/src/Magnum/Shapes/Line.cpp +++ b/src/Magnum/Shapes/Line.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Line.h b/src/Magnum/Shapes/Line.h index b000a14d5..45cdd36d1 100644 --- a/src/Magnum/Shapes/Line.h +++ b/src/Magnum/Shapes/Line.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/LineSegment.h b/src/Magnum/Shapes/LineSegment.h index da20b31b5..ac1f95f09 100644 --- a/src/Magnum/Shapes/LineSegment.h +++ b/src/Magnum/Shapes/LineSegment.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,7 +34,7 @@ namespace Magnum { namespace Shapes { /** -@brief %Line segment, defined by starting and ending point +@brief Line segment, defined by starting and ending point See @ref shapes for brief introduction. @see @ref LineSegment2D, @ref LineSegment3D diff --git a/src/Magnum/Shapes/Plane.cpp b/src/Magnum/Shapes/Plane.cpp index 665a5e2ae..aaa86a064 100644 --- a/src/Magnum/Shapes/Plane.cpp +++ b/src/Magnum/Shapes/Plane.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,8 +25,6 @@ #include "Plane.h" -#include - #include "Magnum/Math/Matrix4.h" #include "Magnum/Math/Geometry/Intersection.h" #include "Magnum/Shapes/LineSegment.h" @@ -45,7 +43,7 @@ Plane Plane::transformed(const Matrix4& matrix) const { bool Plane::operator%(const Line3D& other) const { Float t = Intersection::planeLine(_position, _normal, other.a(), other.b()-other.a()); - return t != t || (t != std::numeric_limits::infinity() && t != -std::numeric_limits::infinity()); + return t != t || (t != Constants::inf() && t != -Constants::inf()); } bool Plane::operator%(const LineSegment3D& other) const { diff --git a/src/Magnum/Shapes/Plane.h b/src/Magnum/Shapes/Plane.h index 70d6ec18c..9a314a668 100644 --- a/src/Magnum/Shapes/Plane.h +++ b/src/Magnum/Shapes/Plane.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -77,10 +77,10 @@ class MAGNUM_SHAPES_EXPORT Plane { _normal = normal; } - /** @brief %Collision occurence with line */ + /** @brief Collision occurence with line */ bool operator%(const Line3D& other) const; - /** @brief %Collision occurence with line segment */ + /** @brief Collision occurence with line segment */ bool operator%(const LineSegment3D& other) const; private: diff --git a/src/Magnum/Shapes/Point.cpp b/src/Magnum/Shapes/Point.cpp index a4bd7c5d2..44ea50f99 100644 --- a/src/Magnum/Shapes/Point.cpp +++ b/src/Magnum/Shapes/Point.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Point.h b/src/Magnum/Shapes/Point.h index b2358ade3..924639e7a 100644 --- a/src/Magnum/Shapes/Point.h +++ b/src/Magnum/Shapes/Point.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,7 +36,7 @@ namespace Magnum { namespace Shapes { /** -@brief %Point +@brief Point See @ref shapes for brief introduction. @see @ref Point2D, @ref Point3D diff --git a/src/Magnum/Shapes/Shape.cpp b/src/Magnum/Shapes/Shape.cpp index 176b4eb54..d5bd56e32 100644 --- a/src/Magnum/Shapes/Shape.cpp +++ b/src/Magnum/Shapes/Shape.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Shape.h b/src/Magnum/Shapes/Shape.h index bf86ee497..61d722a78 100644 --- a/src/Magnum/Shapes/Shape.h +++ b/src/Magnum/Shapes/Shape.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -42,7 +42,7 @@ namespace Implementation { /** @brief Object shape -Adds shape for collision detection to object. Each %Shape is part of +Adds shape for collision detection to object. Each Shape is part of some @ref ShapeGroup, which essentially maintains a set of objects which can collide with each other. See @ref shapes for brief introduction. @@ -67,13 +67,13 @@ Shapes::AbstractShape3D* firstCollision = shapes.firstCollision(shape); @ref DebugTools::ShapeRenderer */ template class Shape: public AbstractShape { - friend struct Implementation::ShapeHelper; + friend Implementation::ShapeHelper; public: /** * @brief Constructor * @param object Object holding this feature - * @param shape %Shape + * @param shape Shape * @param group Group this shape belongs to */ explicit Shape(SceneGraph::AbstractObject& object, const T& shape, ShapeGroup* group = nullptr): AbstractShape(object, group) { diff --git a/src/Magnum/Shapes/ShapeGroup.cpp b/src/Magnum/Shapes/ShapeGroup.cpp index dfe87a2d2..745ac5452 100644 --- a/src/Magnum/Shapes/ShapeGroup.cpp +++ b/src/Magnum/Shapes/ShapeGroup.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/ShapeGroup.h b/src/Magnum/Shapes/ShapeGroup.h index 83ca485d9..fba38afe7 100644 --- a/src/Magnum/Shapes/ShapeGroup.h +++ b/src/Magnum/Shapes/ShapeGroup.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -44,7 +44,7 @@ See @ref Shape for more information. See @ref shapes for brief introduction. @see @ref scenegraph, @ref ShapeGroup2D, @ref ShapeGroup3D */ template class MAGNUM_SHAPES_EXPORT ShapeGroup: public SceneGraph::FeatureGroup, Float> { - friend class AbstractShape; + friend AbstractShape; public: /** diff --git a/src/Magnum/Shapes/Shapes.h b/src/Magnum/Shapes/Shapes.h index 0c5382b09..1f6f3d3e4 100644 --- a/src/Magnum/Shapes/Shapes.h +++ b/src/Magnum/Shapes/Shapes.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,6 +33,7 @@ namespace Magnum { namespace Shapes { +#ifndef DOXYGEN_GENERATING_OUTPUT template class AbstractShape; typedef AbstractShape<2> AbstractShape2D; typedef AbstractShape<3> AbstractShape3D; @@ -88,6 +89,7 @@ class Plane; template class Point; typedef Point<2> Point2D; typedef Point<3> Point3D; +#endif }} diff --git a/src/Magnum/Shapes/Sphere.cpp b/src/Magnum/Shapes/Sphere.cpp index 5d6fba2d1..aca0292aa 100644 --- a/src/Magnum/Shapes/Sphere.cpp +++ b/src/Magnum/Shapes/Sphere.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Sphere.h b/src/Magnum/Shapes/Sphere.h index 0b02115d8..442804d36 100644 --- a/src/Magnum/Shapes/Sphere.h +++ b/src/Magnum/Shapes/Sphere.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,7 +38,7 @@ namespace Magnum { namespace Shapes { /** -@brief %Sphere defined by position and radius +@brief Sphere defined by position and radius Unlike other elements the sphere expects uniform scaling. See @ref shapes for brief introduction. @@ -81,22 +81,22 @@ template class MAGNUM_SHAPES_EXPORT Sphere { /** @brief Set radius */ void setRadius(Float radius) { _radius = radius; } - /** @brief %Collision occurence with point */ + /** @brief Collision occurence with point */ bool operator%(const Point& other) const; - /** @brief %Collision with point */ + /** @brief Collision with point */ Collision operator/(const Point& other) const; - /** @brief %Collision occurence with line */ + /** @brief Collision occurence with line */ bool operator%(const Line& other) const; - /** @brief %Collision occurence with line segment */ + /** @brief Collision occurence with line segment */ bool operator%(const LineSegment& other) const; - /** @brief %Collision occurence with sphere */ + /** @brief Collision occurence with sphere */ bool operator%(const Sphere& other) const; - /** @brief %Collision with sphere */ + /** @brief Collision with sphere */ Collision operator/(const Sphere& other) const; private: @@ -147,16 +147,16 @@ template class MAGNUM_SHAPES_EXPORT InvertedSphere: using Sphere::radius; using Sphere::setRadius; - /** @brief %Collision occurence with point */ + /** @brief Collision occurence with point */ bool operator%(const Point& other) const; - /** @brief %Collision with point */ + /** @brief Collision with point */ Collision operator/(const Point& other) const; - /** @brief %Collision occurence with sphere */ + /** @brief Collision occurence with sphere */ bool operator%(const Sphere& other) const; - /** @brief %Collision with sphere */ + /** @brief Collision with sphere */ Collision operator/(const Sphere& other) const; private: diff --git a/src/Magnum/Shapes/Test/AxisAlignedBoxTest.cpp b/src/Magnum/Shapes/Test/AxisAlignedBoxTest.cpp index ec1af24d6..30eea9890 100644 --- a/src/Magnum/Shapes/Test/AxisAlignedBoxTest.cpp +++ b/src/Magnum/Shapes/Test/AxisAlignedBoxTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,12 +32,11 @@ namespace Magnum { namespace Shapes { namespace Test { -class AxisAlignedBoxTest: public TestSuite::Tester { - public: - AxisAlignedBoxTest(); +struct AxisAlignedBoxTest: TestSuite::Tester { + explicit AxisAlignedBoxTest(); - void transformed(); - void collisionPoint(); + void transformed(); + void collisionPoint(); }; AxisAlignedBoxTest::AxisAlignedBoxTest() { diff --git a/src/Magnum/Shapes/Test/BoxTest.cpp b/src/Magnum/Shapes/Test/BoxTest.cpp index 06b532f3a..c8282dcaa 100644 --- a/src/Magnum/Shapes/Test/BoxTest.cpp +++ b/src/Magnum/Shapes/Test/BoxTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,11 +31,10 @@ namespace Magnum { namespace Shapes { namespace Test { -class BoxTest: public TestSuite::Tester { - public: - BoxTest(); +struct BoxTest: TestSuite::Tester { + explicit BoxTest(); - void transformed(); + void transformed(); }; BoxTest::BoxTest() { diff --git a/src/Magnum/Shapes/Test/CMakeLists.txt b/src/Magnum/Shapes/Test/CMakeLists.txt index 354bf1692..7d9d5b624 100644 --- a/src/Magnum/Shapes/Test/CMakeLists.txt +++ b/src/Magnum/Shapes/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Test/CapsuleTest.cpp b/src/Magnum/Shapes/Test/CapsuleTest.cpp index 86cba1d73..98e2eb86c 100644 --- a/src/Magnum/Shapes/Test/CapsuleTest.cpp +++ b/src/Magnum/Shapes/Test/CapsuleTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,14 +34,13 @@ namespace Magnum { namespace Shapes { namespace Test { -class CapsuleTest: public TestSuite::Tester { - public: - CapsuleTest(); +struct CapsuleTest: TestSuite::Tester { + explicit CapsuleTest(); - void transformed(); - void transformedAverageScaling(); - void collisionPoint(); - void collisionSphere(); + void transformed(); + void transformedAverageScaling(); + void collisionPoint(); + void collisionSphere(); }; CapsuleTest::CapsuleTest() { diff --git a/src/Magnum/Shapes/Test/CollisionTest.cpp b/src/Magnum/Shapes/Test/CollisionTest.cpp index 95cacad6d..7a3a52925 100644 --- a/src/Magnum/Shapes/Test/CollisionTest.cpp +++ b/src/Magnum/Shapes/Test/CollisionTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,12 +30,11 @@ namespace Magnum { namespace Shapes { namespace Test { -class CollisionTest: public TestSuite::Tester { - public: - explicit CollisionTest(); +struct CollisionTest: TestSuite::Tester { + explicit CollisionTest(); - void boolConversion(); - void flipped(); + void boolConversion(); + void flipped(); }; CollisionTest::CollisionTest() { diff --git a/src/Magnum/Shapes/Test/CompositionTest.cpp b/src/Magnum/Shapes/Test/CompositionTest.cpp index 7e49ac66b..e43b29ffc 100644 --- a/src/Magnum/Shapes/Test/CompositionTest.cpp +++ b/src/Magnum/Shapes/Test/CompositionTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,20 +34,19 @@ namespace Magnum { namespace Shapes { namespace Test { -class CompositionTest: public TestSuite::Tester { - public: - CompositionTest(); +struct CompositionTest: TestSuite::Tester { + explicit CompositionTest(); - void negated(); - void anded(); - void ored(); - void multipleUnary(); - void hierarchy(); - void empty(); + void negated(); + void anded(); + void ored(); + void multipleUnary(); + void hierarchy(); + void empty(); - void copy(); - void move(); - void transformed(); + void copy(); + void move(); + void transformed(); }; CompositionTest::CompositionTest() { diff --git a/src/Magnum/Shapes/Test/CylinderTest.cpp b/src/Magnum/Shapes/Test/CylinderTest.cpp index 5541ba190..e345f3d64 100644 --- a/src/Magnum/Shapes/Test/CylinderTest.cpp +++ b/src/Magnum/Shapes/Test/CylinderTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,14 +34,13 @@ namespace Magnum { namespace Shapes { namespace Test { -class CylinderTest: public TestSuite::Tester { - public: - CylinderTest(); +struct CylinderTest: TestSuite::Tester { + explicit CylinderTest(); - void transformed(); - void transformedAverageScaling(); - void collisionPoint(); - void collisionSphere(); + void transformed(); + void transformedAverageScaling(); + void collisionPoint(); + void collisionSphere(); }; CylinderTest::CylinderTest() { diff --git a/src/Magnum/Shapes/Test/LineTest.cpp b/src/Magnum/Shapes/Test/LineTest.cpp index 8c53c14f1..1002e6d1d 100644 --- a/src/Magnum/Shapes/Test/LineTest.cpp +++ b/src/Magnum/Shapes/Test/LineTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,11 +31,10 @@ namespace Magnum { namespace Shapes { namespace Test { -class LineTest: public TestSuite::Tester { - public: - LineTest(); +struct LineTest: TestSuite::Tester { + explicit LineTest(); - void transformed(); + void transformed(); }; LineTest::LineTest() { diff --git a/src/Magnum/Shapes/Test/PlaneTest.cpp b/src/Magnum/Shapes/Test/PlaneTest.cpp index cd400c721..b628fd01c 100644 --- a/src/Magnum/Shapes/Test/PlaneTest.cpp +++ b/src/Magnum/Shapes/Test/PlaneTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,13 +32,12 @@ namespace Magnum { namespace Shapes { namespace Test { -class PlaneTest: public TestSuite::Tester { - public: - PlaneTest(); +struct PlaneTest: TestSuite::Tester { + explicit PlaneTest(); - void transformed(); - void collisionLine(); - void collisionLineSegment(); + void transformed(); + void collisionLine(); + void collisionLineSegment(); }; PlaneTest::PlaneTest() { diff --git a/src/Magnum/Shapes/Test/PointTest.cpp b/src/Magnum/Shapes/Test/PointTest.cpp index 7b8e3e0de..c65b5495f 100644 --- a/src/Magnum/Shapes/Test/PointTest.cpp +++ b/src/Magnum/Shapes/Test/PointTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,11 +31,10 @@ namespace Magnum { namespace Shapes { namespace Test { -class PointTest: public TestSuite::Tester { - public: - PointTest(); +struct PointTest: TestSuite::Tester { + explicit PointTest(); - void transformed(); + void transformed(); }; PointTest::PointTest() { diff --git a/src/Magnum/Shapes/Test/ShapeImplementationTest.cpp b/src/Magnum/Shapes/Test/ShapeImplementationTest.cpp index af86154dc..35d2f0acc 100644 --- a/src/Magnum/Shapes/Test/ShapeImplementationTest.cpp +++ b/src/Magnum/Shapes/Test/ShapeImplementationTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Shapes { namespace Test { -class ShapeImplementationTest: public TestSuite::Tester { - public: - ShapeImplementationTest(); +struct ShapeImplementationTest: TestSuite::Tester { + explicit ShapeImplementationTest(); - void debug(); + void debug(); }; ShapeImplementationTest::ShapeImplementationTest() { diff --git a/src/Magnum/Shapes/Test/ShapeTest.cpp b/src/Magnum/Shapes/Test/ShapeTest.cpp index fe5a50d55..55dc967dd 100644 --- a/src/Magnum/Shapes/Test/ShapeTest.cpp +++ b/src/Magnum/Shapes/Test/ShapeTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,15 +36,14 @@ namespace Magnum { namespace Shapes { namespace Test { -class ShapeTest: public TestSuite::Tester { - public: - ShapeTest(); +struct ShapeTest: TestSuite::Tester { + explicit ShapeTest(); - void clean(); - void collides(); - void collision(); - void firstCollision(); - void shapeGroup(); + void clean(); + void collides(); + void collision(); + void firstCollision(); + void shapeGroup(); }; typedef SceneGraph::Scene Scene2D; diff --git a/src/Magnum/Shapes/Test/ShapeTestBase.h b/src/Magnum/Shapes/Test/ShapeTestBase.h index 91d64b2be..9f82326d8 100644 --- a/src/Magnum/Shapes/Test/ShapeTestBase.h +++ b/src/Magnum/Shapes/Test/ShapeTestBase.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/Test/SphereTest.cpp b/src/Magnum/Shapes/Test/SphereTest.cpp index 79f050fd3..9dc0d2d5b 100644 --- a/src/Magnum/Shapes/Test/SphereTest.cpp +++ b/src/Magnum/Shapes/Test/SphereTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,17 +34,16 @@ namespace Magnum { namespace Shapes { namespace Test { -class SphereTest: public TestSuite::Tester { - public: - SphereTest(); - - void transformed(); - void collisionPoint(); - void collisionPointInverted(); - void collisionLine(); - void collisionLineSegment(); - void collisionSphere(); - void collisionSphereInverted(); +struct SphereTest: TestSuite::Tester { + explicit SphereTest(); + + void transformed(); + void collisionPoint(); + void collisionPointInverted(); + void collisionLine(); + void collisionLineSegment(); + void collisionSphere(); + void collisionSphereInverted(); }; SphereTest::SphereTest() { diff --git a/src/Magnum/Shapes/shapeImplementation.cpp b/src/Magnum/Shapes/shapeImplementation.cpp index bd9e06297..60aad563f 100644 --- a/src/Magnum/Shapes/shapeImplementation.cpp +++ b/src/Magnum/Shapes/shapeImplementation.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/shapeImplementation.h b/src/Magnum/Shapes/shapeImplementation.h index cbaf316d8..9774a40b7 100644 --- a/src/Magnum/Shapes/shapeImplementation.h +++ b/src/Magnum/Shapes/shapeImplementation.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Shapes/visibility.h b/src/Magnum/Shapes/visibility.h index 4ec943f45..d54216f78 100644 --- a/src/Magnum/Shapes/visibility.h +++ b/src/Magnum/Shapes/visibility.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Test/AbstractImageTest.cpp b/src/Magnum/Test/AbstractImageTest.cpp index eb7156282..46feafd63 100644 --- a/src/Magnum/Test/AbstractImageTest.cpp +++ b/src/Magnum/Test/AbstractImageTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,15 +32,14 @@ namespace Magnum { namespace Test { -class AbstractImageTest: public TestSuite::Tester { - public: - explicit AbstractImageTest(); +struct AbstractImageTest: TestSuite::Tester { + explicit AbstractImageTest(); - void pixelSize(); - void dataSize(); + void pixelSize(); + void dataSize(); - void debugFormat(); - void debugType(); + void debugFormat(); + void debugType(); }; AbstractImageTest::AbstractImageTest() { diff --git a/src/Magnum/Test/AbstractObjectGLTest.cpp b/src/Magnum/Test/AbstractObjectGLTest.cpp index eb6488ceb..21649eb44 100644 --- a/src/Magnum/Test/AbstractObjectGLTest.cpp +++ b/src/Magnum/Test/AbstractObjectGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Test { -class AbstractObjectGLTest: public AbstractOpenGLTester { - public: - explicit AbstractObjectGLTest(); +struct AbstractObjectGLTest: AbstractOpenGLTester { + explicit AbstractObjectGLTest(); - void labelNoOp(); + void labelNoOp(); }; AbstractObjectGLTest::AbstractObjectGLTest() { diff --git a/src/Magnum/Test/AbstractOpenGLTester.h b/src/Magnum/Test/AbstractOpenGLTester.h index f03975189..307343df2 100644 --- a/src/Magnum/Test/AbstractOpenGLTester.h +++ b/src/Magnum/Test/AbstractOpenGLTester.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,7 +30,7 @@ #include "Magnum/Context.h" #include "Magnum/Extensions.h" -#include "Magnum/DebugMessage.h" +#include "Magnum/DebugOutput.h" #include "Magnum/Renderer.h" #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_DESKTOP_GLES) @@ -49,21 +49,21 @@ class AbstractOpenGLTester: public TestSuite::Tester, public Platform::Windowles int exec() override final { return TestSuite::Tester::exec(); } private: - static int zero; + static int _zero; }; -AbstractOpenGLTester::AbstractOpenGLTester(): Platform::WindowlessApplication({zero, nullptr}) { +AbstractOpenGLTester::AbstractOpenGLTester(): Platform::WindowlessApplication({_zero, nullptr}) { if(Context::current()->isExtensionSupported()) { Renderer::enable(Renderer::Feature::DebugOutput); Renderer::enable(Renderer::Feature::DebugOutputSynchronous); - DebugMessage::setDefaultCallback(); + DebugOutput::setDefaultCallback(); /* Disable "Buffer detailed info" message on NV (too spammy) */ - DebugMessage::setEnabled(DebugMessage::Source::Api, DebugMessage::Type::Other, {131185}, false); + DebugOutput::setEnabled(DebugOutput::Source::Api, DebugOutput::Type::Other, {131185}, false); } } -int AbstractOpenGLTester::zero = 0; +int AbstractOpenGLTester::_zero = 0; #define MAGNUM_VERIFY_NO_ERROR() CORRADE_COMPARE(Magnum::Renderer::error(), Magnum::Renderer::Error::NoError) diff --git a/src/Magnum/Test/AbstractQueryGLTest.cpp b/src/Magnum/Test/AbstractQueryGLTest.cpp index 47d518039..202316e7a 100644 --- a/src/Magnum/Test/AbstractQueryGLTest.cpp +++ b/src/Magnum/Test/AbstractQueryGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -28,15 +28,14 @@ namespace Magnum { namespace Test { -class AbstractQueryGLTest: public AbstractOpenGLTester { - public: - explicit AbstractQueryGLTest(); +struct AbstractQueryGLTest: AbstractOpenGLTester { + explicit AbstractQueryGLTest(); - void construct(); - void constructCopy(); - void constructMove(); + void construct(); + void constructCopy(); + void constructMove(); - void label(); + void label(); }; AbstractQueryGLTest::AbstractQueryGLTest() { diff --git a/src/Magnum/Test/AbstractShaderProgramGLTest.cpp b/src/Magnum/Test/AbstractShaderProgramGLTest.cpp index f9a1e21a1..480b276e7 100644 --- a/src/Magnum/Test/AbstractShaderProgramGLTest.cpp +++ b/src/Magnum/Test/AbstractShaderProgramGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,6 +23,7 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include "Magnum/AbstractShaderProgram.h" @@ -35,26 +36,26 @@ namespace Magnum { namespace Test { -class AbstractShaderProgramGLTest: public AbstractOpenGLTester { - public: - explicit AbstractShaderProgramGLTest(); +struct AbstractShaderProgramGLTest: AbstractOpenGLTester { + explicit AbstractShaderProgramGLTest(); - void construct(); - void constructCopy(); - void constructMove(); + void construct(); + void constructCopy(); + void constructMove(); - void label(); + void label(); - void create(); - void createMultipleOutputs(); - #ifndef MAGNUM_TARGET_GLES - void createMultipleOutputsIndexed(); - #endif + void create(); + void createMultipleOutputs(); + #ifndef MAGNUM_TARGET_GLES + void createMultipleOutputsIndexed(); + #endif - void uniform(); - void uniformVector(); - void uniformMatrix(); - void uniformArray(); + void uniformLocationOptimizedOut(); + void uniform(); + void uniformVector(); + void uniformMatrix(); + void uniformArray(); }; AbstractShaderProgramGLTest::AbstractShaderProgramGLTest() { @@ -70,6 +71,7 @@ AbstractShaderProgramGLTest::AbstractShaderProgramGLTest() { &AbstractShaderProgramGLTest::createMultipleOutputsIndexed, #endif + &AbstractShaderProgramGLTest::uniformLocationOptimizedOut, &AbstractShaderProgramGLTest::uniform, &AbstractShaderProgramGLTest::uniformVector, &AbstractShaderProgramGLTest::uniformMatrix, @@ -287,6 +289,32 @@ void AbstractShaderProgramGLTest::createMultipleOutputsIndexed() { } #endif +void AbstractShaderProgramGLTest::uniformLocationOptimizedOut() { + MyPublicShader program; + + #ifndef MAGNUM_TARGET_GLES + Shader vert(Version::GL210, Shader::Type::Vertex); + Shader frag(Version::GL210, Shader::Type::Fragment); + #else + Shader vert(Version::GLES200, Shader::Type::Vertex); + Shader frag(Version::GLES200, Shader::Type::Fragment); + #endif + vert.addSource("void main() { gl_Position = vec4(0.0); }"); + frag.addSource("void main() { gl_FragColor = vec4(1.0); }"); + + CORRADE_VERIFY(Shader::compile({vert, frag})); + program.attachShaders({vert, frag}); + CORRADE_VERIFY(program.link()); + + std::ostringstream out; + Warning::setOutput(&out); + program.uniformLocation("nonexistent"); + program.uniformLocation(std::string{"another"}); + CORRADE_COMPARE(out.str(), + "AbstractShaderProgram: location of uniform 'nonexistent' cannot be retrieved!\n" + "AbstractShaderProgram: location of uniform 'another' cannot be retrieved!\n"); +} + namespace { struct MyShader: AbstractShaderProgram { explicit MyShader(); diff --git a/src/Magnum/Test/AbstractShaderProgramTest.cpp b/src/Magnum/Test/AbstractShaderProgramTest.cpp index 1704cb358..460f01828 100644 --- a/src/Magnum/Test/AbstractShaderProgramTest.cpp +++ b/src/Magnum/Test/AbstractShaderProgramTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,28 +29,27 @@ namespace Magnum { namespace Test { -class AbstractShaderProgramTest: public TestSuite::Tester { - public: - explicit AbstractShaderProgramTest(); - - void attributeScalar(); - void attributeScalarInt(); - void attributeScalarUnsignedInt(); - void attributeScalarDouble(); - - void attributeVector(); - void attributeVectorInt(); - void attributeVectorUnsignedInt(); - void attributeVectorDouble(); - void attributeVector4(); - void attributeVectorBGRA(); - - void attributeMatrixNxN(); - #ifndef MAGNUM_TARGET_GLES2 - void attributeMatrixMxN(); - #endif - void attributeMatrixNxNd(); - void attributeMatrixMxNd(); +struct AbstractShaderProgramTest: TestSuite::Tester { + explicit AbstractShaderProgramTest(); + + void attributeScalar(); + void attributeScalarInt(); + void attributeScalarUnsignedInt(); + void attributeScalarDouble(); + + void attributeVector(); + void attributeVectorInt(); + void attributeVectorUnsignedInt(); + void attributeVectorDouble(); + void attributeVector4(); + void attributeVectorBGRA(); + + void attributeMatrixNxN(); + #ifndef MAGNUM_TARGET_GLES2 + void attributeMatrixMxN(); + #endif + void attributeMatrixNxNd(); + void attributeMatrixMxNd(); }; AbstractShaderProgramTest::AbstractShaderProgramTest() { @@ -75,7 +74,7 @@ AbstractShaderProgramTest::AbstractShaderProgramTest() { } void AbstractShaderProgramTest::attributeScalar() { - typedef AbstractShaderProgram::Attribute<3, Float> Attribute; + typedef Magnum::Attribute<3, Float> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::Location), 3); @@ -96,7 +95,7 @@ void AbstractShaderProgramTest::attributeScalar() { void AbstractShaderProgramTest::attributeScalarInt() { #ifndef MAGNUM_TARGET_GLES2 - typedef AbstractShaderProgram::Attribute<3, Int> Attribute; + typedef Magnum::Attribute<3, Int> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 1); @@ -115,7 +114,7 @@ void AbstractShaderProgramTest::attributeScalarInt() { void AbstractShaderProgramTest::attributeScalarUnsignedInt() { #ifndef MAGNUM_TARGET_GLES2 - typedef AbstractShaderProgram::Attribute<3, UnsignedInt> Attribute; + typedef Magnum::Attribute<3, UnsignedInt> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 1); @@ -134,7 +133,7 @@ void AbstractShaderProgramTest::attributeScalarUnsignedInt() { void AbstractShaderProgramTest::attributeScalarDouble() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Double> Attribute; + typedef Magnum::Attribute<3, Double> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 1); @@ -148,7 +147,7 @@ void AbstractShaderProgramTest::attributeScalarDouble() { } void AbstractShaderProgramTest::attributeVector() { - typedef AbstractShaderProgram::Attribute<3, Vector3> Attribute; + typedef Magnum::Attribute<3, Vector3> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 1); @@ -173,7 +172,7 @@ void AbstractShaderProgramTest::attributeVector() { void AbstractShaderProgramTest::attributeVectorInt() { #ifndef MAGNUM_TARGET_GLES2 - typedef AbstractShaderProgram::Attribute<3, Vector2i> Attribute; + typedef Magnum::Attribute<3, Vector2i> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 1); @@ -194,7 +193,7 @@ void AbstractShaderProgramTest::attributeVectorInt() { void AbstractShaderProgramTest::attributeVectorUnsignedInt() { #ifndef MAGNUM_TARGET_GLES2 - typedef AbstractShaderProgram::Attribute<3, Vector4ui> Attribute; + typedef Magnum::Attribute<3, Vector4ui> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 1); @@ -215,7 +214,7 @@ void AbstractShaderProgramTest::attributeVectorUnsignedInt() { void AbstractShaderProgramTest::attributeVectorDouble() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Vector2d> Attribute; + typedef Magnum::Attribute<3, Vector2d> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 1); @@ -235,7 +234,7 @@ void AbstractShaderProgramTest::attributeVectorDouble() { } void AbstractShaderProgramTest::attributeVector4() { - typedef AbstractShaderProgram::Attribute<3, Vector4> Attribute; + typedef Magnum::Attribute<3, Vector4> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 1); @@ -252,7 +251,7 @@ void AbstractShaderProgramTest::attributeVector4() { void AbstractShaderProgramTest::attributeVectorBGRA() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Vector4> Attribute; + typedef Magnum::Attribute<3, Vector4> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 1); @@ -266,7 +265,7 @@ void AbstractShaderProgramTest::attributeVectorBGRA() { } void AbstractShaderProgramTest::attributeMatrixNxN() { - typedef AbstractShaderProgram::Attribute<3, Matrix3> Attribute; + typedef Magnum::Attribute<3, Matrix3> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 3); @@ -280,7 +279,7 @@ void AbstractShaderProgramTest::attributeMatrixNxN() { #ifndef MAGNUM_TARGET_GLES2 void AbstractShaderProgramTest::attributeMatrixMxN() { - typedef AbstractShaderProgram::Attribute<3, Matrix3x4> Attribute; + typedef Magnum::Attribute<3, Matrix3x4> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 3); @@ -295,7 +294,7 @@ void AbstractShaderProgramTest::attributeMatrixMxN() { void AbstractShaderProgramTest::attributeMatrixNxNd() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Matrix4d> Attribute; + typedef Magnum::Attribute<3, Matrix4d> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 4); @@ -312,7 +311,7 @@ void AbstractShaderProgramTest::attributeMatrixNxNd() { void AbstractShaderProgramTest::attributeMatrixMxNd() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Matrix4x2d> Attribute; + typedef Magnum::Attribute<3, Matrix4x2d> Attribute; /* GCC 4.5: no bool conversion operator */ CORRADE_VERIFY((std::is_same::value)); CORRADE_COMPARE(Int(Attribute::VectorCount), 4); diff --git a/src/Magnum/Test/AbstractTextureGLTest.cpp b/src/Magnum/Test/AbstractTextureGLTest.cpp index 0f1664b1e..c8f8a956c 100644 --- a/src/Magnum/Test/AbstractTextureGLTest.cpp +++ b/src/Magnum/Test/AbstractTextureGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,15 +30,14 @@ namespace Magnum { namespace Test { -class AbstractTextureGLTest: public AbstractOpenGLTester { - public: - explicit AbstractTextureGLTest(); +struct AbstractTextureGLTest: AbstractOpenGLTester { + explicit AbstractTextureGLTest(); - void construct(); - void constructCopy(); - void constructMove(); + void construct(); + void constructCopy(); + void constructMove(); - void label(); + void label(); }; AbstractTextureGLTest::AbstractTextureGLTest() { diff --git a/src/Magnum/Test/ArrayTest.cpp b/src/Magnum/Test/ArrayTest.cpp index 79a648dc3..b1c950ec3 100644 --- a/src/Magnum/Test/ArrayTest.cpp +++ b/src/Magnum/Test/ArrayTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,13 +29,12 @@ namespace Magnum { namespace Test { -class ArrayTest: public TestSuite::Tester { - public: - ArrayTest(); +struct ArrayTest: TestSuite::Tester { + explicit ArrayTest(); - void construct(); - void equality(); - void access(); + void construct(); + void equality(); + void access(); }; typedef Magnum::Array1D Array1D; diff --git a/src/Magnum/Test/BufferGLTest.cpp b/src/Magnum/Test/BufferGLTest.cpp index c7b003a64..af79dbdd7 100644 --- a/src/Magnum/Test/BufferGLTest.cpp +++ b/src/Magnum/Test/BufferGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,32 +34,31 @@ namespace Magnum { namespace Test { -class BufferGLTest: public AbstractOpenGLTester { - public: - explicit BufferGLTest(); - - void construct(); - void constructCopy(); - void constructMove(); - - void label(); - - #ifndef MAGNUM_TARGET_GLES2 - void bindBase(); - void bindRange(); - #endif - - void data(); - void map(); - #ifdef MAGNUM_TARGET_GLES2 - void mapSub(); - #endif - void mapRange(); - void mapRangeExplicitFlush(); - #ifndef MAGNUM_TARGET_GLES2 - void copy(); - #endif - void invalidate(); +struct BufferGLTest: AbstractOpenGLTester { + explicit BufferGLTest(); + + void construct(); + void constructCopy(); + void constructMove(); + + void label(); + + #ifndef MAGNUM_TARGET_GLES2 + void bindBase(); + void bindRange(); + #endif + + void data(); + void map(); + #ifdef MAGNUM_TARGET_GLES2 + void mapSub(); + #endif + void mapRange(); + void mapRangeExplicitFlush(); + #ifndef MAGNUM_TARGET_GLES2 + void copy(); + #endif + void invalidate(); }; BufferGLTest::BufferGLTest() { diff --git a/src/Magnum/Test/BufferImageGLTest.cpp b/src/Magnum/Test/BufferImageGLTest.cpp index 19369972d..75c8e9a27 100644 --- a/src/Magnum/Test/BufferImageGLTest.cpp +++ b/src/Magnum/Test/BufferImageGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,31 +31,30 @@ namespace Magnum { namespace Test { -class BufferImageTest: public AbstractOpenGLTester { - public: - explicit BufferImageTest(); +struct BufferImageGLTest: AbstractOpenGLTester { + explicit BufferImageGLTest(); - void construct(); - void constructCopy(); - void constructMove(); + void construct(); + void constructCopy(); + void constructMove(); - void setData(); + void setData(); }; -BufferImageTest::BufferImageTest() { - addTests({&BufferImageTest::construct, - &BufferImageTest::constructCopy, - &BufferImageTest::constructMove, +BufferImageGLTest::BufferImageGLTest() { + addTests({&BufferImageGLTest::construct, + &BufferImageGLTest::constructCopy, + &BufferImageGLTest::constructMove, - &BufferImageTest::setData}); + &BufferImageGLTest::setData}); } -void BufferImageTest::construct() { - const unsigned char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0, 'c', 0, 0, 0 }; +void BufferImageGLTest::construct() { + const char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0, 'c', 0, 0, 0 }; BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data, BufferUsage::StaticDraw); #ifndef MAGNUM_TARGET_GLES - const auto imageData = a.buffer().data(); + const auto imageData = a.buffer().data(); #endif MAGNUM_VERIFY_NO_ERROR(); @@ -66,13 +65,13 @@ void BufferImageTest::construct() { /** @todo How to verify the contents in ES? */ #ifndef MAGNUM_TARGET_GLES - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data + 12), + CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), + std::vector(data, data + 12), TestSuite::Compare::Container); #endif } -void BufferImageTest::constructCopy() { +void BufferImageGLTest::constructCopy() { #ifndef CORRADE_GCC44_COMPATIBILITY CORRADE_VERIFY(!(std::is_constructible::value)); /* GCC 4.6 doesn't have std::is_assignable */ @@ -84,9 +83,9 @@ void BufferImageTest::constructCopy() { #endif } -void BufferImageTest::constructMove() { - const unsigned char data[3] = { 'a', 'b', 'c' }; - BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data, BufferUsage::StaticDraw); +void BufferImageGLTest::constructMove() { + const char data[4] = { 'a', 'b', 'c', 'd' }; + BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {4, 1}, data, BufferUsage::StaticDraw); const Int id = a.buffer().id(); MAGNUM_VERIFY_NO_ERROR(); @@ -99,11 +98,11 @@ void BufferImageTest::constructMove() { CORRADE_COMPARE(b.format(), ColorFormat::Red); CORRADE_COMPARE(b.type(), ColorType::UnsignedByte); - CORRADE_COMPARE(b.size(), Vector2i(1, 3)); + CORRADE_COMPARE(b.size(), Vector2i(4, 1)); CORRADE_COMPARE(b.buffer().id(), id); const unsigned short data2[2*4] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - BufferImage2D c(ColorFormat::RGBA, ColorType::UnsignedShort, {2, 1}, data2, BufferUsage::StaticDraw); + BufferImage2D c(ColorFormat::RGBA, ColorType::UnsignedShort, {1, 2}, data2, BufferUsage::StaticDraw); const Int cId = c.buffer().id(); c = std::move(b); @@ -111,20 +110,20 @@ void BufferImageTest::constructMove() { CORRADE_VERIFY(cId > 0); CORRADE_COMPARE(b.buffer().id(), cId); - CORRADE_COMPARE(b.size(), Vector2i(2, 1)); + CORRADE_COMPARE(b.size(), Vector2i(1, 2)); CORRADE_COMPARE(c.format(), ColorFormat::Red); CORRADE_COMPARE(c.type(), ColorType::UnsignedByte); - CORRADE_COMPARE(c.size(), Vector2i(1, 3)); + CORRADE_COMPARE(c.size(), Vector2i(4, 1)); CORRADE_COMPARE(c.buffer().id(), id); } -void BufferImageTest::setData() { - const unsigned char data[3] = { 'a', 'b', 'c' }; - BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data, BufferUsage::StaticDraw); +void BufferImageGLTest::setData() { + const char data[4] = { 'a', 'b', 'c', 'd' }; + BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {4, 1}, data, BufferUsage::StaticDraw); - const unsigned short data2[2*4] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - a.setData(ColorFormat::RGBA, ColorType::UnsignedShort, {2, 1}, data2, BufferUsage::StaticDraw); + const UnsignedShort data2[2*4] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + a.setData(ColorFormat::RGBA, ColorType::UnsignedShort, {1, 2}, data2, BufferUsage::StaticDraw); #ifndef MAGNUM_TARGET_GLES const auto imageData = a.buffer().data(); @@ -134,7 +133,7 @@ void BufferImageTest::setData() { CORRADE_COMPARE(a.format(), ColorFormat::RGBA); CORRADE_COMPARE(a.type(), ColorType::UnsignedShort); - CORRADE_COMPARE(a.size(), Vector2i(2, 1)); + CORRADE_COMPARE(a.size(), Vector2i(1, 2)); /** @todo How to verify the contents in ES? */ #ifndef MAGNUM_TARGET_GLES @@ -146,4 +145,4 @@ void BufferImageTest::setData() { }} -CORRADE_TEST_MAIN(Magnum::Test::BufferImageTest) +CORRADE_TEST_MAIN(Magnum::Test::BufferImageGLTest) diff --git a/src/Magnum/Test/BufferTextureGLTest.cpp b/src/Magnum/Test/BufferTextureGLTest.cpp index 4c74c33fb..93f9909c9 100644 --- a/src/Magnum/Test/BufferTextureGLTest.cpp +++ b/src/Magnum/Test/BufferTextureGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,14 +31,13 @@ namespace Magnum { namespace Test { -class BufferTextureGLTest: public AbstractOpenGLTester { - public: - explicit BufferTextureGLTest(); +struct BufferTextureGLTest: AbstractOpenGLTester { + explicit BufferTextureGLTest(); - void construct(); - void bind(); - void setBuffer(); - void setBufferOffset(); + void construct(); + void bind(); + void setBuffer(); + void setBufferOffset(); }; BufferTextureGLTest::BufferTextureGLTest() { diff --git a/src/Magnum/Test/CMakeLists.txt b/src/Magnum/Test/CMakeLists.txt index c04344f3b..95db37ec4 100644 --- a/src/Magnum/Test/CMakeLists.txt +++ b/src/Magnum/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -28,7 +28,7 @@ corrade_add_test(AbstractShaderProgramTest AbstractShaderProgramTest.cpp LIBRARI corrade_add_test(ArrayTest ArrayTest.cpp) corrade_add_test(ColorTest ColorTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(ContextTest ContextTest.cpp LIBRARIES Magnum) -corrade_add_test(DebugMessageTest DebugMessageTest.cpp LIBRARIES Magnum) +corrade_add_test(DebugOutputTest DebugOutputTest.cpp LIBRARIES Magnum) corrade_add_test(DefaultFramebufferTest DefaultFramebufferTest.cpp LIBRARIES Magnum) corrade_add_test(FramebufferTest FramebufferTest.cpp LIBRARIES Magnum) corrade_add_test(ImageTest ImageTest.cpp LIBRARIES Magnum) @@ -40,6 +40,13 @@ corrade_add_test(SamplerTest SamplerTest.cpp LIBRARIES Magnum) corrade_add_test(ShaderTest ShaderTest.cpp LIBRARIES Magnum) corrade_add_test(VersionTest VersionTest.cpp LIBRARIES Magnum) +add_library(ResourceManagerLocalInstanceTestLib ${SHARED_OR_STATIC} ResourceManagerLocalInstanceTestLib.cpp) +target_link_libraries(ResourceManagerLocalInstanceTestLib Magnum) +if(NOT BUILD_STATIC) + set_target_properties(ResourceManagerLocalInstanceTestLib PROPERTIES COMPILE_FLAGS "-DResourceManagerLocalInstanceTestLib_EXPORTS") +endif() +corrade_add_test(ResourceManagerLocalInstanceTest ResourceManagerLocalInstanceTest.cpp LIBRARIES Magnum ResourceManagerLocalInstanceTestLib) + if(BUILD_GL_TESTS) corrade_add_test(AbstractObjectGLTest AbstractObjectGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(AbstractQueryGLTest AbstractQueryGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) @@ -47,10 +54,11 @@ if(BUILD_GL_TESTS) corrade_add_test(BufferGLTest BufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(ContextGLTest ContextGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(CubeMapTextureGLTest CubeMapTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) - corrade_add_test(DebugGLTest DebugGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) + corrade_add_test(DebugOutputGLTest DebugOutputGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(FramebufferGLTest FramebufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(MeshGLTest MeshGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(RenderbufferGLTest RenderbufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) + corrade_add_test(SampleQueryGLTest SampleQueryGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(TextureGLTest TextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(TimeQueryGLTest TimeQueryGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) @@ -60,18 +68,6 @@ if(BUILD_GL_TESTS) ${AbstractShaderProgramGLTest_RES} LIBRARIES ${GL_TEST_LIBRARIES}) - corrade_add_resource(QueryGLTest_RES QueryGLTestFiles/resources.conf) - if(NOT MAGNUM_TARGET_GLES2) - corrade_add_test(PrimitiveQueryGLTest - PrimitiveQueryGLTest.cpp - ${QueryGLTest_RES} - LIBRARIES ${GL_TEST_LIBRARIES}) - endif() - corrade_add_test(SampleQueryGLTest - SampleQueryGLTest.cpp - ${QueryGLTest_RES} - LIBRARIES ${GL_TEST_LIBRARIES}) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/configure.h) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) @@ -79,8 +75,10 @@ if(BUILD_GL_TESTS) if(NOT MAGNUM_TARGET_GLES2) corrade_add_test(BufferImageGLTest BufferImageGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) - corrade_add_test(TextureArrayGLTest TextureArrayGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(MultisampleTextureGLTest MultisampleTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) + corrade_add_test(PrimitiveQueryGLTest PrimitiveQueryGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) + corrade_add_test(TextureArrayGLTest TextureArrayGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) + corrade_add_test(TransformFeedbackGLTest TransformFeedbackGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) endif() if(NOT MAGNUM_TARGET_GLES) diff --git a/src/Magnum/Test/ColorTest.cpp b/src/Magnum/Test/ColorTest.cpp index 2c19e312f..304321891 100644 --- a/src/Magnum/Test/ColorTest.cpp +++ b/src/Magnum/Test/ColorTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,35 +31,34 @@ namespace Magnum { namespace Test { -class ColorTest: public TestSuite::Tester { - public: - ColorTest(); +struct ColorTest: TestSuite::Tester { + explicit ColorTest(); - void construct(); - void constructDefault(); - void constructOneValue(); - void constructParts(); - void constructConversion(); - void constructNormalization(); - void constructCopy(); + void construct(); + void constructDefault(); + void constructOneValue(); + void constructParts(); + void constructConversion(); + void constructNormalization(); + void constructCopy(); - void colors(); + void colors(); - void fromHue(); - void fromSaturation(); - void fromValue(); + void fromHue(); + void fromSaturation(); + void fromValue(); - void hue(); - void saturation(); - void value(); + void hue(); + void saturation(); + void value(); - void hsv(); - void hsvOverflow(); - void hsvAlpha(); + void hsv(); + void hsvOverflow(); + void hsvAlpha(); - void swizzleType(); - void debug(); - void configuration(); + void swizzleType(); + void debug(); + void configuration(); }; ColorTest::ColorTest() { diff --git a/src/Magnum/Test/ContextGLTest.cpp b/src/Magnum/Test/ContextGLTest.cpp index 198ea4fd2..0b5a29708 100644 --- a/src/Magnum/Test/ContextGLTest.cpp +++ b/src/Magnum/Test/ContextGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,14 +29,13 @@ namespace Magnum { namespace Test { -class ContextGLTest: public AbstractOpenGLTester { - public: - explicit ContextGLTest(); +struct ContextGLTest: AbstractOpenGLTester { + explicit ContextGLTest(); - void isVersionSupported(); - void supportedVersion(); - void isExtensionSupported(); - void isExtensionDisabled(); + void isVersionSupported(); + void supportedVersion(); + void isExtensionSupported(); + void isExtensionDisabled(); }; ContextGLTest::ContextGLTest() { diff --git a/src/Magnum/Test/ContextTest.cpp b/src/Magnum/Test/ContextTest.cpp index cae8f8084..5c519005b 100644 --- a/src/Magnum/Test/ContextTest.cpp +++ b/src/Magnum/Test/ContextTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Test { -class ContextTest: public TestSuite::Tester { - public: - explicit ContextTest(); +struct ContextTest: TestSuite::Tester { + explicit ContextTest(); - void debugFlag(); + void debugFlag(); }; ContextTest::ContextTest() { diff --git a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp index 6ec415ff8..e598d072d 100644 --- a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,34 +31,36 @@ #include "Magnum/CubeMapTextureArray.h" #include "Magnum/Image.h" #include "Magnum/TextureFormat.h" +#include "Magnum/Math/Range.h" #include "Magnum/Test/AbstractOpenGLTester.h" namespace Magnum { namespace Test { -class CubeMapTextureArrayGLTest: public AbstractOpenGLTester { - public: - explicit CubeMapTextureArrayGLTest(); +struct CubeMapTextureArrayGLTest: AbstractOpenGLTester { + explicit CubeMapTextureArrayGLTest(); - void construct(); - void bind(); + void construct(); + void bind(); - void sampling(); - void samplingSRGBDecode(); - void samplingBorderInteger(); - void samplingSwizzle(); - void samplingDepthStencilMode(); + void sampling(); + void samplingSRGBDecode(); + void samplingBorderInteger(); + void samplingSwizzle(); + void samplingDepthStencilMode(); - void storage(); + void storage(); - void image(); - void imageBuffer(); - void subImage(); - void subImageBuffer(); + void image(); + void imageBuffer(); + void subImage(); + void subImageBuffer(); + void subImageQuery(); + void subImageQueryBuffer(); - void generateMipmap(); + void generateMipmap(); - void invalidateImage(); - void invalidateSubImage(); + void invalidateImage(); + void invalidateSubImage(); }; CubeMapTextureArrayGLTest::CubeMapTextureArrayGLTest() { @@ -77,6 +79,8 @@ CubeMapTextureArrayGLTest::CubeMapTextureArrayGLTest() { &CubeMapTextureArrayGLTest::imageBuffer, &CubeMapTextureArrayGLTest::subImage, &CubeMapTextureArrayGLTest::subImageBuffer, + &CubeMapTextureArrayGLTest::subImageQuery, + &CubeMapTextureArrayGLTest::subImageQueryBuffer, &CubeMapTextureArrayGLTest::generateMipmap, @@ -212,11 +216,8 @@ void CubeMapTextureArrayGLTest::storage() { MAGNUM_VERIFY_NO_ERROR(); } -void CubeMapTextureArrayGLTest::image() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); - - constexpr UnsignedByte data[] = { +namespace { + constexpr UnsignedByte Data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, @@ -235,68 +236,51 @@ void CubeMapTextureArrayGLTest::image() { 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f }; +} + +void CubeMapTextureArrayGLTest::image() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); + CubeMapTextureArray texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, {2, 2, 6}, data)); + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, {2, 2, 6}, Data)); MAGNUM_VERIFY_NO_ERROR(); - Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(2, 2, 6)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 96), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data}, TestSuite::Compare::Container); } void CubeMapTextureArrayGLTest::imageBuffer() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); - constexpr UnsignedByte data[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x16, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x1e, 0x4f, - - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f - }; CubeMapTextureArray texture; texture.setImage(0, TextureFormat::RGBA8, - BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, {2, 2, 6}, data, BufferUsage::StaticDraw)); + BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, {2, 2, 6}, Data, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); - BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(2, 2, 6)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data + 96), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data}, TestSuite::Compare::Container); } -void CubeMapTextureArrayGLTest::subImage() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); +namespace { + constexpr UnsignedByte Zero[4*4*4*6] = {}; - constexpr UnsignedByte zero[4*4*4*6] = {}; - constexpr UnsignedByte subData[] = { + constexpr UnsignedByte SubData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, @@ -309,21 +293,8 @@ void CubeMapTextureArrayGLTest::subImage() { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f }; - CubeMapTextureArray texture; - texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 6}, zero)); - texture.setSubImage(0, Vector3i(1), - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, {2, 2, 4}, subData)); - - MAGNUM_VERIFY_NO_ERROR(); - - Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); - - MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(image.size(), Vector3i(4, 4, 6)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ + constexpr UnsignedByte SubDataComplete[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -353,78 +324,100 @@ void CubeMapTextureArrayGLTest::subImage() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + }; } -void CubeMapTextureArrayGLTest::subImageBuffer() { +void CubeMapTextureArrayGLTest::subImage() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); - constexpr UnsignedByte zero[4*4*4*6] = {}; - constexpr UnsignedByte subData[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + CubeMapTextureArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 6}, Zero)); + texture.setSubImage(0, Vector3i(1), + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, {2, 2, 4}, SubData)); - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + MAGNUM_VERIFY_NO_ERROR(); - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(4, 4, 6)); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{SubDataComplete}, TestSuite::Compare::Container); +} + +void CubeMapTextureArrayGLTest::subImageBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f - }; CubeMapTextureArray texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 6}, zero)); + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 6}, Zero)); texture.setSubImage(0, Vector3i(1), - BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, {2, 2, 4}, subData, BufferUsage::StaticDraw)); + BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, {2, 2, 4}, SubData, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); - BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(4, 4, 6)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{SubDataComplete}, TestSuite::Compare::Container); +} - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +void CubeMapTextureArrayGLTest::subImageQuery() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0, 0, 0, 0, - 0, 0, 0, 0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + CubeMapTextureArray texture; + texture.setStorage(1, TextureFormat::RGBA8, {4, 4, 6}) + .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 6}, SubDataComplete}); - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0, 0, 0, 0, - 0, 0, 0, 0, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + MAGNUM_VERIFY_NO_ERROR(); - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0, 0, 0, 0, - 0, 0, 0, 0, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Image3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, {2, 2, 4}), {ColorFormat::RGBA, ColorType::UnsignedByte}); - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(2, 2, 4)); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{SubData}, TestSuite::Compare::Container); +} + +void CubeMapTextureArrayGLTest::subImageQueryBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + CubeMapTextureArray texture; + texture.setStorage(1, TextureFormat::RGBA8, {4, 4, 6}) + .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 6}, SubDataComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, {2, 2, 4}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(2, 2, 4)); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{SubData}, TestSuite::Compare::Container); } void CubeMapTextureArrayGLTest::generateMipmap() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported.")); CubeMapTextureArray texture; texture.setImage(0, TextureFormat::RGBA8, diff --git a/src/Magnum/Test/CubeMapTextureGLTest.cpp b/src/Magnum/Test/CubeMapTextureGLTest.cpp index e71d10b2c..740960a0a 100644 --- a/src/Magnum/Test/CubeMapTextureGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,48 +34,56 @@ #include "Magnum/CubeMapTexture.h" #include "Magnum/Image.h" #include "Magnum/TextureFormat.h" +#include "Magnum/Math/Range.h" #include "Magnum/Test/AbstractOpenGLTester.h" namespace Magnum { namespace Test { -class CubeMapTextureGLTest: public AbstractOpenGLTester { - public: - explicit CubeMapTextureGLTest(); - - void construct(); - void bind(); - - void sampling(); - void samplingSRGBDecode(); - #ifndef MAGNUM_TARGET_GLES2 - void samplingSwizzle(); - #else - void samplingMaxLevel(); - void samplingCompare(); - #endif - #ifndef MAGNUM_TARGET_GLES - void samplingBorderInteger(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void samplingDepthStencilMode(); - #endif - - void storage(); - - void image(); - #ifndef MAGNUM_TARGET_GLES2 - void imageBuffer(); - #endif - - void subImage(); - #ifndef MAGNUM_TARGET_GLES2 - void subImageBuffer(); - #endif - - void generateMipmap(); - - void invalidateImage(); - void invalidateSubImage(); +struct CubeMapTextureGLTest: AbstractOpenGLTester { + explicit CubeMapTextureGLTest(); + + void construct(); + void bind(); + + void sampling(); + void samplingSRGBDecode(); + #ifndef MAGNUM_TARGET_GLES2 + void samplingSwizzle(); + #else + void samplingMaxLevel(); + void samplingCompare(); + #endif + #ifndef MAGNUM_TARGET_GLES + void samplingBorderInteger(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void samplingDepthStencilMode(); + #endif + + void storage(); + + #ifndef MAGNUM_TARGET_GLES + void imageFull(); + void imageFullBuffer(); + #endif + void image(); + #ifndef MAGNUM_TARGET_GLES2 + void imageBuffer(); + #endif + + void subImage(); + #ifndef MAGNUM_TARGET_GLES2 + void subImageBuffer(); + #endif + #ifndef MAGNUM_TARGET_GLES + void subImageQuery(); + void subImageQueryBuffer(); + #endif + + void generateMipmap(); + + void invalidateImage(); + void invalidateSubImage(); }; CubeMapTextureGLTest::CubeMapTextureGLTest() { @@ -99,10 +107,18 @@ CubeMapTextureGLTest::CubeMapTextureGLTest() { &CubeMapTextureGLTest::storage, + #ifndef MAGNUM_TARGET_GLES + &CubeMapTextureGLTest::imageFull, + &CubeMapTextureGLTest::imageFullBuffer, + #endif &CubeMapTextureGLTest::image, #ifndef MAGNUM_TARGET_GLES2 &CubeMapTextureGLTest::imageBuffer, #endif + #ifndef MAGNUM_TARGET_GLES + &CubeMapTextureGLTest::subImageQuery, + &CubeMapTextureGLTest::subImageQueryBuffer, + #endif &CubeMapTextureGLTest::subImage, #ifndef MAGNUM_TARGET_GLES2 @@ -265,169 +281,241 @@ void CubeMapTextureGLTest::storage() { CORRADE_SKIP("OpenGL ES 3.1 not supported, skipping image size testing"); #endif - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 0), Vector2i(32)); - - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 1), Vector2i(16)); - - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 2), Vector2i(8)); - - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 3), Vector2i(4)); - - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 4), Vector2i(2)); - + CORRADE_COMPARE(texture.imageSize(0), Vector2i(32)); + CORRADE_COMPARE(texture.imageSize(1), Vector2i(16)); + CORRADE_COMPARE(texture.imageSize(2), Vector2i(8)); + CORRADE_COMPARE(texture.imageSize(3), Vector2i(4)); + CORRADE_COMPARE(texture.imageSize(4), Vector2i(2)); /* Not available */ - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 5), Vector2i(0)); + CORRADE_COMPARE(texture.imageSize(5), Vector2i(0)); MAGNUM_VERIFY_NO_ERROR(); #endif } -void CubeMapTextureGLTest::image() { - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, +namespace { + constexpr UnsignedByte DataFull[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + + 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, + + 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, + + 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, + + 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f }; +} + +#ifndef MAGNUM_TARGET_GLES +void CubeMapTextureGLTest::imageFull() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::direct_state_access::string() + std::string(" is not supported.")); + + CubeMapTexture texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector2i{2, 2}) + .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{2, 2, 6}, DataFull}); + + MAGNUM_VERIFY_NO_ERROR(); + + Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(2, 2, 6)); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{DataFull}, TestSuite::Compare::Container); +} + +void CubeMapTextureGLTest::imageFullBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::direct_state_access::string() + std::string(" is not supported.")); + + CubeMapTexture texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector2i{2}) + .setSubImage(0, {}, BufferImage3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{2, 2, 6}, DataFull, BufferUsage::StaticDraw}); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(2, 2, 6)); + const auto imageData = image.buffer().data(); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{DataFull}, TestSuite::Compare::Container); +} +#endif + +namespace { + constexpr UnsignedByte Data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; +} + +void CubeMapTextureGLTest::image() { CubeMapTexture texture; texture.setImage(CubeMapTexture::Coordinate::PositiveX, 0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(CubeMapTexture::Coordinate::PositiveX, 0, image); + Image2D image = texture.image(CubeMapTexture::Coordinate::PositiveX, 0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data+16), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data}, TestSuite::Compare::Container); #endif } #ifndef MAGNUM_TARGET_GLES2 void CubeMapTextureGLTest::imageBuffer() { - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; CubeMapTexture texture; texture.setImage(CubeMapTexture::Coordinate::PositiveX, 0, TextureFormat::RGBA8, - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw)); + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(CubeMapTexture::Coordinate::PositiveX, 0, image, BufferUsage::StaticRead); + BufferImage2D image = texture.image(CubeMapTexture::Coordinate::PositiveX, 0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(2)); - const auto imageData = image.buffer().data(); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data+16), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data}, TestSuite::Compare::Container); #endif } #endif +namespace { + constexpr UnsignedByte Zero[4*4*4] = {}; + constexpr UnsignedByte SubDataComplete[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; +} + void CubeMapTextureGLTest::subImage() { - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; CubeMapTexture texture; texture.setImage(CubeMapTexture::Coordinate::PositiveX, 0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), Zero)); texture.setSubImage(CubeMapTexture::Coordinate::PositiveX, 0, Vector2i(1), - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(CubeMapTexture::Coordinate::PositiveX, 0, image); + Image2D image = texture.image(CubeMapTexture::Coordinate::PositiveX, 0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{SubDataComplete}, TestSuite::Compare::Container); #endif } #ifndef MAGNUM_TARGET_GLES2 void CubeMapTextureGLTest::subImageBuffer() { - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; CubeMapTexture texture; texture.setImage(CubeMapTexture::Coordinate::PositiveX, 0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), Zero)); texture.setSubImage(CubeMapTexture::Coordinate::PositiveX, 0, Vector2i(1), - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw)); + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(CubeMapTexture::Coordinate::PositiveX, 0, image, BufferUsage::StaticRead); + BufferImage2D image = texture.image(CubeMapTexture::Coordinate::PositiveX, 0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(4)); - const auto imageData = image.buffer().data(); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{SubDataComplete}, TestSuite::Compare::Container); #endif } #endif +#ifndef MAGNUM_TARGET_GLES +void CubeMapTextureGLTest::subImageQuery() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + /* I'm too lazy to call setSubImage() six times */ + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::direct_state_access::string() + std::string(" is not supported.")); + + CubeMapTexture texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4}) + .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 1}, SubDataComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + Image3D image = texture.subImage(0, Range3Di::fromSize({1, 1, 0}, {2, 2, 1}), {ColorFormat::RGBA, ColorType::UnsignedByte}); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(2, 2, 1)); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data}, TestSuite::Compare::Container); +} + +void CubeMapTextureGLTest::subImageQueryBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + /* I'm too lazy to call setSubImage() six times */ + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::direct_state_access::string() + std::string(" is not supported.")); + + CubeMapTexture texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4}) + .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 1}, SubDataComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage3D image = texture.subImage(0, Range3Di::fromSize({1, 1, 0}, {2, 2, 1}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(2, 2, 1)); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data}, TestSuite::Compare::Container); +} +#endif + void CubeMapTextureGLTest::generateMipmap() { CubeMapTexture texture; texture.setImage(CubeMapTexture::Coordinate::PositiveX, 0, TextureFormat::RGBA8, @@ -445,8 +533,8 @@ void CubeMapTextureGLTest::generateMipmap() { /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i( 0)); + CORRADE_COMPARE(texture.imageSize(0), Vector2i(32)); + CORRADE_COMPARE(texture.imageSize(1), Vector2i( 0)); #endif texture.generateMipmap(); @@ -455,12 +543,12 @@ void CubeMapTextureGLTest::generateMipmap() { /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 2), Vector2i( 8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 3), Vector2i( 4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 4), Vector2i( 2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 5), Vector2i( 1)); + CORRADE_COMPARE(texture.imageSize(0), Vector2i(32)); + CORRADE_COMPARE(texture.imageSize(1), Vector2i(16)); + CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8)); + CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4)); + CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2)); + CORRADE_COMPARE(texture.imageSize(5), Vector2i( 1)); MAGNUM_VERIFY_NO_ERROR(); #endif diff --git a/src/Magnum/Test/DebugGLTest.cpp b/src/Magnum/Test/DebugGLTest.cpp deleted file mode 100644 index ebe46004a..000000000 --- a/src/Magnum/Test/DebugGLTest.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013, 2014 - Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include - -#include "Magnum/Context.h" -#include "Magnum/DebugMessage.h" -#include "Magnum/Extensions.h" -#include "Magnum/Test/AbstractOpenGLTester.h" - -#ifdef MAGNUM_BUILD_DEPRECATED -#include "Magnum/DebugMarker.h" -#endif - -namespace Magnum { namespace Test { - -class DebugGLTest: public AbstractOpenGLTester { - public: - explicit DebugGLTest(); - - void insertMessageNoOp(); - void insertMessage(); - void insertMessageFallback(); - - void setMessageEnabled(); - - void deprecated(); -}; - -DebugGLTest::DebugGLTest() { - addTests({&DebugGLTest::insertMessageNoOp, - &DebugGLTest::insertMessage, - &DebugGLTest::insertMessageFallback, - - &DebugGLTest::setMessageEnabled, - - #ifdef MAGNUM_BUILD_DEPRECATED - &DebugGLTest::deprecated - #endif - }); -} - -void DebugGLTest::insertMessageNoOp() { - if(Context::current()->isExtensionSupported() || - Context::current()->isExtensionSupported() - #ifndef MAGNUM_TARGET_GLES - || Context::current()->isExtensionSupported() - #endif - ) - CORRADE_SKIP("The extensions are supported, cannot test."); - - DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, - 1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!"); - - MAGNUM_VERIFY_NO_ERROR(); -} - -void DebugGLTest::insertMessage() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is not supported")); - - Renderer::enable(Renderer::Feature::DebugOutput); - - Renderer::enable(Renderer::Feature::DebugOutputSynchronous); - std::ostringstream out; - Debug::setOutput(&out); - DebugMessage::setDefaultCallback(); - DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, - 1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!"); - - Renderer::enable(Renderer::Feature::DebugOutput); - - MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(out.str(), - "DebugMessage::Source::Application DebugMessage::Type::Marker 1337 DebugMessage::Severity::Notification \n" - " Hello from OpenGL command stream!\n"); -} - -void DebugGLTest::insertMessageFallback() { - if(Context::current()->isExtensionSupported() || - (!Context::current()->isExtensionSupported() - #ifndef MAGNUM_TARGET_GLES - && !Context::current()->isExtensionSupported() - #endif - )) - CORRADE_SKIP("No proper extension is supported"); - - DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, - 1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!"); - - MAGNUM_VERIFY_NO_ERROR(); -} - -void DebugGLTest::setMessageEnabled() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is not supported")); - - /* Try at least some combinations */ - DebugMessage::setEnabled(DebugMessage::Source::Application, true); - DebugMessage::setEnabled(DebugMessage::Source::Application, DebugMessage::Type::UndefinedBehavior, {3168, 35487, 234487}, false); - DebugMessage::setEnabled(true); - - MAGNUM_VERIFY_NO_ERROR(); -} - -#ifdef MAGNUM_BUILD_DEPRECATED -void DebugGLTest::deprecated() { - #if defined(__GNUC__) && !defined(CORRADE_GCC45_COMPATIBILITY) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - #endif - DebugMarker::mark("hello"); - #if defined(__GNUC__) && !defined(CORRADE_GCC45_COMPATIBILITY) - #pragma GCC diagnostic pop - #endif - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - -}} - -CORRADE_TEST_MAIN(Magnum::Test::DebugGLTest) diff --git a/src/Magnum/Test/DebugMessageTest.cpp b/src/Magnum/Test/DebugMessageTest.cpp deleted file mode 100644 index 1b44ae0c6..000000000 --- a/src/Magnum/Test/DebugMessageTest.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013, 2014 - Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include -#include - -#include "Magnum/DebugMessage.h" - -namespace Magnum { namespace Test { - -class DebugMessageTest: public TestSuite::Tester { - public: - explicit DebugMessageTest(); - - void debugSource(); - void debugType(); - void debugSeverity(); -}; - -DebugMessageTest::DebugMessageTest() { - addTests({&DebugMessageTest::debugSource, - &DebugMessageTest::debugType, - &DebugMessageTest::debugSeverity}); -} - -void DebugMessageTest::debugSource() { - std::ostringstream o; - Debug(&o) << DebugMessage::Source::ShaderCompiler; - CORRADE_COMPARE(o.str(), "DebugMessage::Source::ShaderCompiler\n"); -} - -void DebugMessageTest::debugType() { - std::ostringstream o; - Debug(&o) << DebugMessage::Type::DeprecatedBehavior; - CORRADE_COMPARE(o.str(), "DebugMessage::Type::DeprecatedBehavior\n"); -} - -void DebugMessageTest::debugSeverity() { - std::ostringstream o; - Debug(&o) << DebugMessage::Severity::Notification; - CORRADE_COMPARE(o.str(), "DebugMessage::Severity::Notification\n"); -} - -}} - -CORRADE_TEST_MAIN(Magnum::Test::DebugMessageTest) diff --git a/src/Magnum/Test/DebugOutputGLTest.cpp b/src/Magnum/Test/DebugOutputGLTest.cpp new file mode 100644 index 000000000..41e0a446d --- /dev/null +++ b/src/Magnum/Test/DebugOutputGLTest.cpp @@ -0,0 +1,206 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Magnum/Context.h" +#include "Magnum/DebugOutput.h" +#include "Magnum/Extensions.h" +#include "Magnum/Test/AbstractOpenGLTester.h" + +#ifdef MAGNUM_BUILD_DEPRECATED +#include "Magnum/DebugMarker.h" +#endif + +namespace Magnum { namespace Test { + +struct DebugOutputGLTest: AbstractOpenGLTester { + explicit DebugOutputGLTest(); + + void setCallback(); + void setEnabled(); + + void messageNoOp(); + void message(); + void messageFallback(); + + void groupNoOp(); + void group(); + void groupFallback(); + + #ifdef MAGNUM_BUILD_DEPRECATED + void deprecated(); + #endif +}; + +DebugOutputGLTest::DebugOutputGLTest() { + addTests({&DebugOutputGLTest::setCallback, + &DebugOutputGLTest::setEnabled, + + &DebugOutputGLTest::messageNoOp, + &DebugOutputGLTest::message, + &DebugOutputGLTest::messageFallback, + + &DebugOutputGLTest::groupNoOp, + &DebugOutputGLTest::group, + &DebugOutputGLTest::groupFallback, + + #ifdef MAGNUM_BUILD_DEPRECATED + &DebugOutputGLTest::deprecated + #endif + }); +} + +void DebugOutputGLTest::setCallback() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is not supported")); + + /* Need to be careful, because the test runner is using debug output too */ + DebugOutput::setDefaultCallback(); + + MAGNUM_VERIFY_NO_ERROR(); +} + +void DebugOutputGLTest::setEnabled() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is not supported")); + + /* Try at least some combinations */ + DebugOutput::setEnabled(DebugOutput::Source::Application, true); + DebugOutput::setEnabled(DebugOutput::Source::Application, DebugOutput::Type::UndefinedBehavior, {3168, 35487, 234487}, false); + DebugOutput::setEnabled(true); + + MAGNUM_VERIFY_NO_ERROR(); +} + +void DebugOutputGLTest::messageNoOp() { + if(Context::current()->isExtensionSupported() || + Context::current()->isExtensionSupported() + #ifndef MAGNUM_TARGET_GLES + || Context::current()->isExtensionSupported() + #endif + ) + CORRADE_SKIP("The extensions are supported, cannot test."); + + DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, + 1337, DebugOutput::Severity::Notification, "Hello from OpenGL command stream!"); + + MAGNUM_VERIFY_NO_ERROR(); +} + +void DebugOutputGLTest::message() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is not supported")); + + /* Need to be careful, because the test runner is using debug output too */ + std::ostringstream out; + Debug::setOutput(&out); + DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, + 1337, DebugOutput::Severity::High, "Hello from OpenGL command stream!"); + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_COMPARE(out.str(), + "Debug output: high severity application marker (1337): Hello from OpenGL command stream!\n"); +} + +void DebugOutputGLTest::messageFallback() { + if(Context::current()->isExtensionSupported() || + (!Context::current()->isExtensionSupported() + #ifndef MAGNUM_TARGET_GLES + && !Context::current()->isExtensionSupported() + #endif + )) + CORRADE_SKIP("No proper extension is supported"); + + DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, + 1337, DebugOutput::Severity::Notification, "Hello from OpenGL command stream!"); + + MAGNUM_VERIFY_NO_ERROR(); +} + +void DebugOutputGLTest::groupNoOp() { + if(Context::current()->isExtensionSupported() || + Context::current()->isExtensionSupported()) + CORRADE_SKIP("The extensions are supported, cannot test."); + + { + DebugGroup g{DebugGroup::Source::Application, 1337, "Debug group"}; + } + + MAGNUM_VERIFY_NO_ERROR(); +} + +void DebugOutputGLTest::group() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is not supported")); + + /* Need to be careful, because the test runner is using debug output too */ + std::ostringstream out; + Debug::setOutput(&out); + { + DebugGroup g1{DebugGroup::Source::Application, 42, "Automatic debug group"}; + DebugGroup g2; + g2.push(DebugGroup::Source::ThirdParty, 1337, "Manual debug group"); + g2.pop(); + } + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_COMPARE(out.str(), + "Debug output: application debug group enter (42): Automatic debug group\n" + "Debug output: third party debug group enter (1337): Manual debug group\n" + "Debug output: third party debug group leave (1337): Manual debug group\n" + "Debug output: application debug group leave (42): Automatic debug group\n"); +} + +void DebugOutputGLTest::groupFallback() { + if(Context::current()->isExtensionSupported() || + !Context::current()->isExtensionSupported()) + CORRADE_SKIP("No proper extension is supported"); + + { + DebugGroup g{DebugGroup::Source::Application, 1337, "Debug group"}; + } + + MAGNUM_VERIFY_NO_ERROR(); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +void DebugOutputGLTest::deprecated() { + #if defined(__GNUC__) && !defined(CORRADE_GCC45_COMPATIBILITY) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #endif + DebugMarker::mark("hello"); + #if defined(__GNUC__) && !defined(CORRADE_GCC45_COMPATIBILITY) + #pragma GCC diagnostic pop + #endif + + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +}} + +CORRADE_TEST_MAIN(Magnum::Test::DebugOutputGLTest) diff --git a/src/Magnum/Test/DebugOutputTest.cpp b/src/Magnum/Test/DebugOutputTest.cpp new file mode 100644 index 000000000..c56f68176 --- /dev/null +++ b/src/Magnum/Test/DebugOutputTest.cpp @@ -0,0 +1,95 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include + +#include "Magnum/DebugOutput.h" + +namespace Magnum { namespace Test { + +struct DebugOutputTest: TestSuite::Tester { + explicit DebugOutputTest(); + + void debugSource(); + void debugType(); + void debugSeverity(); + + void debugMessageSource(); + void debugMessageType(); + + void debugGroupSource(); +}; + +DebugOutputTest::DebugOutputTest() { + addTests({&DebugOutputTest::debugSource, + &DebugOutputTest::debugType, + &DebugOutputTest::debugSeverity, + + &DebugOutputTest::debugMessageSource, + &DebugOutputTest::debugMessageType, + + &DebugOutputTest::debugGroupSource}); +} + +void DebugOutputTest::debugSource() { + std::ostringstream o; + Debug(&o) << DebugOutput::Source::ShaderCompiler; + CORRADE_COMPARE(o.str(), "DebugOutput::Source::ShaderCompiler\n"); +} + +void DebugOutputTest::debugType() { + std::ostringstream o; + Debug(&o) << DebugOutput::Type::PushGroup; + CORRADE_COMPARE(o.str(), "DebugOutput::Type::PushGroup\n"); +} + +void DebugOutputTest::debugSeverity() { + std::ostringstream o; + Debug(&o) << DebugOutput::Severity::Notification; + CORRADE_COMPARE(o.str(), "DebugOutput::Severity::Notification\n"); +} + +void DebugOutputTest::debugMessageSource() { + std::ostringstream o; + Debug(&o) << DebugMessage::Source::Application; + CORRADE_COMPARE(o.str(), "DebugMessage::Source::Application\n"); +} + +void DebugOutputTest::debugMessageType() { + std::ostringstream o; + Debug(&o) << DebugMessage::Type::DeprecatedBehavior; + CORRADE_COMPARE(o.str(), "DebugMessage::Type::DeprecatedBehavior\n"); +} + +void DebugOutputTest::debugGroupSource() { + std::ostringstream o; + Debug(&o) << DebugGroup::Source::ThirdParty; + CORRADE_COMPARE(o.str(), "DebugGroup::Source::ThirdParty\n"); +} + +}} + +CORRADE_TEST_MAIN(Magnum::Test::DebugOutputTest) diff --git a/src/Magnum/Test/DefaultFramebufferTest.cpp b/src/Magnum/Test/DefaultFramebufferTest.cpp index 98c7c7659..b5331ebcb 100644 --- a/src/Magnum/Test/DefaultFramebufferTest.cpp +++ b/src/Magnum/Test/DefaultFramebufferTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Test { -class DefaultFramebufferTest: public TestSuite::Tester { - public: - explicit DefaultFramebufferTest(); +struct DefaultFramebufferTest: TestSuite::Tester { + explicit DefaultFramebufferTest(); - void debugStatus(); + void debugStatus(); }; DefaultFramebufferTest::DefaultFramebufferTest() { diff --git a/src/Magnum/Test/FramebufferGLTest.cpp b/src/Magnum/Test/FramebufferGLTest.cpp index bc098fc26..9e88b3455 100644 --- a/src/Magnum/Test/FramebufferGLTest.cpp +++ b/src/Magnum/Test/FramebufferGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -49,50 +49,51 @@ namespace Magnum { namespace Test { -class FramebufferGLTest: public AbstractOpenGLTester { - public: - explicit FramebufferGLTest(); +struct FramebufferGLTest: AbstractOpenGLTester { + explicit FramebufferGLTest(); - void construct(); - void constructCopy(); - void constructMove(); + void construct(); + void constructCopy(); + void constructMove(); - void label(); + void label(); - void attachRenderbuffer(); - void attachRenderbufferMultisample(); + void attachRenderbuffer(); + void attachRenderbufferMultisample(); - #ifndef MAGNUM_TARGET_GLES - void attachTexture1D(); - #endif - void attachTexture2D(); - void attachTexture3D(); - #ifndef MAGNUM_TARGET_GLES - void attachTexture1DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void attachTexture2DArray(); - void attachTexture2DMultisample(); - #endif - #ifndef MAGNUM_TARGET_GLES - void attachTexture2DMultisampleArray(); - void attachRectangleTexture(); - #endif - void attachCubeMapTexture(); - #ifndef MAGNUM_TARGET_GLES - void attachCubeMapTextureArray(); - #endif + #ifndef MAGNUM_TARGET_GLES + void attachTexture1D(); + #endif + void attachTexture2D(); + void attachTexture3D(); + #ifndef MAGNUM_TARGET_GLES + void attachTexture1DArray(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void attachTexture2DArray(); + void attachTexture2DMultisample(); + #endif + #ifndef MAGNUM_TARGET_GLES + void attachTexture2DMultisampleArray(); + void attachRectangleTexture(); + #endif + void attachCubeMapTexture(); + #ifndef MAGNUM_TARGET_GLES + void attachCubeMapTextureArray(); + #endif - void multipleColorOutputs(); + void multipleColorOutputs(); - void clear(); - void invalidate(); - void invalidateSub(); - void read(); - #ifndef MAGNUM_TARGET_GLES2 - void readBuffer(); - #endif - void blit(); + void clear(); + void invalidate(); + #ifndef MAGNUM_TARGET_GLES2 + void invalidateSub(); + #endif + void read(); + #ifndef MAGNUM_TARGET_GLES2 + void readBuffer(); + #endif + void blit(); #ifdef MAGNUM_TARGET_GLES2 private: @@ -135,7 +136,9 @@ FramebufferGLTest::FramebufferGLTest() { &FramebufferGLTest::clear, &FramebufferGLTest::invalidate, + #ifndef MAGNUM_TARGET_GLES2 &FramebufferGLTest::invalidateSub, + #endif &FramebufferGLTest::read, #ifndef MAGNUM_TARGET_GLES2 &FramebufferGLTest::readBuffer, @@ -274,7 +277,8 @@ void FramebufferGLTest::attachRenderbuffer() { } MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } void FramebufferGLTest::attachRenderbufferMultisample() { @@ -311,7 +315,8 @@ void FramebufferGLTest::attachRenderbufferMultisample() { #endif MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } #ifndef MAGNUM_TARGET_GLES @@ -330,7 +335,8 @@ void FramebufferGLTest::attachTexture1D() { .attachTexture(Framebuffer::BufferAttachment::DepthStencil, depthStencil, 0); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } #endif @@ -390,7 +396,8 @@ void FramebufferGLTest::attachTexture2D() { #endif MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } void FramebufferGLTest::attachTexture3D() { @@ -413,7 +420,8 @@ void FramebufferGLTest::attachTexture3D() { framebuffer.attachTextureLayer(Framebuffer::ColorAttachment(0), color, 0, 0); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } #ifndef MAGNUM_TARGET_GLES @@ -432,7 +440,8 @@ void FramebufferGLTest::attachTexture1DArray() { .attachTextureLayer(Framebuffer::BufferAttachment::DepthStencil, depthStencil, 0, 3); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } #endif @@ -456,7 +465,8 @@ void FramebufferGLTest::attachTexture2DArray() { .attachTextureLayer(Framebuffer::BufferAttachment::DepthStencil, depthStencil, 0, 3); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } #endif @@ -483,7 +493,8 @@ void FramebufferGLTest::attachTexture2DMultisample() { .attachTexture(Framebuffer::BufferAttachment::DepthStencil, depthStencil); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } #endif @@ -505,7 +516,8 @@ void FramebufferGLTest::attachTexture2DMultisampleArray() { .attachTextureLayer(Framebuffer::BufferAttachment::DepthStencil, depthStencil, 3); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } void FramebufferGLTest::attachRectangleTexture() { @@ -525,7 +537,8 @@ void FramebufferGLTest::attachRectangleTexture() { .attachTexture(Framebuffer::BufferAttachment::DepthStencil, depthStencil); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } #endif @@ -575,7 +588,8 @@ void FramebufferGLTest::attachCubeMapTexture() { #endif MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } #ifndef MAGNUM_TARGET_GLES @@ -596,7 +610,8 @@ void FramebufferGLTest::attachCubeMapTextureArray() { .attachTextureLayer(Framebuffer::BufferAttachment::DepthStencil, depthStencil, 0, 3); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } #endif @@ -644,7 +659,8 @@ void FramebufferGLTest::multipleColorOutputs() { } MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); } void FramebufferGLTest::clear() { @@ -717,6 +733,7 @@ void FramebufferGLTest::invalidate() { MAGNUM_VERIFY_NO_ERROR(); } +#ifndef MAGNUM_TARGET_GLES2 void FramebufferGLTest::invalidateSub() { #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) @@ -724,11 +741,7 @@ void FramebufferGLTest::invalidateSub() { #endif Renderbuffer color; - #ifndef MAGNUM_TARGET_GLES2 color.setStorage(RenderbufferFormat::RGBA8, Vector2i(128)); - #else - color.setStorage(RenderbufferFormat::RGBA4, Vector2i(128)); - #endif Renderbuffer depth; depth.setStorage(RenderbufferFormat::DepthComponent16, Vector2i(128)); @@ -738,13 +751,15 @@ void FramebufferGLTest::invalidateSub() { .attachRenderbuffer(Framebuffer::BufferAttachment::Depth, depth); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); framebuffer.invalidate({Framebuffer::InvalidationAttachment::Depth, Framebuffer::ColorAttachment(0)}, {{32, 16}, {79, 64}}); MAGNUM_VERIFY_NO_ERROR(); } +#endif void FramebufferGLTest::read() { #ifndef MAGNUM_TARGET_GLES @@ -787,18 +802,18 @@ void FramebufferGLTest::read() { } MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); Renderer::setClearColor(Math::normalize(Color4ub(128, 64, 32, 17))); Renderer::setClearDepth(Math::normalize(48352)); Renderer::setClearStencil(67); framebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth|FramebufferClear::Stencil); - Image2D colorImage(ColorFormat::RGBA, ColorType::UnsignedByte); - framebuffer.read({16, 8}, {8, 16}, colorImage); - CORRADE_COMPARE(colorImage.size(), Vector2i(8, 16)); + Image2D colorImage = framebuffer.read(Range2Di::fromSize({16, 8}, {8, 16}), {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); + CORRADE_COMPARE(colorImage.size(), Vector2i(8, 16)); CORRADE_COMPARE(colorImage.data()[0], Color4ub(128, 64, 32, 17)); #ifdef MAGNUM_TARGET_GLES @@ -809,8 +824,7 @@ void FramebufferGLTest::read() { Debug() << "Using" << Extensions::GL::NV::read_depth::string(); #endif - Image2D depthImage(ColorFormat::DepthComponent, ColorType::UnsignedShort); - framebuffer.read({}, Vector2i(1), depthImage); + Image2D depthImage = framebuffer.read({{}, Vector2i{1}}, {ColorFormat::DepthComponent, ColorType::UnsignedShort}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(depthImage.data()[0], 48352); @@ -824,8 +838,7 @@ void FramebufferGLTest::read() { Debug() << "Using" << Extensions::GL::NV::read_stencil::string(); #endif - Image2D stencilImage(ColorFormat::StencilIndex, ColorType::UnsignedByte); - framebuffer.read({}, Vector2i(1), stencilImage); + Image2D stencilImage = framebuffer.read({{}, Vector2i{1}}, {ColorFormat::StencilIndex, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(stencilImage.data()[0], 67); @@ -839,8 +852,7 @@ void FramebufferGLTest::read() { Debug() << "Using" << Extensions::GL::NV::read_depth_stencil::string(); #endif - Image2D depthStencilImage(ColorFormat::DepthStencil, ColorType::UnsignedInt248); - framebuffer.read({}, Vector2i(1), depthStencilImage); + Image2D depthStencilImage = framebuffer.read({{}, Vector2i{1}}, {ColorFormat::DepthStencil, ColorType::UnsignedInt248}); MAGNUM_VERIFY_NO_ERROR(); /** @todo This will probably fail on different systems */ @@ -867,15 +879,15 @@ void FramebufferGLTest::readBuffer() { .attachRenderbuffer(Framebuffer::BufferAttachment::DepthStencil, depthStencil); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); Renderer::setClearColor(Math::normalize(Color4ub(128, 64, 32, 17))); Renderer::setClearDepth(Math::normalize(48352)); Renderer::setClearStencil(67); framebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth|FramebufferClear::Stencil); - BufferImage2D colorImage(ColorFormat::RGBA, ColorType::UnsignedByte); - framebuffer.read({16, 8}, {8, 16}, colorImage, BufferUsage::StaticRead); + BufferImage2D colorImage = framebuffer.read(Range2Di::fromSize({16, 8}, {8, 16}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); CORRADE_COMPARE(colorImage.size(), Vector2i(8, 16)); MAGNUM_VERIFY_NO_ERROR(); @@ -912,8 +924,10 @@ void FramebufferGLTest::blit() { b.attachRenderbuffer(Framebuffer::ColorAttachment(0), colorB); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(a.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); - CORRADE_COMPARE(b.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete); + CORRADE_COMPARE(a.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(a.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); + CORRADE_COMPARE(b.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete); + CORRADE_COMPARE(b.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete); /* Clear first with some color and second with another */ Renderer::setClearColor(Math::normalize(Color4ub(128, 64, 32, 17))); @@ -922,18 +936,17 @@ void FramebufferGLTest::blit() { b.clear(FramebufferClear::Color); /* The framebuffer should be black before */ - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - b.read({}, Vector2i(1), image); + Image2D imageBefore = b.read({{}, Vector2i{1}}, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(image.data()[0], Color4ub()); + CORRADE_COMPARE(imageBefore.data()[0], Color4ub()); /* And have given color after */ Framebuffer::blit(a, b, a.viewport(), FramebufferBlit::Color); - b.read({}, Vector2i(1), image); + Image2D imageAfter = b.read({{}, Vector2i{1}}, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(image.data()[0], Color4ub(128, 64, 32, 17)); + CORRADE_COMPARE(imageAfter.data()[0], Color4ub(128, 64, 32, 17)); } }} diff --git a/src/Magnum/Test/FramebufferTest.cpp b/src/Magnum/Test/FramebufferTest.cpp index 259f20558..e691b2721 100644 --- a/src/Magnum/Test/FramebufferTest.cpp +++ b/src/Magnum/Test/FramebufferTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Test { -class FramebufferTest: public TestSuite::Tester { - public: - explicit FramebufferTest(); +struct FramebufferTest: TestSuite::Tester { + explicit FramebufferTest(); - void debugStatus(); + void debugStatus(); }; FramebufferTest::FramebufferTest() { diff --git a/src/Magnum/Test/ImageReferenceTest.cpp b/src/Magnum/Test/ImageReferenceTest.cpp index 669d3c252..cf02c103e 100644 --- a/src/Magnum/Test/ImageReferenceTest.cpp +++ b/src/Magnum/Test/ImageReferenceTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,12 +30,11 @@ namespace Magnum { namespace Test { -class ImageReferenceTest: public TestSuite::Tester { - public: - explicit ImageReferenceTest(); +struct ImageReferenceTest: TestSuite::Tester { + explicit ImageReferenceTest(); - void construct(); - void setData(); + void construct(); + void setData(); }; ImageReferenceTest::ImageReferenceTest() { @@ -44,7 +43,7 @@ ImageReferenceTest::ImageReferenceTest() { } void ImageReferenceTest::construct() { - const unsigned char data[3] = {}; + const char data[3] = {}; ImageReference2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); CORRADE_COMPARE(a.format(), ColorFormat::Red); @@ -54,15 +53,15 @@ void ImageReferenceTest::construct() { } void ImageReferenceTest::setData() { - const unsigned char data[3] = {}; + const char data[3] = {}; ImageReference2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); - const unsigned char data2[8] = {}; + const char data2[8] = {}; a.setData(data2); CORRADE_COMPARE(a.format(), ColorFormat::Red); CORRADE_COMPARE(a.type(), ColorType::UnsignedByte); CORRADE_COMPARE(a.size(), Vector2i(1, 3)); - CORRADE_COMPARE(a.data(), reinterpret_cast(data2)); + CORRADE_COMPARE(a.data(), data2); } }} diff --git a/src/Magnum/Test/ImageTest.cpp b/src/Magnum/Test/ImageTest.cpp index 1fa5366ea..a6110a003 100644 --- a/src/Magnum/Test/ImageTest.cpp +++ b/src/Magnum/Test/ImageTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,17 +30,16 @@ namespace Magnum { namespace Test { -class ImageTest: public TestSuite::Tester { - public: - explicit ImageTest(); +struct ImageTest: TestSuite::Tester { + explicit ImageTest(); - void construct(); - void constructCopy(); - void constructMove(); + void construct(); + void constructCopy(); + void constructMove(); - void setData(); - void toReference(); - void release(); + void setData(); + void toReference(); + void release(); }; ImageTest::ImageTest() { @@ -54,7 +53,7 @@ ImageTest::ImageTest() { } void ImageTest::construct() { - auto data = new unsigned char[3]; + auto data = new char[3]; Image2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); CORRADE_COMPARE(a.format(), ColorFormat::Red); @@ -76,11 +75,11 @@ void ImageTest::constructCopy() { } void ImageTest::constructMove() { - auto data = new unsigned char[3]; + auto data = new char[3]; Image2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); Image2D b(std::move(a)); - CORRADE_COMPARE(a.data(), static_cast(nullptr)); + CORRADE_COMPARE(a.data(), static_cast(nullptr)); CORRADE_COMPARE(a.size(), Vector2i()); CORRADE_COMPARE(b.format(), ColorFormat::Red); @@ -88,7 +87,7 @@ void ImageTest::constructMove() { CORRADE_COMPARE(b.size(), Vector2i(1, 3)); CORRADE_COMPARE(b.data(), data); - auto data2 = new unsigned char[3]; + auto data2 = new char[12*4*2]; Image2D c(ColorFormat::RGBA, ColorType::UnsignedShort, {2, 6}, data2); c = std::move(b); @@ -102,19 +101,19 @@ void ImageTest::constructMove() { } void ImageTest::setData() { - auto data = new unsigned char[3]; + auto data = new char[3]; Image2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); - auto data2 = new unsigned short[2*4]; + auto data2 = new char[2*4]; a.setData(ColorFormat::RGBA, ColorType::UnsignedShort, {2, 1}, data2); CORRADE_COMPARE(a.format(), ColorFormat::RGBA); CORRADE_COMPARE(a.type(), ColorType::UnsignedShort); CORRADE_COMPARE(a.size(), Vector2i(2, 1)); - CORRADE_COMPARE(a.data(), reinterpret_cast(data2)); + CORRADE_COMPARE(a.data(), data2); } void ImageTest::toReference() { - auto data = new unsigned char[3]; + auto data = new char[3]; const Image2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); ImageReference2D b = a; @@ -134,12 +133,12 @@ void ImageTest::toReference() { } void ImageTest::release() { - unsigned char data[] = {'c', 'a', 'f', 'e'}; + char data[] = {'c', 'a', 'f', 'e'}; Image2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 4}, data); - const unsigned char* const pointer = a.release(); + const char* const pointer = a.release(); CORRADE_COMPARE(pointer, data); - CORRADE_COMPARE(a.data(), static_cast(nullptr)); + CORRADE_COMPARE(a.data(), static_cast(nullptr)); CORRADE_COMPARE(a.size(), Vector2i()); } diff --git a/src/Magnum/Test/MeshGLTest.cpp b/src/Magnum/Test/MeshGLTest.cpp index ee4d23d7f..a29a0994e 100644 --- a/src/Magnum/Test/MeshGLTest.cpp +++ b/src/Magnum/Test/MeshGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -23,6 +23,7 @@ DEALINGS IN THE SOFTWARE. */ +#include "Magnum/AbstractShaderProgram.h" #include "Magnum/Buffer.h" #include "Magnum/Color.h" #include "Magnum/ColorFormat.h" @@ -41,98 +42,97 @@ namespace Magnum { namespace Test { /* Tests also MeshView class. */ -class MeshGLTest: public AbstractOpenGLTester { - public: - explicit MeshGLTest(); +struct MeshGLTest: AbstractOpenGLTester { + explicit MeshGLTest(); - void construct(); - void constructCopy(); - void constructMove(); + void construct(); + void constructCopy(); + void constructMove(); - void label(); + void label(); - #ifndef MAGNUM_TARGET_GLES2 - void addVertexBufferUnsignedInt(); - void addVertexBufferInt(); - #endif - void addVertexBufferFloat(); - #ifndef MAGNUM_TARGET_GLES - void addVertexBufferDouble(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void addVertexBufferVectorNui(); - void addVertexBufferVectorNi(); - #endif - void addVertexBufferVectorN(); - #ifndef MAGNUM_TARGET_GLES - void addVertexBufferVectorNd(); - #endif - void addVertexBufferMatrixNxN(); - #ifndef MAGNUM_TARGET_GLES - void addVertexBufferMatrixNxNd(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void addVertexBufferMatrixMxN(); - #endif - #ifndef MAGNUM_TARGET_GLES - void addVertexBufferMatrixMxNd(); - #endif + #ifndef MAGNUM_TARGET_GLES2 + void addVertexBufferUnsignedInt(); + void addVertexBufferInt(); + #endif + void addVertexBufferFloat(); + #ifndef MAGNUM_TARGET_GLES + void addVertexBufferDouble(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void addVertexBufferVectorNui(); + void addVertexBufferVectorNi(); + #endif + void addVertexBufferVectorN(); + #ifndef MAGNUM_TARGET_GLES + void addVertexBufferVectorNd(); + #endif + void addVertexBufferMatrixNxN(); + #ifndef MAGNUM_TARGET_GLES + void addVertexBufferMatrixNxNd(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void addVertexBufferMatrixMxN(); + #endif + #ifndef MAGNUM_TARGET_GLES + void addVertexBufferMatrixMxNd(); + #endif - #ifndef MAGNUM_TARGET_GLES2 - void addVertexBufferUnsignedIntWithUnsignedShort(); - void addVertexBufferUnsignedIntWithShort(); - void addVertexBufferIntWithUnsignedShort(); - void addVertexBufferIntWithShort(); - #endif - /* Other Float types omitted (covered by addVertexBufferNormalized()) */ - void addVertexBufferFloatWithHalfFloat(); - #ifndef MAGNUM_TARGET_GLES - void addVertexBufferFloatWithDouble(); - void addVertexBufferVector3WithUnsignedInt10f11f11fRev(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void addVertexBufferVector4WithUnsignedInt2101010Rev(); - void addVertexBufferVector4WithInt2101010Rev(); - #endif + #ifndef MAGNUM_TARGET_GLES2 + void addVertexBufferUnsignedIntWithUnsignedShort(); + void addVertexBufferUnsignedIntWithShort(); + void addVertexBufferIntWithUnsignedShort(); + void addVertexBufferIntWithShort(); + #endif + /* Other Float types omitted (covered by addVertexBufferNormalized()) */ + void addVertexBufferFloatWithHalfFloat(); + #ifndef MAGNUM_TARGET_GLES + void addVertexBufferFloatWithDouble(); + void addVertexBufferVector3WithUnsignedInt10f11f11fRev(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void addVertexBufferVector4WithUnsignedInt2101010Rev(); + void addVertexBufferVector4WithInt2101010Rev(); + #endif - void addVertexBufferLessVectorComponents(); - void addVertexBufferNormalized(); - #ifndef MAGNUM_TARGET_GLES - void addVertexBufferBGRA(); - #endif + void addVertexBufferLessVectorComponents(); + void addVertexBufferNormalized(); + #ifndef MAGNUM_TARGET_GLES + void addVertexBufferBGRA(); + #endif - void addVertexBufferMultiple(); - void addVertexBufferMultipleGaps(); + void addVertexBufferMultiple(); + void addVertexBufferMultipleGaps(); - void setIndexBuffer(); - void setIndexBufferRange(); - void setIndexBufferUnsignedInt(); + void setIndexBuffer(); + void setIndexBufferRange(); + void setIndexBufferUnsignedInt(); - #ifndef MAGNUM_TARGET_GLES - void setBaseVertex(); - #endif - void setInstanceCount(); - void setInstanceCountIndexed(); - #ifndef MAGNUM_TARGET_GLES - void setInstanceCountBaseInstance(); - void setInstanceCountBaseInstanceIndexed(); - void setInstanceCountBaseVertex(); - void setInstanceCountBaseVertexBaseInstance(); - #endif + #ifndef MAGNUM_TARGET_GLES + void setBaseVertex(); + #endif + void setInstanceCount(); + void setInstanceCountIndexed(); + #ifndef MAGNUM_TARGET_GLES + void setInstanceCountBaseInstance(); + void setInstanceCountBaseInstanceIndexed(); + void setInstanceCountBaseVertex(); + void setInstanceCountBaseVertexBaseInstance(); + #endif - void addVertexBufferInstancedFloat(); - #ifndef MAGNUM_TARGET_GLES2 - void addVertexBufferInstancedInteger(); - #endif - #ifndef MAGNUM_TARGET_GLES - void addVertexBufferInstancedDouble(); - #endif + void addVertexBufferInstancedFloat(); + #ifndef MAGNUM_TARGET_GLES2 + void addVertexBufferInstancedInteger(); + #endif + #ifndef MAGNUM_TARGET_GLES + void addVertexBufferInstancedDouble(); + #endif - void multiDraw(); - void multiDrawIndexed(); - #ifndef MAGNUM_TARGET_GLES - void multiDrawBaseVertex(); - #endif + void multiDraw(); + void multiDrawIndexed(); + #ifndef MAGNUM_TARGET_GLES + void multiDrawBaseVertex(); + #endif }; MeshGLTest::MeshGLTest() { @@ -448,7 +448,7 @@ Checker::Checker(AbstractShaderProgram&& shader, RenderbufferFormat format, Mesh renderbuffer.setStorage(format, Vector2i(1)); framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment(0), renderbuffer); - framebuffer.bind(FramebufferTarget::ReadDraw); + framebuffer.bind(); mesh.setPrimitive(MeshPrimitive::Points) .setCount(2); @@ -465,9 +465,7 @@ Checker::Checker(AbstractShaderProgram&& shader, RenderbufferFormat format, Mesh } template T Checker::get(ColorFormat format, ColorType type) { - Image2D image(format, type); - framebuffer.read(Vector2i{}, Vector2i(1), image); - return image.data()[0]; + return framebuffer.read({{}, Vector2i{1}}, {format, type}).data()[0]; } #endif @@ -478,7 +476,7 @@ void MeshGLTest::addVertexBufferUnsignedInt() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, UnsignedInt> Attribute; + typedef Attribute<0, UnsignedInt> Attribute; constexpr UnsignedInt data[] = { 0, 157, 35681 }; Buffer buffer; @@ -503,7 +501,7 @@ void MeshGLTest::addVertexBufferInt() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Int> Attribute; + typedef Attribute<0, Int> Attribute; constexpr Int data[] = { 0, 457931, 27530 }; Buffer buffer; @@ -524,7 +522,7 @@ void MeshGLTest::addVertexBufferInt() { #endif void MeshGLTest::addVertexBufferFloat() { - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, -0.7f, Math::normalize(96) }; Buffer buffer; @@ -553,7 +551,7 @@ void MeshGLTest::addVertexBufferDouble() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Double> Attribute; + typedef Attribute<0, Double> Attribute; const Double data[] = { 0.0, -0.7, Math::normalize(45828) }; Buffer buffer; @@ -580,7 +578,7 @@ void MeshGLTest::addVertexBufferVectorNui() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector3ui> Attribute; + typedef Attribute<0, Vector3ui> Attribute; constexpr Vector3ui data[] = { {}, {37448, 547686, 156}, {27592, 157, 25} }; Buffer buffer; @@ -605,7 +603,7 @@ void MeshGLTest::addVertexBufferVectorNi() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector2i> Attribute; + typedef Attribute<0, Vector2i> Attribute; constexpr Vector2i data[] = { {}, {-37448, 547686}, {27592, -157} }; Buffer buffer; @@ -626,7 +624,7 @@ void MeshGLTest::addVertexBufferVectorNi() { #endif void MeshGLTest::addVertexBufferVectorN() { - typedef AbstractShaderProgram::Attribute<0, Vector3> Attribute; + typedef Attribute<0, Vector3> Attribute; const Vector3 data[] = { {}, {0.0f, -0.9f, 1.0f}, Math::normalize(Color3ub(96, 24, 156)) }; Buffer buffer; @@ -655,7 +653,7 @@ void MeshGLTest::addVertexBufferVectorNd() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Vector4d> Attribute; + typedef Attribute<0, Vector4d> Attribute; const Vector4d data[] = { {}, {0.0, -0.9, 1.0, 1.25}, @@ -679,7 +677,7 @@ void MeshGLTest::addVertexBufferVectorNd() { #endif void MeshGLTest::addVertexBufferMatrixNxN() { - typedef AbstractShaderProgram::Attribute<0, Matrix3x3> Attribute; + typedef Attribute<0, Matrix3x3> Attribute; const Matrix3x3 data[] = { {}, @@ -708,7 +706,7 @@ void MeshGLTest::addVertexBufferMatrixNxNd() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Matrix3x3d> Attribute; + typedef Attribute<0, Matrix3x3d> Attribute; const Matrix3x3d data[] = { {}, @@ -741,7 +739,7 @@ void MeshGLTest::addVertexBufferMatrixNxNd() { #ifndef MAGNUM_TARGET_GLES2 void MeshGLTest::addVertexBufferMatrixMxN() { - typedef AbstractShaderProgram::Attribute<0, Matrix3x4> Attribute; + typedef Attribute<0, Matrix3x4> Attribute; const Matrix3x4 data[] = { {}, @@ -771,7 +769,7 @@ void MeshGLTest::addVertexBufferMatrixMxNd() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Matrix3x4d> Attribute; + typedef Attribute<0, Matrix3x4d> Attribute; const Matrix3x4d data[] = { {}, @@ -809,7 +807,7 @@ void MeshGLTest::addVertexBufferUnsignedIntWithUnsignedShort() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, UnsignedInt> Attribute; + typedef Attribute<0, UnsignedInt> Attribute; constexpr UnsignedShort data[] = { 0, 49563, 16583 }; Buffer buffer; @@ -834,7 +832,7 @@ void MeshGLTest::addVertexBufferUnsignedIntWithShort() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, UnsignedInt> Attribute; + typedef Attribute<0, UnsignedInt> Attribute; constexpr Short data[] = { 0, 24563, 16583 }; Buffer buffer; @@ -859,7 +857,7 @@ void MeshGLTest::addVertexBufferIntWithUnsignedShort() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Int> Attribute; + typedef Attribute<0, Int> Attribute; constexpr UnsignedShort data[] = { 0, 49563, 16583 }; Buffer buffer; @@ -884,7 +882,7 @@ void MeshGLTest::addVertexBufferIntWithShort() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Int> Attribute; + typedef Attribute<0, Int> Attribute; constexpr Short data[] = { 0, 24563, -16583 }; Buffer buffer; @@ -913,7 +911,7 @@ void MeshGLTest::addVertexBufferFloatWithHalfFloat() { CORRADE_SKIP(Extensions::GL::OES::vertex_half_float::string() + std::string(" is not supported.")); #endif - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; Buffer buffer; buffer.setData({nullptr, 6}, BufferUsage::StaticDraw); @@ -928,7 +926,7 @@ void MeshGLTest::addVertexBufferFloatWithHalfFloat() { #ifndef MAGNUM_TARGET_GLES void MeshGLTest::addVertexBufferFloatWithDouble() { - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Double data[] = { 0.0, -0.7, Math::normalize(186) }; Buffer buffer; @@ -953,7 +951,7 @@ void MeshGLTest::addVertexBufferVector3WithUnsignedInt10f11f11fRev() { CORRADE_SKIP(Extensions::GL::ARB::vertex_type_10f_11f_11f_rev::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector3> Attribute; + typedef Attribute<0, Vector3> Attribute; Buffer buffer; buffer.setData({nullptr, 12}, BufferUsage::StaticDraw); @@ -974,7 +972,7 @@ void MeshGLTest::addVertexBufferVector4WithUnsignedInt2101010Rev() { CORRADE_SKIP(Extensions::GL::ARB::vertex_type_2_10_10_10_rev::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector4> Attribute; + typedef Attribute<0, Vector4> Attribute; Buffer buffer; buffer.setData({nullptr, 12}, BufferUsage::StaticDraw); @@ -993,7 +991,7 @@ void MeshGLTest::addVertexBufferVector4WithInt2101010Rev() { CORRADE_SKIP(Extensions::GL::ARB::vertex_type_2_10_10_10_rev::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector4> Attribute; + typedef Attribute<0, Vector4> Attribute; Buffer buffer; buffer.setData({nullptr, 12}, BufferUsage::StaticDraw); @@ -1008,7 +1006,7 @@ void MeshGLTest::addVertexBufferVector4WithInt2101010Rev() { #endif void MeshGLTest::addVertexBufferLessVectorComponents() { - typedef AbstractShaderProgram::Attribute<0, Vector4> Attribute; + typedef Attribute<0, Vector4> Attribute; const Vector3 data[] = { {}, {0.0f, -0.9f, 1.0f}, @@ -1036,7 +1034,7 @@ void MeshGLTest::addVertexBufferLessVectorComponents() { } void MeshGLTest::addVertexBufferNormalized() { - typedef AbstractShaderProgram::Attribute<0, Vector3> Attribute; + typedef Attribute<0, Vector3> Attribute; constexpr Color3ub data[] = { {}, {0, 128, 64}, {32, 156, 228} }; Buffer buffer; @@ -1067,7 +1065,7 @@ void MeshGLTest::addVertexBufferBGRA() { CORRADE_SKIP(Extensions::GL::ARB::vertex_array_bgra::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector4> Attribute; + typedef Attribute<0, Vector4> Attribute; constexpr Color4ub data[] = { {}, {0, 128, 64, 161}, {96, 24, 156, 225} }; Buffer buffer; @@ -1396,7 +1394,7 @@ void MeshGLTest::setInstanceCount() { CORRADE_SKIP("Required extension is not available."); #endif - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, -0.7f, Math::normalize(96) }; Buffer buffer; @@ -1474,7 +1472,7 @@ void MeshGLTest::setInstanceCountBaseInstance() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::base_instance::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, -0.7f, Math::normalize(96) }; Buffer buffer; @@ -1615,7 +1613,7 @@ void MeshGLTest::addVertexBufferInstancedFloat() { CORRADE_SKIP("Required drawing extension is not available."); #endif - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, /* Offset */ @@ -1656,7 +1654,7 @@ void MeshGLTest::addVertexBufferInstancedInteger() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, UnsignedInt> Attribute; + typedef Attribute<0, UnsignedInt> Attribute; constexpr UnsignedInt data[] = { 0, /* Offset */ @@ -1691,7 +1689,7 @@ void MeshGLTest::addVertexBufferInstancedDouble() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Double> Attribute; + typedef Attribute<0, Double> Attribute; const Double data[] = { 0.0, /* Offset */ @@ -1739,7 +1737,7 @@ MultiChecker::MultiChecker(AbstractShaderProgram&& shader, Mesh& mesh): framebuf Vector2i(1)); framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment(0), renderbuffer); - framebuffer.bind(FramebufferTarget::ReadDraw); + framebuffer.bind(); mesh.setPrimitive(MeshPrimitive::Points) .setCount(2); @@ -1760,10 +1758,7 @@ MultiChecker::MultiChecker(AbstractShaderProgram&& shader, Mesh& mesh): framebuf } template T MultiChecker::get(ColorFormat format, ColorType type) { - Image2D image(format, type); - /* GCC 4.5 needs explicit type here */ - framebuffer.read(Vector2i{}, Vector2i(1), image); - return image.data()[0]; + return framebuffer.read({{}, Vector2i{1}}, {format, type}).data()[0]; } #endif @@ -1773,7 +1768,7 @@ void MeshGLTest::multiDraw() { Debug() << Extensions::GL::EXT::multi_draw_arrays::string() << "not supported, using fallback implementation"; #endif - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, -0.7f, Math::normalize(96) }; Buffer buffer; diff --git a/src/Magnum/Test/MeshTest.cpp b/src/Magnum/Test/MeshTest.cpp index b3a942009..b272d3672 100644 --- a/src/Magnum/Test/MeshTest.cpp +++ b/src/Magnum/Test/MeshTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,16 +31,15 @@ namespace Magnum { namespace Test { -class MeshTest: public TestSuite::Tester { - public: - MeshTest(); +struct MeshTest: TestSuite::Tester { + explicit MeshTest(); - void indexSize(); + void indexSize(); - void debugPrimitive(); - void debugIndexType(); - void configurationPrimitive(); - void configurationIndexType(); + void debugPrimitive(); + void debugIndexType(); + void configurationPrimitive(); + void configurationIndexType(); }; MeshTest::MeshTest() { diff --git a/src/Magnum/Test/MultisampleTextureGLTest.cpp b/src/Magnum/Test/MultisampleTextureGLTest.cpp index c90cc8de3..2c5c3c1da 100644 --- a/src/Magnum/Test/MultisampleTextureGLTest.cpp +++ b/src/Magnum/Test/MultisampleTextureGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,34 +32,33 @@ namespace Magnum { namespace Test { -class MultisampleTextureGLTest: public AbstractOpenGLTester { - public: - explicit MultisampleTextureGLTest(); - - void construct2D(); - #ifndef MAGNUM_TARGET_GLES - void construct2DArray(); - #endif - - void bind2D(); - #ifndef MAGNUM_TARGET_GLES - void bind2DArray(); - #endif - - void storage2D(); - #ifndef MAGNUM_TARGET_GLES - void storage2DArray(); - #endif - - void invalidateImage2D(); - #ifndef MAGNUM_TARGET_GLES - void invalidateImage2DArray(); - #endif - - void invalidateSubImage2D(); - #ifndef MAGNUM_TARGET_GLES - void invalidateSubImage2DArray(); - #endif +struct MultisampleTextureGLTest: AbstractOpenGLTester { + explicit MultisampleTextureGLTest(); + + void construct2D(); + #ifndef MAGNUM_TARGET_GLES + void construct2DArray(); + #endif + + void bind2D(); + #ifndef MAGNUM_TARGET_GLES + void bind2DArray(); + #endif + + void storage2D(); + #ifndef MAGNUM_TARGET_GLES + void storage2DArray(); + #endif + + void invalidateImage2D(); + #ifndef MAGNUM_TARGET_GLES + void invalidateImage2DArray(); + #endif + + void invalidateSubImage2D(); + #ifndef MAGNUM_TARGET_GLES + void invalidateSubImage2DArray(); + #endif }; MultisampleTextureGLTest::MultisampleTextureGLTest() { diff --git a/src/Magnum/Test/PrimitiveQueryGLTest.cpp b/src/Magnum/Test/PrimitiveQueryGLTest.cpp index cb9837fef..7b3f45d7e 100644 --- a/src/Magnum/Test/PrimitiveQueryGLTest.cpp +++ b/src/Magnum/Test/PrimitiveQueryGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -28,64 +28,57 @@ #include "Magnum/AbstractShaderProgram.h" #include "Magnum/Buffer.h" -#include "Magnum/Framebuffer.h" #include "Magnum/Mesh.h" #include "Magnum/PrimitiveQuery.h" -#include "Magnum/Renderbuffer.h" -#include "Magnum/RenderbufferFormat.h" #include "Magnum/Shader.h" +#include "Magnum/TransformFeedback.h" +#include "Magnum/Math/Vector2.h" #include "Magnum/Test/AbstractOpenGLTester.h" namespace Magnum { namespace Test { -class PrimitiveQueryGLTest: public AbstractOpenGLTester { - public: - explicit PrimitiveQueryGLTest(); +struct PrimitiveQueryGLTest: AbstractOpenGLTester { + explicit PrimitiveQueryGLTest(); - void query(); + #ifndef MAGNUM_TARGET_GLES + void primitivesGenerated(); + #endif + void transformFeedbackPrimitivesWritten(); }; PrimitiveQueryGLTest::PrimitiveQueryGLTest() { - addTests({&PrimitiveQueryGLTest::query}); + addTests({ + #ifndef MAGNUM_TARGET_GLES + &PrimitiveQueryGLTest::primitivesGenerated, + #endif + &PrimitiveQueryGLTest::transformFeedbackPrimitivesWritten}); } -void PrimitiveQueryGLTest::query() { - #ifndef MAGNUM_TARGET_GLES +#ifndef MAGNUM_TARGET_GLES +void PrimitiveQueryGLTest::primitivesGenerated() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::transform_feedback::string() + std::string(" is not available.")); - #endif - - #ifndef MAGNUM_TARGET_GLES - class MyShader: public AbstractShaderProgram { - public: - typedef Attribute<0, Vector2> Position; - - explicit MyShader() { - Utility::Resource rs("QueryGLTest"); - - Shader vert(Version::GL210, Shader::Type::Vertex); - Shader frag(Version::GL210, Shader::Type::Fragment); - vert.addSource(rs.get("MyShader.vert")); - frag.addSource(rs.get("MyShader.frag")); + struct MyShader: AbstractShaderProgram { + typedef Attribute<0, Vector2> Position; - CORRADE_INTERNAL_ASSERT_OUTPUT(Shader::compile({std::ref(vert), std::ref(frag)})); + explicit MyShader() { + Shader vert(Version::GL210, Shader::Type::Vertex); - attachShaders({std::ref(vert), std::ref(frag)}); + CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource( + "attribute lowp vec4 position;\n" + "void main() {\n" + " gl_Position = position;\n" + "}\n").compile()); - CORRADE_INTERNAL_ASSERT_OUTPUT(link()); - } + attachShader(vert); + bindAttributeLocation(Position::Location, "position"); + CORRADE_INTERNAL_ASSERT_OUTPUT(link()); + } } shader; - Renderbuffer renderbuffer; - renderbuffer.setStorage(RenderbufferFormat::RGBA8, Vector2i(32)); - - Framebuffer framebuffer({{}, Vector2i(32)}); - framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment(0), renderbuffer); - - constexpr Vector2 data[9]; Buffer vertices; - vertices.setData(data, BufferUsage::StaticDraw); + vertices.setData({nullptr, 9*sizeof(Vector2)}, BufferUsage::StaticDraw); Mesh mesh; mesh.setPrimitive(MeshPrimitive::Triangles) @@ -97,7 +90,7 @@ void PrimitiveQueryGLTest::query() { PrimitiveQuery q{PrimitiveQuery::Target::PrimitivesGenerated}; q.begin(); - framebuffer.bind(FramebufferTarget::ReadDraw); + Renderer::enable(Renderer::Feature::RasterizerDiscard); mesh.draw(shader); q.end(); @@ -109,9 +102,69 @@ void PrimitiveQueryGLTest::query() { CORRADE_VERIFY(!availableBefore); CORRADE_VERIFY(availableAfter); CORRADE_COMPARE(count, 3); - #else - CORRADE_SKIP("Not implemented in OpenGL ES 3.0 yet."); +} +#endif + +void PrimitiveQueryGLTest::transformFeedbackPrimitivesWritten() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::transform_feedback2::string() + std::string(" is not available.")); #endif + + struct MyShader: AbstractShaderProgram { + explicit MyShader() { + #ifndef MAGNUM_TARGET_GLES + Shader vert(Version::GL300, Shader::Type::Vertex); + #else + Shader vert(Version::GLES300, Shader::Type::Vertex); + Shader frag(Version::GLES300, Shader::Type::Fragment); + #endif + + CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource( + "out mediump vec2 outputData;\n" + "void main() {\n" + " outputData = vec2(1.0, -1.0);\n" + "}\n").compile()); + #ifndef MAGNUM_TARGET_GLES + attachShader(vert); + #else + /* ES for some reason needs both vertex and fragment shader */ + CORRADE_INTERNAL_ASSERT_OUTPUT(frag.addSource("void main() {}\n").compile()); + attachShaders({vert, frag}); + #endif + + setTransformFeedbackOutputs({"outputData"}, TransformFeedbackBufferMode::SeparateAttributes); + CORRADE_INTERNAL_ASSERT_OUTPUT(link()); + } + } shader; + + Buffer output; + output.setData({nullptr, 18*sizeof(Vector2)}, BufferUsage::StaticDraw); + + Mesh mesh; + mesh.setPrimitive(MeshPrimitive::Triangles) + .setCount(9); + + MAGNUM_VERIFY_NO_ERROR(); + + TransformFeedback feedback; + feedback.attachBuffer(0, output); + + PrimitiveQuery q{PrimitiveQuery::Target::TransformFeedbackPrimitivesWritten}; + q.begin(); + + Renderer::enable(Renderer::Feature::RasterizerDiscard); + + mesh.draw(shader); /* Draw once without XFB (shouldn't be counted) */ + feedback.begin(shader, TransformFeedback::PrimitiveMode::Triangles); + mesh.draw(shader); + feedback.end(); + + q.end(); + const UnsignedInt count = q.result(); + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_COMPARE(count, 3); /* Three triangles (9 vertices) */ } }} diff --git a/src/Magnum/Test/QueryGLTestFiles/MyShader.frag b/src/Magnum/Test/QueryGLTestFiles/MyShader.frag deleted file mode 100644 index 18cf87582..000000000 --- a/src/Magnum/Test/QueryGLTestFiles/MyShader.frag +++ /dev/null @@ -1,3 +0,0 @@ -void main() { - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); -} diff --git a/src/Magnum/Test/QueryGLTestFiles/MyShader.vert b/src/Magnum/Test/QueryGLTestFiles/MyShader.vert deleted file mode 100644 index 0fd808f4b..000000000 --- a/src/Magnum/Test/QueryGLTestFiles/MyShader.vert +++ /dev/null @@ -1,5 +0,0 @@ -attribute lowp vec4 position; - -void main() { - gl_Position = position; -} diff --git a/src/Magnum/Test/QueryGLTestFiles/resources.conf b/src/Magnum/Test/QueryGLTestFiles/resources.conf deleted file mode 100644 index daf955dd7..000000000 --- a/src/Magnum/Test/QueryGLTestFiles/resources.conf +++ /dev/null @@ -1,7 +0,0 @@ -group=QueryGLTest - -[file] -filename=MyShader.vert - -[file] -filename=MyShader.frag diff --git a/src/Magnum/Test/RectangleTextureGLTest.cpp b/src/Magnum/Test/RectangleTextureGLTest.cpp index 1af159aea..4c8bc74b9 100644 --- a/src/Magnum/Test/RectangleTextureGLTest.cpp +++ b/src/Magnum/Test/RectangleTextureGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,32 +32,34 @@ #include "Magnum/Image.h" #include "Magnum/RectangleTexture.h" #include "Magnum/TextureFormat.h" +#include "Magnum/Math/Range.h" #include "Magnum/Test/AbstractOpenGLTester.h" namespace Magnum { namespace Test { -class RectangleTextureGLTest: public AbstractOpenGLTester { - public: - explicit RectangleTextureGLTest(); +struct RectangleTextureGLTest: AbstractOpenGLTester { + explicit RectangleTextureGLTest(); - void construct(); - void bind(); + void construct(); + void bind(); - void sampling(); - void samplingSRGBDecode(); - void samplingBorderInteger(); - void samplingSwizzle(); - void samplingDepthStencilMode(); + void sampling(); + void samplingSRGBDecode(); + void samplingBorderInteger(); + void samplingSwizzle(); + void samplingDepthStencilMode(); - void storage(); + void storage(); - void image(); - void imageBuffer(); - void subImage(); - void subImageBuffer(); + void image(); + void imageBuffer(); + void subImage(); + void subImageBuffer(); + void subImageQuery(); + void subImageQueryBuffer(); - void invalidateImage(); - void invalidateSubImage(); + void invalidateImage(); + void invalidateSubImage(); }; RectangleTextureGLTest::RectangleTextureGLTest() { @@ -77,6 +79,8 @@ RectangleTextureGLTest::RectangleTextureGLTest() { &RectangleTextureGLTest::subImage, &RectangleTextureGLTest::subImageBuffer, + &RectangleTextureGLTest::subImageQuery, + &RectangleTextureGLTest::subImageQueryBuffer, &RectangleTextureGLTest::invalidateImage, &RectangleTextureGLTest::invalidateSubImage}); @@ -200,116 +204,147 @@ void RectangleTextureGLTest::storage() { MAGNUM_VERIFY_NO_ERROR(); } +namespace { + constexpr UnsignedByte Data[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; +} + void RectangleTextureGLTest::image() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; RectangleTexture texture; texture.setImage(TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data)); MAGNUM_VERIFY_NO_ERROR(); - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(image); + Image2D image = texture.image({ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 16), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data}, TestSuite::Compare::Container); } void RectangleTextureGLTest::imageBuffer() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; RectangleTexture texture; texture.setImage(TextureFormat::RGBA8, - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw)); + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(image, BufferUsage::StaticRead); + BufferImage2D image = texture.image({ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data+16), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data}, TestSuite::Compare::Container); +} + +namespace { + constexpr UnsignedByte Zero[4*4*4] = {}; + + constexpr UnsignedByte SubDataComplete[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; } void RectangleTextureGLTest::subImage() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; RectangleTexture texture; texture.setImage(TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), Zero)); texture.setSubImage(Vector2i(1), - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data)); MAGNUM_VERIFY_NO_ERROR(); - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(image); + Image2D image = texture.image({ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{SubDataComplete}, TestSuite::Compare::Container); } void RectangleTextureGLTest::subImageBuffer() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; RectangleTexture texture; texture.setImage(TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), Zero)); texture.setSubImage(Vector2i(1), - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw)); + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(image, BufferUsage::StaticRead); + BufferImage2D image = texture.image({ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{SubDataComplete}, TestSuite::Compare::Container); +} + +void RectangleTextureGLTest::subImageQuery() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + RectangleTexture texture; + texture.setStorage(TextureFormat::RGBA8, Vector2i{4}) + .setSubImage({}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubDataComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + Image2D image = texture.subImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i{2}); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data}, TestSuite::Compare::Container); +} + +void RectangleTextureGLTest::subImageQueryBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + RectangleTexture texture; + texture.setStorage(TextureFormat::RGBA8, Vector2i{4}) + .setSubImage({}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubDataComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage2D image = texture.subImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i{2}); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data}, TestSuite::Compare::Container); } void RectangleTextureGLTest::invalidateImage() { diff --git a/src/Magnum/Test/RenderbufferGLTest.cpp b/src/Magnum/Test/RenderbufferGLTest.cpp index aa858cf6d..6a4152adb 100644 --- a/src/Magnum/Test/RenderbufferGLTest.cpp +++ b/src/Magnum/Test/RenderbufferGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,18 +32,17 @@ namespace Magnum { namespace Test { -class RenderbufferGLTest: public AbstractOpenGLTester { - public: - explicit RenderbufferGLTest(); +struct RenderbufferGLTest: AbstractOpenGLTester { + explicit RenderbufferGLTest(); - void construct(); - void constructCopy(); - void constructMove(); + void construct(); + void constructCopy(); + void constructMove(); - void label(); + void label(); - void setStorage(); - void setStorageMultisample(); + void setStorage(); + void setStorageMultisample(); }; RenderbufferGLTest::RenderbufferGLTest() { diff --git a/src/Magnum/Test/RendererTest.cpp b/src/Magnum/Test/RendererTest.cpp index 59ddcdee4..fa72db1c4 100644 --- a/src/Magnum/Test/RendererTest.cpp +++ b/src/Magnum/Test/RendererTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,13 +30,12 @@ namespace Magnum { namespace Test { -class RendererTest: public TestSuite::Tester { - public: - explicit RendererTest(); +struct RendererTest: TestSuite::Tester { + explicit RendererTest(); - void debugError(); - void debugResetNotificationStrategy(); - void debugGraphicsResetStatus(); + void debugError(); + void debugResetNotificationStrategy(); + void debugGraphicsResetStatus(); }; RendererTest::RendererTest() { diff --git a/src/Magnum/Test/ResourceManagerLocalInstanceTest.cpp b/src/Magnum/Test/ResourceManagerLocalInstanceTest.cpp new file mode 100644 index 000000000..8efa7f191 --- /dev/null +++ b/src/Magnum/Test/ResourceManagerLocalInstanceTest.cpp @@ -0,0 +1,54 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "ResourceManagerLocalInstanceTestLib.h" + +namespace Magnum { namespace Test { + +struct ResourceManagerLocalInstanceTest: TestSuite::Tester { + explicit ResourceManagerLocalInstanceTest(); + + void instance(); + + ResourceManagerWithLocalInstance manager; +}; + +ResourceManagerLocalInstanceTest::ResourceManagerLocalInstanceTest() { + addTests({&ResourceManagerLocalInstanceTest::instance}); +} + +void ResourceManagerLocalInstanceTest::instance() { + ResourceManagerWithLocalInstance::instance().set("another", 13); + + CORRADE_COMPARE(&manager.staticInstance, &manager.instance()); + CORRADE_COMPARE(manager.count(), 2); + CORRADE_COMPARE(manager.state("integer"), ResourceState::Final); +} + +}} + +CORRADE_TEST_MAIN(Magnum::Test::ResourceManagerLocalInstanceTest) diff --git a/src/Magnum/Text/TextRenderer.h b/src/Magnum/Test/ResourceManagerLocalInstanceTestLib.cpp similarity index 61% rename from src/Magnum/Text/TextRenderer.h rename to src/Magnum/Test/ResourceManagerLocalInstanceTestLib.cpp index d302c280d..08b85ce1b 100644 --- a/src/Magnum/Text/TextRenderer.h +++ b/src/Magnum/Test/ResourceManagerLocalInstanceTestLib.cpp @@ -1,9 +1,7 @@ -#ifndef Magnum_Text_TextRenderer_h -#define Magnum_Text_TextRenderer_h /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,31 +23,21 @@ DEALINGS IN THE SOFTWARE. */ -/** @file - * @brief Typedef @ref Magnum::Text::TextRenderer2D, @ref Magnum::Text::TextRenderer3D - * @deprecated Use @ref Renderer.h instead. - */ +#include "ResourceManagerLocalInstanceTestLib.h" -#include "Magnum/Text/Renderer.h" +#include "Magnum/ResourceManager.hpp" -#ifdef MAGNUM_BUILD_DEPRECATED -namespace Magnum { namespace Text { +namespace Magnum { -/** -@copybrief Renderer2D -@deprecated Use @ref Magnum::Text::Renderer2D "Renderer2D" instead. -*/ -typedef CORRADE_DEPRECATED("use Renderer2D instead") Renderer<2> TextRenderer2D; +namespace Implementation { + template struct CORRADE_VISIBILITY_EXPORT ResourceManagerLocalInstanceImplementation; +} -/** -@copybrief Renderer3D -@deprecated Use @ref Magnum::Text::Renderer3D "Renderer3D" instead. -*/ -typedef CORRADE_DEPRECATED("use Renderer2D instead") Renderer<3> TextRenderer3D; +namespace Test { -}} -#else -#error -#endif +ResourceManagerWithLocalInstance::ResourceManagerWithLocalInstance(): staticInstance(static_cast(instance())) { + /* Add some stuff */ + set("integer", 42); +} -#endif +}} diff --git a/src/Magnum/Test/ResourceManagerLocalInstanceTestLib.h b/src/Magnum/Test/ResourceManagerLocalInstanceTestLib.h new file mode 100644 index 000000000..8b13a6a38 --- /dev/null +++ b/src/Magnum/Test/ResourceManagerLocalInstanceTestLib.h @@ -0,0 +1,50 @@ +#ifndef Magnum_Test_ResourceManagerLocalInstanceTestLib_h +#define Magnum_Test_ResourceManagerLocalInstanceTestLib_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Magnum/ResourceManager.h" + +#ifndef MAGNUM_BUILD_STATIC + #if defined(ResourceManagerLocalInstanceTestLib_EXPORTS) + #define MAGNUM_RESOURCEMANAGERLOCALINSTANCETESTLIB_EXPORT CORRADE_VISIBILITY_EXPORT + #else + #define MAGNUM_RESOURCEMANAGERLOCALINSTANCETESTLIB_EXPORT CORRADE_VISIBILITY_IMPORT + #endif +#else + #define MAGNUM_RESOURCEMANAGERLOCALINSTANCETESTLIB_EXPORT CORRADE_VISIBILITY_STATIC +#endif + +namespace Magnum { namespace Test { + +struct MAGNUM_RESOURCEMANAGERLOCALINSTANCETESTLIB_EXPORT ResourceManagerWithLocalInstance: ResourceManager { + explicit ResourceManagerWithLocalInstance(); + + ResourceManagerWithLocalInstance& staticInstance; +}; + +}} + +#endif diff --git a/src/Magnum/Test/ResourceManagerTest.cpp b/src/Magnum/Test/ResourceManagerTest.cpp index 2971c0226..f102c5cf6 100644 --- a/src/Magnum/Test/ResourceManagerTest.cpp +++ b/src/Magnum/Test/ResourceManagerTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,29 +32,27 @@ namespace Magnum { namespace Test { -class ResourceManagerTest: public TestSuite::Tester { - public: - ResourceManagerTest(); - - void state(); - void stateFallback(); - void stateDisallowed(); - void basic(); - void residentPolicy(); - void referenceCountedPolicy(); - void manualPolicy(); - void defaults(); - void clear(); - void clearWhileReferenced(); - void loader(); +struct ResourceManagerTest: TestSuite::Tester { + explicit ResourceManagerTest(); + + void state(); + void stateFallback(); + void stateDisallowed(); + void basic(); + void residentPolicy(); + void referenceCountedPolicy(); + void manualPolicy(); + void defaults(); + void clear(); + void clearWhileReferenced(); + void loader(); }; -class Data { - public: - static std::size_t count; +struct Data { + static std::size_t count; - Data() { ++count; } - ~Data() { --count; } + explicit Data() { ++count; } + ~Data() { --count; } }; typedef Magnum::ResourceManager ResourceManager; @@ -188,24 +186,29 @@ void ResourceManagerTest::referenceCountedPolicy() { ResourceKey dataRefCountKey("dataRefCount"); - /* Reference counted resources must be requested first */ + /* Resource is deleted after all references are removed */ + rm.set(dataRefCountKey, new Data, ResourceDataState::Final, ResourcePolicy::ReferenceCounted); + CORRADE_COMPARE(rm.count(), 1); { - rm.set(dataRefCountKey, new Data, ResourceDataState::Final, ResourcePolicy::ReferenceCounted); - CORRADE_COMPARE(rm.count(), 0); - Resource data = rm.get(dataRefCountKey); - CORRADE_COMPARE(data.state(), ResourceState::NotLoaded); - CORRADE_COMPARE(Data::count, 0); - } { Resource data = rm.get(dataRefCountKey); - CORRADE_COMPARE(rm.count(), 1); - CORRADE_COMPARE(data.state(), ResourceState::NotLoaded); - rm.set(dataRefCountKey, new Data, ResourceDataState::Final, ResourcePolicy::ReferenceCounted); CORRADE_COMPARE(data.state(), ResourceState::Final); CORRADE_COMPARE(Data::count, 1); } CORRADE_COMPARE(rm.count(), 0); CORRADE_COMPARE(Data::count, 0); + + /* Reference counted resources which were not used once will stay loaded + until free() is called */ + rm.set(dataRefCountKey, new Data, ResourceDataState::Final, ResourcePolicy::ReferenceCounted); + CORRADE_COMPARE(rm.count(), 1); + CORRADE_COMPARE(rm.state(dataRefCountKey), ResourceState::Final); + CORRADE_COMPARE(rm.referenceCount(dataRefCountKey), 0); + + rm.free(); + CORRADE_COMPARE(rm.count(), 0); + CORRADE_COMPARE(rm.state(dataRefCountKey), ResourceState::NotLoaded); + CORRADE_COMPARE(rm.referenceCount(dataRefCountKey), 0); } void ResourceManagerTest::manualPolicy() { diff --git a/src/Magnum/Test/SampleQueryGLTest.cpp b/src/Magnum/Test/SampleQueryGLTest.cpp index 97e132ee9..20c639bba 100644 --- a/src/Magnum/Test/SampleQueryGLTest.cpp +++ b/src/Magnum/Test/SampleQueryGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,14 +38,13 @@ namespace Magnum { namespace Test { -class SampleQueryGLTest: public AbstractOpenGLTester { - public: - explicit SampleQueryGLTest(); +struct SampleQueryGLTest: AbstractOpenGLTester { + explicit SampleQueryGLTest(); - void querySamplesPassed(); - #ifndef MAGNUM_TARGET_GLES - void conditionalRender(); - #endif + void querySamplesPassed(); + #ifndef MAGNUM_TARGET_GLES + void conditionalRender(); + #endif }; SampleQueryGLTest::SampleQueryGLTest() { @@ -67,8 +66,6 @@ namespace { #ifndef DOXYGEN_GENERATING_OUTPUT MyShader::MyShader() { - Utility::Resource rs("QueryGLTest"); - #ifndef MAGNUM_TARGET_GLES Shader vert(Version::GL210, Shader::Type::Vertex); Shader frag(Version::GL210, Shader::Type::Fragment); @@ -77,8 +74,15 @@ MyShader::MyShader() { Shader frag(Version::GLES200, Shader::Type::Fragment); #endif - vert.addSource(rs.get("MyShader.vert")); - frag.addSource(rs.get("MyShader.frag")); + vert.addSource( + "attribute lowp vec4 position;\n" + "void main() {\n" + " gl_Position = position;\n" + "}\n"); + frag.addSource( + "void main() {\n" + " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" + "}\n"); /* GCC 4.4 has explicit std::reference_wrapper constructor */ CORRADE_INTERNAL_ASSERT_OUTPUT(Shader::compile({std::ref(vert), std::ref(frag)})); @@ -112,7 +116,7 @@ void SampleQueryGLTest::querySamplesPassed() { Mesh mesh; mesh.setPrimitive(MeshPrimitive::Triangles) .setCount(3) - .addVertexBuffer(buffer, 0, AbstractShaderProgram::Attribute<0, Vector2>()); + .addVertexBuffer(buffer, 0, Attribute<0, Vector2>{}); MyShader shader; @@ -125,7 +129,7 @@ void SampleQueryGLTest::querySamplesPassed() { #endif q.begin(); - framebuffer.bind(FramebufferTarget::ReadDraw); + framebuffer.bind(); mesh.draw(shader); q.end(); @@ -161,10 +165,10 @@ void SampleQueryGLTest::conditionalRender() { Mesh mesh; mesh.setPrimitive(MeshPrimitive::Triangles) .setCount(3) - .addVertexBuffer(buffer, 0, AbstractShaderProgram::Attribute<0, Vector2>()); + .addVertexBuffer(buffer, 0, Attribute<0, Vector2>{}); MyShader shader; - framebuffer.bind(FramebufferTarget::ReadDraw); + framebuffer.bind(); MAGNUM_VERIFY_NO_ERROR(); diff --git a/src/Magnum/Test/SamplerTest.cpp b/src/Magnum/Test/SamplerTest.cpp index 67d50df29..1e1060d85 100644 --- a/src/Magnum/Test/SamplerTest.cpp +++ b/src/Magnum/Test/SamplerTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,18 +30,17 @@ namespace Magnum { namespace Test { -class SamplerTest: public TestSuite::Tester { - public: - explicit SamplerTest(); - - void debugFilter(); - void debugMipmap(); - void debugWrapping(); - void debugCompareMode(); - void debugCompareFunction(); - #ifndef MAGNUM_TARGET_GLES - void debugDepthStencilMode(); - #endif +struct SamplerTest: TestSuite::Tester { + explicit SamplerTest(); + + void debugFilter(); + void debugMipmap(); + void debugWrapping(); + void debugCompareMode(); + void debugCompareFunction(); + #ifndef MAGNUM_TARGET_GLES + void debugDepthStencilMode(); + #endif }; SamplerTest::SamplerTest() { diff --git a/src/Magnum/Test/ShaderGLTest.cpp b/src/Magnum/Test/ShaderGLTest.cpp index 30e410b6e..5df20ca84 100644 --- a/src/Magnum/Test/ShaderGLTest.cpp +++ b/src/Magnum/Test/ShaderGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,20 +34,19 @@ namespace Magnum { namespace Test { -class ShaderGLTest: public AbstractOpenGLTester { - public: - explicit ShaderGLTest(); +struct ShaderGLTest: AbstractOpenGLTester { + explicit ShaderGLTest(); - void construct(); - void constructNoVersion(); - void constructCopy(); - void constructMove(); + void construct(); + void constructNoVersion(); + void constructCopy(); + void constructMove(); - void label(); + void label(); - void addSource(); - void addFile(); - void compile(); + void addSource(); + void addFile(); + void compile(); }; ShaderGLTest::ShaderGLTest() { diff --git a/src/Magnum/Test/ShaderTest.cpp b/src/Magnum/Test/ShaderTest.cpp index ea6ccda39..5c85dffe9 100644 --- a/src/Magnum/Test/ShaderTest.cpp +++ b/src/Magnum/Test/ShaderTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Test { -class ShaderTest: public TestSuite::Tester { - public: - explicit ShaderTest(); +struct ShaderTest: TestSuite::Tester { + explicit ShaderTest(); - void debugType(); + void debugType(); }; ShaderTest::ShaderTest() { diff --git a/src/Magnum/Test/TextureArrayGLTest.cpp b/src/Magnum/Test/TextureArrayGLTest.cpp index af82f9db3..0edc55ed9 100644 --- a/src/Magnum/Test/TextureArrayGLTest.cpp +++ b/src/Magnum/Test/TextureArrayGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -32,91 +32,97 @@ #include "Magnum/Image.h" #include "Magnum/TextureArray.h" #include "Magnum/TextureFormat.h" +#include "Magnum/Math/Range.h" #include "Magnum/Test/AbstractOpenGLTester.h" namespace Magnum { namespace Test { -class TextureArrayGLTest: public AbstractOpenGLTester { - public: - explicit TextureArrayGLTest(); +struct TextureArrayGLTest: AbstractOpenGLTester { + explicit TextureArrayGLTest(); - #ifndef MAGNUM_TARGET_GLES - void construct1D(); - #endif - void construct2D(); + #ifndef MAGNUM_TARGET_GLES + void construct1D(); + #endif + void construct2D(); - #ifndef MAGNUM_TARGET_GLES - void bind1D(); - #endif - void bind2D(); + #ifndef MAGNUM_TARGET_GLES + void bind1D(); + #endif + void bind2D(); - #ifndef MAGNUM_TARGET_GLES - void sampling1D(); - #endif - void sampling2D(); + #ifndef MAGNUM_TARGET_GLES + void sampling1D(); + #endif + void sampling2D(); - #ifndef MAGNUM_TARGET_GLES - void samplingSRGBDecode1D(); - #endif - void samplingSRGBDecode2D(); + #ifndef MAGNUM_TARGET_GLES + void samplingSRGBDecode1D(); + #endif + void samplingSRGBDecode2D(); - #ifndef MAGNUM_TARGET_GLES2 - #ifndef MAGNUM_TARGET_GLES - void samplingSwizzle1D(); - #endif - void samplingSwizzle2D(); - #else - void samplingMaxLevel2D(); - void samplingCompare2D(); - #endif + #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + void samplingSwizzle1D(); + #endif + void samplingSwizzle2D(); + #else + void samplingMaxLevel2D(); + void samplingCompare2D(); + #endif - #ifndef MAGNUM_TARGET_GLES - void samplingBorderInteger1D(); - void samplingBorderInteger2D(); - void samplingDepthStencilMode1D(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void samplingDepthStencilMode2D(); - #endif - #ifdef MAGNUM_TARGET_GLES - void samplingBorder2D(); - #endif + #ifndef MAGNUM_TARGET_GLES + void samplingBorderInteger1D(); + void samplingBorderInteger2D(); + void samplingDepthStencilMode1D(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void samplingDepthStencilMode2D(); + #endif + #ifdef MAGNUM_TARGET_GLES + void samplingBorder2D(); + #endif - #ifndef MAGNUM_TARGET_GLES - void storage1D(); - #endif - void storage2D(); + #ifndef MAGNUM_TARGET_GLES + void storage1D(); + #endif + void storage2D(); - #ifndef MAGNUM_TARGET_GLES - void image1D(); - void image1DBuffer(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void image2D(); - void image2DBuffer(); - #endif + #ifndef MAGNUM_TARGET_GLES + void image1D(); + void image1DBuffer(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void image2D(); + void image2DBuffer(); + #endif - #ifndef MAGNUM_TARGET_GLES - void subImage1D(); - void subImage1DBuffer(); - #endif - void subImage2D(); - void subImage2DBuffer(); + #ifndef MAGNUM_TARGET_GLES + void subImage1D(); + void subImage1DBuffer(); + void subImage1DQuery(); + void subImage1DQueryBuffer(); + #endif + void subImage2D(); + void subImage2DBuffer(); + #ifndef MAGNUM_TARGET_GLES + void subImage2DQuery(); + void subImage2DQueryBuffer(); + #endif - #ifndef MAGNUM_TARGET_GLES - void generateMipmap1D(); - #endif - void generateMipmap2D(); + #ifndef MAGNUM_TARGET_GLES + void generateMipmap1D(); + #endif + void generateMipmap2D(); - #ifndef MAGNUM_TARGET_GLES - void invalidateImage1D(); - #endif - void invalidateImage2D(); + #ifndef MAGNUM_TARGET_GLES + void invalidateImage1D(); + #endif + void invalidateImage2D(); - #ifndef MAGNUM_TARGET_GLES - void invalidateSubImage1D(); - #endif - void invalidateSubImage2D(); + #ifndef MAGNUM_TARGET_GLES + void invalidateSubImage1D(); + #endif + void invalidateSubImage2D(); }; TextureArrayGLTest::TextureArrayGLTest() { @@ -174,9 +180,15 @@ TextureArrayGLTest::TextureArrayGLTest() { #ifndef MAGNUM_TARGET_GLES &TextureArrayGLTest::subImage1D, &TextureArrayGLTest::subImage1DBuffer, + &TextureArrayGLTest::subImage1DQuery, + &TextureArrayGLTest::subImage1DQueryBuffer, #endif &TextureArrayGLTest::subImage2D, &TextureArrayGLTest::subImage2DBuffer, + #ifndef MAGNUM_TARGET_GLES + &TextureArrayGLTest::subImage2DQuery, + &TextureArrayGLTest::subImage2DQueryBuffer, + #endif #ifndef MAGNUM_TARGET_GLES &TextureArrayGLTest::generateMipmap1D, @@ -535,87 +547,87 @@ void TextureArrayGLTest::storage2D() { #endif } +namespace { + constexpr UnsignedByte Data1D[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; +} + #ifndef MAGNUM_TARGET_GLES void TextureArrayGLTest::image1D() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; Texture1DArray texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data1D)); MAGNUM_VERIFY_NO_ERROR(); - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 16), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data1D}, TestSuite::Compare::Container); } void TextureArrayGLTest::image1DBuffer() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; Texture1DArray texture; texture.setImage(0, TextureFormat::RGBA8, - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw)); + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data1D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data + 16), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data1D}, TestSuite::Compare::Container); } #endif +namespace { + constexpr UnsignedByte Data2D[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f }; +} + void TextureArrayGLTest::image2D() { #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); #endif - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; Texture2DArray texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data)); + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), Data2D)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(2)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 32), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data2D}, TestSuite::Compare::Container); #endif } @@ -625,131 +637,136 @@ void TextureArrayGLTest::image2DBuffer() { CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); #endif - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; Texture2DArray texture; texture.setImage(0, TextureFormat::RGBA8, - BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data, BufferUsage::StaticDraw)); + BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), Data2D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(2)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data + 32), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data2D}, TestSuite::Compare::Container); #endif } +namespace { + constexpr UnsignedByte Zero1D[4*4*4] = {}; + constexpr UnsignedByte SubData1D[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; + constexpr UnsignedByte SubData1DComplete[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; +} + #ifndef MAGNUM_TARGET_GLES void TextureArrayGLTest::subImage1D() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; Texture1DArray texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), Zero1D)); texture.setSubImage(0, Vector2i(1), - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), SubData1D)); MAGNUM_VERIFY_NO_ERROR(); - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{SubData1DComplete}, TestSuite::Compare::Container); } void TextureArrayGLTest::subImage1DBuffer() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; Texture1DArray texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), Zero1D)); texture.setSubImage(0, Vector2i(1), - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw)); + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), SubData1D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{SubData1DComplete}, TestSuite::Compare::Container); } -#endif -void TextureArrayGLTest::subImage2D() { - #ifndef MAGNUM_TARGET_GLES +void TextureArrayGLTest::subImage1DQuery() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); - constexpr UnsignedByte zero[4*4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; - Texture2DArray texture; - texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero)); - texture.setSubImage(0, Vector3i(1), - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData)); + Texture1DArray texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4}) + .setSubImage(0, {}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubData1DComplete}); MAGNUM_VERIFY_NO_ERROR(); - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image2D image = texture.subImage(0, Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(image.size(), Vector3i(4)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ + CORRADE_COMPARE(image.size(), Vector2i{2}); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), Containers::ArrayReference{Data1D}, TestSuite::Compare::Container); +} + +void TextureArrayGLTest::subImage1DQueryBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + Texture1DArray texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4}) + .setSubImage(0, {}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubData1DComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage2D image = texture.subImage(0, Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i{2}); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data1D}, TestSuite::Compare::Container); +} +#endif + +namespace { + constexpr UnsignedByte Zero2D[4*4*4*4] = {}; + constexpr UnsignedByte SubData2D[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f }; + constexpr UnsignedByte SubData2DComplete[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -769,7 +786,32 @@ void TextureArrayGLTest::subImage2D() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + }; +} + +void TextureArrayGLTest::subImage2D() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + Texture2DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), Zero2D)); + texture.setSubImage(0, Vector3i(1), + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), SubData2D)); + + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES + Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(4)); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), Containers::ArrayReference{SubData2DComplete}, TestSuite::Compare::Container); #endif } @@ -779,57 +821,69 @@ void TextureArrayGLTest::subImage2DBuffer() { CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); #endif - constexpr UnsignedByte zero[4*4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; Texture2DArray texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero)); + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), Zero2D)); texture.setSubImage(0, Vector3i(1), - BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData, BufferUsage::StaticDraw)); + BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), SubData2D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(4)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{SubData2DComplete}, TestSuite::Compare::Container); + #endif +} - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#ifndef MAGNUM_TARGET_GLES +void TextureArrayGLTest::subImage2DQuery() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0, 0, 0, 0, - 0, 0, 0, 0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Texture2DArray texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector3i{4}) + .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{4}, SubData2DComplete}); - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); - #endif + MAGNUM_VERIFY_NO_ERROR(); + + Image3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, Vector3i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i{2}); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), Containers::ArrayReference{Data2D}, TestSuite::Compare::Container); +} + +void TextureArrayGLTest::subImage2DQueryBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + Texture2DArray texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector3i{4}) + .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{4}, SubData2DComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, Vector3i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i{2}); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data2D}, TestSuite::Compare::Container); } -#ifndef MAGNUM_TARGET_GLES void TextureArrayGLTest::generateMipmap1D() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported.")); diff --git a/src/Magnum/Test/TextureGLTest.cpp b/src/Magnum/Test/TextureGLTest.cpp index 7a422e78e..de129e4de 100644 --- a/src/Magnum/Test/TextureGLTest.cpp +++ b/src/Magnum/Test/TextureGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,115 +34,125 @@ #include "Magnum/Image.h" #include "Magnum/Texture.h" #include "Magnum/TextureFormat.h" +#include "Magnum/Math/Range.h" #include "Magnum/Test/AbstractOpenGLTester.h" namespace Magnum { namespace Test { -class TextureGLTest: public AbstractOpenGLTester { - public: - explicit TextureGLTest(); +struct TextureGLTest: AbstractOpenGLTester { + explicit TextureGLTest(); - #ifndef MAGNUM_TARGET_GLES - void construct1D(); - #endif - void construct2D(); - void construct3D(); + #ifndef MAGNUM_TARGET_GLES + void construct1D(); + #endif + void construct2D(); + void construct3D(); - #ifndef MAGNUM_TARGET_GLES - void bind1D(); - #endif - void bind2D(); - void bind3D(); + #ifndef MAGNUM_TARGET_GLES + void bind1D(); + #endif + void bind2D(); + void bind3D(); - #ifndef MAGNUM_TARGET_GLES - void sampling1D(); - #endif - void sampling2D(); - void sampling3D(); + #ifndef MAGNUM_TARGET_GLES + void sampling1D(); + #endif + void sampling2D(); + void sampling3D(); - #ifndef MAGNUM_TARGET_GLES - void samplingSRGBDecode1D(); - #endif - void samplingSRGBDecode2D(); - void samplingSRGBDecode3D(); + #ifndef MAGNUM_TARGET_GLES + void samplingSRGBDecode1D(); + #endif + void samplingSRGBDecode2D(); + void samplingSRGBDecode3D(); - #ifndef MAGNUM_TARGET_GLES2 - #ifndef MAGNUM_TARGET_GLES - void samplingSwizzle1D(); - #endif - void samplingSwizzle2D(); - void samplingSwizzle3D(); - #else - void samplingMaxLevel2D(); - void samplingMaxLevel3D(); - void samplingCompare2D(); - #endif + #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + void samplingSwizzle1D(); + #endif + void samplingSwizzle2D(); + void samplingSwizzle3D(); + #else + void samplingMaxLevel2D(); + void samplingMaxLevel3D(); + void samplingCompare2D(); + #endif - #ifndef MAGNUM_TARGET_GLES - void samplingBorderInteger2D(); - void samplingBorderInteger3D(); - void samplingDepthStencilMode1D(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void samplingDepthStencilMode2D(); - void samplingDepthStencilMode3D(); - #endif - #ifdef MAGNUM_TARGET_GLES - void samplingBorder2D(); - void samplingBorder3D(); - #endif + #ifndef MAGNUM_TARGET_GLES + void samplingBorderInteger2D(); + void samplingBorderInteger3D(); + void samplingDepthStencilMode1D(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void samplingDepthStencilMode2D(); + void samplingDepthStencilMode3D(); + #endif + #ifdef MAGNUM_TARGET_GLES + void samplingBorder2D(); + void samplingBorder3D(); + #endif - #ifndef MAGNUM_TARGET_GLES - void storage1D(); - #endif - void storage2D(); - void storage3D(); + #ifndef MAGNUM_TARGET_GLES + void storage1D(); + #endif + void storage2D(); + void storage3D(); - #ifndef MAGNUM_TARGET_GLES - void image1D(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void image1DBuffer(); - #endif - void image2D(); - #ifndef MAGNUM_TARGET_GLES2 - void image2DBuffer(); - #endif - void image3D(); - #ifndef MAGNUM_TARGET_GLES2 - void image3DBuffer(); - #endif + #ifndef MAGNUM_TARGET_GLES + void image1D(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void image1DBuffer(); + #endif + void image2D(); + #ifndef MAGNUM_TARGET_GLES2 + void image2DBuffer(); + #endif + void image3D(); + #ifndef MAGNUM_TARGET_GLES2 + void image3DBuffer(); + #endif - #ifndef MAGNUM_TARGET_GLES - void subImage1D(); - void subImage1DBuffer(); - #endif - void subImage2D(); - #ifndef MAGNUM_TARGET_GLES2 - void subImage2DBuffer(); - #endif - void subImage3D(); - #ifndef MAGNUM_TARGET_GLES2 - void subImage3DBuffer(); - #endif + #ifndef MAGNUM_TARGET_GLES + void subImage1D(); + void subImage1DBuffer(); + void subImage1DQuery(); + void subImage1DQueryBuffer(); + #endif + void subImage2D(); + #ifndef MAGNUM_TARGET_GLES2 + void subImage2DBuffer(); + #endif + #ifndef MAGNUM_TARGET_GLES + void subImage2DQuery(); + void subImage2DQueryBuffer(); + #endif + void subImage3D(); + #ifndef MAGNUM_TARGET_GLES2 + void subImage3DBuffer(); + #endif + #ifndef MAGNUM_TARGET_GLES + void subImage3DQuery(); + void subImage3DQueryBuffer(); + #endif - #ifndef MAGNUM_TARGET_GLES - void generateMipmap1D(); - #endif - void generateMipmap2D(); - void generateMipmap3D(); + #ifndef MAGNUM_TARGET_GLES + void generateMipmap1D(); + #endif + void generateMipmap2D(); + void generateMipmap3D(); - #ifndef MAGNUM_TARGET_GLES - void invalidateImage1D(); - #endif - void invalidateImage2D(); - void invalidateImage3D(); + #ifndef MAGNUM_TARGET_GLES + void invalidateImage1D(); + #endif + void invalidateImage2D(); + void invalidateImage3D(); - #ifndef MAGNUM_TARGET_GLES - void invalidateSubImage1D(); - #endif - void invalidateSubImage2D(); - void invalidateSubImage3D(); + #ifndef MAGNUM_TARGET_GLES + void invalidateSubImage1D(); + #endif + void invalidateSubImage2D(); + void invalidateSubImage3D(); }; TextureGLTest::TextureGLTest() { @@ -219,15 +229,25 @@ TextureGLTest::TextureGLTest() { #ifndef MAGNUM_TARGET_GLES &TextureGLTest::subImage1D, &TextureGLTest::subImage1DBuffer, + &TextureGLTest::subImage1DQuery, + &TextureGLTest::subImage1DQueryBuffer, #endif &TextureGLTest::subImage2D, #ifndef MAGNUM_TARGET_GLES2 &TextureGLTest::subImage2DBuffer, #endif + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::subImage2DQuery, + &TextureGLTest::subImage2DQueryBuffer, + #endif &TextureGLTest::subImage3D, #ifndef MAGNUM_TARGET_GLES2 &TextureGLTest::subImage3DBuffer, #endif + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::subImage3DQuery, + &TextureGLTest::subImage3DQueryBuffer, + #endif #ifndef MAGNUM_TARGET_GLES &TextureGLTest::generateMipmap1D, @@ -715,308 +735,333 @@ void TextureGLTest::storage3D() { #endif } +namespace { + constexpr UnsignedByte Data1D[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07 }; +} + #ifndef MAGNUM_TARGET_GLES void TextureGLTest::image1D() { - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07 }; Texture1D texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference1D(ColorFormat::RGBA, ColorType::UnsignedByte, 2, data)); + ImageReference1D(ColorFormat::RGBA, ColorType::UnsignedByte, 2, Data1D)); MAGNUM_VERIFY_NO_ERROR(); - Image1D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image1D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), 2); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 8), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data1D}, TestSuite::Compare::Container); } void TextureGLTest::image1DBuffer() { - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07 }; Texture1D texture; texture.setImage(0, TextureFormat::RGBA8, - BufferImage1D(ColorFormat::RGBA, ColorType::UnsignedByte, 2, data, BufferUsage::StaticDraw)); + BufferImage1D(ColorFormat::RGBA, ColorType::UnsignedByte, 2, Data1D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); - BufferImage1D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticDraw); + BufferImage1D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticDraw); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), 2); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data + 8), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data1D}, TestSuite::Compare::Container); } #endif +namespace { + constexpr UnsignedByte Data2D[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; +} + void TextureGLTest::image2D() { - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; Texture2D texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data2D)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 16), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data2D}, TestSuite::Compare::Container); #endif } #ifndef MAGNUM_TARGET_GLES2 void TextureGLTest::image2DBuffer() { - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; Texture2D texture; texture.setImage(0, TextureFormat::RGBA8, - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw)); + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data2D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data + 16), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data2D}, TestSuite::Compare::Container); #endif } #endif +namespace { + constexpr UnsignedByte Data3D[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f }; +} + void TextureGLTest::image3D() { #ifdef MAGNUM_TARGET_GLES2 if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::OES::texture_3D::string() + std::string(" is not supported.")); #endif - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; Texture3D texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data)); + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), Data3D)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(2)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 32), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{Data3D}, TestSuite::Compare::Container); #endif } #ifndef MAGNUM_TARGET_GLES2 void TextureGLTest::image3DBuffer() { - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; Texture3D texture; texture.setImage(0, TextureFormat::RGBA8, - BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data, BufferUsage::StaticDraw)); + BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), Data3D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(2)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data + 32), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data3D}, TestSuite::Compare::Container); #endif } #endif +namespace { + constexpr UnsignedByte Zero1D[4*4] = {}; + constexpr UnsignedByte SubData1DComplete[] = { + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0 + }; +} + #ifndef MAGNUM_TARGET_GLES void TextureGLTest::subImage1D() { - constexpr UnsignedByte zero[4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07 }; Texture1D texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference1D(ColorFormat::RGBA, ColorType::UnsignedByte, 4, zero)); + ImageReference1D(ColorFormat::RGBA, ColorType::UnsignedByte, 4, Zero1D)); texture.setSubImage(0, 1, - ImageReference1D(ColorFormat::RGBA, ColorType::UnsignedByte, 2, subData)); + ImageReference1D(ColorFormat::RGBA, ColorType::UnsignedByte, 2, Data1D)); MAGNUM_VERIFY_NO_ERROR(); - Image1D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image1D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), 4); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{SubData1DComplete}, TestSuite::Compare::Container); } void TextureGLTest::subImage1DBuffer() { - constexpr UnsignedByte zero[4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07 }; Texture1D texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference1D(ColorFormat::RGBA, ColorType::UnsignedByte, 4, zero)); + ImageReference1D(ColorFormat::RGBA, ColorType::UnsignedByte, 4, Zero1D)); texture.setSubImage(0, 1, - BufferImage1D(ColorFormat::RGBA, ColorType::UnsignedByte, 2, subData, BufferUsage::StaticDraw)); + BufferImage1D(ColorFormat::RGBA, ColorType::UnsignedByte, 2, Data1D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); - BufferImage1D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage1D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), 4); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{SubData1DComplete}, TestSuite::Compare::Container); +} + +void TextureGLTest::subImage1DQuery() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + Texture1D texture; + texture.setStorage(1, TextureFormat::RGBA8, 4) + .setSubImage(0, {}, ImageReference1D{ColorFormat::RGBA, ColorType::UnsignedByte, 4, SubData1DComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + Image1D image = texture.subImage(0, Range1Di::fromSize(1, 2), {ColorFormat::RGBA, ColorType::UnsignedByte}); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), 2); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), Containers::ArrayReference{Data1D}, TestSuite::Compare::Container); +} + +void TextureGLTest::subImage1DQueryBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + Texture1D texture; + texture.setStorage(1, TextureFormat::RGBA8, 4) + .setSubImage(0, {}, ImageReference1D{ColorFormat::RGBA, ColorType::UnsignedByte, 4, SubData1DComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage1D image = texture.subImage(0, Range1Di::fromSize(1, 2), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), 2); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data1D}, TestSuite::Compare::Container); } #endif +namespace { + constexpr UnsignedByte Zero2D[4*4*4] = {}; + constexpr UnsignedByte SubData2DComplete[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; +} + void TextureGLTest::subImage2D() { - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; Texture2D texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), Zero2D)); texture.setSubImage(0, Vector2i(1), - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data2D)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{SubData2DComplete}, TestSuite::Compare::Container); #endif } #ifndef MAGNUM_TARGET_GLES2 void TextureGLTest::subImage2DBuffer() { - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; Texture2D texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), Zero2D)); texture.setSubImage(0, Vector2i(1), - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw)); + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), Data2D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{SubData2DComplete}, TestSuite::Compare::Container); #endif } #endif -void TextureGLTest::subImage3D() { - #ifdef MAGNUM_TARGET_GLES2 - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::OES::texture_3D::string() + std::string(" is not supported.")); - #endif +#ifndef MAGNUM_TARGET_GLES +void TextureGLTest::subImage2DQuery() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); - constexpr UnsignedByte zero[4*4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; - Texture3D texture; - texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero)); - texture.setSubImage(0, Vector3i(1), - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData)); + Texture2D texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4}) + .setSubImage(0, {}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubData2DComplete}); MAGNUM_VERIFY_NO_ERROR(); - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); + Image2D image = texture.subImage(0, Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); - CORRADE_COMPARE(image.size(), Vector3i(4)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ + CORRADE_COMPARE(image.size(), Vector2i{2}); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), Containers::ArrayReference{Data2D}, TestSuite::Compare::Container); +} + +void TextureGLTest::subImage2DQueryBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + Texture2D texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4}) + .setSubImage(0, {}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubData2DComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage2D image = texture.subImage(0, Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i{2}); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data2D}, TestSuite::Compare::Container); +} +#endif + +namespace { + constexpr UnsignedByte Zero3D[4*4*4*4] = {}; + constexpr UnsignedByte SubData3DComplete[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1036,64 +1081,98 @@ void TextureGLTest::subImage3D() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + }; +} + +void TextureGLTest::subImage3D() { + #ifdef MAGNUM_TARGET_GLES2 + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::OES::texture_3D::string() + std::string(" is not supported.")); + #endif + + Texture3D texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), Zero3D)); + texture.setSubImage(0, Vector3i(1), + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), Data3D)); + + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES + Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(4)); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), + Containers::ArrayReference{SubData3DComplete}, TestSuite::Compare::Container); #endif } #ifndef MAGNUM_TARGET_GLES2 void TextureGLTest::subImage3DBuffer() { - constexpr UnsignedByte zero[4*4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; Texture3D texture; texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero)); + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), Zero3D)); texture.setSubImage(0, Vector3i(1), - BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData, BufferUsage::StaticDraw)); + BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), Data3D, BufferUsage::StaticDraw)); MAGNUM_VERIFY_NO_ERROR(); /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); + BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(4)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0, 0, 0, 0, - 0, 0, 0, 0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{SubData3DComplete}, TestSuite::Compare::Container); #endif } #endif #ifndef MAGNUM_TARGET_GLES +void TextureGLTest::subImage3DQuery() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + Texture3D texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector3i{4}) + .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{4}, SubData3DComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + Image3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, Vector3i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i{2}); + CORRADE_COMPARE_AS( + Containers::ArrayReference(image.data(), image.pixelSize()*image.size().product()), Containers::ArrayReference{Data3D}, TestSuite::Compare::Container); +} + +void TextureGLTest::subImage3DQueryBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); + + Texture3D texture; + texture.setStorage(1, TextureFormat::RGBA8, Vector3i{4}) + .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{4}, SubData3DComplete}); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, Vector3i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i{2}); + CORRADE_COMPARE_AS(imageData, Containers::ArrayReference{Data3D}, TestSuite::Compare::Container); +} + void TextureGLTest::generateMipmap1D() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported.")); diff --git a/src/Magnum/Test/TimeQueryGLTest.cpp b/src/Magnum/Test/TimeQueryGLTest.cpp index 440f5861d..fddd09a64 100644 --- a/src/Magnum/Test/TimeQueryGLTest.cpp +++ b/src/Magnum/Test/TimeQueryGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -28,12 +28,11 @@ namespace Magnum { namespace Test { -class TimeQueryGLTest: public AbstractOpenGLTester { - public: - explicit TimeQueryGLTest(); +struct TimeQueryGLTest: AbstractOpenGLTester { + explicit TimeQueryGLTest(); - void queryTime(); - void queryTimestamp(); + void queryTime(); + void queryTimestamp(); }; TimeQueryGLTest::TimeQueryGLTest() { diff --git a/src/Magnum/Test/TransformFeedbackGLTest.cpp b/src/Magnum/Test/TransformFeedbackGLTest.cpp new file mode 100644 index 000000000..202af4b47 --- /dev/null +++ b/src/Magnum/Test/TransformFeedbackGLTest.cpp @@ -0,0 +1,403 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Magnum/AbstractShaderProgram.h" +#include "Magnum/Buffer.h" +#include "Magnum/Mesh.h" +#include "Magnum/Shader.h" +#include "Magnum/TransformFeedback.h" +#include "Magnum/Math/Vector2.h" +#include "Magnum/Test/AbstractOpenGLTester.h" + +namespace Magnum { namespace Test { + +struct TransformFeedbackGLTest: AbstractOpenGLTester { + explicit TransformFeedbackGLTest(); + + void construct(); + void constructCopy(); + void constructMove(); + + void label(); + + void attachBase(); + void attachRange(); + void attachBases(); + void attachRanges(); + + void interleaved(); +}; + +TransformFeedbackGLTest::TransformFeedbackGLTest() { + addTests({&TransformFeedbackGLTest::construct, + &TransformFeedbackGLTest::constructCopy, + &TransformFeedbackGLTest::constructMove, + + &TransformFeedbackGLTest::label, + + &TransformFeedbackGLTest::attachBase, + &TransformFeedbackGLTest::attachRange, + &TransformFeedbackGLTest::attachBases, + &TransformFeedbackGLTest::attachRanges, + + &TransformFeedbackGLTest::interleaved}); +} + +void TransformFeedbackGLTest::construct() { + { + TransformFeedback feedback; + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_VERIFY(feedback.id() > 0); + } + + MAGNUM_VERIFY_NO_ERROR(); +} + +void TransformFeedbackGLTest::constructCopy() { + CORRADE_VERIFY(!(std::is_constructible{})); + CORRADE_VERIFY(!(std::is_assignable{})); +} + +void TransformFeedbackGLTest::constructMove() { + TransformFeedback a; + const Int id = a.id(); + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_VERIFY(id > 0); + + TransformFeedback b{std::move(a)}; + + CORRADE_COMPARE(a.id(), 0); + CORRADE_COMPARE(b.id(), id); + + TransformFeedback c; + const Int cId = c.id(); + c = std::move(b); + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_VERIFY(cId > 0); + CORRADE_COMPARE(b.id(), cId); + CORRADE_COMPARE(c.id(), id); +} + +void TransformFeedbackGLTest::label() { + /* No-Op version is tested in AbstractObjectGLTest */ + if(!Context::current()->isExtensionSupported() && + !Context::current()->isExtensionSupported()) + CORRADE_SKIP("Required extension is not available"); + + TransformFeedback feedback; + + CORRADE_COMPARE(feedback.label(), ""); + MAGNUM_VERIFY_NO_ERROR(); + + feedback.setLabel("MyXfb"); + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(feedback.label(), "MyXfb"); +} + +namespace { + +constexpr const Vector2 inputData[] = { + {0.0f, 0.0f}, + {-1.0f, 1.0f} +}; + +struct XfbShader: AbstractShaderProgram { + typedef Attribute<0, Vector2> Input; + + explicit XfbShader(); +}; + +XfbShader::XfbShader() { + #ifndef MAGNUM_TARGET_GLES + Shader vert(Version::GL300, Shader::Type::Vertex); + #else + Shader vert(Version::GLES300, Shader::Type::Vertex); + Shader frag(Version::GLES300, Shader::Type::Fragment); + #endif + CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource( + "in mediump vec2 inputData;\n" + "out mediump vec2 outputData;\n" + "void main() {\n" + " outputData = inputData + vec2(1.0, -1.0);\n" + "}\n").compile()); + #ifndef MAGNUM_TARGET_GLES + attachShader(vert); + #else + /* ES for some reason needs both vertex and fragment shader */ + CORRADE_INTERNAL_ASSERT_OUTPUT(frag.addSource("void main() {}\n").compile()); + attachShaders({vert, frag}); + #endif + bindAttributeLocation(Input::Location, "inputData"); + setTransformFeedbackOutputs({"outputData"}, TransformFeedbackBufferMode::SeparateAttributes); + CORRADE_INTERNAL_ASSERT_OUTPUT(link()); +} + +} + +void TransformFeedbackGLTest::attachBase() { + XfbShader shader; + + Buffer input; + input.setData(inputData, BufferUsage::StaticDraw); + Buffer output; + output.setData({nullptr, 2*sizeof(Vector2)}, BufferUsage::StaticRead); + + Mesh mesh; + mesh.setPrimitive(MeshPrimitive::Points) + .addVertexBuffer(input, 0, XfbShader::Input{}) + .setCount(2); + + TransformFeedback feedback; + feedback.attachBuffer(0, output); + + MAGNUM_VERIFY_NO_ERROR(); + + Renderer::enable(Renderer::Feature::RasterizerDiscard); + feedback.begin(shader, TransformFeedback::PrimitiveMode::Points); + mesh.draw(shader); + feedback.end(); + + MAGNUM_VERIFY_NO_ERROR(); + + Vector2* data = reinterpret_cast(output.map(0, 2*sizeof(Vector2), Buffer::MapFlag::Read)); + CORRADE_COMPARE(data[0], Vector2(1.0f, -1.0f)); + CORRADE_COMPARE(data[1], Vector2(0.0f, 0.0f)); + output.unmap(); +} + +void TransformFeedbackGLTest::attachRange() { + XfbShader shader; + + Buffer input; + input.setData(inputData, BufferUsage::StaticDraw); + Buffer output; + output.setData({nullptr, 512 + 2*sizeof(Vector2)}, BufferUsage::StaticRead); + + Mesh mesh; + mesh.setPrimitive(MeshPrimitive::Points) + .addVertexBuffer(input, 0, XfbShader::Input{}) + .setCount(2); + + TransformFeedback feedback; + feedback.attachBuffer(0, output, 256, 2*sizeof(Vector2)); + + MAGNUM_VERIFY_NO_ERROR(); + + Renderer::enable(Renderer::Feature::RasterizerDiscard); + feedback.begin(shader, TransformFeedback::PrimitiveMode::Points); + mesh.draw(shader); + feedback.end(); + + MAGNUM_VERIFY_NO_ERROR(); + + Vector2* data = reinterpret_cast(output.map(256, 2*sizeof(Vector2), Buffer::MapFlag::Read)); + CORRADE_COMPARE(data[0], Vector2(1.0f, -1.0f)); + CORRADE_COMPARE(data[1], Vector2(0.0f, 0.0f)); + output.unmap(); +} + +namespace { + +struct XfbMultiShader: AbstractShaderProgram { + typedef Attribute<0, Vector2> Input; + + explicit XfbMultiShader(); +}; + +XfbMultiShader::XfbMultiShader() { + #ifndef MAGNUM_TARGET_GLES + Shader vert(Version::GL300, Shader::Type::Vertex); + #else + Shader vert(Version::GLES300, Shader::Type::Vertex); + Shader frag(Version::GLES300, Shader::Type::Fragment); + #endif + CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource( + "in mediump vec2 inputData;\n" + "out mediump vec2 output1;\n" + "out mediump float output2;\n" + "void main() {\n" + " output1 = inputData + vec2(1.0, -1.0);\n" + " output2 = inputData.x - inputData.y;\n" + "}\n").compile()); + #ifndef MAGNUM_TARGET_GLES + attachShader(vert); + #else + /* ES for some reason needs both vertex and fragment shader */ + CORRADE_INTERNAL_ASSERT_OUTPUT(frag.addSource("void main() {}\n").compile()); + attachShaders({vert, frag}); + #endif + bindAttributeLocation(Input::Location, "inputData"); + setTransformFeedbackOutputs({"output1", "output2"}, TransformFeedbackBufferMode::SeparateAttributes); + CORRADE_INTERNAL_ASSERT_OUTPUT(link()); +} + +} + +void TransformFeedbackGLTest::attachBases() { + XfbMultiShader shader; + + Buffer input; + input.setData(inputData, BufferUsage::StaticDraw); + Buffer output1, output2; + output1.setData({nullptr, 2*sizeof(Vector2)}, BufferUsage::StaticRead); + output2.setData({nullptr, 2*sizeof(Float)}, BufferUsage::StaticRead); + + Mesh mesh; + mesh.setPrimitive(MeshPrimitive::Points) + .addVertexBuffer(input, 0, XfbMultiShader::Input{}) + .setCount(2); + + TransformFeedback feedback; + feedback.attachBuffers(0, {&output1, &output2}); + + MAGNUM_VERIFY_NO_ERROR(); + + Renderer::enable(Renderer::Feature::RasterizerDiscard); + feedback.begin(shader, TransformFeedback::PrimitiveMode::Points); + mesh.draw(shader); + feedback.end(); + + MAGNUM_VERIFY_NO_ERROR(); + + Vector2* data1 = reinterpret_cast(output1.map(0, 2*sizeof(Vector2), Buffer::MapFlag::Read)); + CORRADE_COMPARE(data1[0], Vector2(1.0f, -1.0f)); + CORRADE_COMPARE(data1[1], Vector2(0.0f, 0.0f)); + output1.unmap(); + + Float* data2 = reinterpret_cast(output2.map(0, 2*sizeof(Float), Buffer::MapFlag::Read)); + CORRADE_COMPARE(data2[0], 0.0f); + CORRADE_COMPARE(data2[1], -2.0f); + output2.unmap(); +} + +void TransformFeedbackGLTest::attachRanges() { + Buffer input; + input.setData(inputData, BufferUsage::StaticDraw); + Buffer output1, output2; + output1.setData({nullptr, 512 + 2*sizeof(Vector2)}, BufferUsage::StaticRead); + output2.setData({nullptr, 768 + 2*sizeof(Float)}, BufferUsage::StaticRead); + + XfbMultiShader shader; + + Mesh mesh; + mesh.setPrimitive(MeshPrimitive::Points) + .addVertexBuffer(input, 0, XfbMultiShader::Input{}) + .setCount(2); + + TransformFeedback feedback; + feedback.attachBuffers(0, { + std::make_tuple(&output1, 256, 2*sizeof(Vector2)), + std::make_tuple(&output2, 512, 2*sizeof(Float)) + }); + + MAGNUM_VERIFY_NO_ERROR(); + + Renderer::enable(Renderer::Feature::RasterizerDiscard); + feedback.begin(shader, TransformFeedback::PrimitiveMode::Points); + mesh.draw(shader); + feedback.end(); + + MAGNUM_VERIFY_NO_ERROR(); + + Vector2* data1 = reinterpret_cast(output1.map(256, 2*sizeof(Vector2), Buffer::MapFlag::Read)); + CORRADE_COMPARE(data1[0], Vector2(1.0f, -1.0f)); + CORRADE_COMPARE(data1[1], Vector2(0.0f, 0.0f)); + output1.unmap(); + + Float* data2 = reinterpret_cast(output2.map(512, 2*sizeof(Float), Buffer::MapFlag::Read)); + CORRADE_COMPARE(data2[0], 0.0f); + CORRADE_COMPARE(data2[1], -2.0f); + output2.unmap(); +} + +void TransformFeedbackGLTest::interleaved() { + struct XfbInterleavedShader: AbstractShaderProgram { + typedef Attribute<0, Vector2> Input; + + explicit XfbInterleavedShader() { + #ifndef MAGNUM_TARGET_GLES + Shader vert(Version::GL300, Shader::Type::Vertex); + #else + Shader vert(Version::GLES300, Shader::Type::Vertex); + Shader frag(Version::GLES300, Shader::Type::Fragment); + #endif + CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource( + "in mediump vec2 inputData;\n" + "out mediump vec2 output1;\n" + "out mediump float output2;\n" + "void main() {\n" + " output1 = inputData + vec2(1.0, -1.0);\n" + " output2 = inputData.x - inputData.y + 5.0;\n" + "}\n").compile()); + #ifndef MAGNUM_TARGET_GLES + attachShader(vert); + #else + /* ES for some reason needs both vertex and fragment shader */ + CORRADE_INTERNAL_ASSERT_OUTPUT(frag.addSource("void main() {}\n").compile()); + attachShaders({vert, frag}); + #endif + bindAttributeLocation(Input::Location, "inputData"); + setTransformFeedbackOutputs({"output1", "gl_SkipComponents1", "output2"}, TransformFeedbackBufferMode::InterleavedAttributes); + CORRADE_INTERNAL_ASSERT_OUTPUT(link()); + } + } shader; + + Buffer input; + input.setData(inputData, BufferUsage::StaticDraw); + Buffer output; + output.setData({nullptr, 4*sizeof(Vector2)}, BufferUsage::StaticRead); + + Mesh mesh; + mesh.setPrimitive(MeshPrimitive::Points) + .addVertexBuffer(input, 0, XfbInterleavedShader::Input{}) + .setCount(2); + + TransformFeedback feedback; + feedback.attachBuffer(0, output); + + MAGNUM_VERIFY_NO_ERROR(); + + Renderer::enable(Renderer::Feature::RasterizerDiscard); + feedback.begin(shader, TransformFeedback::PrimitiveMode::Points); + mesh.draw(shader); + feedback.end(); + + MAGNUM_VERIFY_NO_ERROR(); + + Vector2* data = reinterpret_cast(output.map(0, 4*sizeof(Vector2), Buffer::MapFlag::Read)); + CORRADE_COMPARE(data[0], Vector2(1.0f, -1.0f)); + CORRADE_COMPARE(data[1].y(), 5.0f); + CORRADE_COMPARE(data[2], Vector2(0.0f, 0.0f)); + CORRADE_COMPARE(data[3].y(), 3.0f); + output.unmap(); +} + +}} + +CORRADE_TEST_MAIN(Magnum::Test::TransformFeedbackGLTest) diff --git a/src/Magnum/Test/VersionTest.cpp b/src/Magnum/Test/VersionTest.cpp index 5f3fc82d5..bbb8a9d85 100644 --- a/src/Magnum/Test/VersionTest.cpp +++ b/src/Magnum/Test/VersionTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,17 +29,18 @@ namespace Magnum { namespace Test { -class VersionTest: public TestSuite::Tester { - public: - explicit VersionTest(); +struct VersionTest: TestSuite::Tester { + explicit VersionTest(); - void fromNumber(); - void toNumber(); + void fromNumber(); + void toNumber(); + void compare(); }; VersionTest::VersionTest() { addTests({&VersionTest::fromNumber, - &VersionTest::toNumber}); + &VersionTest::toNumber, + &VersionTest::compare}); } void VersionTest::fromNumber() { @@ -58,6 +59,14 @@ void VersionTest::toNumber() { #endif } +void VersionTest::compare() { + #ifndef MAGNUM_TARGET_GLES + CORRADE_VERIFY(version(1, 1) < Version::GL210); + #else + CORRADE_VERIFY(version(1, 1) < Version::GLES200); + #endif +} + }} CORRADE_TEST_MAIN(Magnum::Test::VersionTest) diff --git a/src/Magnum/Test/configure.h.cmake b/src/Magnum/Test/configure.h.cmake index 57d0960d5..af1f028a6 100644 --- a/src/Magnum/Test/configure.h.cmake +++ b/src/Magnum/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Text/AbstractFont.cpp b/src/Magnum/Text/AbstractFont.cpp index 341401b71..4b894e339 100644 --- a/src/Magnum/Text/AbstractFont.cpp +++ b/src/Magnum/Text/AbstractFont.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,7 +38,7 @@ AbstractFont::AbstractFont(): _size(0.0f) {} AbstractFont::AbstractFont(PluginManager::AbstractManager& manager, std::string plugin): AbstractPlugin(manager, std::move(plugin)), _size(0.0f), _lineHeight(0.0f) {} -bool AbstractFont::openData(const std::vector>>& data, const Float size) { +bool AbstractFont::openData(const std::vector>>& data, const Float size) { CORRADE_ASSERT(features() & Feature::OpenData, "Text::AbstractFont::openData(): feature not supported", false); CORRADE_ASSERT(!data.empty(), @@ -50,7 +50,7 @@ bool AbstractFont::openData(const std::vector AbstractFont::doOpenData(const std::vector>>& data, const Float size) { +std::pair AbstractFont::doOpenData(const std::vector>>& data, const Float size) { CORRADE_ASSERT(!(features() & Feature::MultiFile), "Text::AbstractFont::openData(): feature advertised but not implemented", {}); CORRADE_ASSERT(data.size() == 1, @@ -60,7 +60,7 @@ std::pair AbstractFont::doOpenData(const std::vector data, const Float size) { +bool AbstractFont::openSingleData(const Containers::ArrayReference data, const Float size) { CORRADE_ASSERT(features() & Feature::OpenData, "Text::AbstractFont::openSingleData(): feature not supported", false); CORRADE_ASSERT(!(features() & Feature::MultiFile), @@ -72,7 +72,7 @@ bool AbstractFont::openSingleData(const Containers::ArrayReference AbstractFont::doOpenSingleData(Containers::ArrayReference, Float) { +std::pair AbstractFont::doOpenSingleData(Containers::ArrayReference, Float) { CORRADE_ASSERT(false, "Text::AbstractFont::openSingleData(): feature advertised but not implemented", {}); } diff --git a/src/Magnum/Text/AbstractFont.h b/src/Magnum/Text/AbstractFont.h index 0137d385c..5acaae006 100644 --- a/src/Magnum/Text/AbstractFont.h +++ b/src/Magnum/Text/AbstractFont.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -125,7 +125,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { * file. Available only if @ref Feature::OpenData is supported. Returns * `true` on success, `false` otherwise. */ - bool openData(const std::vector>>& data, Float size); + bool openData(const std::vector>>& data, Float size); /** * @brief Open font from single data @@ -137,7 +137,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { * plugin doesn't have @ref Feature::MultiFile. Returns `true` on * success, `false` otherwise. */ - bool openSingleData(Containers::ArrayReference data, Float size); + bool openSingleData(Containers::ArrayReference data, Float size); /** * @brief Open font from file @@ -217,7 +217,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { * @brief Layout the text using font's own layouter * @param cache Glyph cache * @param size Font size - * @param text %Text to layout + * @param text Text to layout * * Note that the layouters support rendering of single-line text only. * See @ref Renderer class for more advanced text layouting. @@ -243,7 +243,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { * zeros otherwise. If the plugin doesn't have @ref Feature::MultiFile, * default implementation calls @ref doOpenSingleData(). */ - virtual std::pair doOpenData(const std::vector>>& data, Float size); + virtual std::pair doOpenData(const std::vector>>& data, Float size); /** * @brief Implementation for @ref openSingleData() @@ -251,7 +251,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { * Return size and line height of opened font on successful opening, * zeros otherwise. */ - virtual std::pair doOpenSingleData(Containers::ArrayReference data, Float size); + virtual std::pair doOpenSingleData(Containers::ArrayReference data, Float size); /** * @brief Implementation for @ref openFile() @@ -277,7 +277,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { * * The string is converted from UTF-8 to UTF-32, unique characters are * *not* removed. - * @note On Windows uses `std::vector` instead of + * @note On MinGW uses `std::vector` instead of * `std::u32string`. See @ref Corrade::Utility::Unicode::utf32() * for more information. */ diff --git a/src/Magnum/Text/AbstractFontConverter.cpp b/src/Magnum/Text/AbstractFontConverter.cpp index dd6c6fc6e..531af8721 100644 --- a/src/Magnum/Text/AbstractFontConverter.cpp +++ b/src/Magnum/Text/AbstractFontConverter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -35,34 +35,58 @@ namespace Magnum { namespace Text { +namespace { + +#ifndef __MINGW32__ +std::u32string uniqueUnicode(const std::string& characters) +#else +std::vector uniqueUnicode(const std::string& characters) +#endif +{ + /* Convert UTF-8 to UTF-32 */ + #ifndef __MINGW32__ + std::u32string result = Utility::Unicode::utf32(characters); + #else + std::vector result = Utility::Unicode::utf32(characters); + #endif + + /* Remove duplicate glyphs */ + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), result.end()); + + return result; +} + +} + AbstractFontConverter::AbstractFontConverter() = default; AbstractFontConverter::AbstractFontConverter(PluginManager::AbstractManager& manager, std::string plugin): PluginManager::AbstractPlugin(manager, std::move(plugin)) {} -std::vector>> AbstractFontConverter::exportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::string& characters) const { +std::vector>> AbstractFontConverter::exportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::string& characters) const { /* MSVC 2013 complains about deleted Array copy constructor if {} is used */ CORRADE_ASSERT(features() >= (Feature::ExportFont|Feature::ConvertData), - "Text::AbstractFontConverter::exportFontToData(): feature not supported", (std::vector>>{})); + "Text::AbstractFontConverter::exportFontToData(): feature not supported", (std::vector>>{})); return doExportFontToData(font, cache, filename, uniqueUnicode(characters)); } #ifndef __MINGW32__ -std::vector>> AbstractFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const +std::vector>> AbstractFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const #else -std::vector>> AbstractFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector& characters) const +std::vector>> AbstractFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector& characters) const #endif { /* MSVC 2013 complains about deleted Array copy constructor if {} is used */ CORRADE_ASSERT(!(features() & Feature::MultiFile), - "Text::AbstractFontConverter::exportFontToData(): feature advertised but not implemented", (std::vector>>{})); + "Text::AbstractFontConverter::exportFontToData(): feature advertised but not implemented", (std::vector>>{})); - std::vector>> out; + std::vector>> out; out.emplace_back(filename, std::move(doExportFontToSingleData(font, cache, characters))); - return std::move(out); + return out; } -Containers::Array AbstractFontConverter::exportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::string& characters) const { +Containers::Array AbstractFontConverter::exportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::string& characters) const { #ifndef CORRADE_GCC45_COMPATIBILITY CORRADE_ASSERT(features() >= (Feature::ExportFont|Feature::ConvertData), "Text::AbstractFontConverter::exportFontToSingleData(): feature not supported", nullptr); @@ -79,9 +103,9 @@ Containers::Array AbstractFontConverter::exportFontToSingleData(A } #ifndef __MINGW32__ -Containers::Array AbstractFontConverter::doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string&) const +Containers::Array AbstractFontConverter::doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string&) const #else -Containers::Array AbstractFontConverter::doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector&) const +Containers::Array AbstractFontConverter::doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector&) const #endif { #ifndef CORRADE_GCC45_COMPATIBILITY @@ -120,25 +144,25 @@ bool AbstractFontConverter::doExportFontToFile(AbstractFont& font, GlyphCache& c return true; } -std::vector>> AbstractFontConverter::exportGlyphCacheToData(GlyphCache& cache, const std::string& filename) const { +std::vector>> AbstractFontConverter::exportGlyphCacheToData(GlyphCache& cache, const std::string& filename) const { /* MSVC 2013 complains about deleted Array copy constructor if {} is used */ CORRADE_ASSERT(features() >= (Feature::ExportGlyphCache|Feature::ConvertData), - "Text::AbstractFontConverter::exportGlyphCacheToData(): feature not supported", (std::vector>>{})); + "Text::AbstractFontConverter::exportGlyphCacheToData(): feature not supported", (std::vector>>{})); return doExportGlyphCacheToData(cache, filename); } -std::vector>> AbstractFontConverter::doExportGlyphCacheToData(GlyphCache& cache, const std::string& filename) const { +std::vector>> AbstractFontConverter::doExportGlyphCacheToData(GlyphCache& cache, const std::string& filename) const { /* MSVC 2013 complains about deleted Array copy constructor if {} is used */ CORRADE_ASSERT(!(features() & Feature::MultiFile), - "Text::AbstractFontConverter::exportGlyphCacheToData(): feature advertised but not implemented", (std::vector>>{})); + "Text::AbstractFontConverter::exportGlyphCacheToData(): feature advertised but not implemented", (std::vector>>{})); - std::vector>> out; + std::vector>> out; out.emplace_back(filename, std::move(doExportGlyphCacheToSingleData(cache))); - return std::move(out); + return out; } -Containers::Array AbstractFontConverter::exportGlyphCacheToSingleData(GlyphCache& cache) const { +Containers::Array AbstractFontConverter::exportGlyphCacheToSingleData(GlyphCache& cache) const { #ifndef CORRADE_GCC45_COMPATIBILITY CORRADE_ASSERT(features() >= (Feature::ExportGlyphCache|Feature::ConvertData), "Text::AbstractFontConverter::exportGlyphCacheToSingleData(): feature not supported", nullptr); @@ -154,7 +178,7 @@ Containers::Array AbstractFontConverter::exportGlyphCacheToSingle return doExportGlyphCacheToSingleData(cache); } -Containers::Array AbstractFontConverter::doExportGlyphCacheToSingleData(GlyphCache&) const { +Containers::Array AbstractFontConverter::doExportGlyphCacheToSingleData(GlyphCache&) const { #ifndef CORRADE_GCC45_COMPATIBILITY CORRADE_ASSERT(false, "Text::AbstractFontConverter::exportGlyphCacheToSingleData(): feature advertised but not implemented", nullptr); @@ -185,7 +209,7 @@ bool AbstractFontConverter::doExportGlyphCacheToFile(GlyphCache& cache, const st return true; } -std::unique_ptr AbstractFontConverter::importGlyphCacheFromData(const std::vector>>& data) const { +std::unique_ptr AbstractFontConverter::importGlyphCacheFromData(const std::vector>>& data) const { CORRADE_ASSERT(features() >= (Feature::ImportGlyphCache|Feature::ConvertData), "Text::AbstractFontConverter::importGlyphCacheFromData(): feature not supported", {}); CORRADE_ASSERT(!data.empty(), @@ -194,7 +218,7 @@ std::unique_ptr AbstractFontConverter::importGlyphCacheFromData(cons return doImportGlyphCacheFromData(data); } -std::unique_ptr AbstractFontConverter::doImportGlyphCacheFromData(const std::vector>>& data) const { +std::unique_ptr AbstractFontConverter::doImportGlyphCacheFromData(const std::vector>>& data) const { CORRADE_ASSERT(!(features() & Feature::MultiFile), "Text::AbstractFontConverter::importGlyphCacheFromData(): feature advertised but not implemented", {}); CORRADE_ASSERT(data.size() == 1, @@ -203,7 +227,7 @@ std::unique_ptr AbstractFontConverter::doImportGlyphCacheFromData(co return doImportGlyphCacheFromSingleData(data[0].second); } -std::unique_ptr AbstractFontConverter::importGlyphCacheFromSingleData(Containers::ArrayReference data) const { +std::unique_ptr AbstractFontConverter::importGlyphCacheFromSingleData(Containers::ArrayReference data) const { CORRADE_ASSERT(features() >= (Feature::ImportGlyphCache|Feature::ConvertData), "Text::AbstractFontConverter::importGlyphCacheFromSingleData(): feature not supported", {}); CORRADE_ASSERT(!(features() & Feature::MultiFile), @@ -212,7 +236,7 @@ std::unique_ptr AbstractFontConverter::importGlyphCacheFromSingleDat return doImportGlyphCacheFromSingleData(data); } -std::unique_ptr AbstractFontConverter::doImportGlyphCacheFromSingleData(Containers::ArrayReference) const { +std::unique_ptr AbstractFontConverter::doImportGlyphCacheFromSingleData(Containers::ArrayReference) const { CORRADE_ASSERT(false, "Text::AbstractFontConverter::importGlyphCacheFromSingleData(): feature advertised but not implemented", {}); } @@ -237,24 +261,4 @@ std::unique_ptr AbstractFontConverter::doImportGlyphCacheFromFile(co return doImportGlyphCacheFromSingleData(Utility::Directory::read(filename)); } -#ifndef __MINGW32__ -std::u32string AbstractFontConverter::uniqueUnicode(const std::string& characters) -#else -std::vector AbstractFontConverter::uniqueUnicode(const std::string& characters) -#endif -{ - /* Convert UTF-8 to UTF-32 */ - #ifndef __MINGW32__ - std::u32string result = Utility::Unicode::utf32(characters); - #else - std::vector result = Utility::Unicode::utf32(characters); - #endif - - /* Remove duplicate glyphs */ - std::sort(result.begin(), result.end()); - result.erase(std::unique(result.begin(), result.end()), result.end()); - - return std::move(result); -} - }} diff --git a/src/Magnum/Text/AbstractFontConverter.h b/src/Magnum/Text/AbstractFontConverter.h index fabbbe2cd..b7ef8268b 100644 --- a/src/Magnum/Text/AbstractFontConverter.h +++ b/src/Magnum/Text/AbstractFontConverter.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -149,7 +149,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * @see @ref features(), @ref exportFontToFile(), * @ref exportGlyphCacheToData() */ - std::vector>> exportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::string& characters) const; + std::vector>> exportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::string& characters) const; /** * @brief Export font to single raw data @@ -161,7 +161,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * @see @ref features(), @ref exportFontToFile(), * @ref exportGlyphCacheToSingleData() */ - Containers::Array exportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::string& characters) const; + Containers::Array exportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::string& characters) const; /** * @brief Export font to file @@ -193,7 +193,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * @see @ref features(), @ref exportGlyphCacheToFile(), * @ref exportFontToData() */ - std::vector>> exportGlyphCacheToData(GlyphCache& cache, const std::string& filename) const; + std::vector>> exportGlyphCacheToData(GlyphCache& cache, const std::string& filename) const; /** * @brief Export glyph cache to single raw data @@ -205,7 +205,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * @see @ref features(), @ref exportGlyphCacheToFile(), * @ref importGlyphCacheFromSingleData() */ - Containers::Array exportGlyphCacheToSingleData(GlyphCache& cache) const; + Containers::Array exportGlyphCacheToSingleData(GlyphCache& cache) const; /** * @brief Export glyph cache to file @@ -232,7 +232,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * @see @ref features(), @ref importGlyphCacheFromFile(), * @ref exportGlyphCacheToData() */ - std::unique_ptr importGlyphCacheFromData(const std::vector>>& data) const; + std::unique_ptr importGlyphCacheFromData(const std::vector>>& data) const; /** * @brief Import glyph cache from single raw data @@ -244,7 +244,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * @see @ref features(), @ref importGlyphCacheFromFile(), * @ref exportFontToSingleData() */ - std::unique_ptr importGlyphCacheFromSingleData(Containers::ArrayReference data) const; + std::unique_ptr importGlyphCacheFromSingleData(Containers::ArrayReference data) const; /** * @brief Import glyph cache from file @@ -272,27 +272,27 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * * If the plugin doesn't have @ref Feature::MultiFile, default * implementation calls @ref doExportFontToSingleData(). - * @note On Windows uses `std::vector` instead of + * @note On MinGW uses `std::vector` instead of * `std::u32string`. See @ref Corrade::Utility::Unicode::utf32() * for more information. */ #ifndef __MINGW32__ - virtual std::vector>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const; + virtual std::vector>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const; #else - virtual std::vector>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector& characters) const; + virtual std::vector>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector& characters) const; #endif /** * @brief Implementation for @ref exportFontToSingleData() * - * @note On Windows uses `std::vector` instead of + * @note On MinGW uses `std::vector` instead of * `std::u32string`. See @ref Corrade::Utility::Unicode::utf32() * for more information. */ #ifndef __MINGW32__ - virtual Containers::Array doExportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::u32string& characters) const; + virtual Containers::Array doExportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::u32string& characters) const; #else - virtual Containers::Array doExportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::vector& characters) const; + virtual Containers::Array doExportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::vector& characters) const; #endif /** @@ -301,7 +301,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * If @ref Feature::ConvertData is supported, default implementation * calls @ref doExportFontToData() and saves the result to given * file(s). - * @note On Windows uses `std::vector` instead of + * @note On MinGW uses `std::vector` instead of * `std::u32string`. See @ref Corrade::Utility::Unicode::utf32() * for more information. */ @@ -317,10 +317,10 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * If the plugin doesn't have @ref Feature::MultiFile, default * implementation calls @ref doExportGlyphCacheToSingleData(). */ - virtual std::vector>> doExportGlyphCacheToData(GlyphCache& cache, const std::string& filename) const; + virtual std::vector>> doExportGlyphCacheToData(GlyphCache& cache, const std::string& filename) const; /** @brief Implementation for @ref exportGlyphCacheToSingleData() */ - virtual Containers::Array doExportGlyphCacheToSingleData(GlyphCache& cache) const; + virtual Containers::Array doExportGlyphCacheToSingleData(GlyphCache& cache) const; /** * @brief Implementation for @ref exportGlyphCacheToFile() @@ -337,10 +337,10 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * If the plugin doesn't have @ref Feature::MultiFile, default * implementation calls @ref doImportGlyphCacheFromSingleData(). */ - virtual std::unique_ptr doImportGlyphCacheFromData(const std::vector>>& data) const; + virtual std::unique_ptr doImportGlyphCacheFromData(const std::vector>>& data) const; /** @brief Implementation for @ref importGlyphCacheFromSingleData() */ - virtual std::unique_ptr doImportGlyphCacheFromSingleData(Containers::ArrayReference data) const; + virtual std::unique_ptr doImportGlyphCacheFromSingleData(Containers::ArrayReference data) const; /** * @brief Implementation for @ref importGlyphCacheFromFile() @@ -350,13 +350,6 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl * and calls @ref doImportGlyphCacheFromSingleData() with its contents. */ virtual std::unique_ptr doImportGlyphCacheFromFile(const std::string& filename) const; - - private: - #ifndef __MINGW32__ - MAGNUM_TEXT_LOCAL static std::u32string uniqueUnicode(const std::string& characters); - #else - MAGNUM_TEXT_LOCAL static std::vector uniqueUnicode(const std::string& characters); - #endif }; CORRADE_ENUMSET_OPERATORS(AbstractFontConverter::Features) diff --git a/src/Magnum/Text/Alignment.h b/src/Magnum/Text/Alignment.h index 37c3b2144..c2e0b1365 100644 --- a/src/Magnum/Text/Alignment.h +++ b/src/Magnum/Text/Alignment.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -50,77 +50,77 @@ namespace Implementation { } /** -@brief %Text rendering alignment +@brief Text rendering alignment @see @ref Renderer::render(), @ref Renderer::Renderer() */ enum class Alignment: UnsignedByte { - /** %Text start and line is at origin */ + /** Text start and line is at origin */ LineLeft = Implementation::AlignmentLine|Implementation::AlignmentLeft, /** - * %Text center and line is at origin + * Text center and line is at origin * * @see @ref Alignment::LineCenterIntegral */ LineCenter = Implementation::AlignmentLine|Implementation::AlignmentCenter, - /** %Text end and line is at origin */ + /** Text end and line is at origin */ LineRight = Implementation::AlignmentLine|Implementation::AlignmentRight, /** - * %Text start and vertical middle is at origin + * Text start and vertical middle is at origin * * @see @ref Alignment::MiddleLeftIntegral */ MiddleLeft = Implementation::AlignmentMiddle|Implementation::AlignmentLeft, /** - * %Text center and vertical middle is at origin + * Text center and vertical middle is at origin * * @see @ref Alignment::MiddleRightIntegral */ MiddleCenter = Implementation::AlignmentMiddle|Implementation::AlignmentCenter, /** - * %Text end and vertical middle is at origin + * Text end and vertical middle is at origin * * @see @ref Alignment::MiddleRightIntegral */ MiddleRight = Implementation::AlignmentMiddle|Implementation::AlignmentRight, - /** %Text start and top is at origin */ + /** Text start and top is at origin */ TopLeft = Implementation::AlignmentTop|Implementation::AlignmentLeft, - /** %Text center and top is at origin */ + /** Text center and top is at origin */ TopCenter = Implementation::AlignmentTop|Implementation::AlignmentCenter, - /** %Text end and top is at origin */ + /** Text end and top is at origin */ TopRight = Implementation::AlignmentTop|Implementation::AlignmentRight, /** - * %Text center and line is at origin and alignment offset is integral + * Text center and line is at origin and alignment offset is integral * * @see @ref Alignment::LineCenter */ LineCenterIntegral = Implementation::AlignmentLine|Implementation::AlignmentCenter|Implementation::AlignmentIntegral, /** - * %Text start and vertical middle is at origin and alignment offset is integral + * Text start and vertical middle is at origin and alignment offset is integral * * @see @ref Alignment::MiddleLeft */ MiddleLeftIntegral = Implementation::AlignmentMiddle|Implementation::AlignmentLeft|Implementation::AlignmentIntegral, /** - * %Text center and vertical middle is at origin and alignment offset is integral + * Text center and vertical middle is at origin and alignment offset is integral * * @see @ref Alignment::MiddleCenter */ MiddleCenterIntegral = Implementation::AlignmentMiddle|Implementation::AlignmentCenter|Implementation::AlignmentIntegral, /** - * %Text end and vertical middle is at origin and alignment offset is integral + * Text end and vertical middle is at origin and alignment offset is integral * * @see @ref Alignment::MiddleRight */ diff --git a/src/Magnum/Text/CMakeLists.txt b/src/Magnum/Text/CMakeLists.txt index 4127a15b6..de84e7ed8 100644 --- a/src/Magnum/Text/CMakeLists.txt +++ b/src/Magnum/Text/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -40,19 +40,15 @@ set(MagnumText_HEADERS visibility.h) -if(MAGNUM_BUILD_DEPRECATED) - set(MagnumText_HEADERS ${MagnumText_HEADERS} - TextRenderer.h) -endif() - +# Text library add_library(MagnumText ${SHARED_OR_STATIC} ${MagnumText_SRCS} ${MagnumText_HEADERS}) set_target_properties(MagnumText PROPERTIES DEBUG_POSTFIX "-d") if(BUILD_STATIC_PIC) - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumText PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") + set_target_properties(MagnumText PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() + target_link_libraries(MagnumText Magnum MagnumTextureTools) install(TARGETS MagnumText diff --git a/src/Magnum/Text/DistanceFieldGlyphCache.cpp b/src/Magnum/Text/DistanceFieldGlyphCache.cpp index f49782064..76fc6c9a9 100644 --- a/src/Magnum/Text/DistanceFieldGlyphCache.cpp +++ b/src/Magnum/Text/DistanceFieldGlyphCache.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Text/DistanceFieldGlyphCache.h b/src/Magnum/Text/DistanceFieldGlyphCache.h index 260b8ff9c..cefc3d6fb 100644 --- a/src/Magnum/Text/DistanceFieldGlyphCache.h +++ b/src/Magnum/Text/DistanceFieldGlyphCache.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Text/GlyphCache.cpp b/src/Magnum/Text/GlyphCache.cpp index ec0a8db35..467b65efb 100644 --- a/src/Magnum/Text/GlyphCache.cpp +++ b/src/Magnum/Text/GlyphCache.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Text/GlyphCache.h b/src/Magnum/Text/GlyphCache.h index de428a524..312e567bb 100644 --- a/src/Magnum/Text/GlyphCache.h +++ b/src/Magnum/Text/GlyphCache.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -45,7 +45,7 @@ Contains font glyphs prerendered into texture atlas. ## Usage -Create %GlyphCache object with sufficient size and then call +Create GlyphCache object with sufficient size and then call @ref AbstractFont::createGlyphCache() to fill it with glyphs. @code Text::AbstractFont* font; diff --git a/src/Magnum/Text/Renderer.cpp b/src/Magnum/Text/Renderer.cpp index 37d66aa23..40f6cbba0 100644 --- a/src/Magnum/Text/Renderer.cpp +++ b/src/Magnum/Text/Renderer.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -176,23 +176,23 @@ std::tuple, Range2D> renderVerticesInternal(AbstractFont& fo return std::make_tuple(std::move(vertices), rectangle); } -std::pair, Mesh::IndexType> renderIndicesInternal(const UnsignedInt glyphCount) { +std::pair, Mesh::IndexType> renderIndicesInternal(const UnsignedInt glyphCount) { const UnsignedInt vertexCount = glyphCount*4; const UnsignedInt indexCount = glyphCount*6; - Containers::Array indices; + Containers::Array indices; Mesh::IndexType indexType; if(vertexCount <= 256) { indexType = Mesh::IndexType::UnsignedByte; - indices = Containers::Array(indexCount*sizeof(UnsignedByte)); + indices = Containers::Array(indexCount*sizeof(UnsignedByte)); createIndices(indices, glyphCount); } else if(vertexCount <= 65536) { indexType = Mesh::IndexType::UnsignedShort; - indices = Containers::Array(indexCount*sizeof(UnsignedShort)); + indices = Containers::Array(indexCount*sizeof(UnsignedShort)); createIndices(indices, glyphCount); } else { indexType = Mesh::IndexType::UnsignedInt; - indices = Containers::Array(indexCount*sizeof(UnsignedInt)); + indices = Containers::Array(indexCount*sizeof(UnsignedInt)); createIndices(indices, glyphCount); } @@ -210,7 +210,7 @@ std::tuple renderInternal(AbstractFont& font, const GlyphCache& c const UnsignedInt indexCount = glyphCount*6; /* Render indices and upload them */ - Containers::Array indices; + Containers::Array indices; Mesh::IndexType indexType; std::tie(indices, indexType) = renderIndicesInternal(glyphCount); indexBuffer.setData(indices, usage); @@ -259,7 +259,7 @@ template std::tuple Renderer: typename Shaders::AbstractVector::Position( Shaders::AbstractVector::Position::Components::Two), typename Shaders::AbstractVector::TextureCoordinates()); - return std::move(r); + return r; } #if defined(MAGNUM_TARGET_GLES2) && !defined(CORRADE_TARGET_EMSCRIPTEN) @@ -350,7 +350,7 @@ void AbstractRenderer::reserve(const uint32_t glyphCount, const BufferUsage vert _mesh.setCount(0); /* Render indices */ - Containers::Array indexData; + Containers::Array indexData; Mesh::IndexType indexType; std::tie(indexData, indexType) = renderIndicesInternal(glyphCount); @@ -363,7 +363,7 @@ void AbstractRenderer::reserve(const uint32_t glyphCount, const BufferUsage vert .setIndexBuffer(_indexBuffer, 0, indexType, 0, vertexCount); /* Prefill index buffer */ - unsigned char* const indices = static_cast(bufferMapImplementation(_indexBuffer, indexData.size())); + char* const indices = static_cast(bufferMapImplementation(_indexBuffer, indexData.size())); CORRADE_INTERNAL_ASSERT(indices); /** @todo Emscripten: it can be done without this copying altogether */ std::copy(indexData.begin(), indexData.end(), indices); diff --git a/src/Magnum/Text/Renderer.h b/src/Magnum/Text/Renderer.h index 18a567922..115ff412a 100644 --- a/src/Magnum/Text/Renderer.h +++ b/src/Magnum/Text/Renderer.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -56,8 +56,8 @@ class MAGNUM_TEXT_EXPORT AbstractRenderer { * @param font Font * @param cache Glyph cache * @param size Font size - * @param text %Text to render - * @param alignment %Text alignment + * @param text Text to render + * @param alignment Text alignment * * Returns tuple with vertex positions, texture coordinates, indices * and rectangle spanning the rendered text. @@ -80,7 +80,7 @@ class MAGNUM_TEXT_EXPORT AbstractRenderer { /** @brief Index buffer */ Buffer& indexBuffer() { return _indexBuffer; } - /** @brief %Mesh */ + /** @brief Mesh */ Mesh& mesh() { return _mesh; } /** @@ -164,7 +164,7 @@ class MAGNUM_TEXT_EXPORT AbstractRenderer { }; /** -@brief %Text renderer +@brief Text renderer Lays out the text into mesh using given font. Use of ligatures, kerning etc. depends on features supported by particular font and its layouter. @@ -241,11 +241,11 @@ template class MAGNUM_TEXT_EXPORT Renderer: public Abstr * @param font Font * @param cache Glyph cache * @param size Font size - * @param text %Text to render - * @param vertexBuffer %Buffer where to store vertices - * @param indexBuffer %Buffer where to store indices + * @param text Text to render + * @param vertexBuffer Buffer where to store vertices + * @param indexBuffer Buffer where to store indices * @param usage Usage of vertex and index buffer - * @param alignment %Text alignment + * @param alignment Text alignment * * Returns mesh prepared for use with @ref Shaders::AbstractVector * subclasses and rectangle spanning the rendered text. @@ -257,7 +257,7 @@ template class MAGNUM_TEXT_EXPORT Renderer: public Abstr * @param font Font * @param cache Glyph cache * @param size Font size - * @param alignment %Text alignment + * @param alignment Text alignment */ explicit Renderer(AbstractFont& font, const GlyphCache& cache, Float size, Alignment alignment = Alignment::LineLeft); Renderer(AbstractFont&, GlyphCache&&, Float, Alignment alignment = Alignment::LineLeft) = delete; /**< @overload */ diff --git a/src/Magnum/Text/Test/AbstractFontConverterTest.cpp b/src/Magnum/Text/Test/AbstractFontConverterTest.cpp index fecfaabf8..615c70536 100644 --- a/src/Magnum/Text/Test/AbstractFontConverterTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontConverterTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "Magnum/Text/AbstractFontConverter.h" @@ -35,20 +36,19 @@ namespace Magnum { namespace Text { namespace Test { -class AbstractFontConverterTest: public TestSuite::Tester { - public: - explicit AbstractFontConverterTest(); +struct AbstractFontConverterTest: TestSuite::Tester { + explicit AbstractFontConverterTest(); - void convertGlyphs(); + void convertGlyphs(); - void exportFontToSingleData(); - void exportFontToFile(); + void exportFontToSingleData(); + void exportFontToFile(); - void exportGlyphCacheToSingleData(); - void exportGlyphCacheToFile(); + void exportGlyphCacheToSingleData(); + void exportGlyphCacheToFile(); - void importGlyphCacheFromSingleData(); - void importGlyphCacheFromFile(); + void importGlyphCacheFromSingleData(); + void importGlyphCacheFromFile(); }; AbstractFontConverterTest::AbstractFontConverterTest() { @@ -64,6 +64,13 @@ AbstractFontConverterTest::AbstractFontConverterTest() { &AbstractFontConverterTest::importGlyphCacheFromFile}); } +namespace { + /* *static_cast(nullptr) makes Clang Analyzer grumpy */ + char nullData; + AbstractFont& nullFont = *reinterpret_cast(nullData); + GlyphCache& nullGlyphCache = *reinterpret_cast(nullData); +} + void AbstractFontConverterTest::convertGlyphs() { class GlyphExporter: public AbstractFontConverter { public: @@ -77,9 +84,9 @@ void AbstractFontConverterTest::convertGlyphs() { Features doFeatures() const override { return Feature::ConvertData|Feature::ExportFont; } #ifndef __MINGW32__ - Containers::Array doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string& characters) const override + Containers::Array doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string& characters) const override #else - Containers::Array doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector& characters) const override + Containers::Array doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector& characters) const override #endif { this->characters = characters; @@ -103,7 +110,7 @@ void AbstractFontConverterTest::convertGlyphs() { std::vector characters; #endif GlyphExporter exporter(characters); - exporter.exportFontToSingleData(*static_cast(nullptr), *static_cast(nullptr), "abC01a0 "); + exporter.exportFontToSingleData(nullFont, nullGlyphCache, "abC01a0 "); #if !defined(__MINGW32__) && !defined(CORRADE_MSVC2013_COMPATIBILITY) CORRADE_COMPARE(characters, U" 01Cab"); #elif defined(CORRADE_MSVC2013_COMPATIBILITY) @@ -121,24 +128,24 @@ void AbstractFontConverterTest::exportFontToSingleData() { Features doFeatures() const override { return Feature::ConvertData|Feature::ExportFont; } #ifndef __MINGW32__ - Containers::Array doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string&) const override + Containers::Array doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string&) const override #else - Containers::Array doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector&) const override + Containers::Array doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector&) const override #endif { - Containers::Array data(1); - data[0] = 0xee; - return std::move(data); + Containers::Array data(1); + data[0] = '\xee'; + return data; } }; /* doExportFontToData() should call doExportFontToSingleData() */ SingleDataExporter exporter; - auto ret = exporter.exportFontToData(*static_cast(nullptr), *static_cast(nullptr), "font.out", {}); + auto ret = exporter.exportFontToData(nullFont, nullGlyphCache, "font.out", {}); CORRADE_COMPARE(ret.size(), 1); CORRADE_COMPARE(ret[0].first, "font.out"); CORRADE_COMPARE(ret[0].second.size(), 1); - CORRADE_COMPARE(ret[0].second[0], 0xee); + CORRADE_COMPARE(ret[0].second[0], '\xee'); } void AbstractFontConverterTest::exportFontToFile() { @@ -147,22 +154,17 @@ void AbstractFontConverterTest::exportFontToFile() { Features doFeatures() const override { return Feature::ConvertData|Feature::ExportFont|Feature::MultiFile; } #ifndef __MINGW32__ - std::vector>> doExportFontToData(AbstractFont&, GlyphCache&, const std::string& filename, const std::u32string&) const override + std::vector>> doExportFontToData(AbstractFont&, GlyphCache&, const std::string& filename, const std::u32string&) const override #else - std::vector>> doExportFontToData(AbstractFont&, GlyphCache&, const std::string& filename, const std::vector&) const override + std::vector>> doExportFontToData(AbstractFont&, GlyphCache&, const std::string& filename, const std::vector&) const override #endif { - Containers::Array file(1); - file[0] = 0xf0; - - Containers::Array data(2); - data[0] = 0xfe; - data[1] = 0xed; - - std::vector>> out; - out.emplace_back(filename, std::move(file)); - out.emplace_back(filename + ".data", std::move(data)); - return std::move(out); + /* Why the hell GCC 4.9 fails to do proper move so I need to + work around that this ugly way?! */ + std::vector>> ret; + ret.emplace_back(filename, Containers::Array::from('\xf0')); + ret.emplace_back(filename + ".data", Containers::Array::from('\xfe', '\xed')); + return ret; } }; @@ -173,7 +175,7 @@ void AbstractFontConverterTest::exportFontToFile() { /* doExportToFile() should call doExportToData() */ DataExporter exporter; /* MSVC 2013 can't handle {} here */ - bool exported = exporter.exportFontToFile(*static_cast(nullptr), *static_cast(nullptr), Utility::Directory::join(TEXT_TEST_OUTPUT_DIR, "font.out"), std::string()); + bool exported = exporter.exportFontToFile(nullFont, nullGlyphCache, Utility::Directory::join(TEXT_TEST_OUTPUT_DIR, "font.out"), std::string()); CORRADE_VERIFY(exported); CORRADE_COMPARE_AS(Utility::Directory::join(TEXT_TEST_OUTPUT_DIR, "font.out"), "\xf0", TestSuite::Compare::FileToString); @@ -186,20 +188,17 @@ void AbstractFontConverterTest::exportGlyphCacheToSingleData() { private: Features doFeatures() const override { return Feature::ConvertData|Feature::ExportGlyphCache; } - Containers::Array doExportGlyphCacheToSingleData(GlyphCache&) const override { - Containers::Array data(1); - data[0] = 0xee; - return std::move(data); + Containers::Array doExportGlyphCacheToSingleData(GlyphCache&) const override { + return Containers::Array::from('\xee'); } }; /* doExportGlyphCacheToData() should call doExportGlyphCacheToSingleData() */ SingleDataExporter exporter; - auto ret = exporter.exportGlyphCacheToData(*static_cast(nullptr), "font.out"); + auto ret = exporter.exportGlyphCacheToData(nullGlyphCache, "font.out"); CORRADE_COMPARE(ret.size(), 1); CORRADE_COMPARE(ret[0].first, "font.out"); - CORRADE_COMPARE(ret[0].second.size(), 1); - CORRADE_COMPARE(ret[0].second[0], 0xee); + CORRADE_COMPARE_AS(ret[0].second, Containers::Array::from('\xee'), TestSuite::Compare::Container); } void AbstractFontConverterTest::exportGlyphCacheToFile() { @@ -207,18 +206,13 @@ void AbstractFontConverterTest::exportGlyphCacheToFile() { private: Features doFeatures() const override { return Feature::ConvertData|Feature::ExportGlyphCache|Feature::MultiFile; } - std::vector>> doExportGlyphCacheToData(GlyphCache&, const std::string& filename) const override { - Containers::Array file(1); - file[0] = 0xf0; - - Containers::Array data(2); - data[0] = 0xfe; - data[1] = 0xed; - - std::vector>> out; - out.emplace_back(filename, std::move(file)); - out.emplace_back(filename + ".data", std::move(data)); - return std::move(out); + std::vector>> doExportGlyphCacheToData(GlyphCache&, const std::string& filename) const override { + /* Why the hell GCC 4.9 fails to do proper move so I need to + work around that this ugly way?! */ + std::vector>> ret; + ret.emplace_back(filename, Containers::Array::from('\xf0')); + ret.emplace_back(filename + ".data", Containers::Array::from('\xfe', '\xed')); + return ret; } }; @@ -228,7 +222,7 @@ void AbstractFontConverterTest::exportGlyphCacheToFile() { /* doExportGlyphCacheToFile() should call doExportGlyphCacheToData() */ DataExporter exporter; - bool exported = exporter.exportGlyphCacheToFile(*static_cast(nullptr), Utility::Directory::join(TEXT_TEST_OUTPUT_DIR, "glyphcache.out")); + bool exported = exporter.exportGlyphCacheToFile(nullGlyphCache, Utility::Directory::join(TEXT_TEST_OUTPUT_DIR, "glyphcache.out")); CORRADE_VERIFY(exported); CORRADE_COMPARE_AS(Utility::Directory::join(TEXT_TEST_OUTPUT_DIR, "glyphcache.out"), "\xf0", TestSuite::Compare::FileToString); @@ -242,8 +236,8 @@ class SingleGlyphCacheDataImporter: public Text::AbstractFontConverter { private: Features doFeatures() const override { return Feature::ConvertData|Feature::ImportGlyphCache; } - std::unique_ptr doImportGlyphCacheFromSingleData(const Containers::ArrayReference data) const override { - if(data.size() == 1 && data[0] == 0xa5) + std::unique_ptr doImportGlyphCacheFromSingleData(const Containers::ArrayReference data) const override { + if(data.size() == 1 && data[0] == '\xa5') return std::unique_ptr(reinterpret_cast(0xdeadbeef)); return {}; } @@ -254,8 +248,8 @@ class SingleGlyphCacheDataImporter: public Text::AbstractFontConverter { void AbstractFontConverterTest::importGlyphCacheFromSingleData() { /* doImportFromData() should call doImportFromSingleData() */ SingleGlyphCacheDataImporter importer; - const unsigned char data[] = {0xa5}; - std::unique_ptr cache = importer.importGlyphCacheFromData(std::vector>>{{{}, data}}); + const char data[] = {'\xa5'}; + std::unique_ptr cache = importer.importGlyphCacheFromData(std::vector>>{{{}, data}}); CORRADE_COMPARE(cache.get(), reinterpret_cast(0xdeadbeef)); /* The pointer is invalid, avoid deletion */ diff --git a/src/Magnum/Text/Test/AbstractFontTest.cpp b/src/Magnum/Text/Test/AbstractFontTest.cpp index ea60e38d0..26a000f29 100644 --- a/src/Magnum/Text/Test/AbstractFontTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,12 +34,11 @@ namespace Magnum { namespace Text { namespace Test { -class AbstractFontTest: public TestSuite::Tester { - public: - explicit AbstractFontTest(); +struct AbstractFontTest: TestSuite::Tester { + explicit AbstractFontTest(); - void openSingleData(); - void openFile(); + void openSingleData(); + void openFile(); }; AbstractFontTest::AbstractFontTest() { @@ -57,8 +56,8 @@ class SingleDataFont: public Text::AbstractFont { bool doIsOpened() const override { return opened; } void doClose() override {} - std::pair doOpenSingleData(const Containers::ArrayReference data, Float) override { - opened = (data.size() == 1 && data[0] == 0xa5); + std::pair doOpenSingleData(const Containers::ArrayReference data, Float) override { + opened = (data.size() == 1 && data[0] == '\xa5'); return {}; } @@ -78,9 +77,9 @@ class SingleDataFont: public Text::AbstractFont { void AbstractFontTest::openSingleData() { /* doOpenData() should call doOpenSingleData() */ SingleDataFont font; - const unsigned char data[] = {0xa5}; + const char data[] = {'\xa5'}; CORRADE_VERIFY(!font.isOpened()); - font.openData(std::vector>>{{{}, data}}, 3.0f); + font.openData(std::vector>>{{{}, data}}, 3.0f); CORRADE_VERIFY(font.isOpened()); } diff --git a/src/Magnum/Text/Test/AbstractLayouterTest.cpp b/src/Magnum/Text/Test/AbstractLayouterTest.cpp index 02496bf0b..86f087615 100644 --- a/src/Magnum/Text/Test/AbstractLayouterTest.cpp +++ b/src/Magnum/Text/Test/AbstractLayouterTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,11 +30,10 @@ namespace Magnum { namespace Text { namespace Test { -class AbstractLayouterTest: public TestSuite::Tester { - public: - explicit AbstractLayouterTest(); +struct AbstractLayouterTest: TestSuite::Tester { + explicit AbstractLayouterTest(); - void renderGlyph(); + void renderGlyph(); }; AbstractLayouterTest::AbstractLayouterTest() { diff --git a/src/Magnum/Text/Test/CMakeLists.txt b/src/Magnum/Text/Test/CMakeLists.txt index 116a641fa..c90206ac7 100644 --- a/src/Magnum/Text/Test/CMakeLists.txt +++ b/src/Magnum/Text/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Text/Test/GlyphCacheGLTest.cpp b/src/Magnum/Text/Test/GlyphCacheGLTest.cpp index c07aeb3c9..f9c40ce2b 100644 --- a/src/Magnum/Text/Test/GlyphCacheGLTest.cpp +++ b/src/Magnum/Text/Test/GlyphCacheGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -30,13 +30,12 @@ namespace Magnum { namespace Text { namespace Test { -class GlyphCacheGLTest: public Magnum::Test::AbstractOpenGLTester { - public: - explicit GlyphCacheGLTest(); +struct GlyphCacheGLTest: Magnum::Test::AbstractOpenGLTester { + explicit GlyphCacheGLTest(); - void initialize(); - void access(); - void reserve(); + void initialize(); + void access(); + void reserve(); }; GlyphCacheGLTest::GlyphCacheGLTest() { diff --git a/src/Magnum/Text/Test/RendererGLTest.cpp b/src/Magnum/Text/Test/RendererGLTest.cpp index 561ca0d50..55513a03f 100644 --- a/src/Magnum/Text/Test/RendererGLTest.cpp +++ b/src/Magnum/Text/Test/RendererGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,16 +29,15 @@ namespace Magnum { namespace Text { namespace Test { -class RendererGLTest: public Magnum::Test::AbstractOpenGLTester { - public: - explicit RendererGLTest(); +struct RendererGLTest: Magnum::Test::AbstractOpenGLTester { + explicit RendererGLTest(); - void renderData(); - void renderMesh(); - void renderMeshIndexType(); - void mutableText(); + void renderData(); + void renderMesh(); + void renderMeshIndexType(); + void mutableText(); - void multiline(); + void multiline(); }; RendererGLTest::RendererGLTest() { @@ -82,6 +81,10 @@ class TestFont: public Text::AbstractFont { } }; +/* *static_cast(nullptr) makes Clang Analyzer grumpy */ +char glyphCacheData; +GlyphCache& nullGlyphCache = *reinterpret_cast(&glyphCacheData); + } void RendererGLTest::renderData() { @@ -90,7 +93,7 @@ void RendererGLTest::renderData() { std::vector textureCoordinates; std::vector indices; Range2D bounds; - std::tie(positions, textureCoordinates, indices, bounds) = Text::AbstractRenderer::render(font, *static_cast(nullptr), 0.25f, "abc", Alignment::MiddleRightIntegral); + std::tie(positions, textureCoordinates, indices, bounds) = Text::AbstractRenderer::render(font, nullGlyphCache, 0.25f, "abc", Alignment::MiddleRightIntegral); /* Three glyphs, three quads -> 12 vertices, 18 indices */ CORRADE_COMPARE(positions.size(), 12); @@ -172,7 +175,7 @@ void RendererGLTest::renderMesh() { Mesh mesh; Buffer vertexBuffer, indexBuffer; Range2D bounds; - std::tie(mesh, bounds) = Text::Renderer3D::render(font, *static_cast(nullptr), + std::tie(mesh, bounds) = Text::Renderer3D::render(font, nullGlyphCache, 0.25f, "abc", vertexBuffer, indexBuffer, BufferUsage::StaticDraw, Alignment::TopCenter); MAGNUM_VERIFY_NO_ERROR(); @@ -224,7 +227,7 @@ void RendererGLTest::renderMeshIndexType() { texture coordinates, each float is four bytes; six indices per glyph. */ /* 8-bit indices (exactly 256 vertices) */ - std::tie(mesh, std::ignore) = Text::Renderer3D::render(font, *static_cast(nullptr), + std::tie(mesh, std::ignore) = Text::Renderer3D::render(font, nullGlyphCache, 1.0f, std::string(64, 'a'), vertexBuffer, indexBuffer, BufferUsage::StaticDraw); MAGNUM_VERIFY_NO_ERROR(); Containers::Array indicesByte = indexBuffer.data(); @@ -237,7 +240,7 @@ void RendererGLTest::renderMeshIndexType() { })); /* 16-bit indices (260 vertices) */ - std::tie(mesh, std::ignore) = Text::Renderer3D::render(font, *static_cast(nullptr), + std::tie(mesh, std::ignore) = Text::Renderer3D::render(font, nullGlyphCache, 1.0f, std::string(65, 'a'), vertexBuffer, indexBuffer, BufferUsage::StaticDraw); MAGNUM_VERIFY_NO_ERROR(); Containers::Array indicesShort = indexBuffer.data(); @@ -266,7 +269,7 @@ void RendererGLTest::mutableText() { #endif TestFont font; - Text::Renderer2D renderer(font, *static_cast(nullptr), 0.25f); + Text::Renderer2D renderer(font, nullGlyphCache, 0.25f); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(renderer.capacity(), 0); CORRADE_COMPARE(renderer.rectangle(), Range2D()); @@ -338,7 +341,7 @@ void RendererGLTest::multiline() { bool doIsOpened() const override { return _opened; } void doClose() override { _opened = false; } - std::pair doOpenFile(const std::string&, Float) { + std::pair doOpenFile(const std::string&, Float) override { _opened = true; return {0.5f, 0.75f}; } @@ -359,7 +362,7 @@ void RendererGLTest::multiline() { std::vector indices; std::vector positions, textureCoordinates; std::tie(positions, textureCoordinates, indices, rectangle) = Text::Renderer2D::render(font, - *static_cast(nullptr), 2.0f, "abcd\nef\n\nghi", Alignment::MiddleCenter); + nullGlyphCache, 2.0f, "abcd\nef\n\nghi", Alignment::MiddleCenter); /* We're rendering text at 2.0f size and the font is scaled to 0.3f, so the line advance should be 0.75f*2.0f/0.5f = 3.0f */ diff --git a/src/Magnum/Text/Test/configure.h.cmake b/src/Magnum/Text/Test/configure.h.cmake index 319ab3df7..0221eb5ec 100644 --- a/src/Magnum/Text/Test/configure.h.cmake +++ b/src/Magnum/Text/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Text/Text.h b/src/Magnum/Text/Text.h index 106ccae77..0b2e108fd 100644 --- a/src/Magnum/Text/Text.h +++ b/src/Magnum/Text/Text.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,6 +36,7 @@ namespace Magnum { namespace Text { +#ifndef DOXYGEN_GENERATING_OUTPUT class AbstractFont; class AbstractFontConverter; class AbstractLayouter; @@ -50,10 +51,6 @@ class AbstractRenderer; template class Renderer; typedef Renderer<2> Renderer2D; typedef Renderer<3> Renderer3D; - -#ifdef MAGNUM_BUILD_DEPRECATED -typedef Renderer<2> TextRenderer2D; -typedef Renderer<3> TextRenderer3D; #endif }} diff --git a/src/Magnum/Text/fontconverter.cpp b/src/Magnum/Text/fontconverter.cpp index 88a76db64..586f3b6c5 100644 --- a/src/Magnum/Text/fontconverter.cpp +++ b/src/Magnum/Text/fontconverter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -62,7 +62,7 @@ Arguments: - `--font FONT` -- font plugin - `--converter CONVERTER` -- font converter plugin - `--plugin-dir DIR` -- base plugin dir (defaults to plugin directory in - %Magnum install location) + Magnum install location) - `--characters CHARACTERS` -- characters to include in the output (default: `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789?!:;,. `) - `--font-size N` -- input font size (default: `128`) diff --git a/src/Magnum/Text/fontconverterConfigure.h.cmake b/src/Magnum/Text/fontconverterConfigure.h.cmake index 5fc249d4e..1464161ef 100644 --- a/src/Magnum/Text/fontconverterConfigure.h.cmake +++ b/src/Magnum/Text/fontconverterConfigure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Text/visibility.h b/src/Magnum/Text/visibility.h index b76697571..61677ce2e 100644 --- a/src/Magnum/Text/visibility.h +++ b/src/Magnum/Text/visibility.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Texture.cpp b/src/Magnum/Texture.cpp index a7566f218..79e9ab3a3 100644 --- a/src/Magnum/Texture.cpp +++ b/src/Magnum/Texture.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -28,11 +28,18 @@ #include "Magnum/Context.h" #include "Magnum/Extensions.h" +#ifndef MAGNUM_TARGET_GLES +#include "Magnum/BufferImage.h" +#include "Magnum/Image.h" +#endif + #include "Implementation/maxTextureSize.h" #include "Implementation/State.h" #include "Implementation/TextureState.h" -namespace Magnum { namespace Implementation { +namespace Magnum { + +namespace Implementation { template typename DimensionTraits::VectorType maxTextureSize() { return typename DimensionTraits::VectorType{Implementation::maxTextureSideSize()}; @@ -51,4 +58,52 @@ template<> MAGNUM_EXPORT Vector3i maxTextureSize<3>() { return {Vector2i(Implementation::maxTextureSideSize()), Implementation::max3DTextureDepth()}; } -}} +} + +#ifndef MAGNUM_TARGET_GLES +template Image Texture::image(const Int level, Image&& image) { + this->image(level, image); + return std::move(image); +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +template MAGNUM_EXPORT Image<1> Texture<1>::image(Int, Image<1>&&); +template MAGNUM_EXPORT Image<2> Texture<2>::image(Int, Image<2>&&); +template MAGNUM_EXPORT Image<3> Texture<3>::image(Int, Image<3>&&); +#endif + +template BufferImage Texture::image(const Int level, BufferImage&& image, const BufferUsage usage) { + this->image(level, image, usage); + return std::move(image); +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +template MAGNUM_EXPORT BufferImage<1> Texture<1>::image(Int, BufferImage<1>&&, BufferUsage); +template MAGNUM_EXPORT BufferImage<2> Texture<2>::image(Int, BufferImage<2>&&, BufferUsage); +template MAGNUM_EXPORT BufferImage<3> Texture<3>::image(Int, BufferImage<3>&&, BufferUsage); +#endif + +template Image Texture::subImage(const Int level, const RangeTypeFor& range, Image&& image) { + this->subImage(level, range, image); + return std::move(image); +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +template MAGNUM_EXPORT Image<1> Texture<1>::subImage(Int, const Range1Di&, Image<1>&&); +template MAGNUM_EXPORT Image<2> Texture<2>::subImage(Int, const Range2Di&, Image<2>&&); +template MAGNUM_EXPORT Image<3> Texture<3>::subImage(Int, const Range3Di&, Image<3>&&); +#endif + +template BufferImage Texture::subImage(const Int level, const RangeTypeFor& range, BufferImage&& image, const BufferUsage usage) { + this->subImage(level, range, image, usage); + return std::move(image); +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +template MAGNUM_EXPORT BufferImage<1> Texture<1>::subImage(Int, const Range1Di&, BufferImage<1>&&, BufferUsage); +template MAGNUM_EXPORT BufferImage<2> Texture<2>::subImage(Int, const Range2Di&, BufferImage<2>&&, BufferUsage); +template MAGNUM_EXPORT BufferImage<3> Texture<3>::subImage(Int, const Range3Di&, BufferImage<3>&&, BufferUsage); +#endif +#endif + +} diff --git a/src/Magnum/Texture.h b/src/Magnum/Texture.h index 76fca6985..1ad5e3482 100644 --- a/src/Magnum/Texture.h +++ b/src/Magnum/Texture.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -41,10 +41,10 @@ namespace Magnum { namespace Implementation { template constexpr GLenum textureTarget(); #ifndef MAGNUM_TARGET_GLES - template<> inline constexpr GLenum textureTarget<1>() { return GL_TEXTURE_1D; } + template<> constexpr GLenum textureTarget<1>() { return GL_TEXTURE_1D; } #endif - template<> inline constexpr GLenum textureTarget<2>() { return GL_TEXTURE_2D; } - template<> inline constexpr GLenum textureTarget<3>() { + template<> constexpr GLenum textureTarget<2>() { return GL_TEXTURE_2D; } + template<> constexpr GLenum textureTarget<3>() { #ifndef MAGNUM_TARGET_GLES2 return GL_TEXTURE_3D; #else @@ -57,7 +57,7 @@ namespace Implementation { } /** -@brief %Texture +@brief Texture Template class for one- to three-dimensional textures. See also @ref AbstractTexture documentation for more information. @@ -96,17 +96,17 @@ in shaders. @see @ref Texture1D, @ref Texture2D, @ref Texture3D, @ref TextureArray, @ref CubeMapTexture, @ref CubeMapTextureArray, @ref RectangleTexture, @ref BufferTexture, @ref MultisampleTexture -@requires_gles30 %Extension @es_extension{OES,texture_3D} for 3D textures in +@requires_gles30 Extension @es_extension{OES,texture_3D} for 3D textures in OpenGL ES 2.0 @requires_gl 1D textures are not available in OpenGL ES, only 2D and 3D ones. */ template class Texture: public AbstractTexture { public: - static const UnsignedInt Dimensions = dimensions; /**< @brief %Texture dimension count */ + static const UnsignedInt Dimensions = dimensions; /**< @brief Texture dimension count */ #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief %Texture target + * @brief Texture target * * @deprecated Use dedicated classes instead, see documentation of * particular enum value for more information. @@ -188,7 +188,7 @@ template class Texture: public AbstractTexture { */ explicit CORRADE_DEPRECATED("use the parameterless constructor or dedicated TextureArray, MultisampleTexture, RectangleTexture classes instead") Texture(Target target): AbstractTexture(GLenum(target)) {} - /** @brief %Texture target + /** @brief Texture target * @deprecated Use dedicated @ref Magnum::Texture "Texture", * @ref Magnum::TextureArray "TextureArray", * @ref Magnum::MultisampleTexture "MultisampleTexture", @@ -198,25 +198,6 @@ template class Texture: public AbstractTexture { constexpr CORRADE_DEPRECATED("use dedicated Texture, TextureArray, MultisampleTexture, RectangleTexture classes instead") Target target() const { return static_cast(_target); } #endif - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief %Image size in given mip level - * - * The result is not cached in any way. If - * @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. - * @see @ref image(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or - * @def_gl{TEXTURE_DEPTH} - * @requires_gles31 %Texture image size queries are not available in - * OpenGL ES 3.0 and older. - */ - typename DimensionTraits::VectorType imageSize(Int level) { - return DataHelper::imageSize(*this, _target, level); - } - #endif - #ifndef MAGNUM_TARGET_GLES2 /** * @brief Set base mip level @@ -224,11 +205,15 @@ template class Texture: public AbstractTexture { * * Taken into account when generating mipmap using @ref generateMipmap() * and when considering texture completeness when using mipmap - * filtering. Initial value is `0`. + * filtering. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is `0`. * @see @ref setMaxLevel(), @ref setMinificationFilter(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_BASE_LEVEL} + * @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_BASE_LEVEL} * @requires_gles30 Base level is always `0` in OpenGL ES 2.0. */ Texture& setBaseLevel(Int level) { @@ -243,13 +228,17 @@ template class Texture: public AbstractTexture { * * Taken into account when generating mipmap using @ref generateMipmap() * and when considering texture completeness when using mipmap - * filtering. Initial value is `1000`, which is clamped to count of + * filtering. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is `1000`, which is clamped to count of * levels specified when using @ref setStorage(). * @see @ref setBaseLevel(), @ref setMinificationFilter(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_MAX_LEVEL} - * @requires_gles30 %Extension @es_extension{APPLE,texture_max_level}, + * @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_LEVEL} + * @requires_gles30 Extension @es_extension{APPLE,texture_max_level}, * otherwise the max level is always set to largest possible value * in OpenGL ES 2.0. */ @@ -267,15 +256,16 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Sets filter used when the object pixel size is smaller than the - * texture size. If @extension{EXT,direct_state_access} is not - * available, the texture is bound to some texture unit before the - * operation. Initial value is {@ref Sampler::Filter::Nearest, + * texture size. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is {@ref Sampler::Filter::Nearest, * @ref Sampler::Mipmap::Linear}. * @see @ref setMagnificationFilter(), @ref setBaseLevel(), - * @ref setMaxLevel(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} - * and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MIN_FILTER} + * @ref setMaxLevel(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MIN_FILTER} */ Texture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { AbstractTexture::setMinificationFilter(filter, mipmap); @@ -288,13 +278,14 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Sets filter used when the object pixel size is larger than largest - * texture size. If @extension{EXT,direct_state_access} is not - * available, the texture is bound to some texture unit before the - * operation. Initial value is @ref Sampler::Filter::Linear. - * @see @ref setMinificationFilter(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MAG_FILTER} + * texture size. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is @ref Sampler::Filter::Linear. + * @see @ref setMinificationFilter(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MAG_FILTER} */ Texture& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); @@ -306,15 +297,16 @@ template class Texture: public AbstractTexture { * @brief Set minimum level-of-detail parameter * @return Reference to self (for method chaining) * - * Limits selection of highest resolution mipmap. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. Initial value is + * Limits selection of highest resolution mipmap. If on OpenGL ES or + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * `-1000.0f`. - * @see @ref setMaxLod(), @ref setLodBias(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MIN_LOD} - * @requires_gles30 %Texture LOD parameters are not available in OpenGL + * @see @ref setMaxLod(), @ref setLodBias(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MIN_LOD} + * @requires_gles30 Texture LOD parameters are not available in OpenGL * ES 2.0. */ Texture& setMinLod(Float lod) { @@ -326,15 +318,16 @@ template class Texture: public AbstractTexture { * @brief Set maximum level-of-detail parameter * @return Reference to self (for method chaining) * - * Limits selection of lowest resolution mipmap. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. Initial value is + * Limits selection of lowest resolution mipmap. If on OpenGL ES or + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * `1000.0f`. - * @see @ref setMinLod(), @ref setLodBias(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MAX_LOD} - * @requires_gles30 %Texture LOD parameters are not available in OpenGL + * @see @ref setMinLod(), @ref setLodBias(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_LOD} + * @requires_gles30 Texture LOD parameters are not available in OpenGL * ES 2.0. */ Texture& setMaxLod(Float lod) { @@ -349,14 +342,16 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Fixed bias value that is added to the level-of-detail parameter. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. Initial value is + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * `0.0f`. * @see @ref maxLodBias(), @ref setMinLod(), @ref setMaxLod(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_LOD_BIAS} - * @requires_gl %Texture LOD bias can be specified only directly in + * @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_LOD_BIAS} + * @requires_gl Texture LOD bias can be specified only directly in * fragment shader in OpenGL ES. */ Texture& setLodBias(Float bias) { @@ -371,14 +366,15 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Sets wrapping type for coordinates out of range @f$ [ 0.0, 1.0 ] @f$. - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. Initial value is - * @ref Sampler::Wrapping::Repeat. - * @see @ref setBorderColor(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T}, - * @def_gl{TEXTURE_WRAP_R} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). Initial + * value is @ref Sampler::Wrapping::Repeat. + * @see @ref setBorderColor(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_WRAP_S}, + * @def_gl{TEXTURE_WRAP_T}, @def_gl{TEXTURE_WRAP_R} */ Texture& setWrapping(const Array& wrapping) { DataHelper::setWrapping(*this, wrapping); @@ -390,14 +386,15 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Border color when wrapping is set to @ref Sampler::Wrapping::ClampToBorder. - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. Initial value is - * `{0.0f, 0.0f, 0.0f, 0.0f}`. - * @see @ref setWrapping(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} - * and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_BORDER_COLOR} - * @requires_es_extension %Extension @es_extension{NV,texture_border_clamp} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). Initial + * value is `{0.0f, 0.0f, 0.0f, 0.0f}`. + * @see @ref setWrapping(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_BORDER_COLOR} + * @requires_es_extension Extension @es_extension{NV,texture_border_clamp} */ Texture& setBorderColor(const Color4& color) { AbstractTexture::setBorderColor(color); @@ -410,13 +407,16 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Border color for integer textures when wrapping is set to - * @ref Sampler::Wrapping::ClampToBorder. If @extension{EXT,direct_state_access} - * is not available, the texture is bound to some texture unit before - * the operation. Initial value is `{0, 0, 0, 0}`. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_BORDER_COLOR} - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @ref Sampler::Wrapping::ClampToBorder. If neither + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is + * `{0, 0, 0, 0}`. + * @see @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_BORDER_COLOR} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gl Border is available only for float textures in OpenGL * ES. */ @@ -426,7 +426,7 @@ template class Texture: public AbstractTexture { } /** @overload - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gl Border is available only for float textures in OpenGL * ES. */ @@ -443,13 +443,14 @@ template class Texture: public AbstractTexture { * Default value is `1.0f`, which means no anisotropy. Set to value * greater than `1.0f` for anisotropic filtering. If extension * @extension{EXT,texture_filter_anisotropic} (desktop or ES) is not - * available, this function does nothing. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. - * @see @ref Sampler::maxMaxAnisotropy(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MAX_ANISOTROPY_EXT} + * available, this function does nothing. If on OpenGL ES or neither + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). + * @see @ref Sampler::maxMaxAnisotropy(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_ANISOTROPY_EXT} */ Texture& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); @@ -460,13 +461,16 @@ template class Texture: public AbstractTexture { * @brief Set sRGB decoding * @return Reference to self (for method chaining) * - * Disables or reenables decoding of sRGB values. Initial value is + * Disables or reenables decoding of sRGB values. If on OpenGL ES or + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * `true`. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_SRGB_DECODE_EXT} - * @requires_extension %Extension @extension{EXT,texture_sRGB_decode} + * @see @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_SRGB_DECODE_EXT} + * @requires_extension Extension @extension{EXT,texture_sRGB_decode} * @requires_es_extension OpenGL ES 3.0 or extension * @es_extension{EXT,sRGB} and * @es_extension2{EXT,texture_sRGB_decode,texture_sRGB_decode} @@ -487,17 +491,19 @@ template class Texture: public AbstractTexture { * @code * texture.setSwizzle<'b', 'g', 'r', '0'>(); * @endcode - * If @extension{EXT,direct_state_access} is not available, - * the texture is bound to some texture unit before the operation. - * Initial value is `rgba`. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_SWIZZLE_RGBA} (or @def_gl{TEXTURE_SWIZZLE_R}, - * @def_gl{TEXTURE_SWIZZLE_G}, @def_gl{TEXTURE_SWIZZLE_B} and - * @def_gl{TEXTURE_SWIZZLE_A} separately in OpenGL ES) - * @requires_gl33 %Extension @extension{ARB,texture_swizzle} - * @requires_gles30 %Texture swizzle is not available in OpenGL ES 2.0. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). Initial + * value is `rgba`. + * @see @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_SWIZZLE_RGBA} (or + * @def_gl{TEXTURE_SWIZZLE_R}, @def_gl{TEXTURE_SWIZZLE_G}, + * @def_gl{TEXTURE_SWIZZLE_B} and @def_gl{TEXTURE_SWIZZLE_A} + * separately in OpenGL ES) + * @requires_gl33 Extension @extension{ARB,texture_swizzle} + * @requires_gles30 Texture swizzle is not available in OpenGL ES 2.0. */ template Texture& setSwizzle() { AbstractTexture::setSwizzle(); @@ -509,15 +515,16 @@ template class Texture: public AbstractTexture { * @brief Set depth texture comparison mode * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, - * the texture is bound to some texture unit before the operation. - * Initial value is @ref Sampler::CompareMode::None. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). Initial + * value is @ref Sampler::CompareMode::None. * @note Depth textures can be only 1D or 2D. - * @see @ref setCompareFunction(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_COMPARE_MODE} - * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} + * @see @ref setCompareFunction(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_COMPARE_MODE} + * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} */ Texture& setCompareMode(Sampler::CompareMode mode) { AbstractTexture::setCompareMode(mode); @@ -529,16 +536,17 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Comparison operator used when comparison mode is set to - * @ref Sampler::CompareMode::CompareRefToTexture. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. Initial value is + * @ref Sampler::CompareMode::CompareRefToTexture. If on OpenGL ES or + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * @ref Sampler::CompareFunction::LessOrEqual. * @note Depth textures can be only 1D or 2D. - * @see @ref setCompareMode(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_COMPARE_FUNC} - * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} + * @see @ref setCompareMode(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_COMPARE_FUNC} + * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} */ Texture& setCompareFunction(Sampler::CompareFunction function) { AbstractTexture::setCompareFunction(function); @@ -551,14 +559,16 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Selects which component of packed depth/stencil texture is used for - * texturing. If @extension{EXT,direct_state_access} is not available, - * the texture is bound to some texture unit before the operation. - * Initial value is @ref Sampler::DepthStencilMode::DepthComponent. + * texturing. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is @ref Sampler::DepthStencilMode::DepthComponent. * @note Depth textures can be only 1D or 2D. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{DEPTH_STENCIL_TEXTURE_MODE} - * @requires_gl43 %Extension @extension{ARB,stencil_texturing} + * @see @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{DEPTH_STENCIL_TEXTURE_MODE} + * @requires_gl43 Extension @extension{ARB,stencil_texturing} * @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0 * and older. */ @@ -575,78 +585,171 @@ template class Texture: public AbstractTexture { * @param size Size of largest mip level * @return Reference to self (for method chaining) * - * Specifies entire structure of a texture at once, removing the need - * for additional consistency checks and memory reallocations when - * updating the data later. After calling this function the texture - * is immutable and calling @ref setStorage() or @ref setImage() is not - * allowed. - * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. If - * @extension{ARB,texture_storage} (part of OpenGL 4.2), OpenGL ES 3.0 - * or @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not - * available, the feature is emulated with sequence of @ref setImage() - * calls. - * @see @ref maxSize(), @ref setMaxLevel(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and - * @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D} - * or @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/ + * After calling this function the texture is immutable and calling + * @ref setStorage() or @ref setImage() is not allowed. + * + * If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). If neither @extension{ARB,texture_storage} (part of OpenGL + * 4.2), OpenGL ES 3.0 nor @es_extension{EXT,texture_storage} in OpenGL + * ES 2.0 is available, the feature is emulated with sequence of + * @ref setImage() calls. + * @see @ref maxSize(), @ref setMaxLevel(), @fn_gl2{TextureStorage1D,TexStorage1D} / + * @fn_gl2{TextureStorage2D,TexStorage2D} / @fn_gl2{TextureStorage3D,TexStorage3D}, + * @fn_gl_extension{TextureStorage1D,EXT,direct_state_access} / + * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access} / * @fn_gl_extension{TextureStorage3D,EXT,direct_state_access}, - * eventually @fn_gl{TexImage1D}/@fn_gl{TexImage2D}/@fn_gl{TexImage3D} - * or @fn_gl_extension{TextureImage1D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureImage3D,EXT,direct_state_access} + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D} * @todo allow the user to specify ColorType explicitly to avoid * issues in WebGL (see setSubImage()) */ Texture& setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits::VectorType& size) { - DataHelper::setStorage(*this, _target, levels, internalFormat, size); + DataHelper::setStorage(*this, levels, internalFormat, size); return *this; } + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Image size in given mip level + * + * The result is not cached in any way. If on OpenGL ES or neither + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). + * @see @ref image(), @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter}, + * @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{GetTexLevelParameter} with @def_gl{TEXTURE_WIDTH}, + * @def_gl{TEXTURE_HEIGHT}, @def_gl{TEXTURE_DEPTH} + * @requires_gles31 Texture image size queries are not available in + * OpenGL ES 3.0 and older. + */ + typename DimensionTraits::VectorType imageSize(Int level) { + return DataHelper::imageSize(*this, level); + } + #endif + #ifndef MAGNUM_TARGET_GLES /** * @brief Read given mip level of texture to image * @param level Mip level - * @param image %Image where to put the data + * @param image Image where to put the data * - * %Image parameters like format and type of pixel data are taken from + * Image parameters like format and type of pixel data are taken from * given image, image size is taken from the texture using * @ref imageSize(). * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. If - * @extension{ARB,robustness} is available, the operation is protected - * from buffer overflow. However, if both @extension{EXT,direct_state_access} - * and @extension{ARB,robustness} are available, the DSA version is - * used, because it is better for performance and there isn't any - * function combining both features. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or @def_gl{TEXTURE_DEPTH}, - * then @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access} - * or @fn_gl_extension{GetnTexImage,ARB,robustness} - * @requires_gl %Texture image queries are not available in OpenGL ES. + * If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) + * nor @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). If either + * @extension{ARB,direct_state_access} or @extension{ARB,robustness} + * is available, the operation is protected from buffer overflow. + * However, if @extension{ARB,direct_state_access} is not available and + * both @extension{EXT,direct_state_access} and @extension{ARB,robustness} + * are available, the robust operation is preferred over DSA. + * @see @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter}, + * @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{GetTexLevelParameter} with @def_gl{TEXTURE_WIDTH}, + * @def_gl{TEXTURE_HEIGHT}, @def_gl{TEXTURE_DEPTH}, then + * @fn_gl2{GetTextureImage,GetTexImage}, + * @fn_gl_extension{GetnTexImage,ARB,robustness}, + * @fn_gl_extension{GetTextureImage,EXT,direct_state_access}, + * eventually @fn_gl{GetTexImage} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. */ void image(Int level, Image& image) { - AbstractTexture::image(_target, level, image); + AbstractTexture::image(level, image); } + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image image(Int level, Image&& image); + /** * @brief Read given mip level of texture to buffer image * @param level Mip level - * @param image %Buffer image where to put the data - * @param usage %Buffer usage + * @param image Buffer image where to put the data + * @param usage Buffer usage * * See @ref image(Int, Image&) for more information. - * @requires_gl %Texture image queries are not available in OpenGL ES. + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. * @todo Make it more flexible (usable with * @extension{ARB,buffer_storage}, avoiding relocations...) */ void image(Int level, BufferImage& image, BufferUsage usage) { - AbstractTexture::image(_target, level, image, usage); + AbstractTexture::image(level, image, usage); + } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage image(Int level, BufferImage&& image, BufferUsage usage); + + /** + * @brief Read range of given texture mip level to image + * @param level Mip level + * @param range Range to read + * @param image Image where to put the data + * + * Image parameters like format and type of pixel data are taken from + * given image. + * @see @fn_gl{GetTextureSubImage} + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ + void subImage(Int level, const RangeTypeFor& range, Image& image) { + AbstractTexture::subImage(level, range, image); + } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image2D image = texture.subImage(0, rect, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image subImage(Int level, const RangeTypeFor& range, Image&& image); + + /** + * @brief Read range of given texture mip level to buffer image + * @param level Mip level + * @param range Range to read + * @param image Buffer image where to put the data + * @param usage Buffer usage + * + * See @ref subImage(Int, const RangeTypeFor&, Image&) + * for more information. + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ + void subImage(Int level, const RangeTypeFor& range, BufferImage& image, BufferUsage usage) { + AbstractTexture::subImage(level, range, image, usage); } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage2D image = texture.subImage(0, rect, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage subImage(Int level, const RangeTypeFor& range, BufferImage&& image, BufferUsage usage); #endif /** @@ -657,31 +760,42 @@ template class Texture: public AbstractTexture { * @ref Trade::ImageData of the same dimension count * @return Reference to self (for method chaining) * - * For better performance when generating mipmaps using - * @ref generateMipmap() or calling @ref setImage() more than once use - * @ref setStorage() and @ref setSubImage() instead. - * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. + * On platforms that support it prefer to use @ref setStorage() and + * @ref setSubImage() instead, as it avoids unnecessary reallocations + * and has better performance characteristics. This call also has no + * equivalent in @extension{ARB,direct_state_access}, thus the texture + * needs to be bound to some texture unit before the operation. * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexImage1D}/@fn_gl{TexImage2D}/@fn_gl{TexImage3D} or - * @fn_gl_extension{TextureImage1D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureImage3D,EXT,direct_state_access} + * @fn_gl{TexImage1D} / @fn_gl{TexImage2D} / @fn_gl{TexImage3D} + * @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()" + * and @ref Magnum::Texture::setSubImage() "setSubImage()" + * instead. */ Texture& setImage(Int level, TextureFormat internalFormat, const ImageReference& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + DataHelper::setImage(*this, level, internalFormat, image); return *this; } #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + * @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()" + * and @ref Magnum::Texture::setSubImage() "setSubImage()" + * instead. + */ Texture& setImage(Int level, TextureFormat internalFormat, BufferImage& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + DataHelper::setImage(*this, level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + * @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()" + * and @ref Magnum::Texture::setSubImage() "setSubImage()" + * instead. + */ Texture& setImage(Int level, TextureFormat internalFormat, BufferImage&& image) { return setImage(level, internalFormat, image); } @@ -695,34 +809,42 @@ template class Texture: public AbstractTexture { * @ref Trade::ImageData of the same dimension count * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). * * @attention In @ref MAGNUM_TARGET_WEBGL "WebGL" the @ref ColorType of * data passed in @p image must match the original one specified * in @ref setImage(). It means that you might not be able to use * @ref setStorage() as it uses implicit @ref ColorType value. * - * @see @ref setStorage(), @ref setImage(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexSubImage1D}/ - * @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} or - * @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} + * @see @ref setStorage(), @fn_gl2{TextureSubImage1D,TexSubImage1D} / + * @fn_gl2{TextureSubImage2D,TexSubImage2D} / @fn_gl2{TextureSubImage3D,TexSubImage3D}, + * @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access} / + * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access} / + * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexSubImage1D} / @fn_gl{TexSubImage2D} / @fn_gl{TexSubImage3D} */ Texture& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, const ImageReference& image) { - DataHelper::setSubImage(*this, _target, level, offset, image); + DataHelper::setSubImage(*this, level, offset, image); return *this; } #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + */ Texture& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage& image) { - DataHelper::setSubImage(*this, _target, level, offset, image); + DataHelper::setSubImage(*this, level, offset, image); return *this; } - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + */ Texture& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage&& image) { return setSubImage(level, offset, image); } @@ -732,12 +854,14 @@ template class Texture: public AbstractTexture { * @brief Generate mipmap * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. - * @see @ref setMinificationFilter(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{GenerateMipmap} or - * @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} - * @requires_gl30 %Extension @extension{ARB,framebuffer_object} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). + * @see @ref setMinificationFilter(), @fn_gl2{GenerateTextureMipmap,GenerateMipmap}, + * @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{GenerateMipmap} + * @requires_gl30 Extension @extension{ARB,framebuffer_object} */ Texture& generateMipmap() { AbstractTexture::generateMipmap(); @@ -796,7 +920,7 @@ typedef Texture<2> Texture2D; /** @brief Three-dimensional texture -@requires_gles30 %Extension @es_extension{OES,texture_3D} in OpenGL ES 2.0 +@requires_gles30 Extension @es_extension{OES,texture_3D} in OpenGL ES 2.0 */ typedef Texture<3> Texture3D; diff --git a/src/Magnum/TextureArray.cpp b/src/Magnum/TextureArray.cpp index fafd9d47b..470362849 100644 --- a/src/Magnum/TextureArray.cpp +++ b/src/Magnum/TextureArray.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -29,6 +29,11 @@ #include "Magnum/Context.h" #include "Magnum/Extensions.h" +#ifndef MAGNUM_TARGET_GLES +#include "Magnum/BufferImage.h" +#include "Magnum/Image.h" +#endif + #include "Implementation/maxTextureSize.h" namespace Magnum { @@ -49,6 +54,28 @@ template typename DimensionTraits::Ve Implementation::maxTextureArrayLayers()}; } +#ifndef MAGNUM_TARGET_GLES +template Image TextureArray::image(const Int level, Image&& image) { + this->image(level, image); + return std::move(image); +} + +template BufferImage TextureArray::image(const Int level, BufferImage&& image, const BufferUsage usage) { + this->image(level, image, usage); + return std::move(image); +} + +template Image TextureArray::subImage(const Int level, const RangeTypeFor& range, Image&& image) { + this->subImage(level, range, image); + return std::move(image); +} + +template BufferImage TextureArray::subImage(const Int level, const RangeTypeFor& range, BufferImage&& image, const BufferUsage usage) { + this->subImage(level, range, image, usage); + return std::move(image); +} +#endif + #ifndef MAGNUM_TARGET_GLES template class MAGNUM_EXPORT TextureArray<1>; #endif diff --git a/src/Magnum/TextureArray.h b/src/Magnum/TextureArray.h index 84ae2f2f9..0ba00affc 100644 --- a/src/Magnum/TextureArray.h +++ b/src/Magnum/TextureArray.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -42,13 +42,13 @@ namespace Magnum { namespace Implementation { template constexpr GLenum textureArrayTarget(); #ifndef MAGNUM_TARGET_GLES - template<> inline constexpr GLenum textureArrayTarget<1>() { return GL_TEXTURE_1D_ARRAY; } + template<> constexpr GLenum textureArrayTarget<1>() { return GL_TEXTURE_1D_ARRAY; } #endif - template<> inline constexpr GLenum textureArrayTarget<2>() { return GL_TEXTURE_2D_ARRAY; } + template<> constexpr GLenum textureArrayTarget<2>() { return GL_TEXTURE_2D_ARRAY; } } /** -@brief %Texture array +@brief Texture array Template class for one- and two-dimensional texture arrays. See also @ref AbstractTexture documentation for more information. @@ -87,14 +87,14 @@ documentation for more information about usage in shaders. @see @ref Texture1DArray, @ref Texture2DArray, @ref Texture, @ref CubeMapTexture, @ref CubeMapTextureArray, @ref RectangleTexture, @ref BufferTexture, @ref MultisampleTexture -@requires_gl30 %Extension @extension{EXT,texture_array} -@requires_gles30 %Array textures are not available in OpenGL ES 2.0. +@requires_gl30 Extension @extension{EXT,texture_array} +@requires_gles30 Array textures are not available in OpenGL ES 2.0. @requires_gl 1D array textures are not available in OpenGL ES, only 2D ones. @todo Fix this when @es_extension{NV,texture_array} is in ES2 extension headers */ template class TextureArray: public AbstractTexture { public: - static const UnsignedInt Dimensions = dimensions; /**< @brief %Texture dimension count */ + static const UnsignedInt Dimensions = dimensions; /**< @brief Texture dimension count */ /** * @brief Max supported texture array size @@ -118,107 +118,179 @@ template class TextureArray: public AbstractTexture { */ explicit TextureArray(): AbstractTexture(Implementation::textureArrayTarget()) {} - #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setBaseLevel() */ + /** + * @copybrief Texture::setBaseLevel() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBaseLevel() for more information. + */ TextureArray& setBaseLevel(Int level) { AbstractTexture::setBaseLevel(level); return *this; } - #endif - /** @copydoc Texture::setMaxLevel() */ + /** + * @copybrief Texture::setMaxLevel() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxLevel() for more information. + */ TextureArray& setMaxLevel(Int level) { AbstractTexture::setMaxLevel(level); return *this; } - /** @copydoc Texture::setMinificationFilter() */ + /** + * @copybrief Texture::setMinificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinificationFilter() for more information. + */ TextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { AbstractTexture::setMinificationFilter(filter, mipmap); return *this; } - /** @copydoc Texture::setMagnificationFilter() */ + /** + * @copybrief Texture::setMagnificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMagnificationFilter() for more information. + */ TextureArray& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); return *this; } - #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setMinLod() */ + /** + * @copybrief Texture::setMinLod() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinLod() for more information. + */ TextureArray& setMinLod(Float lod) { AbstractTexture::setMinLod(lod); return *this; } - /** @copydoc Texture::setMaxLod() */ + /** + * @copybrief Texture::setMaxLod() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxLod() for more information. + */ TextureArray& setMaxLod(Float lod) { AbstractTexture::setMaxLod(lod); return *this; } - #endif #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::setLodBias() */ + /** + * @copybrief Texture::setLodBias() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setLodBias() for more information. + * @requires_gl Texture LOD bias can be specified only directly in + * fragment shader in OpenGL ES. + */ TextureArray& setLodBias(Float bias) { AbstractTexture::setLodBias(bias); return *this; } #endif - /** @copydoc Texture::setWrapping() */ + /** + * @copybrief Texture::setWrapping() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setWrapping() for more information. + */ TextureArray& setWrapping(const Array& wrapping) { DataHelper::setWrapping(*this, wrapping); return *this; } - /** @copydoc Texture::setBorderColor(const Color4&) */ + /** + * @copybrief Texture::setBorderColor(const Color4&) + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBorderColor(const Color4&) for more + * information. + * @requires_es_extension Extension @es_extension{NV,texture_border_clamp} + */ TextureArray& setBorderColor(const Color4& color) { AbstractTexture::setBorderColor(color); return *this; } #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::setBorderColor(const Vector4ui&) */ + /** + * @copybrief Texture::setBorderColor(const Vector4ui&) + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBorderColor(const Vector4ui&) for more + * information. + * @requires_gl30 Extension @extension{EXT,texture_integer} + * @requires_gl Border is available only for float textures in OpenGL + * ES. + */ TextureArray& setBorderColor(const Vector4ui& color) { AbstractTexture::setBorderColor(color); return *this; } - /** @copydoc Texture::setBorderColor(const Vector4i&) */ + /** @overload + * @requires_gl30 Extension @extension{EXT,texture_integer} + * @requires_gl Border is available only for float textures in OpenGL + * ES. + */ TextureArray& setBorderColor(const Vector4i& color) { AbstractTexture::setBorderColor(color); return *this; } #endif - /** @copydoc Texture::setMaxAnisotropy() */ + /** + * @copybrief Texture::setMaxAnisotropy() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxAnisotropy() for more information. + */ TextureArray& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return *this; } - /** @copydoc Texture::setSRGBDecode() */ + /** + * @copybrief Texture::setSRGBDecode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSRGBDecode() for more information. + * @requires_extension Extension @extension{EXT,texture_sRGB_decode} + * @requires_es_extension Extension @es_extension2{EXT,texture_sRGB_decode,texture_sRGB_decode} + */ TextureArray& setSRGBDecode(bool decode) { AbstractTexture::setSRGBDecode(decode); return *this; } - #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setSwizzle() */ + /** + * @copybrief Texture::setSwizzle() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSwizzle() for more information. + * @requires_gl33 Extension @extension{ARB,texture_swizzle} + */ template TextureArray& setSwizzle() { AbstractTexture::setSwizzle(); return *this; } - #endif /** * @copybrief Texture::setCompareMode() * @return Reference to self (for method chaining) * * See @ref Texture::setCompareMode() for more information. - * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} and - * @es_extension{NV,shadow_samplers_array} */ TextureArray& setCompareMode(Sampler::CompareMode mode) { AbstractTexture::setCompareMode(mode); @@ -230,113 +302,171 @@ template class TextureArray: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setCompareFunction() for more information. - * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} and - * @es_extension{NV,shadow_samplers_array} */ TextureArray& setCompareFunction(Sampler::CompareFunction function) { AbstractTexture::setCompareFunction(function); return *this; } - #ifndef MAGNUM_TARGET_GLES2 /** * @copybrief Texture::setDepthStencilMode() * @return Reference to self (for method chaining) * * See @ref Texture::setDepthStencilMode() for more information. + * @requires_gl43 Extension @extension{ARB,stencil_texturing} + * @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0 + * and older. */ TextureArray& setDepthStencilMode(Sampler::DepthStencilMode mode) { AbstractTexture::setDepthStencilMode(mode); return *this; } - #endif - - #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::imageSize() */ - typename DimensionTraits::VectorType imageSize(Int level) { - return DataHelper::imageSize(*this, _target, level); - } - #endif /** - * @brief Set storage - * @param levels Mip level count - * @param internalFormat Internal format - * @param size Size of largest mip level + * @copybrief Texture::setStorage() * @return Reference to self (for method chaining) * - * Specifies entire structure of a texture at once, removing the need - * for additional consistency checks and memory reallocations when - * updating the data later. After calling this function the texture - * is immutable and calling @ref setStorage() or @ref setImage() is not - * allowed. - * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. If - * @extension{ARB,texture_storage} (part of OpenGL 4.2) or OpenGL ES - * 3.0 is not available, the feature is emulated with sequence of - * @ref setImage() calls. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexStorage2D}/@fn_gl{TexStorage3D} or - * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureStorage3D,EXT,direct_state_access}, - * eventually @fn_gl{TexImage2D}/@fn_gl{TexImage3D} or - * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureImage3D,EXT,direct_state_access}. + * See @ref Texture::setStorage() for more information. + * @see @ref maxSize() */ TextureArray& setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits::VectorType& size) { - DataHelper::setStorage(*this, _target, levels, internalFormat, size); + DataHelper::setStorage(*this, levels, internalFormat, size); return *this; } + /** + * @copybrief Texture::imageSize() + * + * See @ref Texture::imageSize() for more information. + * @requires_gles31 Texture image size queries are not available in + * OpenGL ES 3.0 and older. + */ + typename DimensionTraits::VectorType imageSize(Int level) { + return DataHelper::imageSize(*this, level); + } + #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::image(Int, Image&) */ + /** + * @copybrief Texture::image(Int, Image&) + * @return Reference to self (for method chaining) + * + * See @ref Texture::image(Int, Image&) for more information. + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ void image(Int level, Image& image) { - AbstractTexture::image(_target, level, image); + AbstractTexture::image(level, image); } - /** @copydoc Texture::imate(Int, BufferImage&, BufferUsage) */ + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image image(Int level, Image&& image); + + /** + * @copybrief Texture::image(Int, BufferImage&, BufferUsage) + * @return Reference to self (for method chaining) + * + * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more + * information. + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ void image(Int level, BufferImage& image, BufferUsage usage) { - AbstractTexture::image(_target, level, image, usage); + AbstractTexture::image(level, image, usage); } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage image(Int level, BufferImage&& image, BufferUsage usage); + + /** + * @copybrief Texture::subImage(Int, const RangeTypeFor&, Image&) + * + * See @ref Texture::subImage(Int, const RangeTypeFor&, Image&) + * for more information. + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ + void subImage(Int level, const RangeTypeFor& range, Image& image) { + AbstractTexture::subImage(level, range, image); + } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * Image3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte}); + * @endcode + */ + Image subImage(Int level, const RangeTypeFor& range, Image&& image); + + /** + * @copybrief Texture::subImage(Int, const RangeTypeFor&, BufferImage&, BufferUsage) + * + * See @ref Texture::subImage(Int, const RangeTypeFor&, BufferImage&, BufferUsage) + * for more information. + * @requires_gl45 Extension @extension{ARB,get_texture_sub_image} + * @requires_gl Texture image queries are not available in OpenGL ES. + * See @ref Framebuffer::read() for possible workaround. + */ + void subImage(Int level, const RangeTypeFor& range, BufferImage& image, BufferUsage usage) { + AbstractTexture::subImage(level, range, image, usage); + } + + /** @overload + * + * Convenience alternative to the above, example usage: + * @code + * BufferImage3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead); + * @endcode + */ + BufferImage subImage(Int level, const RangeTypeFor& range, BufferImage&& image, BufferUsage usage); #endif /** - * @brief Set image data - * @param level Mip level - * @param internalFormat Internal format - * @param image @ref Image, @ref ImageReference or - * @ref Trade::ImageData of the same dimension count + * @copybrief Texture::setImage() * @return Reference to self (for method chaining) * - * For better performance when generating mipmaps using - * @ref generateMipmap() or calling @ref setImage() more than once use - * @ref setStorage() and @ref setSubImage() instead. - * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexImage2D}/@fn_gl{TexImage3D} or - * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureImage3D,EXT,direct_state_access} + * See @ref Texture::setImage() for more information. + * @see @ref maxSize() + * @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()" + * and @ref Magnum::TextureArray::setSubImage() "setSubImage()" + * instead. */ TextureArray& setImage(Int level, TextureFormat internalFormat, const ImageReference& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + DataHelper::setImage(*this, level, internalFormat, image); return *this; } - #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()" + * and @ref Magnum::TextureArray::setSubImage() "setSubImage()" + * instead. + */ TextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + DataHelper::setImage(*this, level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()" + * and @ref Magnum::TextureArray::setSubImage() "setSubImage()" + * instead. + */ TextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage&& image) { return setImage(level, internalFormat, image); } - #endif /** * @brief Set image subdata @@ -346,22 +476,24 @@ template class TextureArray: public AbstractTexture { * @ref Trade::ImageData of the same dimension count * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. - * @see @ref setStorage(), @ref setImage(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} - * or @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). + * @see @ref setStorage(), @fn_gl2{TextureSubImage2D,TexSubImage2D}/ + * @fn_gl2{TextureSubImage3D,TexSubImage3D}, + * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ + * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} */ TextureArray& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, const ImageReference& image) { - DataHelper::setSubImage(*this, _target, level, offset, image); + DataHelper::setSubImage(*this, level, offset, image); return *this; } - #ifndef MAGNUM_TARGET_GLES2 /** @overload */ TextureArray& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage& image) { - DataHelper::setSubImage(*this, _target, level, offset, image); + DataHelper::setSubImage(*this, level, offset, image); return *this; } @@ -369,18 +501,33 @@ template class TextureArray: public AbstractTexture { TextureArray& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage&& image) { return setSubImage(level, offset, image); } - #endif - /** @copydoc Texture::generateMipmap() */ + /** + * @copybrief Texture::generateMipmap() + * @return Reference to self (for method chaining) + * + * See @ref Texture::generateMipmap() for more information. + * @requires_gl30 Extension @extension{ARB,framebuffer_object} + */ TextureArray& generateMipmap() { AbstractTexture::generateMipmap(); return *this; } - /** @copydoc Texture::invalidateImage() */ + /** + * @copybrief Texture::invalidateImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::invalidateImage() for more information. + */ void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } - /** @copydoc Texture::invalidateSubImage() */ + /** + * @copybrief Texture::invalidateSubImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::invalidateSubImage() for more information. + */ void invalidateSubImage(Int level, const typename DimensionTraits::VectorType& offset, const typename DimensionTraits::VectorType& size) { DataHelper::invalidateSubImage(*this, level, offset, size); } @@ -402,7 +549,7 @@ template class TextureArray: public AbstractTexture { /** @brief One-dimensional texture array -@requires_gl30 %Extension @extension{EXT,texture_array} +@requires_gl30 Extension @extension{EXT,texture_array} @requires_gl Only @ref Magnum::Texture2DArray "Texture2DArray" is available in OpenGL ES. */ @@ -412,8 +559,8 @@ typedef TextureArray<1> Texture1DArray; /** @brief Two-dimensional texture array -@requires_gl30 %Extension @extension{EXT,texture_array} -@requires_gles30 %Array textures are not available in OpenGL ES 2.0. +@requires_gl30 Extension @extension{EXT,texture_array} +@requires_gles30 Array textures are not available in OpenGL ES 2.0. */ typedef TextureArray<2> Texture2DArray; diff --git a/src/Magnum/TextureFormat.h b/src/Magnum/TextureFormat.h index 88f89e70c..821a7911b 100644 --- a/src/Magnum/TextureFormat.h +++ b/src/Magnum/TextureFormat.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -51,8 +51,8 @@ enum class TextureFormat: GLenum { * allowed in unemulated @ref Texture::setStorage() "*Texture::setStorage()" * calls, in that case use @ref TextureFormat::R8 "TextureFormat::R8" * instead. - * @requires_gl30 %Extension @extension{ARB,texture_rg} - * @requires_gles30 %Extension @es_extension{EXT,texture_rg} in OpenGL ES + * @requires_gl30 Extension @extension{ARB,texture_rg} + * @requires_gles30 Extension @es_extension{EXT,texture_rg} in OpenGL ES * 2.0 * @deprecated_gl Prefer to use the exactly specified version of this * format, e.g. @ref Magnum::TextureFormat::R8 "TextureFormat::R8". @@ -65,8 +65,8 @@ enum class TextureFormat: GLenum { /** * Red component, normalized unsigned byte. - * @requires_gl30 %Extension @extension{ARB,texture_rg} - * @requires_gles30 %Extension @es_extension{EXT,texture_rg} and + * @requires_gl30 Extension @extension{ARB,texture_rg} + * @requires_gles30 Extension @es_extension{EXT,texture_rg} and * @es_extension{EXT,texture_storage} in OpenGL ES 2.0. For texture * storage only, for image specification use * @ref Magnum::TextureFormat::Red "TextureFormat::Red" instead. @@ -82,8 +82,8 @@ enum class TextureFormat: GLenum { * implementation-dependent. Not allowed in unemulated * @ref Texture::setStorage() "*Texture::setStorage()" calls, in that case * use @ref TextureFormat::RG8 "TextureFormat::RG8" instead. - * @requires_gl30 %Extension @extension{ARB,texture_rg} - * @requires_gles30 %Extension @es_extension{EXT,texture_rg} in OpenGL ES + * @requires_gl30 Extension @extension{ARB,texture_rg} + * @requires_gles30 Extension @es_extension{EXT,texture_rg} in OpenGL ES * 2.0 * @deprecated_gl Prefer to use the exactly specified version of this * format, e.g. @ref Magnum::TextureFormat::RG8 "TextureFormat::RG8". @@ -96,8 +96,8 @@ enum class TextureFormat: GLenum { /** * Red and green component, each normalized unsigned byte. - * @requires_gl30 %Extension @extension{ARB,texture_rg} - * @requires_gles30 %Extension @es_extension{EXT,texture_rg} and + * @requires_gl30 Extension @extension{ARB,texture_rg} + * @requires_gles30 Extension @es_extension{EXT,texture_rg} and * @es_extension{EXT,texture_storage} in OpenGL ES 2.0. For texture * storage only, for image specification use * @ref Magnum::TextureFormat::RG "TextureFormat::RG" instead. @@ -119,7 +119,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component normalized unsigned byte. - * @requires_gles30 %Extension @es_extension{OES,required_internalformat} + * @requires_gles30 Extension @es_extension{OES,required_internalformat} * (for image specification) or @es_extension{EXT,texture_storage} * (for texture storage) in OpenGL ES 2.0 */ @@ -140,7 +140,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component normalized unsigned byte. - * @requires_gles30 %Extension @es_extension{OES,required_internalformat} + * @requires_gles30 Extension @es_extension{OES,required_internalformat} * (for image specification) or @es_extension{EXT,texture_storage} * (for texture storage) in OpenGL ES 2.0 */ @@ -153,28 +153,28 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * Red component, normalized signed byte. - * @requires_gl31 %Extension @extension{EXT,texture_snorm} + * @requires_gl31 Extension @extension{EXT,texture_snorm} * @requires_gles30 Only unsigned formats are available in OpenGL ES 2.0. */ R8Snorm = GL_R8_SNORM, /** * Red and green component, each normalized signed byte. - * @requires_gl31 %Extension @extension{EXT,texture_snorm} + * @requires_gl31 Extension @extension{EXT,texture_snorm} * @requires_gles30 Only unsigned formats are available in OpenGL ES 2.0. */ RG8Snorm = GL_RG8_SNORM, /** * RGB, each component normalized signed byte. - * @requires_gl31 %Extension @extension{EXT,texture_snorm} + * @requires_gl31 Extension @extension{EXT,texture_snorm} * @requires_gles30 Only unsigned formats are available in OpenGL ES 2.0. */ RGB8Snorm = GL_RGB8_SNORM, /** * RGBA, each component normalized signed byte. - * @requires_gl31 %Extension @extension{EXT,texture_snorm} + * @requires_gl31 Extension @extension{EXT,texture_snorm} * @requires_gles30 Only unsigned formats are available in OpenGL ES 2.0. */ RGBA8Snorm = GL_RGBA8_SNORM, @@ -183,7 +183,7 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Red component, normalized unsigned short. - * @requires_gl30 %Extension @extension{ARB,texture_rg} + * @requires_gl30 Extension @extension{ARB,texture_rg} * @requires_gl Only byte-sized normalized formats are available in OpenGL * ES. */ @@ -191,7 +191,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each normalized unsigned short. - * @requires_gl30 %Extension @extension{ARB,texture_rg} + * @requires_gl30 Extension @extension{ARB,texture_rg} * @requires_gl Only byte-sized normalized formats are available in OpenGL * ES. */ @@ -213,7 +213,7 @@ enum class TextureFormat: GLenum { /** * Red component, normalized signed short. - * @requires_gl31 %Extension @extension{EXT,texture_snorm} + * @requires_gl31 Extension @extension{EXT,texture_snorm} * @requires_gl Only byte-sized normalized formats are available in OpenGL * ES. */ @@ -221,7 +221,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each normalized signed short. - * @requires_gl31 %Extension @extension{EXT,texture_snorm} + * @requires_gl31 Extension @extension{EXT,texture_snorm} * @requires_gl Only byte-sized normalized formats are available in OpenGL * ES. */ @@ -229,7 +229,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component normalized signed short. - * @requires_gl31 %Extension @extension{EXT,texture_snorm} + * @requires_gl31 Extension @extension{EXT,texture_snorm} * @requires_gl Only byte-sized normalized formats are available in OpenGL * ES. */ @@ -237,7 +237,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component normalized signed short. - * @requires_gl31 %Extension @extension{EXT,texture_snorm} + * @requires_gl31 Extension @extension{EXT,texture_snorm} * @requires_gl Only byte-sized normalized formats are available in OpenGL * ES. */ @@ -247,7 +247,7 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * Red component, non-normalized unsigned byte. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -255,7 +255,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each non-normalized unsigned byte. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -263,7 +263,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component non-normalized unsigned byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -271,7 +271,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component non-normalized unsigned byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -279,7 +279,7 @@ enum class TextureFormat: GLenum { /** * Red component, non-normalized signed byte. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -287,7 +287,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each non-normalized signed byte. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -295,7 +295,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component non-normalized signed byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -303,7 +303,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component non-normalized signed byte. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -311,7 +311,7 @@ enum class TextureFormat: GLenum { /** * Red component, non-normalized unsigned short. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -319,7 +319,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each non-normalized unsigned short. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -327,7 +327,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component non-normalized unsigned short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -335,7 +335,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component non-normalized unsigned short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -343,7 +343,7 @@ enum class TextureFormat: GLenum { /** * Red component, non-normalized signed short. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -351,7 +351,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each non-normalized signed short. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -359,7 +359,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component non-normalized signed short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -367,7 +367,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component non-normalized signed short. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -375,7 +375,7 @@ enum class TextureFormat: GLenum { /** * Red component, non-normalized unsigned int. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -383,7 +383,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each non-normalized unsigned int. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -391,7 +391,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component non-normalized unsigned int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -399,7 +399,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component non-normalized unsigned int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -407,7 +407,7 @@ enum class TextureFormat: GLenum { /** * Red component, non-normalized signed int. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -415,7 +415,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each non-normalized signed int. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -423,7 +423,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component non-normalized signed int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -431,7 +431,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component non-normalized signed int. - * @requires_gl30 %Extension @extension{EXT,texture_integer} + * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -439,7 +439,7 @@ enum class TextureFormat: GLenum { /** * Red component, half float. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{ARB,texture_float} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -447,7 +447,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each half float. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{ARB,texture_float} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -455,7 +455,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component half float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -463,7 +463,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component half float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -471,7 +471,7 @@ enum class TextureFormat: GLenum { /** * Red component, float. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{ARB,texture_float} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -479,7 +479,7 @@ enum class TextureFormat: GLenum { /** * Red and green component, each float. - * @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_rg} and @extension{ARB,texture_float} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -487,7 +487,7 @@ enum class TextureFormat: GLenum { /** * RGB, each component float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -495,7 +495,7 @@ enum class TextureFormat: GLenum { /** * RGBA, each component float. - * @requires_gl30 %Extension @extension{ARB,texture_float} + * @requires_gl30 Extension @extension{ARB,texture_float} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -551,7 +551,7 @@ enum class TextureFormat: GLenum { /** * RGB, normalized unsigned, red and blue component 5bit, green 6bit. - * @requires_gles30 %Extension @es_extension{OES,required_internalformat} + * @requires_gles30 Extension @es_extension{OES,required_internalformat} * (for image specification) or @es_extension{EXT,texture_storage} * (for texture storage) in OpenGL ES 2.0 */ @@ -560,7 +560,7 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES3 /** * RGB, each component normalized unsigned 10bit. - * @requires_es_extension %Extension @es_extension{EXT,texture_type_2_10_10_10_REV} + * @requires_es_extension Extension @es_extension{EXT,texture_type_2_10_10_10_REV} * and either @es_extension{OES,required_internalformat} (for image * specification) or @es_extension{EXT,texture_storage} (for texture * storage) in OpenGL ES 2.0. Included for compatibility reasons only, @@ -585,7 +585,7 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * RGB, float, red and green component 11bit, blue 10bit. - * @requires_gl30 %Extension @extension{EXT,packed_float} + * @requires_gl30 Extension @extension{EXT,packed_float} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -593,7 +593,7 @@ enum class TextureFormat: GLenum { /** * RGB, unsigned with exponent, each RGB component 9bit, exponent 5bit. - * @requires_gl30 %Extension @extension{EXT,texture_shared_exponent} + * @requires_gl30 Extension @extension{EXT,texture_shared_exponent} * @requires_gles30 Use @ref Magnum::TextureFormat::RGB "TextureFormat::RGB" * in OpenGL ES 2.0 instead. */ @@ -604,7 +604,7 @@ enum class TextureFormat: GLenum { * sRGB, normalized unsigned, size implementation-dependent. Not allowed in * unemulated @ref Texture::setStorage() "*Texture::setStorage()" calls, in * that case use @ref TextureFormat::SRGB8 "TextureFormat::SRGB8" instead. - * @requires_es_extension %Extension @es_extension{EXT,sRGB} + * @requires_es_extension Extension @es_extension{EXT,sRGB} * @deprecated_gl Prefer to use the exactly specified version of this * format, i.e. @ref Magnum::TextureFormat::SRGB8 "TextureFormat::SRGB8". * @todo is this allowed in core? @@ -634,7 +634,7 @@ enum class TextureFormat: GLenum { /** * RGBA, normalized unsigned, each component 4bit. - * @requires_gles30 %Extension @es_extension{OES,required_internalformat} + * @requires_gles30 Extension @es_extension{OES,required_internalformat} * (for image specification) or @es_extension{EXT,texture_storage} * (for texture storage) in OpenGL ES 2.0 */ @@ -642,7 +642,7 @@ enum class TextureFormat: GLenum { /** * RGBA, normalized unsigned, each RGB component 5bit, alpha 1bit. - * @requires_gles30 %Extension @es_extension{OES,required_internalformat} + * @requires_gles30 Extension @es_extension{OES,required_internalformat} * (for image specification) or @es_extension{EXT,texture_storage} * (for texture storage) in OpenGL ES 2.0 */ @@ -650,7 +650,7 @@ enum class TextureFormat: GLenum { /** * RGBA, normalized unsigned, each RGB component 10bit, alpha 2bit. - * @requires_gles30 %Extension @es_extension{EXT,texture_type_2_10_10_10_REV} + * @requires_gles30 Extension @es_extension{EXT,texture_type_2_10_10_10_REV} * and either @es_extension{OES,required_internalformat} (for image * specification) or @es_extension{EXT,texture_storage} (for texture * storage) in OpenGL ES 2.0 @@ -664,7 +664,7 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * RGBA, non-normalized unsigned, each RGB component 10bit, alpha 2bit. - * @requires_gl33 %Extension @extension{ARB,texture_rgb10_a2ui} + * @requires_gl33 Extension @extension{ARB,texture_rgb10_a2ui} * @requires_gles30 Only normalized integral formats are available in * OpenGL ES 2.0. */ @@ -683,7 +683,7 @@ enum class TextureFormat: GLenum { * sRGBA, normalized unsigned, size implementation-dependent. Not allowed in * unemulated @ref Texture::setStorage() "*Texture::setStorage()" calls, in * that case use @ref TextureFormat::SRGB8Alpha8 "TextureFormat::SRGB8Alpha8" instead. - * @requires_es_extension %Extension @es_extension{EXT,sRGB} + * @requires_es_extension Extension @es_extension{EXT,sRGB} * @deprecated_gl Prefer to use the exactly specified version of this * format, i.e. @ref Magnum::TextureFormat::SRGB8Alpha8 "TextureFormat::SRGB8Alpha8". * @todo is this allowed in core? @@ -707,7 +707,7 @@ enum class TextureFormat: GLenum { /** * Compressed red channel, normalized unsigned. **Not available on * multisample textures.** - * @requires_gl30 %Extension @extension{ARB,texture_rg} + * @requires_gl30 Extension @extension{ARB,texture_rg} * @requires_gl Generic texture compression is not available in OpenGL ES. */ CompressedRed = GL_COMPRESSED_RED, @@ -715,7 +715,7 @@ enum class TextureFormat: GLenum { /** * Compressed red and green channel, normalized unsigned. **Not available * on multisample textures.** - * @requires_gl30 %Extension @extension{ARB,texture_rg} + * @requires_gl30 Extension @extension{ARB,texture_rg} * @requires_gl Generic texture compression is not available in OpenGL ES. */ CompressedRG = GL_COMPRESSED_RG, @@ -737,7 +737,7 @@ enum class TextureFormat: GLenum { /** * RGTC compressed red channel, normalized unsigned. **Not available on * multisample textures.** - * @requires_gl30 %Extension @extension{EXT,texture_compression_rgtc} + * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} * @requires_gl RGTC texture compression is not available in OpenGL ES. */ CompressedRedRgtc1 = GL_COMPRESSED_RED_RGTC1, @@ -745,7 +745,7 @@ enum class TextureFormat: GLenum { /** * RGTC compressed red and green channel, normalized unsigned. **Not * available on multisample textures.** - * @requires_gl30 %Extension @extension{EXT,texture_compression_rgtc} + * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} * @requires_gl RGTC texture compression is not available in OpenGL ES. */ CompressedRGRgtc2 = GL_COMPRESSED_RG_RGTC2, @@ -753,7 +753,7 @@ enum class TextureFormat: GLenum { /** * RGTC compressed red channel, normalized signed. **Not available on * multisample textures.** - * @requires_gl30 %Extension @extension{EXT,texture_compression_rgtc} + * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} * @requires_gl RGTC texture compression is not available in OpenGL ES. */ CompressedSignedRedRgtc1 = GL_COMPRESSED_SIGNED_RED_RGTC1, @@ -761,7 +761,7 @@ enum class TextureFormat: GLenum { /** * RGTC compressed red and green channel, normalized signed. **Not * available on multisample textures.** - * @requires_gl30 %Extension @extension{EXT,texture_compression_rgtc} + * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} * @requires_gl RGTC texture compression is not available in OpenGL ES. */ CompressedSignedRGRgtc2 = GL_COMPRESSED_SIGNED_RG_RGTC2, @@ -769,7 +769,7 @@ enum class TextureFormat: GLenum { /** * BPTC compressed RGB, unsigned float. **Not available on multisample * textures.** - * @requires_gl42 %Extension @extension{ARB,texture_compression_bptc} + * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} * @requires_gl BPTC texture compression is not available in OpenGL ES. */ CompressedRGBBptcUnsignedFloat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, @@ -777,7 +777,7 @@ enum class TextureFormat: GLenum { /** * BPTC compressed RGB, signed float. **Not available on multisample * textures.** - * @requires_gl42 %Extension @extension{ARB,texture_compression_bptc} + * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} * @requires_gl BPTC texture compression is not available in OpenGL ES. */ CompressedRGBBptcSignedFloat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, @@ -785,7 +785,7 @@ enum class TextureFormat: GLenum { /** * BPTC compressed RGBA, normalized unsigned. **Not available on * multisample textures.** - * @requires_gl42 %Extension @extension{ARB,texture_compression_bptc} + * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} * @requires_gl BPTC texture compression is not available in OpenGL ES. */ CompressedRGBABptcUnorm = GL_COMPRESSED_RGBA_BPTC_UNORM, @@ -793,7 +793,7 @@ enum class TextureFormat: GLenum { /** * BPTC compressed sRGBA, normalized unsigned. **Not available on * multisample textures.** - * @requires_gl42 %Extension @extension{ARB,texture_compression_bptc} + * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} * @requires_gl BPTC texture compression is not available in OpenGL ES. */ CompressedSRGBAlphaBptcUnorm = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, @@ -804,7 +804,7 @@ enum class TextureFormat: GLenum { * textures. Not allowed in unemulated @ref Texture::setStorage() * "*Texture::setStorage()" calls, in that case use e.g. * @ref TextureFormat::DepthComponent24 "TextureFormat::DepthComponent24" instead. - * @requires_gles30 %Extension @es_extension{OES,depth_texture} or + * @requires_gles30 Extension @es_extension{OES,depth_texture} or * @es_extension{ANGLE,depth_texture} in OpenGL ES 2.0 * @deprecated_gl Prefer to use the exactly specified version of this * format, e.g. @ref Magnum::TextureFormat::DepthComponent24 "TextureFormat::DepthComponent24". @@ -813,7 +813,7 @@ enum class TextureFormat: GLenum { /** * Depth component, 16bit. Not supported in 3D textures. - * @requires_gles30 %Extension @es_extension{OES,depth_texture} or + * @requires_gles30 Extension @es_extension{OES,depth_texture} or * @es_extension{ANGLE,depth_texture} and either * @es_extension{OES,required_internalformat} (for image * specification) or @es_extension{EXT,texture_storage} (for texture @@ -823,7 +823,7 @@ enum class TextureFormat: GLenum { /** * Depth component, 24bit. Not supported in 3D textures. - * @requires_gles30 %Extension @es_extension{OES,required_internalformat}, + * @requires_gles30 Extension @es_extension{OES,required_internalformat}, * @es_extension{OES,depth_texture} and @es_extension{OES,depth24} in * OpenGL ES 2.0 */ @@ -835,7 +835,7 @@ enum class TextureFormat: GLenum { /** * Depth component, 32bit. Not supported in 3D textures. - * @requires_es_extension %Extension @es_extension{OES,depth_texture} or + * @requires_es_extension Extension @es_extension{OES,depth_texture} or * @es_extension{ANGLE,depth_texture} and @es_extension{OES,depth32} * and @es_extension{OES,required_internalformat} (for image * specification) or @es_extension{EXT,texture_storage} (for texture @@ -850,7 +850,7 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * Depth component, 32bit float. Not supported in 3D textures. - * @requires_gl30 %Extension @extension{ARB,depth_buffer_float} + * @requires_gl30 Extension @extension{ARB,depth_buffer_float} * @requires_gles30 Only integral depth textures are available in OpenGL ES * 2.0. */ @@ -860,7 +860,7 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Stencil index, 8bit. Not supported in 3D textures. - * @requires_gl44 %Extension @extension{ARB,texture_stencil8} + * @requires_gl44 Extension @extension{ARB,texture_stencil8} * @requires_gl Only available as renderbuffer format in OpenGL ES. */ StencilIndex8 = GL_STENCIL_INDEX8, @@ -873,7 +873,7 @@ enum class TextureFormat: GLenum { * use e.g. @ref TextureFormat::Depth24Stencil8 "TextureFormat::Depth24Stencil8" * instead. * @see @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()" - * @requires_gles30 %Extension @es_extension{OES,packed_depth_stencil} or + * @requires_gles30 Extension @es_extension{OES,packed_depth_stencil} or * @es_extension{ANGLE,depth_texture} in OpenGL ES 2.0 * @deprecated_gl Prefer to use exactly specified version of this format, * e.g. @ref Magnum::TextureFormat::Depth24Stencil8 "TextureFormat::Depth24Stencil8". @@ -887,8 +887,8 @@ enum class TextureFormat: GLenum { /** * 24bit depth and 8bit stencil component. Not supported in 3D textures. * @see @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()" - * @requires_gl30 %Extension @extension{ARB,framebuffer_object} - * @requires_gles30 %Extension @es_extension{OES,packed_depth_stencil} or + * @requires_gl30 Extension @extension{ARB,framebuffer_object} + * @requires_gles30 Extension @es_extension{OES,packed_depth_stencil} or * @es_extension{ANGLE,depth_texture} and either * @es_extension{OES,required_internalformat} (for image * specification) or @es_extension{EXT,texture_storage} (for texture @@ -905,7 +905,7 @@ enum class TextureFormat: GLenum { * 32bit float depth component and 8bit stencil component. Not supported in * 3D textures. * @see @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()" - * @requires_gl30 %Extension @extension{ARB,depth_buffer_float} + * @requires_gl30 Extension @extension{ARB,depth_buffer_float} * @requires_gles30 Only integral depth textures are available in OpenGL ES * 2.0. */ diff --git a/src/Magnum/TextureTools/Atlas.cpp b/src/Magnum/TextureTools/Atlas.cpp index b0b2fa934..da91dce6a 100644 --- a/src/Magnum/TextureTools/Atlas.cpp +++ b/src/Magnum/TextureTools/Atlas.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/TextureTools/Atlas.h b/src/Magnum/TextureTools/Atlas.h index 57ac04e9d..a1c409b8f 100644 --- a/src/Magnum/TextureTools/Atlas.h +++ b/src/Magnum/TextureTools/Atlas.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,7 +33,7 @@ #include "Magnum/Magnum.h" #include "Magnum/Math/Vector2.h" -#include "Magnum/TextureTools/magnumTextureToolsVisibility.h" +#include "Magnum/TextureTools/visibility.h" namespace Magnum { namespace TextureTools { diff --git a/src/Magnum/TextureTools/CMakeLists.txt b/src/Magnum/TextureTools/CMakeLists.txt index 8621c2a63..6530aa88e 100644 --- a/src/Magnum/TextureTools/CMakeLists.txt +++ b/src/Magnum/TextureTools/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -34,20 +34,21 @@ set(MagnumTextureTools_HEADERS Atlas.h DistanceField.h - magnumTextureToolsVisibility.h) + visibility.h) if(BUILD_STATIC) - set(MagnumTextureTools_HEADERS ${MagnumTextureTools_HEADERS} magnumTextureToolsResourceImport.hpp) + list(APPEND MagnumTextureTools_HEADERS resourceImport.hpp) endif() +# TextureTools library add_library(MagnumTextureTools ${SHARED_OR_STATIC} ${MagnumTextureTools_SRCS} ${MagnumTextureTools_HEADERS}) set_target_properties(MagnumTextureTools PROPERTIES DEBUG_POSTFIX "-d") if(BUILD_STATIC_PIC) - # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(MagnumTextureTools PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") + set_target_properties(MagnumTextureTools PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() + target_link_libraries(MagnumTextureTools Magnum) if(WITH_DISTANCEFIELDCONVERTER) diff --git a/src/Magnum/TextureTools/DistanceField.cpp b/src/Magnum/TextureTools/DistanceField.cpp index 7fbd18dc9..e989c167a 100644 --- a/src/Magnum/TextureTools/DistanceField.cpp +++ b/src/Magnum/TextureTools/DistanceField.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -152,7 +152,7 @@ void distanceField(Texture2D& input, Texture2D& output, const Range2Di& rectangl Framebuffer framebuffer(rectangle); framebuffer.attachTexture(Framebuffer::ColorAttachment(0), output, 0); - framebuffer.bind(FramebufferTarget::Draw); + framebuffer.bind(); framebuffer.clear(FramebufferClear::Color); const Framebuffer::Status status = framebuffer.checkStatus(FramebufferTarget::Draw); diff --git a/src/Magnum/TextureTools/DistanceField.h b/src/Magnum/TextureTools/DistanceField.h index 342ecb092..2df3fd9ea 100644 --- a/src/Magnum/TextureTools/DistanceField.h +++ b/src/Magnum/TextureTools/DistanceField.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,7 +34,7 @@ #endif #include "Magnum/Magnum.h" -#include "Magnum/TextureTools/magnumTextureToolsVisibility.h" +#include "Magnum/TextureTools/visibility.h" namespace Magnum { namespace TextureTools { diff --git a/src/Magnum/TextureTools/DistanceFieldShader.frag b/src/Magnum/TextureTools/DistanceFieldShader.frag index 1224b7f72..cd305a041 100644 --- a/src/Magnum/TextureTools/DistanceFieldShader.frag +++ b/src/Magnum/TextureTools/DistanceFieldShader.frag @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/TextureTools/DistanceFieldShader.vert b/src/Magnum/TextureTools/DistanceFieldShader.vert index 49aa1ab3b..bb8637604 100644 --- a/src/Magnum/TextureTools/DistanceFieldShader.vert +++ b/src/Magnum/TextureTools/DistanceFieldShader.vert @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/TextureTools/Test/AtlasTest.cpp b/src/Magnum/TextureTools/Test/AtlasTest.cpp index 684b85a12..3a1711431 100644 --- a/src/Magnum/TextureTools/Test/AtlasTest.cpp +++ b/src/Magnum/TextureTools/Test/AtlasTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,14 +31,13 @@ namespace Magnum { namespace TextureTools { namespace Test { -class AtlasTest: public TestSuite::Tester { - public: - explicit AtlasTest(); +struct AtlasTest: TestSuite::Tester { + explicit AtlasTest(); - void create(); - void createPadding(); - void createEmpty(); - void createTooSmall(); + void create(); + void createPadding(); + void createEmpty(); + void createTooSmall(); }; AtlasTest::AtlasTest() { diff --git a/src/Magnum/TextureTools/Test/CMakeLists.txt b/src/Magnum/TextureTools/Test/CMakeLists.txt index beebf24af..1c42d070d 100644 --- a/src/Magnum/TextureTools/Test/CMakeLists.txt +++ b/src/Magnum/TextureTools/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/TextureTools/distancefieldconverter.cpp b/src/Magnum/TextureTools/distancefieldconverter.cpp index 703e2ed3d..3c2ed6971 100644 --- a/src/Magnum/TextureTools/distancefieldconverter.cpp +++ b/src/Magnum/TextureTools/distancefieldconverter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -53,7 +53,7 @@ namespace Magnum { /** @page magnum-distancefieldconverter Distance Field conversion utility -@brief Converts black&white image to distance field representation +@brief Converts red channel of an image to distance field representation @section magnum-distancefieldconverter-usage Usage @@ -67,10 +67,13 @@ Arguments: - `--importer IMPORTER` -- image importer plugin (default: @ref Trade::TgaImporter "TgaImporter") - `--converter CONVERTER` -- image converter plugin (default: @ref Trade::TgaImageConverter "TgaImageConverter") - `--plugin-dir DIR` -- base plugin dir (defaults to plugin directory in - %Magnum install location) + Magnum install location) - `--output-size "X Y"` -- size of output image - `--radius N` -- distance field computation radius +Images with @ref ColorFormat::Red, @ref ColorFormat::RGB or @ref ColorFormat::RGBA +are accepted on input. + The resulting image can be then used with @ref Shaders::DistanceFieldVector shader. See also @ref TextureTools::distanceField() for more information about the algorithm and parameters. @@ -105,7 +108,7 @@ DistanceFieldConverter::DistanceFieldConverter(const Arguments& arguments): Plat .addOption("plugin-dir", MAGNUM_PLUGINS_DIR).setHelpKey("plugin-dir", "DIR").setHelp("plugin-dir", "base plugin dir") .addNamedArgument("output-size").setHelpKey("output-size", "\"X Y\"").setHelp("output-size", "size of output image") .addNamedArgument("radius").setHelpKey("radius", "N").setHelp("radius", "distance field computation radius") - .setHelp("Converts black&white image to distance field representation.") + .setHelp("Converts red channel of an image to distance field representation.") .parse(arguments.argc, arguments.argv); createContext(); @@ -131,7 +134,12 @@ int DistanceFieldConverter::exec() { return 1; } - if(image->format() != ColorFormat::Red) { + /* Decide about internal format */ + TextureFormat internalFormat; + if(image->format() == ColorFormat::Red) internalFormat = TextureFormat::R8; + else if(image->format() == ColorFormat::RGB) internalFormat = TextureFormat::RGB8; + else if(image->format() == ColorFormat::RGBA) internalFormat = TextureFormat::RGBA8; + else { Error() << "Unsupported image format" << image->format(); return 1; } @@ -141,7 +149,8 @@ int DistanceFieldConverter::exec() { input.setMinificationFilter(Sampler::Filter::Linear) .setMagnificationFilter(Sampler::Filter::Linear) .setWrapping(Sampler::Wrapping::ClampToEdge) - .setImage(0, TextureFormat::R8, *image); + .setStorage(1, internalFormat, image->size()) + .setSubImage(0, {}, *image); /* Output texture */ Texture2D output; diff --git a/src/Magnum/TextureTools/distancefieldconverterConfigure.h.cmake b/src/Magnum/TextureTools/distancefieldconverterConfigure.h.cmake index 5fc249d4e..1464161ef 100644 --- a/src/Magnum/TextureTools/distancefieldconverterConfigure.h.cmake +++ b/src/Magnum/TextureTools/distancefieldconverterConfigure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/TextureTools/magnumTextureToolsResourceImport.hpp b/src/Magnum/TextureTools/resourceImport.hpp similarity index 86% rename from src/Magnum/TextureTools/magnumTextureToolsResourceImport.hpp rename to src/Magnum/TextureTools/resourceImport.hpp index 58d60eacb..0464b6cc2 100644 --- a/src/Magnum/TextureTools/magnumTextureToolsResourceImport.hpp +++ b/src/Magnum/TextureTools/resourceImport.hpp @@ -1,9 +1,9 @@ -#ifndef Magnum_TextureTools_magnumTextureToolsResourceImport_hpp -#define Magnum_TextureTools_magnumTextureToolsResourceImport_hpp +#ifndef Magnum_TextureTools_resourceImport_hpp +#define Magnum_TextureTools_resourceImport_hpp /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -25,7 +25,7 @@ DEALINGS IN THE SOFTWARE. */ -#include "Magnum/magnumConfigure.h" +#include "Magnum/configure.h" #ifdef MAGNUM_BUILD_STATIC #include @@ -35,6 +35,8 @@ static int magnumTextureToolsResourceImport() { CORRADE_RESOURCE_INITIALIZE(MagnumTextureTools_RCS) return 0; } CORRADE_AUTOMATIC_INITIALIZER(magnumTextureToolsResourceImport) +#else +#error this header is available only in static build #endif #endif diff --git a/src/Magnum/TextureTools/magnumTextureToolsVisibility.h b/src/Magnum/TextureTools/visibility.h similarity index 90% rename from src/Magnum/TextureTools/magnumTextureToolsVisibility.h rename to src/Magnum/TextureTools/visibility.h index 3d329a101..8d9aec05a 100644 --- a/src/Magnum/TextureTools/magnumTextureToolsVisibility.h +++ b/src/Magnum/TextureTools/visibility.h @@ -1,9 +1,9 @@ -#ifndef Magnum_TextureTools_magnumTextureToolsVisibility_h -#define Magnum_TextureTools_magnumTextureToolsVisibility_h +#ifndef Magnum_TextureTools_visibility_h +#define Magnum_TextureTools_visibility_h /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/TimeQuery.h b/src/Magnum/TimeQuery.h index 397a71e8d..b6aa194fd 100644 --- a/src/Magnum/TimeQuery.h +++ b/src/Magnum/TimeQuery.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -31,6 +31,10 @@ #include "Magnum/AbstractQuery.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif + namespace Magnum { /** @@ -62,8 +66,8 @@ UnsignedInt timeElapsed1 = tmp-q1.result(); UnsignedInt timeElapsed2 = q3.result()-tmp; @endcode Using the latter results in fewer OpenGL calls when doing more measures. -@requires_gl33 %Extension @extension{ARB,timer_query} -@requires_es_extension %Extension @es_extension{EXT,disjoint_timer_query} +@requires_gl33 Extension @extension{ARB,timer_query} +@requires_es_extension Extension @es_extension{EXT,disjoint_timer_query} @see @ref PrimitiveQuery, @ref SampleQuery @todo timestamp with glGet + example usage diff --git a/src/Magnum/Timeline.cpp b/src/Magnum/Timeline.cpp index 24947a894..3d5df8646 100644 --- a/src/Magnum/Timeline.cpp +++ b/src/Magnum/Timeline.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Timeline.h b/src/Magnum/Timeline.h index 94de7e176..a74fa7c90 100644 --- a/src/Magnum/Timeline.h +++ b/src/Magnum/Timeline.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,7 +38,7 @@ namespace Magnum { /** -@brief %Timeline +@brief Timeline Keeps track of time delta between frames and allows FPS limiting. Can be used as source for animation speed computations. @@ -100,8 +100,12 @@ class MAGNUM_EXPORT Timeline { * @brief Set minimal frame time * @return Reference to self (for method chaining) * - * Default value is 0. - * @see @ref nextFrame() + * Default value is `0.0f`. Cannot be used on some platforms where + * blocking the main loop is not allowed (such as + * @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten"). Prefer to use VSync + * where possible. + * @see @ref nextFrame(), + * @ref Platform::Sdl2Application::setSwapInterval() "Platform::*Application::setSwapInterval()" */ Timeline& setMinimalFrameTime(Float seconds) { _minimalFrameTime = seconds; diff --git a/src/Magnum/Trade/AbstractImageConverter.cpp b/src/Magnum/Trade/AbstractImageConverter.cpp index 42323169f..1bb741b14 100644 --- a/src/Magnum/Trade/AbstractImageConverter.cpp +++ b/src/Magnum/Trade/AbstractImageConverter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -46,7 +46,7 @@ Image2D* AbstractImageConverter::doExportToImage(const ImageReference2D&) const CORRADE_ASSERT(false, "Trade::AbstractImageConverter::exportToImage(): feature advertised but not implemented", nullptr); } -Containers::Array AbstractImageConverter::exportToData(const ImageReference2D& image) const { +Containers::Array AbstractImageConverter::exportToData(const ImageReference2D& image) const { #ifndef CORRADE_GCC45_COMPATIBILITY CORRADE_ASSERT(features() & Feature::ConvertData, "Trade::AbstractImageConverter::exportToData(): feature not supported", nullptr); @@ -58,7 +58,7 @@ Containers::Array AbstractImageConverter::exportToData(const Imag return doExportToData(image); } -Containers::Array AbstractImageConverter::doExportToData(const ImageReference2D&) const { +Containers::Array AbstractImageConverter::doExportToData(const ImageReference2D&) const { #ifndef CORRADE_GCC45_COMPATIBILITY CORRADE_ASSERT(false, "Trade::AbstractImageConverter::exportToData(): feature advertised but not implemented", nullptr); #else diff --git a/src/Magnum/Trade/AbstractImageConverter.h b/src/Magnum/Trade/AbstractImageConverter.h index cb855ad0d..4015ef954 100644 --- a/src/Magnum/Trade/AbstractImageConverter.h +++ b/src/Magnum/Trade/AbstractImageConverter.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -107,7 +107,7 @@ class MAGNUM_EXPORT AbstractImageConverter: public PluginManager::AbstractPlugin * data on success, zero-sized array otherwise. * @see @ref features(), @ref exportToImage(), @ref exportToFile() */ - Containers::Array exportToData(const ImageReference2D& image) const; + Containers::Array exportToData(const ImageReference2D& image) const; /** * @brief Export image to file @@ -129,7 +129,7 @@ class MAGNUM_EXPORT AbstractImageConverter: public PluginManager::AbstractPlugin virtual Image2D* doExportToImage(const ImageReference2D& image) const; /** @brief Implementation of @ref exportToData() */ - virtual Containers::Array doExportToData(const ImageReference2D& image) const; + virtual Containers::Array doExportToData(const ImageReference2D& image) const; /** * @brief Implementation of @ref exportToFile() diff --git a/src/Magnum/Trade/AbstractImporter.cpp b/src/Magnum/Trade/AbstractImporter.cpp index b797aecf9..fb347f53f 100644 --- a/src/Magnum/Trade/AbstractImporter.cpp +++ b/src/Magnum/Trade/AbstractImporter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -49,7 +49,7 @@ AbstractImporter::AbstractImporter(PluginManager::Manager& man AbstractImporter::AbstractImporter(PluginManager::AbstractManager& manager, std::string plugin): PluginManager::AbstractManagingPlugin(manager, std::move(plugin)) {} -bool AbstractImporter::openData(Containers::ArrayReference data) { +bool AbstractImporter::openData(Containers::ArrayReference data) { CORRADE_ASSERT(features() & Feature::OpenData, "Trade::AbstractImporter::openData(): feature not supported", nullptr); @@ -58,7 +58,7 @@ bool AbstractImporter::openData(Containers::ArrayReference return isOpened(); } -void AbstractImporter::doOpenData(Containers::ArrayReference) { +void AbstractImporter::doOpenData(Containers::ArrayReference) { CORRADE_ASSERT(false, "Trade::AbstractImporter::openData(): feature advertised but not implemented", ); } diff --git a/src/Magnum/Trade/AbstractImporter.h b/src/Magnum/Trade/AbstractImporter.h index 348dde22f..acc2d8404 100644 --- a/src/Magnum/Trade/AbstractImporter.h +++ b/src/Magnum/Trade/AbstractImporter.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -116,7 +116,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug * `true` on success, `false` otherwise. * @see @ref features(), @ref openFile() */ - bool openData(Containers::ArrayReference data); + bool openData(Containers::ArrayReference data); /** * @brief Open file @@ -145,11 +145,11 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug */ Int defaultScene(); - /** @brief %Scene count */ + /** @brief Scene count */ UnsignedInt sceneCount() const; /** - * @brief %Scene ID for given name + * @brief Scene ID for given name * * If no scene for given name exists, returns `-1`. * @see @ref sceneName() @@ -157,26 +157,26 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug Int sceneForName(const std::string& name); /** - * @brief %Scene name - * @param id %Scene ID, from range [0, @ref sceneCount()). + * @brief Scene name + * @param id Scene ID, from range [0, @ref sceneCount()). * * @see @ref sceneForName() */ std::string sceneName(UnsignedInt id); /** - * @brief %Scene - * @param id %Scene ID, from range [0, @ref sceneCount()). + * @brief Scene + * @param id Scene ID, from range [0, @ref sceneCount()). * * Returns given scene or `std::nullopt` if import failed. */ std::optional scene(UnsignedInt id); - /** @brief %Light count */ + /** @brief Light count */ UnsignedInt lightCount() const; /** - * @brief %Light ID for given name + * @brief Light ID for given name * * If no light for given name exists, returns `-1`. * @see @ref lightName() @@ -184,16 +184,16 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug Int lightForName(const std::string& name); /** - * @brief %Light name - * @param id %Light ID, from range [0, @ref lightCount()). + * @brief Light name + * @param id Light ID, from range [0, @ref lightCount()). * * @see @ref lightForName() */ std::string lightName(UnsignedInt id); /** - * @brief %Light - * @param id %Light ID, from range [0, @ref lightCount()). + * @brief Light + * @param id Light ID, from range [0, @ref lightCount()). * * Returns given light or `std::nullopt` if importing failed. */ @@ -293,7 +293,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief Two-dimensional mesh name - * @param id %Mesh ID, from range [0, @ref mesh2DCount()). + * @param id Mesh ID, from range [0, @ref mesh2DCount()). * * @see @ref mesh2DForName() */ @@ -301,7 +301,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief Two-dimensional mesh - * @param id %Mesh ID, from range [0, @ref mesh2DCount()). + * @param id Mesh ID, from range [0, @ref mesh2DCount()). * * Returns given mesh or `std::nullopt` if importing failed. */ @@ -320,7 +320,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief Three-dimensional mesh name - * @param id %Mesh ID, from range [0, @ref mesh3DCount()). + * @param id Mesh ID, from range [0, @ref mesh3DCount()). * * @see @ref mesh3DForName() */ @@ -328,7 +328,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief Three-dimensional mesh - * @param id %Mesh ID, from range [0, @ref mesh3DCount()). + * @param id Mesh ID, from range [0, @ref mesh3DCount()). * * Returns given mesh or `std::nullopt` if importing failed. */ @@ -361,11 +361,11 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug */ std::unique_ptr material(UnsignedInt id); - /** @brief %Texture count */ + /** @brief Texture count */ UnsignedInt textureCount() const; /** - * @brief %Texture ID for given name + * @brief Texture ID for given name * * If no texture for given name exists, returns `-1`. * @see @ref textureName() @@ -373,16 +373,16 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug Int textureForName(const std::string& name); /** - * @brief %Texture name - * @param id %Texture ID, from range [0, @ref textureCount()). + * @brief Texture name + * @param id Texture ID, from range [0, @ref textureCount()). * * @see @ref textureForName() */ std::string textureName(UnsignedInt id); /** - * @brief %Texture - * @param id %Texture ID, from range [0, @ref textureCount()). + * @brief Texture + * @param id Texture ID, from range [0, @ref textureCount()). * * Returns given texture or `std::nullopt` if importing failed. */ @@ -401,7 +401,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief One-dimensional image name - * @param id %Image ID, from range [0, @ref image1DCount()). + * @param id Image ID, from range [0, @ref image1DCount()). * * @see @ref image1DForName() */ @@ -409,7 +409,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief One-dimensional image - * @param id %Image ID, from range [0, @ref image1DCount()). + * @param id Image ID, from range [0, @ref image1DCount()). * * Returns given image or `std::nullopt` if importing failed. */ @@ -428,7 +428,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief Two-dimensional image name - * @param id %Image ID, from range [0, @ref image2DCount()). + * @param id Image ID, from range [0, @ref image2DCount()). * * @see @ref image2DForName() */ @@ -436,7 +436,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief Two-dimensional image - * @param id %Image ID, from range [0, @ref image2DCount()). + * @param id Image ID, from range [0, @ref image2DCount()). * * Returns given image or `std::nullopt` if importing failed. */ @@ -455,7 +455,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief Three-dimensional image name - * @param id %Image ID, from range [0, @ref image3DCount()). + * @param id Image ID, from range [0, @ref image3DCount()). * * @see @ref image3DForName() */ @@ -463,7 +463,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /** * @brief Three-dimensional image - * @param id %Image ID, from range [0, @ref image3DCount()). + * @param id Image ID, from range [0, @ref image3DCount()). * * Returns given image or `std::nullopt` if importing failed. */ @@ -471,6 +471,17 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug /*@}*/ + protected: + /** + * @brief Implementation for @ref openFile() + * + * If @ref Feature::OpenData is supported, default implementation opens + * the file and calls @ref doOpenData() with its contents. It is + * allowed to call this function from your @ref doOpenFile() + * implementation. + */ + virtual void doOpenFile(const std::string& filename); + #ifndef DOXYGEN_GENERATING_OUTPUT private: #else @@ -483,161 +494,301 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlug virtual bool doIsOpened() const = 0; /** @brief Implementation for @ref openData() */ - virtual void doOpenData(Containers::ArrayReference data); - - /** - * @brief Implementation for @ref openFile() - * - * If @ref Feature::OpenData is supported, default implementation opens - * the file and calls @ref doOpenData() with its contents. - */ - virtual void doOpenFile(const std::string& filename); + virtual void doOpenData(Containers::ArrayReference data); /** @brief Implementation for @ref close() */ virtual void doClose() = 0; - /** @brief Implementation for @ref defaultScene() */ + /** + * @brief Implementation for @ref defaultScene() + * + * Default implementation returns `-1`. + */ virtual Int doDefaultScene(); - /** @brief Implementation for @ref sceneCount() */ + /** + * @brief Implementation for @ref sceneCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doSceneCount() const; - /** @brief Implementation for @ref sceneForName() */ + /** + * @brief Implementation for @ref sceneForName() + * + * Default implementation returns `-1`. + */ virtual Int doSceneForName(const std::string& name); - /** @brief Implementation for @ref sceneName() */ + /** + * @brief Implementation for @ref sceneName() + * + * Default implementation returns empty string. + */ virtual std::string doSceneName(UnsignedInt id); /** @brief Implementation for @ref scene() */ virtual std::optional doScene(UnsignedInt id); - /** @brief Implementation for @ref lightCount() */ + /** + * @brief Implementation for @ref lightCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doLightCount() const; - /** @brief Implementation for @ref lightForName() */ + /** + * @brief Implementation for @ref lightForName() + * + * Default implementation returns `-1`. + */ virtual Int doLightForName(const std::string& name); - /** @brief Implementation for @ref lightName() */ + /** + * @brief Implementation for @ref lightName() + * + * Default implementation returns empty string. + */ virtual std::string doLightName(UnsignedInt id); /** @brief Implementation for @ref light() */ virtual std::optional doLight(UnsignedInt id); - /** @brief Implementation for @ref cameraCount() */ + /** + * @brief Implementation for @ref cameraCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doCameraCount() const; - /** @brief Implementation for @ref cameraForName() */ + /** + * @brief Implementation for @ref cameraForName() + * + * Default implementation returns `-1`. + */ virtual Int doCameraForName(const std::string& name); - /** @brief Implementation for @ref cameraName() */ + /** + * @brief Implementation for @ref cameraName() + * + * Default implementation returns empty string. + */ virtual std::string doCameraName(UnsignedInt id); /** @brief Implementation for @ref camera() */ virtual std::optional doCamera(UnsignedInt id); - /** @brief Implementation for @ref object2DCount() */ + /** + * @brief Implementation for @ref object2DCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doObject2DCount() const; - /** @brief Implementation for @ref object2DForName() */ + /** + * @brief Implementation for @ref object2DForName() + * + * Default implementation returns `-1`. + */ virtual Int doObject2DForName(const std::string& name); - /** @brief Implementation for @ref object2DName() */ + /** + * @brief Implementation for @ref object2DName() + * + * Default implementation returns empty string. + */ virtual std::string doObject2DName(UnsignedInt id); /** @brief Implementation for @ref object2D() */ virtual std::unique_ptr doObject2D(UnsignedInt id); - /** @brief Implementation for @ref object3DCount() */ + /** + * @brief Implementation for @ref object3DCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doObject3DCount() const; - /** @brief Implementation for @ref object3DForName() */ + /** + * @brief Implementation for @ref object3DForName() + * + * Default implementation returns `-1`. + */ virtual Int doObject3DForName(const std::string& name); - /** @brief Implementation for @ref object3DName() */ + /** + * @brief Implementation for @ref object3DName() + * + * Default implementation returns empty string. + */ virtual std::string doObject3DName(UnsignedInt id); /** @brief Implementation for @ref object3D() */ virtual std::unique_ptr doObject3D(UnsignedInt id); - /** @brief Implementation for @ref mesh2DCount() */ + /** + * @brief Implementation for @ref mesh2DCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doMesh2DCount() const; - /** @brief Implementation for @ref mesh2DForName() */ + /** + * @brief Implementation for @ref mesh2DForName() + * + * Default implementation returns `-1`. + */ virtual Int doMesh2DForName(const std::string& name); - /** @brief Implementation for @ref mesh2DName() */ + /** + * @brief Implementation for @ref mesh2DName() + * + * Default implementation returns empty string. + */ virtual std::string doMesh2DName(UnsignedInt id); /** @brief Implementation for @ref mesh2D() */ virtual std::optional doMesh2D(UnsignedInt id); - /** @brief Implementation for @ref mesh3DCount() */ + /** + * @brief Implementation for @ref mesh3DCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doMesh3DCount() const; - /** @brief Implementation for @ref mesh3DForName() */ + /** + * @brief Implementation for @ref mesh3DForName() + * + * Default implementation returns `-1`. + */ virtual Int doMesh3DForName(const std::string& name); - /** @brief Implementation for @ref mesh3DName() */ + /** + * @brief Implementation for @ref mesh3DName() + * + * Default implementation returns empty string. + */ virtual std::string doMesh3DName(UnsignedInt id); /** @brief Implementation for @ref mesh3D() */ virtual std::optional doMesh3D(UnsignedInt id); - /** @brief Implementation for @ref materialCount() */ + /** + * @brief Implementation for @ref materialCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doMaterialCount() const; - /** @brief Implementation for @ref materialForName() */ + /** + * @brief Implementation for @ref materialForName() + * + * Default implementation returns `-1`. + */ virtual Int doMaterialForName(const std::string& name); - /** @brief Implementation for @ref materialName() */ + /** + * @brief Implementation for @ref materialName() + * + * Default implementation returns empty string. + */ virtual std::string doMaterialName(UnsignedInt id); /** @brief Implementation for @ref material() */ virtual std::unique_ptr doMaterial(UnsignedInt id); - /** @brief Implementation for @ref textureCount() */ + /** + * @brief Implementation for @ref textureCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doTextureCount() const; - /** @brief Implementation for @ref textureForName() */ + /** + * @brief Implementation for @ref textureForName() + * + * Default implementation returns `-1`. + */ virtual Int doTextureForName(const std::string& name); - /** @brief Implementation for @ref textureName() */ + /** + * @brief Implementation for @ref textureName() + * + * Default implementation returns empty string. + */ virtual std::string doTextureName(UnsignedInt id); /** @brief Implementation for @ref texture() */ virtual std::optional doTexture(UnsignedInt id); - /** @brief Implementation for @ref image1DCount() */ + /** + * @brief Implementation for @ref image1DCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doImage1DCount() const; - /** @brief Implementation for @ref image1DForName() */ + /** + * @brief Implementation for @ref image1DForName() + * + * Default implementation returns `-1`. + */ virtual Int doImage1DForName(const std::string& name); - /** @brief Implementation for @ref image1DName() */ + /** + * @brief Implementation for @ref image1DName() + * + * Default implementation returns empty string. + */ virtual std::string doImage1DName(UnsignedInt id); /** @brief Implementation for @ref image1D() */ virtual std::optional doImage1D(UnsignedInt id); - /** @brief Implementation for @ref image2DCount() */ + /** + * @brief Implementation for @ref image2DCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doImage2DCount() const; - /** @brief Implementation for @ref image2DForName() */ + /** + * @brief Implementation for @ref image2DForName() + * + * Default implementation returns `-1`. + */ virtual Int doImage2DForName(const std::string& name); - /** @brief Implementation for @ref image2DName() */ + /** + * @brief Implementation for @ref image2DName() + * + * Default implementation returns empty string. + */ virtual std::string doImage2DName(UnsignedInt id); /** @brief Implementation for @ref image2D() */ virtual std::optional doImage2D(UnsignedInt id); - /** @brief Implementation for @ref image3DCount() */ + /** + * @brief Implementation for @ref image3DCount() + * + * Default implementation returns `0`. + */ virtual UnsignedInt doImage3DCount() const; - /** @brief Implementation for @ref image3DForName() */ + /** + * @brief Implementation for @ref image3DForName() + * + * Default implementation returns `-1`. + */ virtual Int doImage3DForName(const std::string& name); - /** @brief Implementation for @ref image3DName() */ + /** + * @brief Implementation for @ref image3DName() + * + * Default implementation returns empty string. + */ virtual std::string doImage3DName(UnsignedInt id); /** @brief Implementation for @ref image3D() */ diff --git a/src/Magnum/Trade/AbstractMaterialData.cpp b/src/Magnum/Trade/AbstractMaterialData.cpp index 51e1e2d8a..f954f37f9 100644 --- a/src/Magnum/Trade/AbstractMaterialData.cpp +++ b/src/Magnum/Trade/AbstractMaterialData.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/AbstractMaterialData.h b/src/Magnum/Trade/AbstractMaterialData.h index 2765d4e42..a2f5b8978 100644 --- a/src/Magnum/Trade/AbstractMaterialData.h +++ b/src/Magnum/Trade/AbstractMaterialData.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/CMakeLists.txt b/src/Magnum/Trade/CMakeLists.txt index 229492815..0e20dd89c 100644 --- a/src/Magnum/Trade/CMakeLists.txt +++ b/src/Magnum/Trade/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/CameraData.h b/src/Magnum/Trade/CameraData.h index f5267bfd5..e06ff3403 100644 --- a/src/Magnum/Trade/CameraData.h +++ b/src/Magnum/Trade/CameraData.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,7 +34,7 @@ namespace Magnum { namespace Trade { /** -@brief %Camera data +@brief Camera data */ class MAGNUM_EXPORT CameraData {}; diff --git a/src/Magnum/Trade/ImageData.h b/src/Magnum/Trade/ImageData.h index 167ee6f38..20cc26d37 100644 --- a/src/Magnum/Trade/ImageData.h +++ b/src/Magnum/Trade/ImageData.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,7 +34,7 @@ namespace Magnum { namespace Trade { /** -@brief %Image data +@brief Image data Access to image data provided by @ref AbstractImporter subclasses. Interchangeable with @ref Image, @ref ImageReference or @ref BufferImage. @@ -42,19 +42,19 @@ Interchangeable with @ref Image, @ref ImageReference or @ref BufferImage. */ template class ImageData: public AbstractImage { public: - const static UnsignedInt Dimensions = dimensions; /**< @brief %Image dimension count */ + const static UnsignedInt Dimensions = dimensions; /**< @brief Image dimension count */ /** * @brief Constructor * @param format Format of pixel data * @param type Data type of pixel data - * @param size %Image size - * @param data %Image data + * @param size Image size + * @param data Image data * * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - explicit ImageData(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} + explicit ImageData(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, void* data): AbstractImage{format, type}, _size{size}, _data{reinterpret_cast(data)} {} /** @brief Copying is not allowed */ ImageData(const ImageData&) = delete; @@ -84,7 +84,7 @@ template class ImageData: public AbstractImage { /*implicit*/ operator ImageReference() const && = delete; #endif - /** @brief %Image size */ + /** @brief Image size */ typename DimensionTraits::VectorType size() const { return _size; } /** @copydoc Image::dataSize() */ @@ -97,12 +97,12 @@ template class ImageData: public AbstractImage { * * @see @ref release() */ - template T* data() { + template T* data() { return reinterpret_cast(_data); } /** @overload */ - template const T* data() const { + template const T* data() const { return reinterpret_cast(_data); } @@ -113,11 +113,11 @@ template class ImageData: public AbstractImage { * to default. Deleting the returned array is then user responsibility. * @see @ref data() */ - unsigned char* release(); + char* release(); private: Math::Vector _size; - unsigned char* _data; + char* _data; }; /** @brief One-dimensional image */ @@ -136,8 +136,9 @@ template inline ImageData::ImageData(ImageDa template inline ImageData& ImageData::operator=(ImageData&& other) noexcept { AbstractImage::operator=(std::move(other)); - std::swap(_size, other._size); - std::swap(_data, other._data); + using std::swap; + swap(_size, other._size); + swap(_data, other._data); return *this; } @@ -151,9 +152,9 @@ const return ImageReference(AbstractImage::format(), AbstractImage::type(), _size, _data); } -template inline unsigned char* ImageData::release() { +template inline char* ImageData::release() { /** @todo I need `std::exchange` NOW. */ - unsigned char* const data = _data; + char* const data = _data; _size = {}; _data = nullptr; return data; diff --git a/src/Magnum/Trade/LightData.h b/src/Magnum/Trade/LightData.h index 1220dae46..6ce97def7 100644 --- a/src/Magnum/Trade/LightData.h +++ b/src/Magnum/Trade/LightData.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -34,7 +34,7 @@ namespace Magnum { namespace Trade { /** -@brief %Light data +@brief Light data */ class MAGNUM_EXPORT LightData {}; diff --git a/src/Magnum/Trade/MeshData2D.cpp b/src/Magnum/Trade/MeshData2D.cpp index 788820839..5ea11911c 100644 --- a/src/Magnum/Trade/MeshData2D.cpp +++ b/src/Magnum/Trade/MeshData2D.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/MeshData2D.h b/src/Magnum/Trade/MeshData2D.h index 2ea7236bf..0d0c09b8e 100644 --- a/src/Magnum/Trade/MeshData2D.h +++ b/src/Magnum/Trade/MeshData2D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -113,7 +113,7 @@ class MAGNUM_EXPORT MeshData2D { /** * @brief 2D texture coordinates - * @param id %Texture coordinate array ID + * @param id Texture coordinate array ID * * @see @ref textureCoords2DArrayCount() */ diff --git a/src/Magnum/Trade/MeshData3D.cpp b/src/Magnum/Trade/MeshData3D.cpp index 3173b6ae8..4940a51e7 100644 --- a/src/Magnum/Trade/MeshData3D.cpp +++ b/src/Magnum/Trade/MeshData3D.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/MeshData3D.h b/src/Magnum/Trade/MeshData3D.h index 3ca1b65d9..0811f4f15 100644 --- a/src/Magnum/Trade/MeshData3D.h +++ b/src/Magnum/Trade/MeshData3D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -129,7 +129,7 @@ class MAGNUM_EXPORT MeshData3D { /** * @brief 2D texture coordinates - * @param id %Texture coordinate array ID + * @param id Texture coordinate array ID * * @see @ref textureCoords2DArrayCount() */ diff --git a/src/Magnum/Trade/MeshObjectData2D.cpp b/src/Magnum/Trade/MeshObjectData2D.cpp index 1ae62b65b..4ba9639b7 100644 --- a/src/Magnum/Trade/MeshObjectData2D.cpp +++ b/src/Magnum/Trade/MeshObjectData2D.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/MeshObjectData2D.h b/src/Magnum/Trade/MeshObjectData2D.h index dce39e796..44cf09471 100644 --- a/src/Magnum/Trade/MeshObjectData2D.h +++ b/src/Magnum/Trade/MeshObjectData2D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/MeshObjectData3D.cpp b/src/Magnum/Trade/MeshObjectData3D.cpp index 5da1654d9..39733da3e 100644 --- a/src/Magnum/Trade/MeshObjectData3D.cpp +++ b/src/Magnum/Trade/MeshObjectData3D.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/MeshObjectData3D.h b/src/Magnum/Trade/MeshObjectData3D.h index 020e09b68..7a2bd54cf 100644 --- a/src/Magnum/Trade/MeshObjectData3D.h +++ b/src/Magnum/Trade/MeshObjectData3D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/ObjectData2D.cpp b/src/Magnum/Trade/ObjectData2D.cpp index c1f4d3bd5..b4eeccd99 100644 --- a/src/Magnum/Trade/ObjectData2D.cpp +++ b/src/Magnum/Trade/ObjectData2D.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/ObjectData2D.h b/src/Magnum/Trade/ObjectData2D.h index 0dd7a9798..23d684b43 100644 --- a/src/Magnum/Trade/ObjectData2D.h +++ b/src/Magnum/Trade/ObjectData2D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/ObjectData3D.cpp b/src/Magnum/Trade/ObjectData3D.cpp index a81cfb2ad..5bb120fbb 100644 --- a/src/Magnum/Trade/ObjectData3D.cpp +++ b/src/Magnum/Trade/ObjectData3D.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/ObjectData3D.h b/src/Magnum/Trade/ObjectData3D.h index 61ef895cb..b41467320 100644 --- a/src/Magnum/Trade/ObjectData3D.h +++ b/src/Magnum/Trade/ObjectData3D.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/PhongMaterialData.cpp b/src/Magnum/Trade/PhongMaterialData.cpp index 5c018bf2a..ff586ad4e 100644 --- a/src/Magnum/Trade/PhongMaterialData.cpp +++ b/src/Magnum/Trade/PhongMaterialData.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/PhongMaterialData.h b/src/Magnum/Trade/PhongMaterialData.h index 0f97c2506..b6b9fbc0a 100644 --- a/src/Magnum/Trade/PhongMaterialData.h +++ b/src/Magnum/Trade/PhongMaterialData.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/SceneData.cpp b/src/Magnum/Trade/SceneData.cpp index bdbf7669f..d830cf025 100644 --- a/src/Magnum/Trade/SceneData.cpp +++ b/src/Magnum/Trade/SceneData.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/SceneData.h b/src/Magnum/Trade/SceneData.h index bfe23a10b..6c4703ba5 100644 --- a/src/Magnum/Trade/SceneData.h +++ b/src/Magnum/Trade/SceneData.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -38,7 +38,7 @@ namespace Magnum { namespace Trade { /** -@brief %Scene data +@brief Scene data */ class MAGNUM_EXPORT SceneData { public: diff --git a/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp b/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp index 67ffd361f..528557970 100644 --- a/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -52,11 +52,8 @@ void AbstractImageConverterTest::exportToFile() { private: Features doFeatures() const override { return Feature::ConvertData; } - Containers::Array doExportToData(const ImageReference2D& image) const override { - Containers::Array out(2); - out[0] = static_cast(image.size().x()); - out[1] = static_cast(image.size().y()); - return out; + Containers::Array doExportToData(const ImageReference2D& image) const override { + return Containers::Array::from(char(image.size().x()), char(image.size().y())); }; }; diff --git a/src/Magnum/Trade/Test/AbstractImporterTest.cpp b/src/Magnum/Trade/Test/AbstractImporterTest.cpp index b5b256b59..515806691 100644 --- a/src/Magnum/Trade/Test/AbstractImporterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImporterTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -54,8 +54,8 @@ void AbstractImporterTest::openFile() { bool doIsOpened() const override { return opened; } void doClose() override {} - void doOpenData(Containers::ArrayReference data) override { - opened = (data.size() == 1 && data[0] == 0xa5); + void doOpenData(Containers::ArrayReference data) override { + opened = (data.size() == 1 && data[0] == '\xa5'); } bool opened; diff --git a/src/Magnum/Trade/Test/AbstractMaterialDataTest.cpp b/src/Magnum/Trade/Test/AbstractMaterialDataTest.cpp index e550b1ad2..ae14ca6c8 100644 --- a/src/Magnum/Trade/Test/AbstractMaterialDataTest.cpp +++ b/src/Magnum/Trade/Test/AbstractMaterialDataTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/Test/CMakeLists.txt b/src/Magnum/Trade/Test/CMakeLists.txt index b612a72c0..73aca1c1b 100644 --- a/src/Magnum/Trade/Test/CMakeLists.txt +++ b/src/Magnum/Trade/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/Test/ImageDataTest.cpp b/src/Magnum/Trade/Test/ImageDataTest.cpp index a8ef8697e..5ece2ab59 100644 --- a/src/Magnum/Trade/Test/ImageDataTest.cpp +++ b/src/Magnum/Trade/Test/ImageDataTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -52,7 +52,7 @@ ImageDataTest::ImageDataTest() { } void ImageDataTest::construct() { - auto data = new unsigned char[3]; + auto data = new char[3]; Trade::ImageData2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); CORRADE_COMPARE(a.format(), ColorFormat::Red); @@ -74,11 +74,11 @@ void ImageDataTest::constructCopy() { } void ImageDataTest::constructMove() { - auto data = new unsigned char[3]; + auto data = new char[3]; Trade::ImageData2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); Trade::ImageData2D b(std::move(a)); - CORRADE_COMPARE(a.data(), static_cast(nullptr)); + CORRADE_COMPARE(a.data(), static_cast(nullptr)); CORRADE_COMPARE(a.size(), Vector2i()); CORRADE_COMPARE(b.format(), ColorFormat::Red); @@ -86,7 +86,7 @@ void ImageDataTest::constructMove() { CORRADE_COMPARE(b.size(), Vector2i(1, 3)); CORRADE_COMPARE(b.data(), data); - auto data2 = new unsigned char[3]; + auto data2 = new char[3]; Trade::ImageData2D c(ColorFormat::RGBA, ColorType::UnsignedShort, {2, 6}, data2); c = std::move(b); @@ -100,7 +100,7 @@ void ImageDataTest::constructMove() { } void ImageDataTest::toReference() { - auto data = new unsigned char[3]; + auto data = new char[3]; const Trade::ImageData2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); ImageReference2D b = a; @@ -120,12 +120,12 @@ void ImageDataTest::toReference() { } void ImageDataTest::release() { - unsigned char data[] = {'b', 'e', 'e', 'r'}; + char data[] = {'b', 'e', 'e', 'r'}; ImageData2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 4}, data); - const unsigned char* const pointer = a.release(); + const char* const pointer = a.release(); CORRADE_COMPARE(pointer, data); - CORRADE_COMPARE(a.data(), static_cast(nullptr)); + CORRADE_COMPARE(a.data(), static_cast(nullptr)); CORRADE_COMPARE(a.size(), Vector2i()); } diff --git a/src/Magnum/Trade/Test/ObjectData2DTest.cpp b/src/Magnum/Trade/Test/ObjectData2DTest.cpp index 6388b2cce..b8324ff8a 100644 --- a/src/Magnum/Trade/Test/ObjectData2DTest.cpp +++ b/src/Magnum/Trade/Test/ObjectData2DTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/Test/ObjectData3DTest.cpp b/src/Magnum/Trade/Test/ObjectData3DTest.cpp index ac48bd45f..610963bea 100644 --- a/src/Magnum/Trade/Test/ObjectData3DTest.cpp +++ b/src/Magnum/Trade/Test/ObjectData3DTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/Test/TextureDataTest.cpp b/src/Magnum/Trade/Test/TextureDataTest.cpp index 2b036989d..87c68f1e3 100644 --- a/src/Magnum/Trade/Test/TextureDataTest.cpp +++ b/src/Magnum/Trade/Test/TextureDataTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/Test/configure.h.cmake b/src/Magnum/Trade/Test/configure.h.cmake index 0ffc772a0..51b292ac3 100644 --- a/src/Magnum/Trade/Test/configure.h.cmake +++ b/src/Magnum/Trade/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/TextureData.cpp b/src/Magnum/Trade/TextureData.cpp index ae69ab885..bcfdbd39e 100644 --- a/src/Magnum/Trade/TextureData.cpp +++ b/src/Magnum/Trade/TextureData.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Trade/TextureData.h b/src/Magnum/Trade/TextureData.h index d8e0c5bde..f93baa2b0 100644 --- a/src/Magnum/Trade/TextureData.h +++ b/src/Magnum/Trade/TextureData.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -36,12 +36,12 @@ namespace Magnum { namespace Trade { /** -@brief %Texture data +@brief Texture data */ class TextureData { public: /** - * @brief %Texture type + * @brief Texture type * * @see @ref type() */ @@ -54,12 +54,12 @@ class TextureData { /** * @brief Constructor - * @param type %Texture type + * @param type Texture type * @param minificationFilter Minification filter * @param magnificationFilter Magnification filter * @param mipmapFilter Mipmap filter * @param wrapping Wrapping - * @param image %Texture image ID + * @param image Texture image ID */ TextureData(Type type, Sampler::Filter minificationFilter, Sampler::Filter magnificationFilter, Sampler::Mipmap mipmapFilter, Array3D wrapping, UnsignedInt image): _type(type), _minificationFilter(minificationFilter), _magnificationFilter(magnificationFilter), _mipmapFilter(mipmapFilter), _wrapping(wrapping), _image(image) {} @@ -75,7 +75,7 @@ class TextureData { /** @brief Move assignment */ TextureData& operator=(TextureData&&); - /** @brief %Texture type */ + /** @brief Texture type */ Type type() const { return _type; } /** @brief Minification filter */ @@ -91,7 +91,7 @@ class TextureData { Array3D wrapping() const { return _wrapping; } /** - * @brief %Image ID + * @brief Image ID * * ID of 1D, 2D or 3D image based on texture type. If type is * @ref Type::Cube the function returns first of six consecutive diff --git a/src/Magnum/Trade/Trade.h b/src/Magnum/Trade/Trade.h index d289f2510..0371ddce8 100644 --- a/src/Magnum/Trade/Trade.h +++ b/src/Magnum/Trade/Trade.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -33,6 +33,7 @@ namespace Magnum { namespace Trade { +#ifndef DOXYGEN_GENERATING_OUTPUT class AbstractImageConverter; class AbstractImporter; class AbstractMaterialData; @@ -53,6 +54,7 @@ class ObjectData3D; class PhongMaterialData; class TextureData; class SceneData; +#endif }} diff --git a/src/Magnum/TransformFeedback.cpp b/src/Magnum/TransformFeedback.cpp new file mode 100644 index 000000000..def84607c --- /dev/null +++ b/src/Magnum/TransformFeedback.cpp @@ -0,0 +1,258 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "TransformFeedback.h" + +#ifndef MAGNUM_TARGET_GLES2 +#include + +#include "Magnum/AbstractShaderProgram.h" +#include "Magnum/Buffer.h" +#include "Magnum/Context.h" +#include "Magnum/Extensions.h" +#include "Magnum/Implementation/DebugState.h" +#include "Magnum/Implementation/State.h" +#include "Magnum/Implementation/TransformFeedbackState.h" + +namespace Magnum { + +Int TransformFeedback::maxInterleavedComponents() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + return 0; + #endif + + GLint& value = Context::current()->state().transformFeedback->maxInterleavedComponents; + + if(value == 0) + glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &value); + + return value; +} + +Int TransformFeedback::maxSeparateAttributes() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + return 0; + #endif + + GLint& value = Context::current()->state().transformFeedback->maxSeparateAttributes; + + if(value == 0) + glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &value); + + return value; +} + +Int TransformFeedback::maxSeparateComponents() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + return 0; + #endif + + GLint& value = Context::current()->state().transformFeedback->maxSeparateComponents; + + if(value == 0) + glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &value); + + return value; +} + +#ifndef MAGNUM_TARGET_GLES +Int TransformFeedback::maxBuffers() { + if(!Context::current()->isExtensionSupported()) + return maxSeparateAttributes(); + + GLint& value = Context::current()->state().transformFeedback->maxBuffers; + + if(value == 0) + glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &value); + + return value; +} +#endif + +TransformFeedback::TransformFeedback() { + (this->*Context::current()->state().transformFeedback->createImplementation)(); + CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding); +} + +void TransformFeedback::createImplementationDefault() { + glGenTransformFeedbacks(1, &_id); + _created = false; +} + +#ifndef MAGNUM_TARGET_GLES +void TransformFeedback::createImplementationDSA() { + glCreateTransformFeedbacks(1, &_id); + _created = true; +} +#endif + +TransformFeedback::~TransformFeedback() { + if(!_id) return; + + /* If bound, remove itself from state */ + GLuint& binding = Context::current()->state().transformFeedback->binding; + if(binding == _id) binding = 0; + + glDeleteTransformFeedbacks(1, &_id); +} + +void TransformFeedback::bindInternal() { + GLuint& bound = Context::current()->state().transformFeedback->binding; + + /* Already bound, nothing to do */ + if(bound == _id) return; + + /* Bind the transform feedback otherwise, which will also finally create it */ + bound = _id; + _created = true; + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _id); +} + +inline void TransformFeedback::createIfNotAlready() { + if(_created) return; + + /* glGen*() does not create the object, just reserves the name. Some + commands (such as glObjectLabel()) operate with IDs directly and they + require the object to be created. Binding the transform feedback finally + creates it. Also all EXT DSA functions implicitly create it. */ + bindInternal(); + CORRADE_INTERNAL_ASSERT(_created); +} + +std::string TransformFeedback::label() { + createIfNotAlready(); + return Context::current()->state().debug->getLabelImplementation(GL_TRANSFORM_FEEDBACK, _id); +} + +TransformFeedback& TransformFeedback::setLabelInternal(const Containers::ArrayReference label) { + createIfNotAlready(); + Context::current()->state().debug->labelImplementation(GL_TRANSFORM_FEEDBACK, _id, label); + return *this; +} + +TransformFeedback& TransformFeedback::attachBuffer(const UnsignedInt index, Buffer& buffer, const GLintptr offset, const GLsizeiptr size) { + (this->*Context::current()->state().transformFeedback->attachRangeImplementation)(index, buffer, offset, size); + return *this; +} + +TransformFeedback& TransformFeedback::attachBuffer(const UnsignedInt index, Buffer& buffer) { + (this->*Context::current()->state().transformFeedback->attachBaseImplementation)(index, buffer); + return *this; +} + +void TransformFeedback::attachImplementationFallback(const GLuint index, Buffer& buffer, const GLintptr offset, const GLsizeiptr size) { + bindInternal(); + buffer.bind(Buffer::Target(GL_TRANSFORM_FEEDBACK_BUFFER), index, offset, size); +} + +#ifndef MAGNUM_TARGET_GLES +void TransformFeedback::attachImplementationDSA(const GLuint index, Buffer& buffer, const GLintptr offset, const GLsizeiptr size) { + glTransformFeedbackBufferRange(_id, index, buffer.id(), offset, size); +} +#endif + +void TransformFeedback::attachImplementationFallback(const GLuint index, Buffer& buffer) { + bindInternal(); + buffer.bind(Buffer::Target(GL_TRANSFORM_FEEDBACK_BUFFER), index); +} + +#ifndef MAGNUM_TARGET_GLES +void TransformFeedback::attachImplementationDSA(const GLuint index, Buffer& buffer) { + glTransformFeedbackBufferBase(_id, index, buffer.id()); +} +#endif + +/** @todoc const std::initializer_list makes Doxygen grumpy */ +TransformFeedback& TransformFeedback::attachBuffers(const UnsignedInt firstIndex, std::initializer_list> buffers) { + (this->*Context::current()->state().transformFeedback->attachRangesImplementation)(firstIndex, buffers); + return *this; +} + +/** @todoc const std::initializer_list makes Doxygen grumpy */ +TransformFeedback& TransformFeedback::attachBuffers(const UnsignedInt firstIndex, std::initializer_list buffers) { + (this->*Context::current()->state().transformFeedback->attachBasesImplementation)(firstIndex, buffers); + return *this; +} + +/** @todoc const std::initializer_list makes Doxygen grumpy */ +void TransformFeedback::attachImplementationFallback(const GLuint firstIndex, std::initializer_list> buffers) { + bindInternal(); + Buffer::bind(Buffer::Target(GL_TRANSFORM_FEEDBACK_BUFFER), firstIndex, buffers); +} + +#ifndef MAGNUM_TARGET_GLES +/** @todoc const Containers::ArrayReference makes Doxygen grumpy */ +void TransformFeedback::attachImplementationDSA(const GLuint firstIndex, std::initializer_list> buffers) { + for(std::size_t i = 0; i != buffers.size(); ++i) { + Buffer* buffer; + GLintptr offset; + GLsizeiptr size; + std::tie(buffer, offset, size) = *(buffers.begin() + i); + + glTransformFeedbackBufferRange(_id, firstIndex + i, buffer ? buffer->id() : 0, offset, size); + } +} +#endif + +/** @todoc const Containers::ArrayReference makes Doxygen grumpy */ +void TransformFeedback::attachImplementationFallback(const GLuint firstIndex, std::initializer_list buffers) { + bindInternal(); + Buffer::bind(Buffer::Target(GL_TRANSFORM_FEEDBACK_BUFFER), firstIndex, buffers); +} + +#ifndef MAGNUM_TARGET_GLES +/** @todoc const Containers::ArrayReference makes Doxygen grumpy */ +void TransformFeedback::attachImplementationDSA(const GLuint firstIndex, std::initializer_list buffers) { + for(std::size_t i = 0; i != buffers.size(); ++i) + glTransformFeedbackBufferBase(_id, firstIndex + i, *(buffers.begin() + i) ? (*(buffers.begin() + i))->id() : 0); +} +#endif + +void TransformFeedback::begin(AbstractShaderProgram& shader, const PrimitiveMode mode) { + shader.use(); + bindInternal(); + glBeginTransformFeedback(GLenum(mode)); +} + +void TransformFeedback::pause() { + bindInternal(); + glPauseTransformFeedback(); +} + +void TransformFeedback::resume() { + bindInternal(); + glResumeTransformFeedback(); +} + +void TransformFeedback::end() { + bindInternal(); + glEndTransformFeedback(); +} + +} +#endif diff --git a/src/Magnum/TransformFeedback.h b/src/Magnum/TransformFeedback.h new file mode 100644 index 000000000..7566be996 --- /dev/null +++ b/src/Magnum/TransformFeedback.h @@ -0,0 +1,388 @@ +#ifndef Magnum_TransformFeedback_h +#define Magnum_TransformFeedback_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Magnum/AbstractObject.h" + +#ifndef MAGNUM_TARGET_GLES2 +/** @file + * @brief Class @ref Magnum::TransformFeedback + */ +#endif + +#ifndef MAGNUM_TARGET_GLES2 +namespace Magnum { + +namespace Implementation { struct TransformFeedbackState; } + +/** +@brief Transform feedback + +## Performance optimizations + +The engine tracks currently bound transform feedback to avoid unnecessary calls +to @fn_gl{BindTransformFeedback}. Transform feedback limits and +implementation-defined values (such as @ref maxSeparateComponents()) are +cached, so repeated queries don't result in repeated @fn_gl{Get} calls. + +If extension @extension{ARB,direct_state_access} (part of OpenGL 4.5) is +available, functions @ref attachBuffer() and @ref attachBuffers() use DSA to +avoid unnecessary call to @fn_gl{BindTransformFeedback}. See their respective +documentation for more information. + +@see @ref PrimitiveQuery +@requires_gl40 Extension @extension{ARB,transform_feedback2} +@requires_gles30 Transform feedback is not available in OpenGL ES 2.0 +@todo @extension{AMD,transform_feedback3_lines_triangles}? +*/ +class MAGNUM_EXPORT TransformFeedback: public AbstractObject { + friend Implementation::TransformFeedbackState; + + public: + /** + * @brief Transform feedback primitive mode + * + * @see @ref begin() + */ + enum class PrimitiveMode: GLenum { + /** + * Points. If no geometry shader is present, allowed only in + * combination with @ref MeshPrimitive::Points mesh primitive type. + * If geometry shader is present, allowed only in combination with + * `points` output primitive type. + */ + Points = GL_POINTS, + + /** + * Lines. If no geometry shader is present, allowed only in + * combination with @ref MeshPrimitive::LineStrip, + * @ref MeshPrimitive::LineLoop, @ref MeshPrimitive::Lines, + * @ref MeshPrimitive::LineStripAdjacency and + * @ref MeshPrimitive::LinesAdjacency mesh primitive type. If + * geometry shader is present, allowed only in combination with + * `line_strip` output primitive type. + */ + Lines = GL_LINES, + + /** + * Triangles. If no geometry shader is present, allowed only in + * combination with @ref MeshPrimitive::TriangleStrip, + * @ref MeshPrimitive::TriangleFan, @ref MeshPrimitive::Triangles, + * @ref MeshPrimitive::TriangleStripAdjacency and + * @ref MeshPrimitive::TrianglesAdjacency mesh primitive type. If + * geometry shader is present, allowed only in commbination with + * `triangle_strip` output primitive type. + */ + Triangles = GL_TRIANGLES + }; + + /** + * @brief Max supported interleaved component count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If extension @extension{EXT,transform_feedback} + * (part of OpenGL 3.0) is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS} + */ + static Int maxInterleavedComponents(); + + /** + * @brief Max supported separate attribute count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If extension @extension{EXT,transform_feedback} + * (part of OpenGL 3.0) is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS} + */ + static Int maxSeparateAttributes(); + + /** + * @brief Max supported separate component count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If extension @extension{EXT,transform_feedback} + * (part of OpenGL 3.0) is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS} + */ + static Int maxSeparateComponents(); + + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Max supported buffer count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If extension @extension{ARB,transform_feedback3} + * (part of OpenGL 4.0) is not available, returns the same value as + * @ref maxSeparateAttributes(). + * @see @fn_gl{Get} with @def_gl{MAX_TRANSFORM_FEEDBACK_BUFFERS} + * @requires_gl Use @ref Magnum::TransformFeedback::maxSeparateAttributes() "maxSeparateAttributes()" + * in OpenGL ES. + */ + static Int maxBuffers(); + #endif + + /** + * @brief Constructor + * + * Creates new OpenGL transform feedback object. If + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not + * supported, the transform feedback object is created on first use. + * @see @fn_gl{CreateTransformFeedbacks}, eventually + * @fn_gl{GenTransformFeedbacks} + */ + explicit TransformFeedback(); + + /** @brief Copying is not allowed */ + TransformFeedback(const TransformFeedback&) = delete; + + /** @brief Move constructor */ + TransformFeedback(TransformFeedback&& other) noexcept; + + /** + * @brief Destructor + * + * Deletes associated OpenGL transform feedback object. + * @see @fn_gl{DeleteTransformFeedbacks} + */ + ~TransformFeedback(); + + /** @brief Copying is not allowed */ + TransformFeedback& operator=(const TransformFeedback&) = delete; + + /** @brief Move assignment */ + TransformFeedback& operator=(TransformFeedback&& other) noexcept; + + /** @brief OpenGL transform feedback ID */ + GLuint id() const { return _id; } + + /** + * @brief Buffer label + * + * The result is *not* cached, repeated queries will result in repeated + * OpenGL calls. If OpenGL 4.3 is not supported and neither + * @extension{KHR,debug} nor @extension2{EXT,debug_label} desktop or ES + * extension is available, this function returns empty string. + * @see @fn_gl{GetObjectLabel} or @fn_gl_extension2{GetObjectLabel,EXT,debug_label} + * with @def_gl{TRANSFORM_FEEDBACK} + */ + std::string label(); + + /** + * @brief Set buffer label + * @return Reference to self (for method chaining) + * + * Default is empty string. If OpenGL 4.3 is not supported and neither + * @extension{KHR,debug} nor @extension2{EXT,debug_label} desktop or ES + * extension is available, this function does nothing. + * @see @ref maxLabelLength(), @fn_gl{ObjectLabel} or + * @fn_gl_extension2{LabelObject,EXT,debug_label} with + * @def_gl{TRANSFORM_FEEDBACK} + */ + TransformFeedback& setLabel(const std::string& label) { + return setLabelInternal({label.data(), label.size()}); + } + + /** @overload */ + template TransformFeedback& setLabel(const char(&label)[size]) { + return setLabelInternal(label); + } + + /** + * @brief Attach range of buffer + * @return Reference to self (for method chaining) + * + * The @p offset parameter must be aligned to 4 bytes. If on OpenGL ES + * or @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not + * available, the transform feedback object is bound (if not already) + * and the operation is then done equivalently to + * @ref Buffer::bind(Buffer::Target, UnsignedInt, GLintptr, GLsizeiptr). + * @note This function is meant to be used only internally from + * @ref AbstractShaderProgram subclasses. See its documentation + * for more information. + * @see @ref attachBuffers(), @ref maxBuffers()/@ref maxSeparateAttributes(), + * @fn_gl{TransformFeedbackBufferRange}, eventually + * @fn_gl{BindTransformFeedback} and @fn_gl{BindBuffersRange} or + * @fn_gl{BindBufferRange} + */ + TransformFeedback& attachBuffer(UnsignedInt index, Buffer& buffer, GLintptr offset, GLsizeiptr size); + + /** + * @brief Attach buffer + * @return Reference to self (for method chaining) + * + * If on OpenGL ES or @extension{ARB,direct_state_access} (part of + * OpenGL 4.5) is not available, the transform feedback object is bound + * (if not already) and the operation is then done equivalently to + * @ref Buffer::bind(Buffer::Target, UnsignedInt). + * @note This function is meant to be used only internally from + * @ref AbstractShaderProgram subclasses. See its documentation + * for more information. + * @see @ref attachBuffers(), @ref maxBuffers()/@ref maxSeparateAttributes(), + * @fn_gl{TransformFeedbackBufferRange}, eventually + * @fn_gl{BindTransformFeedback} and @fn_gl{BindBuffersRange} or + * @fn_gl{BindBufferRange} + */ + TransformFeedback& attachBuffer(UnsignedInt index, Buffer& buffer); + + /** + * @brief Attach ranges of buffers + * @return Reference to self (for method chaining) + * + * Attches first buffer in the list to @p firstIndex, second to + * `firstIndex + 1` etc. Second parameter is offset, third is size. If + * any buffer is `nullptr`, given attachment point is detached. The + * range of indices must respect @ref maxBuffers() (@ref maxSeparateComponents() + * in OpenGL ES or if @extension{ARB,transform_feedback3} (part of + * OpenGL 4.0) is not available). The offsets must be aligned to 4 + * bytes. All the buffers must have allocated data store. If on OpenGL + * ES or @extension{ARB,direct_state_access} (part of OpenGL 4.5) is + * not available, the transform feedback object is bound (if not + * already) and the operation is then done equivalently to + * @ref Buffer::bind(Buffer::Target, UnsignedInt, std::initializer_list>). + * @note This function is meant to be used only internally from + * @ref AbstractShaderProgram subclasses. See its documentation + * for more information. + * @see @ref attachBuffer(), @fn_gl{TransformFeedbackBufferRange}, + * eventually @fn_gl{BindTransformFeedback} and + * @fn_gl{BindBuffersRange} or @fn_gl{BindBufferRange} + */ + TransformFeedback& attachBuffers(UnsignedInt firstIndex, std::initializer_list> buffers); + + /** + * @brief Attach buffers + * @return Reference to self (for method chaining) + * + * Attches first buffer in the list to @p firstIndex, second to + * `firstIndex + 1` etc. If any buffer is `nullptr`, given index is + * detached. The range of indices must respect @ref maxBuffers() + * (@ref maxSeparateComponents() in OpenGL ES or if + * @extension{ARB,transform_feedback3} (part of OpenGL 4.0) is not + * available). All the buffers must have allocated data store. If on + * OpenGL ES or @extension{ARB,direct_state_access} (part of OpenGL + * 4.5) is not available, the transform feedback object is bound (if + * not already) and the operation then is done equivalently to + * @ref Buffer::bind(Buffer::Target, UnsignedInt, std::initializer_list). + * @note This function is meant to be used only internally from + * @ref AbstractShaderProgram subclasses. See its documentation + * for more information. + * @see @ref attachBuffer(), @fn_gl{TransformFeedbackBufferBase}, + * eventually @fn_gl{BindTransformFeedback} and + * @fn_gl{BindBuffersBase} or @fn_gl{BindBufferBase} + */ + TransformFeedback& attachBuffers(UnsignedInt firstIndex, std::initializer_list buffers); + + /** + * @brief Begin transform feedback + * @param shader Shader from which to capture data + * @param mode Primitive mode + * + * When transform feedback is active, only shader given in @p shader + * and meshes with primitive type (or geometry shaders with output + * primitive type) compatible with @p mode can be used. Only one + * transform feedback object can be active at a time. + * @see @ref pause(), @ref end(), @fn_gl{BindTransformFeedback} and + * @fn_gl{BeginTransformFeedback} + */ + void begin(AbstractShaderProgram& shader, PrimitiveMode mode); + + /** + * @brief Pause transform feedback + * + * Pausing transform feedback makes it inactive, allowing to use + * different shader, or starting another transform feedback. + * @see @ref resume(), @ref end(), @fn_gl{BindTransformFeedback} and + * @fn_gl{PauseTransformFeedback} + */ + void pause(); + + /** + * @brief Resume transform feedback + * + * Resumes transform feedback so the next captured data are appended to + * already captured ones. The restrictions specified for @ref begin() + * still apply after resuming. Only one transform feedback object can + * be active at a time. + * @see @ref pause(), @ref end(), @fn_gl{BindTransformFeedback} and + * @fn_gl{ResumeTransformFeedback} + */ + void resume(); + + /** + * @brief End transform feedback + * + * Ends transform feedback so the captured data can be used. + * @see @ref begin(), @fn_gl{BindTransformFeedback} and + * @fn_gl{EndTransformFeedback} + */ + void end(); + + private: + void bindInternal(); + + void MAGNUM_LOCAL createIfNotAlready(); + + void MAGNUM_LOCAL createImplementationDefault(); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL createImplementationDSA(); + #endif + + void MAGNUM_LOCAL attachImplementationFallback(GLuint index, Buffer& buffer, GLintptr offset, GLsizeiptr size); + void MAGNUM_LOCAL attachImplementationFallback(GLuint index, Buffer& buffer); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL attachImplementationDSA(GLuint index, Buffer& buffer, GLintptr offset, GLsizeiptr size); + void MAGNUM_LOCAL attachImplementationDSA(GLuint index, Buffer& buffer); + #endif + + void MAGNUM_LOCAL attachImplementationFallback(GLuint firstIndex, std::initializer_list> buffers); + void MAGNUM_LOCAL attachImplementationFallback(GLuint firstIndex, std::initializer_list buffers); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL attachImplementationDSA(GLuint firstIndex, std::initializer_list> buffers); + void MAGNUM_LOCAL attachImplementationDSA(GLuint firstIndex, std::initializer_list buffers); + #endif + + TransformFeedback& setLabelInternal(Containers::ArrayReference label); + + GLuint _id; + bool _created; /* see createIfNotAlready() for details */ +}; + +inline TransformFeedback::TransformFeedback(TransformFeedback&& other) noexcept: _id{other._id}, _created{other._created} { + other._id = 0; +} + +inline TransformFeedback& TransformFeedback::operator=(TransformFeedback&& other) noexcept { + using std::swap; + swap(_id, other._id); + swap(_created, other._created); + return *this; +} + +} +#endif + +#endif diff --git a/src/Magnum/Types.h b/src/Magnum/Types.h index ef3de0a72..f27374ee6 100644 --- a/src/Magnum/Types.h +++ b/src/Magnum/Types.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Version.cpp b/src/Magnum/Version.cpp index b51b09c6e..c9745b14f 100644 --- a/src/Magnum/Version.cpp +++ b/src/Magnum/Version.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/Version.h b/src/Magnum/Version.h index f08786e4e..729f92135 100644 --- a/src/Magnum/Version.h +++ b/src/Magnum/Version.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/configure.h.cmake b/src/Magnum/configure.h.cmake index 75a46c114..2f7d74c0a 100644 --- a/src/Magnum/configure.h.cmake +++ b/src/Magnum/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/Magnum/visibility.h b/src/Magnum/visibility.h index d0c5aec9f..771f6ea34 100644 --- a/src/Magnum/visibility.h +++ b/src/Magnum/visibility.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumExternal/CMakeLists.txt b/src/MagnumExternal/CMakeLists.txt index d18b639e6..842b6c8d3 100644 --- a/src/MagnumExternal/CMakeLists.txt +++ b/src/MagnumExternal/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumExternal/OpenGL/CMakeLists.txt b/src/MagnumExternal/OpenGL/CMakeLists.txt index db8d74939..2a95c3225 100644 --- a/src/MagnumExternal/OpenGL/CMakeLists.txt +++ b/src/MagnumExternal/OpenGL/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumExternal/OpenGL/GL/CMakeLists.txt b/src/MagnumExternal/OpenGL/GL/CMakeLists.txt index e9976019f..9a2fed073 100644 --- a/src/MagnumExternal/OpenGL/GL/CMakeLists.txt +++ b/src/MagnumExternal/OpenGL/GL/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -27,9 +27,12 @@ add_library(MagnumFlextGLObjects OBJECT flextGL.cpp) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?Clang") - set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS} -fvisibility=hidden -DFlextGL_EXPORTS") + set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -DFlextGL_EXPORTS") else() - set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS} -DFlextGL_EXPORTS") + set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "-DFlextGL_EXPORTS") +endif() +if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) + set_target_properties(MagnumFlextGLObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() install(FILES flextGL.h DESTINATION ${MAGNUM_EXTERNAL_INCLUDE_INSTALL_DIR}/OpenGL/GL) diff --git a/src/MagnumExternal/OpenGL/GL/flextGL.cpp b/src/MagnumExternal/OpenGL/GL/flextGL.cpp index 232e52871..6185c2556 100644 --- a/src/MagnumExternal/OpenGL/GL/flextGL.cpp +++ b/src/MagnumExternal/OpenGL/GL/flextGL.cpp @@ -613,6 +613,10 @@ FLEXTGL_EXPORT void(APIENTRY *flextglGetVertexArrayIndexed64iv)(GLuint, GLuint, FLEXTGL_EXPORT void(APIENTRY *flextglCreateSamplers)(GLsizei, GLuint *) = nullptr; FLEXTGL_EXPORT void(APIENTRY *flextglCreateProgramPipelines)(GLsizei, GLuint *) = nullptr; FLEXTGL_EXPORT void(APIENTRY *flextglCreateQueries)(GLenum, GLsizei, GLuint *) = nullptr; +FLEXTGL_EXPORT void(APIENTRY *flextglGetQueryBufferObjecti64v)(GLuint, GLuint, GLenum, GLintptr) = nullptr; +FLEXTGL_EXPORT void(APIENTRY *flextglGetQueryBufferObjectiv)(GLuint, GLuint, GLenum, GLintptr) = nullptr; +FLEXTGL_EXPORT void(APIENTRY *flextglGetQueryBufferObjectui64v)(GLuint, GLuint, GLenum, GLintptr) = nullptr; +FLEXTGL_EXPORT void(APIENTRY *flextglGetQueryBufferObjectuiv)(GLuint, GLuint, GLenum, GLintptr) = nullptr; FLEXTGL_EXPORT void(APIENTRY *flextglMemoryBarrierByRegion)(GLbitfield) = nullptr; FLEXTGL_EXPORT void(APIENTRY *flextglGetTextureSubImage)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLsizei, void *) = nullptr; FLEXTGL_EXPORT void(APIENTRY *flextglGetCompressedTextureSubImage)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, void *) = nullptr; diff --git a/src/MagnumExternal/OpenGL/GL/flextGL.h b/src/MagnumExternal/OpenGL/GL/flextGL.h index a6752e6d8..13718c29d 100644 --- a/src/MagnumExternal/OpenGL/GL/flextGL.h +++ b/src/MagnumExternal/OpenGL/GL/flextGL.h @@ -1,6 +1,10 @@ #ifndef _flextgl_h_ #define _flextgl_h_ +#include + +#include "Magnum/configure.h" + /* Defensive include guards */ #if defined(__glew_h__) || defined(__GLEW_H__) @@ -36,14 +40,14 @@ void flextGLInit(); /* Function declaration macros */ -#ifdef _WIN32 +#ifndef MAGNUM_BUILD_STATIC #ifdef FlextGL_EXPORTS - #define FLEXTGL_EXPORT __declspec(dllexport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define FLEXTGL_EXPORT __declspec(dllimport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_IMPORT #endif #else - #define FLEXTGL_EXPORT __attribute__ ((visibility ("default"))) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_STATIC #endif #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) @@ -1082,6 +1086,10 @@ typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum /* GL_VERSION_4_2 */ +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 #define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 #define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 #define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 @@ -1512,6 +1520,7 @@ typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum #define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A #define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 #define GL_TEXTURE_BINDING 0x82EB +#define GL_BACK 0x0405 #define GL_NO_ERROR 0 #define GL_GUILTY_CONTEXT_RESET 0x8253 #define GL_INNOCENT_CONTEXT_RESET 0x8254 @@ -2843,6 +2852,14 @@ GLAPI FLEXTGL_EXPORT void(APIENTRY *flextglCreateProgramPipelines)(GLsizei, GLui #define glCreateProgramPipelines flextglCreateProgramPipelines GLAPI FLEXTGL_EXPORT void(APIENTRY *flextglCreateQueries)(GLenum, GLsizei, GLuint *); #define glCreateQueries flextglCreateQueries +GLAPI FLEXTGL_EXPORT void(APIENTRY *flextglGetQueryBufferObjecti64v)(GLuint, GLuint, GLenum, GLintptr); +#define glGetQueryBufferObjecti64v flextglGetQueryBufferObjecti64v +GLAPI FLEXTGL_EXPORT void(APIENTRY *flextglGetQueryBufferObjectiv)(GLuint, GLuint, GLenum, GLintptr); +#define glGetQueryBufferObjectiv flextglGetQueryBufferObjectiv +GLAPI FLEXTGL_EXPORT void(APIENTRY *flextglGetQueryBufferObjectui64v)(GLuint, GLuint, GLenum, GLintptr); +#define glGetQueryBufferObjectui64v flextglGetQueryBufferObjectui64v +GLAPI FLEXTGL_EXPORT void(APIENTRY *flextglGetQueryBufferObjectuiv)(GLuint, GLuint, GLenum, GLintptr); +#define glGetQueryBufferObjectuiv flextglGetQueryBufferObjectuiv GLAPI FLEXTGL_EXPORT void(APIENTRY *flextglMemoryBarrierByRegion)(GLbitfield); #define glMemoryBarrierByRegion flextglMemoryBarrierByRegion GLAPI FLEXTGL_EXPORT void(APIENTRY *flextglGetTextureSubImage)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLsizei, void *); diff --git a/src/MagnumExternal/OpenGL/GL/flextGL.h.template b/src/MagnumExternal/OpenGL/GL/flextGL.h.template index 0876bca4e..e0507a03d 100644 --- a/src/MagnumExternal/OpenGL/GL/flextGL.h.template +++ b/src/MagnumExternal/OpenGL/GL/flextGL.h.template @@ -2,6 +2,10 @@ #ifndef _flextgl_h_ #define _flextgl_h_ +#include + +#include "Magnum/configure.h" + /* Defensive include guards */ #if defined(__glew_h__) || defined(__GLEW_H__) @@ -37,14 +41,14 @@ void flextGLInit(); /* Function declaration macros */ -#ifdef _WIN32 +#ifndef MAGNUM_BUILD_STATIC #ifdef FlextGL_EXPORTS - #define FLEXTGL_EXPORT __declspec(dllexport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define FLEXTGL_EXPORT __declspec(dllimport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_IMPORT #endif #else - #define FLEXTGL_EXPORT __attribute__ ((visibility ("default"))) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_STATIC #endif #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) diff --git a/src/MagnumExternal/OpenGL/GL/flextGLPlatform.cpp b/src/MagnumExternal/OpenGL/GL/flextGLPlatform.cpp index c27911197..bdbdcb8bc 100644 --- a/src/MagnumExternal/OpenGL/GL/flextGLPlatform.cpp +++ b/src/MagnumExternal/OpenGL/GL/flextGLPlatform.cpp @@ -615,6 +615,10 @@ void flextGLInit() { flextglCreateSamplers = reinterpret_cast(loader.load("glCreateSamplers")); flextglCreateProgramPipelines = reinterpret_cast(loader.load("glCreateProgramPipelines")); flextglCreateQueries = reinterpret_cast(loader.load("glCreateQueries")); + flextglGetQueryBufferObjecti64v = reinterpret_cast(loader.load("glGetQueryBufferObjecti64v")); + flextglGetQueryBufferObjectiv = reinterpret_cast(loader.load("glGetQueryBufferObjectiv")); + flextglGetQueryBufferObjectui64v = reinterpret_cast(loader.load("glGetQueryBufferObjectui64v")); + flextglGetQueryBufferObjectuiv = reinterpret_cast(loader.load("glGetQueryBufferObjectuiv")); flextglMemoryBarrierByRegion = reinterpret_cast(loader.load("glMemoryBarrierByRegion")); flextglGetTextureSubImage = reinterpret_cast(loader.load("glGetTextureSubImage")); flextglGetCompressedTextureSubImage = reinterpret_cast(loader.load("glGetCompressedTextureSubImage")); diff --git a/src/MagnumExternal/OpenGL/GLES2/CMakeLists.txt b/src/MagnumExternal/OpenGL/GLES2/CMakeLists.txt index 11840c3b8..180c3bc7e 100644 --- a/src/MagnumExternal/OpenGL/GLES2/CMakeLists.txt +++ b/src/MagnumExternal/OpenGL/GLES2/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -29,9 +29,12 @@ if(NOT CORRADE_TARGET_NACL AND NOT CORRADE_TARGET_EMSCRIPTEN) add_library(MagnumFlextGLObjects OBJECT flextGL.cpp) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?Clang") - set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS} -fvisibility=hidden -DFlextGL_EXPORTS") + set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -DFlextGL_EXPORTS") else() - set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS} -DFlextGL_EXPORTS") + set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "-DFlextGL_EXPORTS") + endif() + if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) + set_target_properties(MagnumFlextGLObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() endif() diff --git a/src/MagnumExternal/OpenGL/GLES2/README.md b/src/MagnumExternal/OpenGL/GLES2/README.md index edabc8827..c7942fabf 100644 --- a/src/MagnumExternal/OpenGL/GLES2/README.md +++ b/src/MagnumExternal/OpenGL/GLES2/README.md @@ -1,7 +1,7 @@ OpenGL header and extension loader is generated using flextGL, get it at -[](https://github.com/ginkgo/flextGL). +https://github.com/ginkgo/flextGL. -See [](extensions.txt) for requested version and a list of non-core extensions. +See [extensions.txt](extensions.txt) for requested version and a list of non-core extensions. Call `flextGLgen.py` in this directory with the following arguments to generate files for generic GLES2 implementations: diff --git a/src/MagnumExternal/OpenGL/GLES2/flextGL.h b/src/MagnumExternal/OpenGL/GLES2/flextGL.h index 3c7c11b2c..6d7b3ca08 100644 --- a/src/MagnumExternal/OpenGL/GLES2/flextGL.h +++ b/src/MagnumExternal/OpenGL/GLES2/flextGL.h @@ -1,6 +1,10 @@ #ifndef _flextgl_h_ #define _flextgl_h_ +#include + +#include "Magnum/configure.h" + /* Defensive include guards */ #if defined(__gl_h_) || defined(__gl2_h_) @@ -26,14 +30,14 @@ void flextGLInit(); /* Function declaration macros */ -#ifdef _WIN32 +#ifndef MAGNUM_BUILD_STATIC #ifdef FlextGL_EXPORTS - #define FLEXTGL_EXPORT __declspec(dllexport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define FLEXTGL_EXPORT __declspec(dllimport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_IMPORT #endif #else - #define FLEXTGL_EXPORT __attribute__ ((visibility ("default"))) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_STATIC #endif #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) diff --git a/src/MagnumExternal/OpenGL/GLES2/flextGL.h.template b/src/MagnumExternal/OpenGL/GLES2/flextGL.h.template index c7632591b..c923899c4 100644 --- a/src/MagnumExternal/OpenGL/GLES2/flextGL.h.template +++ b/src/MagnumExternal/OpenGL/GLES2/flextGL.h.template @@ -2,6 +2,10 @@ #ifndef _flextgl_h_ #define _flextgl_h_ +#include + +#include "Magnum/configure.h" + /* Defensive include guards */ #if defined(__gl_h_) || defined(__gl2_h_) @@ -27,14 +31,14 @@ void flextGLInit(); /* Function declaration macros */ -#ifdef _WIN32 +#ifndef MAGNUM_BUILD_STATIC #ifdef FlextGL_EXPORTS - #define FLEXTGL_EXPORT __declspec(dllexport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define FLEXTGL_EXPORT __declspec(dllimport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_IMPORT #endif #else - #define FLEXTGL_EXPORT __attribute__ ((visibility ("default"))) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_STATIC #endif #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) diff --git a/src/MagnumExternal/OpenGL/GLES3/CMakeLists.txt b/src/MagnumExternal/OpenGL/GLES3/CMakeLists.txt index 31dec6995..0788e54e9 100644 --- a/src/MagnumExternal/OpenGL/GLES3/CMakeLists.txt +++ b/src/MagnumExternal/OpenGL/GLES3/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -27,9 +27,12 @@ add_library(MagnumFlextGLObjects OBJECT flextGL.cpp) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?Clang") - set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS} -fvisibility=hidden -DFlextGL_EXPORTS") + set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -DFlextGL_EXPORTS") else() - set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS} -DFlextGL_EXPORTS") + set_target_properties(MagnumFlextGLObjects PROPERTIES COMPILE_FLAGS "-DFlextGL_EXPORTS") +endif() +if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) + set_target_properties(MagnumFlextGLObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() install(FILES flextGL.h DESTINATION ${MAGNUM_EXTERNAL_INCLUDE_INSTALL_DIR}/OpenGL/GLES3) diff --git a/src/MagnumExternal/OpenGL/GLES3/flextGL.h b/src/MagnumExternal/OpenGL/GLES3/flextGL.h index a14c4a911..7c5b2ed59 100644 --- a/src/MagnumExternal/OpenGL/GLES3/flextGL.h +++ b/src/MagnumExternal/OpenGL/GLES3/flextGL.h @@ -1,6 +1,10 @@ #ifndef _flextgl_h_ #define _flextgl_h_ +#include + +#include "Magnum/configure.h" + /* Defensive include guards */ #if defined(__gl_h_) || defined(__gl2_h_) || defined(__gl3_h_) || defined(__gl31_h_) @@ -30,14 +34,14 @@ void flextGLInit(); /* Function declaration macros */ -#ifdef _WIN32 +#ifndef MAGNUM_BUILD_STATIC #ifdef FlextGL_EXPORTS - #define FLEXTGL_EXPORT __declspec(dllexport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define FLEXTGL_EXPORT __declspec(dllimport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_IMPORT #endif #else - #define FLEXTGL_EXPORT __attribute__ ((visibility ("default"))) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_STATIC #endif #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) diff --git a/src/MagnumExternal/OpenGL/GLES3/flextGL.h.template b/src/MagnumExternal/OpenGL/GLES3/flextGL.h.template index 42bafb2e8..3c49a3e78 100644 --- a/src/MagnumExternal/OpenGL/GLES3/flextGL.h.template +++ b/src/MagnumExternal/OpenGL/GLES3/flextGL.h.template @@ -2,6 +2,10 @@ #ifndef _flextgl_h_ #define _flextgl_h_ +#include + +#include "Magnum/configure.h" + /* Defensive include guards */ #if defined(__gl_h_) || defined(__gl2_h_) || defined(__gl3_h_) || defined(__gl31_h_) @@ -31,14 +35,14 @@ void flextGLInit(); /* Function declaration macros */ -#ifdef _WIN32 +#ifndef MAGNUM_BUILD_STATIC #ifdef FlextGL_EXPORTS - #define FLEXTGL_EXPORT __declspec(dllexport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define FLEXTGL_EXPORT __declspec(dllimport) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_IMPORT #endif #else - #define FLEXTGL_EXPORT __attribute__ ((visibility ("default"))) + #define FLEXTGL_EXPORT CORRADE_VISIBILITY_STATIC #endif #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) diff --git a/src/MagnumExternal/OpenGL/KHR/CMakeLists.txt b/src/MagnumExternal/OpenGL/KHR/CMakeLists.txt index 5e11dde0c..d4c06d3c7 100644 --- a/src/MagnumExternal/OpenGL/KHR/CMakeLists.txt +++ b/src/MagnumExternal/OpenGL/KHR/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumExternal/Optional/CMakeLists.txt b/src/MagnumExternal/Optional/CMakeLists.txt index 350f35b05..c92bd42e0 100644 --- a/src/MagnumExternal/Optional/CMakeLists.txt +++ b/src/MagnumExternal/Optional/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/CMakeLists.txt b/src/MagnumPlugins/CMakeLists.txt index 59dab5adb..c5c617fc3 100644 --- a/src/MagnumPlugins/CMakeLists.txt +++ b/src/MagnumPlugins/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -25,7 +25,7 @@ # Wrapper for creating given plugin type macro(add_plugin plugin_name debug_install_dir release_install_dir metadata_file) - if(NOT BUILD_STATIC) + if(NOT BUILD_PLUGINS_STATIC) corrade_add_plugin(${plugin_name} ${debug_install_dir} ${release_install_dir} ${metadata_file} ${ARGN}) else() corrade_add_static_plugin(${plugin_name} ${release_install_dir} ${metadata_file} ${ARGN}) diff --git a/src/MagnumPlugins/MagnumFont/CMakeLists.txt b/src/MagnumPlugins/MagnumFont/CMakeLists.txt index a6c112d60..e91405250 100644 --- a/src/MagnumPlugins/MagnumFont/CMakeLists.txt +++ b/src/MagnumPlugins/MagnumFont/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -23,21 +23,28 @@ # DEALINGS IN THE SOFTWARE. # -set(MagnumFont_SOURCES +set(MagnumFont_SRCS MagnumFont.cpp) set(MagnumFont_HEADERS MagnumFont.h) -add_library(MagnumFontObjects OBJECT ${MagnumFont_SOURCES}) -set_target_properties(MagnumFontObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +# Objects shared between plugin and test library +add_library(MagnumFontObjects OBJECT ${MagnumFont_SRCS}) +if(NOT BUILD_PLUGINS_STATIC OR BUILD_STATIC_PIC) + set_target_properties(MagnumFontObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() +# MagnumFont plugin add_plugin(MagnumFont ${MAGNUM_PLUGINS_FONT_DEBUG_INSTALL_DIR} ${MAGNUM_PLUGINS_FONT_RELEASE_INSTALL_DIR} MagnumFont.conf $ pluginRegistration.cpp) -target_link_libraries(MagnumFont Magnum MagnumText) +if(BUILD_STATIC_PIC) + set_target_properties(MagnumFont PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() +target_link_libraries(MagnumFont Magnum MagnumText) if(CORRADE_TARGET_WINDOWS) target_link_libraries(MagnumFont TgaImporter) endif() @@ -46,17 +53,6 @@ install(FILES ${MagnumFont_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL if(BUILD_GL_TESTS) add_library(MagnumMagnumFontTestLib STATIC $) - set_target_properties(MagnumMagnumFontTestLib PROPERTIES DEBUG_POSTFIX "-d") target_link_libraries(MagnumMagnumFontTestLib Magnum MagnumText MagnumTgaImporterTestLib) - - # On Windows we need to install first and then run the tests to avoid "DLL - # not found" hell, thus we need to install this too - if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING) - install(TARGETS MagnumMagnumFontTestLib - RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} - LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} - ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) - endif() - add_subdirectory(Test) endif() diff --git a/src/MagnumPlugins/MagnumFont/MagnumFont.cpp b/src/MagnumPlugins/MagnumFont/MagnumFont.cpp index 95e244b64..63032ff2b 100644 --- a/src/MagnumPlugins/MagnumFont/MagnumFont.cpp +++ b/src/MagnumPlugins/MagnumFont/MagnumFont.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -72,7 +72,7 @@ auto MagnumFont::doFeatures() const -> Features { return Feature::OpenData|Featu bool MagnumFont::doIsOpened() const { return _opened; } -std::pair MagnumFont::doOpenData(const std::vector>>& data, const Float) { +std::pair MagnumFont::doOpenData(const std::vector>>& data, const Float) { /* We need just the configuration file and image file */ if(data.size() != 2) { Error() << "Text::MagnumFont::openData(): wanted two files, got" << data.size(); @@ -80,7 +80,8 @@ std::pair MagnumFont::doOpenData(const std::vector(data[0].second.begin()), data[0].second.size())); + /* GCC 4.5 needs explicit type to avoid ambiguous call */ + std::istringstream in(std::string(data[0].second.begin(), data[0].second.size())); Utility::Configuration conf(in, Utility::Configuration::Flag::SkipComments); if(!conf.isValid() || conf.isEmpty()) { Error() << "Text::MagnumFont::openData(): cannot open file" << data[0].first; diff --git a/src/MagnumPlugins/MagnumFont/MagnumFont.h b/src/MagnumPlugins/MagnumFont/MagnumFont.h index ad7ae65d8..4ff51174c 100644 --- a/src/MagnumPlugins/MagnumFont/MagnumFont.h +++ b/src/MagnumPlugins/MagnumFont/MagnumFont.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,7 +26,7 @@ */ /** @file - * @brief Class Magnum::Text::MagnumFont + * @brief Class @ref Magnum::Text::MagnumFont */ #include "Magnum/Text/AbstractFont.h" @@ -38,10 +38,10 @@ namespace Magnum { namespace Text { @brief Simple bitmap font plugin This plugin depends on @ref Trade::TgaImporter "TgaImporter" plugin and is -built if `WITH_MAGNUMFONT` is enabled when building %Magnum. To use dynamic -plugin, you need to load `%MagnumFont` plugin from `MAGNUM_PLUGINS_FONT_DIR`. +built if `WITH_MAGNUMFONT` is enabled when building Magnum. To use dynamic +plugin, you need to load `MagnumFont` plugin from `MAGNUM_PLUGINS_FONT_DIR`. To use static plugin or use this as a dependency of another plugin, you need to -request `%MagnumFont` component of `%Magnum` package in CMake and link to +request `MagnumFont` component of `Magnum` package in CMake and link to `${MAGNUM_MAGNUMFONT_LIBRARIES}`. See @ref building, @ref cmake and @ref plugins for more information. @@ -120,7 +120,7 @@ class MagnumFont: public AbstractFont { bool doIsOpened() const override; - std::pair doOpenData(const std::vector>>& data, Float) override; + std::pair doOpenData(const std::vector>>& data, Float) override; std::pair doOpenFile(const std::string& filename, Float) override; diff --git a/src/MagnumPlugins/MagnumFont/Test/CMakeLists.txt b/src/MagnumPlugins/MagnumFont/Test/CMakeLists.txt index 544e85504..f73da3d62 100644 --- a/src/MagnumPlugins/MagnumFont/Test/CMakeLists.txt +++ b/src/MagnumPlugins/MagnumFont/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/MagnumFont/Test/MagnumFontGLTest.cpp b/src/MagnumPlugins/MagnumFont/Test/MagnumFontGLTest.cpp index b164e0810..6935f55e3 100644 --- a/src/MagnumPlugins/MagnumFont/Test/MagnumFontGLTest.cpp +++ b/src/MagnumPlugins/MagnumFont/Test/MagnumFontGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/MagnumFont/Test/configure.h.cmake b/src/MagnumPlugins/MagnumFont/Test/configure.h.cmake index e463e200c..9284dbef6 100644 --- a/src/MagnumPlugins/MagnumFont/Test/configure.h.cmake +++ b/src/MagnumPlugins/MagnumFont/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/MagnumFont/pluginRegistration.cpp b/src/MagnumPlugins/MagnumFont/pluginRegistration.cpp index a6ca7eec6..5d121821d 100644 --- a/src/MagnumPlugins/MagnumFont/pluginRegistration.cpp +++ b/src/MagnumPlugins/MagnumFont/pluginRegistration.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/MagnumFontConverter/CMakeLists.txt b/src/MagnumPlugins/MagnumFontConverter/CMakeLists.txt index d6ef7f848..af66c6084 100644 --- a/src/MagnumPlugins/MagnumFontConverter/CMakeLists.txt +++ b/src/MagnumPlugins/MagnumFontConverter/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -23,21 +23,28 @@ # DEALINGS IN THE SOFTWARE. # -set(MagnumFontConverter_SOURCES +set(MagnumFontConverter_SRCS MagnumFontConverter.cpp) set(MagnumFontConverter_HEADERS MagnumFontConverter.h) -add_library(MagnumFontConverterObjects OBJECT ${MagnumFontConverter_SOURCES}) -set_target_properties(MagnumFontConverterObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +# Objects shared between plugin and test library +add_library(MagnumFontConverterObjects OBJECT ${MagnumFontConverter_SRCS}) +if(NOT BUILD_PLUGINS_STATIC OR BUILD_STATIC_PIC) + set_target_properties(MagnumFontConverterObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() +# MagnumFontConverter plugin add_plugin(MagnumFontConverter ${MAGNUM_PLUGINS_FONTCONVERTER_DEBUG_INSTALL_DIR} ${MAGNUM_PLUGINS_FONTCONVERTER_RELEASE_INSTALL_DIR} MagnumFontConverter.conf $ pluginRegistration.cpp) -target_link_libraries(MagnumFontConverter Magnum MagnumText) +if(BUILD_STATIC_PIC) + set_target_properties(MagnumFontConverter PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() +target_link_libraries(MagnumFontConverter Magnum MagnumText) if(CORRADE_TARGET_WINDOWS) target_link_libraries(MagnumFontConverter TgaImageConverter) endif() @@ -46,17 +53,6 @@ install(FILES ${MagnumFontConverter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUD if(BUILD_GL_TESTS) add_library(MagnumMagnumFontConverterTestLib STATIC $) - set_target_properties(MagnumMagnumFontConverterTestLib PROPERTIES DEBUG_POSTFIX "-d") target_link_libraries(MagnumMagnumFontConverterTestLib Magnum MagnumText MagnumTgaImageConverterTestLib) - - # On Windows we need to install first and then run the tests to avoid "DLL - # not found" hell, thus we need to install this too - if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING) - install(TARGETS MagnumMagnumFontConverterTestLib - RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} - LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} - ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) - endif() - add_subdirectory(Test) endif() diff --git a/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp b/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp index 2708bd787..d7d79c66c 100644 --- a/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp +++ b/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -46,9 +46,9 @@ auto MagnumFontConverter::doFeatures() const -> Features { } #ifndef __MINGW32__ -std::vector>> MagnumFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const +std::vector>> MagnumFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const #else -std::vector>> MagnumFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector& characters) const +std::vector>> MagnumFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector& characters) const #endif { Utility::Configuration configuration; @@ -114,7 +114,7 @@ std::vector>> MagnumFont std::ostringstream confOut; configuration.save(confOut); std::string confStr = confOut.str(); - Containers::Array confData{confStr.size()}; + Containers::Array confData{confStr.size()}; std::copy(confStr.begin(), confStr.end(), confData.begin()); /* Save cache image */ @@ -122,10 +122,10 @@ std::vector>> MagnumFont cache.texture().image(0, image); auto tgaData = Trade::TgaImageConverter().exportToData(image); - std::vector>> out; + std::vector>> out; out.emplace_back(filename + ".conf", std::move(confData)); out.emplace_back(filename + ".tga", std::move(tgaData)); - return std::move(out); + return out; } }} diff --git a/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.h b/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.h index cb2813a84..f82583770 100644 --- a/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.h +++ b/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,7 +26,7 @@ */ /** @file - * @brief Class Magnum::Text::MagnumFontConverter + * @brief Class @ref Magnum::Text::MagnumFontConverter */ #include "Magnum/Text/AbstractFontConverter.h" @@ -42,11 +42,11 @@ Expects filename prefix, creates two files, `prefix.conf` and `prefix.tga`. See This plugin is available only on desktop OpenGL, as it uses @ref Texture::image() to read back the generated data. It depends on @ref Trade::TgaImageConverter "TgaImageConverter" plugin and is built if -`WITH_MAGNUMFONTCONVERTER` is enabled when building %Magnum. To use dynamic -plugin, you need to load `%MagnumFontConverter` plugin from +`WITH_MAGNUMFONTCONVERTER` is enabled when building Magnum. To use dynamic +plugin, you need to load `MagnumFontConverter` plugin from `MAGNUM_PLUGINS_FONTCONVERTER_DIR`. To use static plugin or use this as a -dependency of another plugin, you need to request `%MagnumFontConverter` -component of `%Magnum` package in CMake and link to +dependency of another plugin, you need to request `MagnumFontConverter` +component of `Magnum` package in CMake and link to `${MAGNUM_MAGNUMFONTCONVERTER_LIBRARIES}`. See @ref building, @ref cmake and @ref plugins for more information. */ @@ -61,9 +61,9 @@ class MagnumFontConverter: public Text::AbstractFontConverter { private: Features doFeatures() const override; #ifndef __MINGW32__ - std::vector>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const override; + std::vector>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const override; #else - std::vector>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector& characters) const override; + std::vector>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector& characters) const override; #endif }; diff --git a/src/MagnumPlugins/MagnumFontConverter/Test/CMakeLists.txt b/src/MagnumPlugins/MagnumFontConverter/Test/CMakeLists.txt index de49a126c..5cebe78fa 100644 --- a/src/MagnumPlugins/MagnumFontConverter/Test/CMakeLists.txt +++ b/src/MagnumPlugins/MagnumFontConverter/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterGLTest.cpp b/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterGLTest.cpp index 6bb4a6dab..d1c3e320b 100644 --- a/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterGLTest.cpp +++ b/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterGLTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/MagnumFontConverter/Test/configure.h.cmake b/src/MagnumPlugins/MagnumFontConverter/Test/configure.h.cmake index c8241941c..84061f8ce 100644 --- a/src/MagnumPlugins/MagnumFontConverter/Test/configure.h.cmake +++ b/src/MagnumPlugins/MagnumFontConverter/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/MagnumFontConverter/pluginRegistration.cpp b/src/MagnumPlugins/MagnumFontConverter/pluginRegistration.cpp index 912211e95..01390adf4 100644 --- a/src/MagnumPlugins/MagnumFontConverter/pluginRegistration.cpp +++ b/src/MagnumPlugins/MagnumFontConverter/pluginRegistration.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/ObjImporter/CMakeLists.txt b/src/MagnumPlugins/ObjImporter/CMakeLists.txt index b8a62f5b7..2fb9c018b 100644 --- a/src/MagnumPlugins/ObjImporter/CMakeLists.txt +++ b/src/MagnumPlugins/ObjImporter/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -23,32 +23,35 @@ # DEALINGS IN THE SOFTWARE. # -add_library(ObjImporterObjects OBJECT ObjImporter.cpp) -if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) - set_target_properties(ObjImporterObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +set(ObjImporter_SRCS + ObjImporter.cpp) + +set(ObjImporter_HEADERS + ObjImporter.h) + +# Objects shared between plugin and test library +add_library(ObjImporterObjects OBJECT + ${ObjImporter_SRCS} + ${ObjImporter_HEADERS}) +if(NOT BUILD_PLUGINS_STATIC OR BUILD_STATIC_PIC) + set_target_properties(ObjImporterObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() +# ObjImporter plugin add_plugin(ObjImporter ${MAGNUM_PLUGINS_IMPORTER_DEBUG_INSTALL_DIR} ${MAGNUM_PLUGINS_IMPORTER_RELEASE_INSTALL_DIR} ObjImporter.conf $ pluginRegistration.cpp) +if(BUILD_STATIC_PIC) + set_target_properties(ObjImporter PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() + target_link_libraries(ObjImporter Magnum MagnumMeshTools) -install(FILES ObjImporter.h DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/ObjImporter) +install(FILES ${ObjImporter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/ObjImporter) if(BUILD_TESTS) add_library(MagnumObjImporterTestLib STATIC $) - set_target_properties(MagnumObjImporterTestLib PROPERTIES DEBUG_POSTFIX "-d") target_link_libraries(MagnumObjImporterTestLib Magnum MagnumMeshTools) - - # On Windows we need to install first and then run the tests to avoid "DLL - # not found" hell, thus we need to install this too - if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING) - install(TARGETS MagnumObjImporterTestLib - RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} - LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} - ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) - endif() - add_subdirectory(Test) endif() diff --git a/src/MagnumPlugins/ObjImporter/ObjImporter.cpp b/src/MagnumPlugins/ObjImporter/ObjImporter.cpp index de3ae8d08..bdd1eb010 100644 --- a/src/MagnumPlugins/ObjImporter/ObjImporter.cpp +++ b/src/MagnumPlugins/ObjImporter/ObjImporter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -80,6 +80,10 @@ template Math::Vector extractFloatData(std::strin } if(data.size() == size+1) { + /* This should be obvious from the first if, but add this just to make + Clang Analyzer happy */ + CORRADE_INTERNAL_ASSERT(extra); + #if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) *extra = std::stof(data.back()); #else @@ -128,11 +132,11 @@ void ObjImporter::doOpenFile(const std::string& filename) { parseMeshNames(); } -void ObjImporter::doOpenData(Containers::ArrayReference data) { +void ObjImporter::doOpenData(Containers::ArrayReference data) { /* Open file in *text* mode (to avoid \r handling) */ _file.reset(new File); /* GCC 4.5 needs explicit type to avoid ambiguous call */ - _file->in.reset(new std::istringstream{std::string(reinterpret_cast(data.begin()), data.size())}); + _file->in.reset(new std::istringstream{std::string(data.begin(), data.size())}); parseMeshNames(); } diff --git a/src/MagnumPlugins/ObjImporter/ObjImporter.h b/src/MagnumPlugins/ObjImporter/ObjImporter.h index cf6931667..28fe640d6 100644 --- a/src/MagnumPlugins/ObjImporter/ObjImporter.h +++ b/src/MagnumPlugins/ObjImporter/ObjImporter.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -44,10 +44,10 @@ Supported features: Polygons (quads etc.), automatic normal generation and material properties are currently not supported. -This plugin is built if `WITH_OBJIMPORTER` is enabled when building %Magnum. To -use dynamic plugin, you need to load `%ObjImporter` plugin from +This plugin is built if `WITH_OBJIMPORTER` is enabled when building Magnum. To +use dynamic plugin, you need to load `ObjImporter` plugin from `MAGNUM_PLUGINS_IMPORTER_DIR`. To use static plugin or use this as a dependency -of another plugin, you need to request `%ObjImporter` component of `%Magnum` +of another plugin, you need to request `ObjImporter` component of `Magnum` package in CMake and link to `${MAGNUM_OBJIMPORTER_LIBRARIES}`. See @ref building, @ref cmake and @ref plugins for more information. */ @@ -67,7 +67,7 @@ class ObjImporter: public AbstractImporter { Features doFeatures() const override; bool doIsOpened() const override; - void doOpenData(Containers::ArrayReference data) override; + void doOpenData(Containers::ArrayReference data) override; void doOpenFile(const std::string& filename) override; void doClose() override; diff --git a/src/MagnumPlugins/ObjImporter/Test/CMakeLists.txt b/src/MagnumPlugins/ObjImporter/Test/CMakeLists.txt index 269fd9d4f..ecbd0e1a6 100644 --- a/src/MagnumPlugins/ObjImporter/Test/CMakeLists.txt +++ b/src/MagnumPlugins/ObjImporter/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/ObjImporter/Test/Test.cpp b/src/MagnumPlugins/ObjImporter/Test/Test.cpp index 7b728a173..5a7187c1d 100644 --- a/src/MagnumPlugins/ObjImporter/Test/Test.cpp +++ b/src/MagnumPlugins/ObjImporter/Test/Test.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/ObjImporter/Test/configure.h.cmake b/src/MagnumPlugins/ObjImporter/Test/configure.h.cmake index 484448999..c0f82e29a 100644 --- a/src/MagnumPlugins/ObjImporter/Test/configure.h.cmake +++ b/src/MagnumPlugins/ObjImporter/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/ObjImporter/pluginRegistration.cpp b/src/MagnumPlugins/ObjImporter/pluginRegistration.cpp index 4ded696b1..ba5190e6a 100644 --- a/src/MagnumPlugins/ObjImporter/pluginRegistration.cpp +++ b/src/MagnumPlugins/ObjImporter/pluginRegistration.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/TgaImageConverter/CMakeLists.txt b/src/MagnumPlugins/TgaImageConverter/CMakeLists.txt index 08f4ff875..e15dadd10 100644 --- a/src/MagnumPlugins/TgaImageConverter/CMakeLists.txt +++ b/src/MagnumPlugins/TgaImageConverter/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -23,36 +23,46 @@ # DEALINGS IN THE SOFTWARE. # +if(BUILD_PLUGINS_STATIC) + set(MAGNUM_TGAIMAGECONVERTER_BUILD_STATIC 1) +endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h) + set(TgaImageConverter_SRCS TgaImageConverter.cpp) set(TgaImageConverter_HEADERS TgaImageConverter.h) -add_library(TgaImageConverterObjects OBJECT ${TgaImageConverter_SRCS}) -set_target_properties(TgaImageConverterObjects PROPERTIES COMPILE_FLAGS "-DTgaImageConverterObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +# Objects shared between plugin and test library +add_library(TgaImageConverterObjects OBJECT + ${TgaImageConverter_SRCS} + ${TgaImageConverter_HEADERS}) +if(NOT BUILD_PLUGINS_STATIC) + set_target_properties(TgaImageConverterObjects PROPERTIES COMPILE_FLAGS "-DTgaImageConverterObjects_EXPORTS") +endif() +if(NOT BUILD_PLUGINS_STATIC OR BUILD_STATIC_PIC) + set_target_properties(TgaImageConverterObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() +# TgaImageConverter plugin add_plugin(TgaImageConverter ${MAGNUM_PLUGINS_IMAGECONVERTER_DEBUG_INSTALL_DIR} ${MAGNUM_PLUGINS_IMAGECONVERTER_RELEASE_INSTALL_DIR} TgaImageConverter.conf $ pluginRegistration.cpp) +if(BUILD_STATIC_PIC) + set_target_properties(TgaImageConverter PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() + target_link_libraries(TgaImageConverter Magnum) install(FILES ${TgaImageConverter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImageConverter) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/configure.h DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImageConverter/configure.h) if(BUILD_TESTS) - add_library(MagnumTgaImageConverterTestLib ${SHARED_OR_STATIC} $) - set_target_properties(MagnumTgaImageConverterTestLib PROPERTIES DEBUG_POSTFIX "-d") + add_library(MagnumTgaImageConverterTestLib STATIC $) target_link_libraries(MagnumTgaImageConverterTestLib Magnum) - - # On Windows we need to install first and then run the tests to avoid "DLL - # not found" hell, thus we need to install this too - if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING) - install(TARGETS MagnumTgaImageConverterTestLib - RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} - LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} - ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) - endif() - add_subdirectory(Test) endif() diff --git a/src/MagnumPlugins/TgaImageConverter/Test/CMakeLists.txt b/src/MagnumPlugins/TgaImageConverter/Test/CMakeLists.txt index 08100b92a..3a471c284 100644 --- a/src/MagnumPlugins/TgaImageConverter/Test/CMakeLists.txt +++ b/src/MagnumPlugins/TgaImageConverter/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -29,3 +29,11 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) corrade_add_test(TgaImageConverterTest TgaImageConverterTest.cpp LIBRARIES MagnumTgaImageConverterTestLib MagnumTgaImporterTestLib) +# On Win32 we need to avoid dllimporting TgaImporter and TgaImageConverterTest +# symbols, because it would search for the symbols in some DLL even when they +# were linked statically. However it apparently doesn't matter that they were +# dllexported when building the static library. EH. +if(WIN32) + set_target_properties(TgaImageConverterTest PROPERTIES COMPILE_FLAGS + "-DMAGNUM_TGAIMAGECONVERTER_BUILD_STATIC -DMAGNUM_TGAIMPORTER_BUILD_STATIC") +endif() diff --git a/src/MagnumPlugins/TgaImageConverter/Test/TgaImageConverterTest.cpp b/src/MagnumPlugins/TgaImageConverter/Test/TgaImageConverterTest.cpp index 9254b55da..60a49e1cf 100644 --- a/src/MagnumPlugins/TgaImageConverter/Test/TgaImageConverterTest.cpp +++ b/src/MagnumPlugins/TgaImageConverter/Test/TgaImageConverterTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -78,7 +78,7 @@ void TgaImageConverterTest::wrongFormat() { const auto data = TgaImageConverter().exportToData(image); CORRADE_VERIFY(!data); - CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::convertToData(): unsupported image format ColorFormat::RG\n"); + CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::exportToData(): unsupported color format ColorFormat::RG\n"); } void TgaImageConverterTest::wrongType() { @@ -89,7 +89,7 @@ void TgaImageConverterTest::wrongType() { const auto data = TgaImageConverter().exportToData(image); CORRADE_VERIFY(!data); - CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::convertToData(): unsupported image type ColorType::Float\n"); + CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::exportToData(): unsupported color type ColorType::Float\n"); } void TgaImageConverterTest::data() { @@ -107,8 +107,8 @@ void TgaImageConverterTest::data() { CORRADE_COMPARE(converted->format(), ColorFormat::RGB); #endif CORRADE_COMPARE(converted->type(), ColorType::UnsignedByte); - CORRADE_COMPARE(std::string(reinterpret_cast(converted->data()), 2*3*3), - std::string(reinterpret_cast(original.data()), 2*3*3)); + CORRADE_COMPARE((std::string{converted->data(), 2*3*3}), + (std::string{original.data(), 2*3*3})); } }}} diff --git a/src/MagnumPlugins/TgaImageConverter/Test/configure.h.cmake b/src/MagnumPlugins/TgaImageConverter/Test/configure.h.cmake index 8633b1d40..1489956ed 100644 --- a/src/MagnumPlugins/TgaImageConverter/Test/configure.h.cmake +++ b/src/MagnumPlugins/TgaImageConverter/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp index 7de4fd4be..845de9333 100644 --- a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp +++ b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -60,7 +60,7 @@ TgaImageConverter::TgaImageConverter(PluginManager::AbstractManager& manager, st auto TgaImageConverter::doFeatures() const -> Features { return Feature::ConvertData; } -Containers::Array TgaImageConverter::doExportToData(const ImageReference2D& image) const { +Containers::Array TgaImageConverter::doExportToData(const ImageReference2D& image) const { #ifndef MAGNUM_TARGET_GLES if(image.format() != ColorFormat::BGR && image.format() != ColorFormat::BGRA && @@ -71,7 +71,7 @@ Containers::Array TgaImageConverter::doExportToData(const ImageRe image.format() != ColorFormat::Red) #endif { - Error() << "Trade::TgaImageConverter::convertToData(): unsupported image format" << image.format(); + Error() << "Trade::TgaImageConverter::exportToData(): unsupported color format" << image.format(); #ifndef CORRADE_GCC45_COMPATIBILITY return nullptr; #else @@ -80,7 +80,7 @@ Containers::Array TgaImageConverter::doExportToData(const ImageRe } if(image.type() != ColorType::UnsignedByte) { - Error() << "Trade::TgaImageConverter::convertToData(): unsupported image type" << image.type(); + Error() << "Trade::TgaImageConverter::exportToData(): unsupported color type" << image.type(); #ifndef CORRADE_GCC45_COMPATIBILITY return nullptr; #else @@ -90,7 +90,7 @@ Containers::Array TgaImageConverter::doExportToData(const ImageRe /* Initialize data buffer */ const auto pixelSize = UnsignedByte(image.pixelSize()); - auto data = Containers::Array::zeroInitialized(sizeof(TgaHeader) + pixelSize*image.size().product()); + auto data = Containers::Array::zeroInitialized(sizeof(TgaHeader) + pixelSize*image.size().product()); /* Fill header */ auto header = reinterpret_cast(data.begin()); @@ -112,7 +112,7 @@ Containers::Array TgaImageConverter::doExportToData(const ImageRe } #endif - return std::move(data); + return data; } }} diff --git a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h index 20514bc9e..625abf4eb 100644 --- a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h +++ b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,13 +26,15 @@ */ /** @file - * @brief Class Magnum::Trade::TgaImageConverter + * @brief Class @ref Magnum::Trade::TgaImageConverter */ #include "Magnum/Trade/AbstractImageConverter.h" +#include "MagnumPlugins/TgaImageConverter/configure.h" + #ifndef DOXYGEN_GENERATING_OUTPUT -#ifndef MAGNUM_BUILD_STATIC +#ifndef MAGNUM_TGAIMAGECONVERTER_BUILD_STATIC #if defined(TgaImageConverter_EXPORTS) || defined(TgaImageConverterObjects_EXPORTS) #define MAGNUM_TRADE_TGAIMAGECONVERTER_EXPORT CORRADE_VISIBILITY_EXPORT #else @@ -49,14 +51,15 @@ namespace Magnum { namespace Trade { /** @brief TGA image converter plugin -Supports images with format @ref ColorFormat::BGR, @ref ColorFormat::BGRA or +Supports images with format @ref ColorFormat::BGR, @ref ColorFormat::BGRA +(@ref ColorFormat::RGB/@ref ColorFormat::RGBA on OpenGL ES) or @ref ColorFormat::Red and type @ref ColorType::UnsignedByte. This plugin is built if `WITH_TGAIMAGECONVERTER` is enabled when building -%Magnum. To use dynamic plugin, you need to load `%TgaImageConverter` plugin +Magnum. To use dynamic plugin, you need to load `TgaImageConverter` plugin from `MAGNUM_PLUGINS_IMAGECONVERTER_DIR`. To use static plugin or use this as a -dependency of another plugin, you need to request `%TgaImageConverter` -component of `%Magnum` package in CMake and link to +dependency of another plugin, you need to request `TgaImageConverter` +component of `Magnum` package in CMake and link to `${MAGNUM_TGAIMAGECONVERTER_LIBRARIES}`. See @ref building, @ref cmake and @ref plugins for more information. */ @@ -70,7 +73,7 @@ class MAGNUM_TRADE_TGAIMAGECONVERTER_EXPORT TgaImageConverter: public AbstractIm private: Features MAGNUM_TRADE_TGAIMAGECONVERTER_LOCAL doFeatures() const override; - Containers::Array MAGNUM_TRADE_TGAIMAGECONVERTER_LOCAL doExportToData(const ImageReference2D& image) const override; + Containers::Array MAGNUM_TRADE_TGAIMAGECONVERTER_LOCAL doExportToData(const ImageReference2D& image) const override; }; }} diff --git a/src/MagnumPlugins/TgaImageConverter/configure.h.cmake b/src/MagnumPlugins/TgaImageConverter/configure.h.cmake new file mode 100644 index 000000000..d0c23cf82 --- /dev/null +++ b/src/MagnumPlugins/TgaImageConverter/configure.h.cmake @@ -0,0 +1,26 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#cmakedefine MAGNUM_TGAIMAGECONVERTER_BUILD_STATIC diff --git a/src/MagnumPlugins/TgaImageConverter/pluginRegistration.cpp b/src/MagnumPlugins/TgaImageConverter/pluginRegistration.cpp index 2f70dac52..341cc233e 100644 --- a/src/MagnumPlugins/TgaImageConverter/pluginRegistration.cpp +++ b/src/MagnumPlugins/TgaImageConverter/pluginRegistration.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/TgaImporter/CMakeLists.txt b/src/MagnumPlugins/TgaImporter/CMakeLists.txt index afb01bc62..732250c03 100644 --- a/src/MagnumPlugins/TgaImporter/CMakeLists.txt +++ b/src/MagnumPlugins/TgaImporter/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -23,6 +23,13 @@ # DEALINGS IN THE SOFTWARE. # +if(BUILD_PLUGINS_STATIC) + set(MAGNUM_TGAIMPORTER_BUILD_STATIC 1) +endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h) + set(TgaImporter_SRCS TgaImporter.cpp) @@ -30,30 +37,33 @@ set(TgaImporter_HEADERS TgaHeader.h TgaImporter.h) -add_library(TgaImporterObjects OBJECT ${TgaImporter_SRCS}) -set_target_properties(TgaImporterObjects PROPERTIES COMPILE_FLAGS "-DTgaImporterObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +# Objects shared between plugin and test library +add_library(TgaImporterObjects OBJECT + ${TgaImporter_SRCS} + ${TgaImporter_HEADERS}) +if(NOT BUILD_PLUGINS_STATIC) + set_target_properties(TgaImporterObjects PROPERTIES COMPILE_FLAGS "-DTgaImporterObjects_EXPORTS") +endif() +if(NOT BUILD_PLUGINS_STATIC OR BUILD_STATIC_PIC) + set_target_properties(TgaImporterObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() +# TgaImporter plugin add_plugin(TgaImporter ${MAGNUM_PLUGINS_IMPORTER_DEBUG_INSTALL_DIR} ${MAGNUM_PLUGINS_IMPORTER_RELEASE_INSTALL_DIR} TgaImporter.conf $ pluginRegistration.cpp) +if(BUILD_STATIC_PIC) + set_target_properties(TgaImporter PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() + target_link_libraries(TgaImporter Magnum) install(FILES ${TgaImporter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImporter) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/configure.h DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImporter/configure.h) if(BUILD_TESTS) - add_library(MagnumTgaImporterTestLib ${SHARED_OR_STATIC} $) - set_target_properties(MagnumTgaImporterTestLib PROPERTIES DEBUG_POSTFIX "-d") + add_library(MagnumTgaImporterTestLib STATIC $) target_link_libraries(MagnumTgaImporterTestLib Magnum) - - # On Windows we need to install first and then run the tests to avoid "DLL - # not found" hell, thus we need to install this too - if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING) - install(TARGETS MagnumTgaImporterTestLib - RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} - LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} - ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) - endif() - add_subdirectory(Test) endif() diff --git a/src/MagnumPlugins/TgaImporter/Test/CMakeLists.txt b/src/MagnumPlugins/TgaImporter/Test/CMakeLists.txt index 143202d8c..51f20b106 100644 --- a/src/MagnumPlugins/TgaImporter/Test/CMakeLists.txt +++ b/src/MagnumPlugins/TgaImporter/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -29,3 +29,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) corrade_add_test(TgaImporterTest TgaImporterTest.cpp LIBRARIES MagnumTgaImporterTestLib) +# On Win32 we need to avoid dllimporting TgaImporter symbols, because it would +# search for the symbols in some DLL even when they were linked statically. +# However it apparently doesn't matter that they were dllexported when building +# the static library. EH. +if(WIN32) + set_target_properties(TgaImporterTest PROPERTIES COMPILE_FLAGS "-DMAGNUM_TGAIMPORTER_BUILD_STATIC") +endif() diff --git a/src/MagnumPlugins/TgaImporter/Test/TgaImporterTest.cpp b/src/MagnumPlugins/TgaImporter/Test/TgaImporterTest.cpp index a7f09a4cf..4ce72096d 100644 --- a/src/MagnumPlugins/TgaImporter/Test/TgaImporterTest.cpp +++ b/src/MagnumPlugins/TgaImporter/Test/TgaImporterTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -82,7 +82,7 @@ void TgaImporterTest::openNonexistent() { void TgaImporterTest::openShort() { TgaImporter importer; - const unsigned char data[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + const char data[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; CORRADE_VERIFY(importer.openData(data)); std::ostringstream debug; @@ -93,7 +93,7 @@ void TgaImporterTest::openShort() { void TgaImporterTest::paletted() { TgaImporter importer; - const unsigned char data[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + const char data[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; CORRADE_VERIFY(importer.openData(data)); std::ostringstream debug; @@ -104,7 +104,7 @@ void TgaImporterTest::paletted() { void TgaImporterTest::compressed() { TgaImporter importer; - const unsigned char data[] = { 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + const char data[] = { 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; CORRADE_VERIFY(importer.openData(data)); std::ostringstream debug; @@ -115,7 +115,7 @@ void TgaImporterTest::compressed() { void TgaImporterTest::colorBits16() { TgaImporter importer; - const unsigned char data[] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0 }; + const char data[] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0 }; CORRADE_VERIFY(importer.openData(data)); std::ostringstream debug; @@ -126,14 +126,14 @@ void TgaImporterTest::colorBits16() { void TgaImporterTest::colorBits24() { TgaImporter importer; - const unsigned char data[] = { + const char data[] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 24, 0, 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7, 6, 7, 8 }; #ifndef MAGNUM_TARGET_GLES - const char* pixels = reinterpret_cast(data) + 18; + const char* pixels = data + 18; #else const char pixels[] = { 3, 2, 1, 4, 3, 2, @@ -152,19 +152,20 @@ void TgaImporterTest::colorBits24() { #endif CORRADE_COMPARE(image->size(), Vector2i(2, 3)); CORRADE_COMPARE(image->type(), ColorType::UnsignedByte); - CORRADE_COMPARE(std::string(reinterpret_cast(image->data()), 2*3*3), std::string(pixels, 2*3*3)); + CORRADE_COMPARE((std::string{image->data(), 2*3*3}), + (std::string{pixels, 2*3*3})); } void TgaImporterTest::colorBits32() { TgaImporter importer; - const unsigned char data[] = { + const char data[] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 32, 0, 1, 2, 3, 1, 2, 3, 4, 1, 3, 4, 5, 1, 4, 5, 6, 1, 5, 6, 7, 1, 6, 7, 8, 1 }; #ifndef MAGNUM_TARGET_GLES - const char* pixels = reinterpret_cast(data) + 18; + const char* pixels = data + 18; #else const char pixels[] = { 3, 2, 1, 1, 4, 3, 2, 1, @@ -183,12 +184,13 @@ void TgaImporterTest::colorBits32() { #endif CORRADE_COMPARE(image->size(), Vector2i(2, 3)); CORRADE_COMPARE(image->type(), ColorType::UnsignedByte); - CORRADE_COMPARE(std::string(reinterpret_cast(image->data()), 2*3*3), std::string(pixels, 2*3*3)); + CORRADE_COMPARE((std::string{image->data(), 2*3*3}), + (std::string{pixels, 2*3*3})); } void TgaImporterTest::grayscaleBits8() { TgaImporter importer; - const unsigned char data[] = { + const char data[] = { 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 8, 0, 1, 2, 3, 4, @@ -205,13 +207,13 @@ void TgaImporterTest::grayscaleBits8() { #endif CORRADE_COMPARE(image->size(), Vector2i(2, 3)); CORRADE_COMPARE(image->type(), ColorType::UnsignedByte); - CORRADE_COMPARE(std::string(reinterpret_cast(image->data()), 2*3), - std::string(reinterpret_cast(data) + 18, 2*3)); + CORRADE_COMPARE((std::string{image->data(), 2*3}), + (std::string{data + 18, 2*3})); } void TgaImporterTest::grayscaleBits16() { TgaImporter importer; - const unsigned char data[] = { 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0 }; + const char data[] = { 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0 }; CORRADE_VERIFY(importer.openData(data)); std::ostringstream debug; @@ -222,7 +224,7 @@ void TgaImporterTest::grayscaleBits16() { void TgaImporterTest::file() { TgaImporter importer; - const unsigned char data[] = { + const char data[] = { 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 8, 0, 1, 2, 3, 4, @@ -239,8 +241,8 @@ void TgaImporterTest::file() { #endif CORRADE_COMPARE(image->size(), Vector2i(2, 3)); CORRADE_COMPARE(image->type(), ColorType::UnsignedByte); - CORRADE_COMPARE(std::string(reinterpret_cast(image->data()), 2*3), - std::string(reinterpret_cast(data) + 18, 2*3)); + CORRADE_COMPARE((std::string{image->data(), 2*3}), + (std::string{data + 18, 2*3})); } }}} diff --git a/src/MagnumPlugins/TgaImporter/Test/configure.h.cmake b/src/MagnumPlugins/TgaImporter/Test/configure.h.cmake index b2b016f03..20b731aa2 100644 --- a/src/MagnumPlugins/TgaImporter/Test/configure.h.cmake +++ b/src/MagnumPlugins/TgaImporter/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/TgaImporter/TgaHeader.h b/src/MagnumPlugins/TgaImporter/TgaHeader.h index 74b04efb9..0ccb681fd 100644 --- a/src/MagnumPlugins/TgaImporter/TgaHeader.h +++ b/src/MagnumPlugins/TgaImporter/TgaHeader.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,7 +26,7 @@ */ /** @file - * @brief Struct Magnum::Trade::TgaHeader + * @brief Struct @ref Magnum::Trade::TgaHeader */ #include "Magnum/Types.h" @@ -43,12 +43,12 @@ struct TgaHeader { UnsignedShort colorMapStart; /**< @brief First color map entry */ UnsignedShort colorMapLength; /**< @brief Number of colors */ UnsignedByte colorMapBpp; /**< @brief Bits per palette entry */ - UnsignedShort beginX; /**< @brief %Image x origin */ - UnsignedShort beginY; /**< @brief %Image y origin */ - UnsignedShort width; /**< @brief %Image width */ - UnsignedShort height; /**< @brief %Image height */ + UnsignedShort beginX; /**< @brief Image x origin */ + UnsignedShort beginY; /**< @brief Image y origin */ + UnsignedShort width; /**< @brief Image width */ + UnsignedShort height; /**< @brief Image height */ UnsignedByte bpp; /**< @brief Bits per pixel (8, 16, 24, 32) */ - UnsignedByte descriptor; /**< @brief %Image descriptor */ + UnsignedByte descriptor; /**< @brief Image descriptor */ }; #pragma pack() diff --git a/src/MagnumPlugins/TgaImporter/TgaImporter.cpp b/src/MagnumPlugins/TgaImporter/TgaImporter.cpp index 41842987e..b96e543af 100644 --- a/src/MagnumPlugins/TgaImporter/TgaImporter.cpp +++ b/src/MagnumPlugins/TgaImporter/TgaImporter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -69,8 +69,8 @@ auto TgaImporter::doFeatures() const -> Features { return Feature::OpenData; } bool TgaImporter::doIsOpened() const { return in; } -void TgaImporter::doOpenData(const Containers::ArrayReference data) { - in = new std::istringstream(std::string(reinterpret_cast(data.begin()), data.size())); +void TgaImporter::doOpenData(const Containers::ArrayReference data) { + in = new std::istringstream{{data, data.size()}}; } void TgaImporter::doOpenFile(const std::string& filename) { diff --git a/src/MagnumPlugins/TgaImporter/TgaImporter.h b/src/MagnumPlugins/TgaImporter/TgaImporter.h index c4a31664d..c7890c0cb 100644 --- a/src/MagnumPlugins/TgaImporter/TgaImporter.h +++ b/src/MagnumPlugins/TgaImporter/TgaImporter.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,15 +26,17 @@ */ /** @file - * @brief Class Magnum::Trade::TgaImporter + * @brief Class @ref Magnum::Trade::TgaImporter */ #include #include "Magnum/Trade/AbstractImporter.h" +#include "MagnumPlugins/TgaImporter/configure.h" + #ifndef DOXYGEN_GENERATING_OUTPUT -#ifndef MAGNUM_BUILD_STATIC +#ifndef MAGNUM_TGAIMPORTER_BUILD_STATIC #if defined(TgaImporter_EXPORTS) || defined(TgaImporterObjects_EXPORTS) #define MAGNUM_TRADE_TGAIMPORTER_EXPORT CORRADE_VISIBILITY_EXPORT #else @@ -53,10 +55,10 @@ namespace Magnum { namespace Trade { Supports uncompressed BGR, BGRA or grayscale images with 8 bits per channel. -This plugin is built if `WITH_TGAIMPORTER` is enabled when building %Magnum. To -use dynamic plugin, you need to load `%TgaImporter` plugin from +This plugin is built if `WITH_TGAIMPORTER` is enabled when building Magnum. To +use dynamic plugin, you need to load `TgaImporter` plugin from `MAGNUM_PLUGINS_IMPORTER_DIR`. To use static plugin or use this as a dependency -of another plugin, you need to request `%TgaImporter` component of `%Magnum` +of another plugin, you need to request `TgaImporter` component of `Magnum` package in CMake and link to `${MAGNUM_TGAIMPORTER_LIBRARIES}`. See @ref building, @ref cmake and @ref plugins for more information. @@ -82,7 +84,7 @@ class MAGNUM_TRADE_TGAIMPORTER_EXPORT TgaImporter: public AbstractImporter { private: Features MAGNUM_TRADE_TGAIMPORTER_LOCAL doFeatures() const override; bool MAGNUM_TRADE_TGAIMPORTER_LOCAL doIsOpened() const override; - void MAGNUM_TRADE_TGAIMPORTER_LOCAL doOpenData(Containers::ArrayReference data) override; + void MAGNUM_TRADE_TGAIMPORTER_LOCAL doOpenData(Containers::ArrayReference data) override; void MAGNUM_TRADE_TGAIMPORTER_LOCAL doOpenFile(const std::string& filename) override; void MAGNUM_TRADE_TGAIMPORTER_LOCAL doClose() override; UnsignedInt MAGNUM_TRADE_TGAIMPORTER_LOCAL doImage2DCount() const override; diff --git a/src/MagnumPlugins/TgaImporter/configure.h.cmake b/src/MagnumPlugins/TgaImporter/configure.h.cmake new file mode 100644 index 000000000..aea9ee97c --- /dev/null +++ b/src/MagnumPlugins/TgaImporter/configure.h.cmake @@ -0,0 +1,26 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#cmakedefine MAGNUM_TGAIMPORTER_BUILD_STATIC diff --git a/src/MagnumPlugins/TgaImporter/pluginRegistration.cpp b/src/MagnumPlugins/TgaImporter/pluginRegistration.cpp index e43bbf985..03e613f66 100644 --- a/src/MagnumPlugins/TgaImporter/pluginRegistration.cpp +++ b/src/MagnumPlugins/TgaImporter/pluginRegistration.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/WavAudioImporter/CMakeLists.txt b/src/MagnumPlugins/WavAudioImporter/CMakeLists.txt index 3660b3128..ff9fbca3d 100644 --- a/src/MagnumPlugins/WavAudioImporter/CMakeLists.txt +++ b/src/MagnumPlugins/WavAudioImporter/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a @@ -34,32 +34,29 @@ set(WavAudioImporter_HEADERS WavHeader.h WavImporter.h) -add_library(WavAudioImporterObjects OBJECT ${WavAudioImporter_SRCS}) -if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) - set_target_properties(WavAudioImporterObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +# Objects shared between plugin and test library +add_library(WavAudioImporterObjects OBJECT + ${WavAudioImporter_SRCS} + ${WavAudioImporter_HEADERS}) +if(NOT BUILD_PLUGINS_STATIC OR BUILD_STATIC_PIC) + set_target_properties(WavAudioImporterObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() +# WavAudioImporter plugin add_plugin(WavAudioImporter ${MAGNUM_PLUGINS_AUDIOIMPORTER_DEBUG_INSTALL_DIR} ${MAGNUM_PLUGINS_AUDIOIMPORTER_RELEASE_INSTALL_DIR} WavAudioImporter.conf $ pluginRegistration.cpp) +if(BUILD_STATIC_PIC) + set_target_properties(WavAudioImporter PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() + target_link_libraries(WavAudioImporter Magnum MagnumAudio) install(FILES ${WavAudioImporter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/WavAudioImporter) if(BUILD_TESTS) add_library(MagnumWavAudioImporterTestLib STATIC $) - set_target_properties(MagnumWavAudioImporterTestLib PROPERTIES DEBUG_POSTFIX "-d") target_link_libraries(MagnumWavAudioImporterTestLib Magnum MagnumAudio) - - # On Windows we need to install first and then run the tests to avoid "DLL - # not found" hell, thus we need to install this too - if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING) - install(TARGETS MagnumWavAudioImporterTestLib - RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} - LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} - ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) - endif() - add_subdirectory(Test) endif() diff --git a/src/MagnumPlugins/WavAudioImporter/Test/CMakeLists.txt b/src/MagnumPlugins/WavAudioImporter/Test/CMakeLists.txt index 53d5f7fb8..dfdc7c078 100644 --- a/src/MagnumPlugins/WavAudioImporter/Test/CMakeLists.txt +++ b/src/MagnumPlugins/WavAudioImporter/Test/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of Magnum. # -# Copyright © 2010, 2011, 2012, 2013, 2014 +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015 # Vladimír Vondruš # # Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/WavAudioImporter/Test/WavImporterTest.cpp b/src/MagnumPlugins/WavAudioImporter/Test/WavImporterTest.cpp index 85eb51e88..c19f55134 100644 --- a/src/MagnumPlugins/WavAudioImporter/Test/WavImporterTest.cpp +++ b/src/MagnumPlugins/WavAudioImporter/Test/WavImporterTest.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -60,7 +60,7 @@ void WavImporterTest::wrongSize() { Error::setOutput(&out); WavImporter importer; - CORRADE_VERIFY(!importer.openData(Containers::Array(43))); + CORRADE_VERIFY(!importer.openData(Containers::Array(43))); CORRADE_COMPARE(out.str(), "Audio::WavImporter::openData(): the file is too short: 43 bytes\n"); } @@ -97,12 +97,12 @@ void WavImporterTest::mono16() { CORRADE_COMPARE(importer.format(), Buffer::Format::Mono16); CORRADE_COMPARE(importer.frequency(), 44000); - Containers::Array data = importer.data(); + Containers::Array data = importer.data(); CORRADE_COMPARE(data.size(), 4); - CORRADE_COMPARE(data[0], 0x1d); - CORRADE_COMPARE(data[1], 0x10); - CORRADE_COMPARE(data[2], 0x71); - CORRADE_COMPARE(data[3], 0xC5); + CORRADE_COMPARE(data[0], '\x1d'); + CORRADE_COMPARE(data[1], '\x10'); + CORRADE_COMPARE(data[2], '\x71'); + CORRADE_COMPARE(data[3], '\xc5'); } void WavImporterTest::stereo8() { @@ -111,12 +111,12 @@ void WavImporterTest::stereo8() { CORRADE_COMPARE(importer.format(), Buffer::Format::Stereo8); CORRADE_COMPARE(importer.frequency(), 96000); - Containers::Array data = importer.data(); + Containers::Array data = importer.data(); CORRADE_COMPARE(data.size(), 4); - CORRADE_COMPARE(data[0], 0xde); - CORRADE_COMPARE(data[1], 0xfe); - CORRADE_COMPARE(data[2], 0xca); - CORRADE_COMPARE(data[3], 0x7e); + CORRADE_COMPARE(data[0], '\xde'); + CORRADE_COMPARE(data[1], '\xfe'); + CORRADE_COMPARE(data[2], '\xca'); + CORRADE_COMPARE(data[3], '\x7e'); } }}} diff --git a/src/MagnumPlugins/WavAudioImporter/Test/configure.h.cmake b/src/MagnumPlugins/WavAudioImporter/Test/configure.h.cmake index 4bc54750c..ca489a0fe 100644 --- a/src/MagnumPlugins/WavAudioImporter/Test/configure.h.cmake +++ b/src/MagnumPlugins/WavAudioImporter/Test/configure.h.cmake @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/src/MagnumPlugins/WavAudioImporter/WavHeader.h b/src/MagnumPlugins/WavAudioImporter/WavHeader.h index 8fe1aa71c..9b368a982 100644 --- a/src/MagnumPlugins/WavAudioImporter/WavHeader.h +++ b/src/MagnumPlugins/WavAudioImporter/WavHeader.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,7 +26,7 @@ */ /** @file - * @brief Struct Magnum::Audio::WavHeader + * @brief Struct @ref Magnum::Audio::WavHeader */ #include "Magnum/Types.h" diff --git a/src/MagnumPlugins/WavAudioImporter/WavImporter.cpp b/src/MagnumPlugins/WavAudioImporter/WavImporter.cpp index 73141bcdf..512f06432 100644 --- a/src/MagnumPlugins/WavAudioImporter/WavImporter.cpp +++ b/src/MagnumPlugins/WavAudioImporter/WavImporter.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -43,7 +43,7 @@ auto WavImporter::doFeatures() const -> Features { return Feature::OpenData; } bool WavImporter::doIsOpened() const { return _data; } -void WavImporter::doOpenData(Containers::ArrayReference data) { +void WavImporter::doOpenData(Containers::ArrayReference data) { /* Check file size */ if(data.size() < sizeof(WavHeader)) { Error() << "Audio::WavImporter::openData(): the file is too short:" << data.size() << "bytes"; @@ -111,7 +111,7 @@ void WavImporter::doOpenData(Containers::ArrayReference dat CORRADE_INTERNAL_ASSERT(!Utility::Endianness::isBigEndian()); /* Copy the data */ - _data = Containers::Array(header.subChunk2Size); + _data = Containers::Array(header.subChunk2Size); std::copy(data.begin()+sizeof(WavHeader), data.end(), _data.begin()); return; } @@ -128,8 +128,8 @@ Buffer::Format WavImporter::doFormat() const { return _format; } UnsignedInt WavImporter::doFrequency() const { return _frequency; } -Containers::Array WavImporter::doData() { - Containers::Array copy(_data.size()); +Containers::Array WavImporter::doData() { + Containers::Array copy(_data.size()); std::copy(_data.begin(), _data.end(), copy.begin()); return copy; } diff --git a/src/MagnumPlugins/WavAudioImporter/WavImporter.h b/src/MagnumPlugins/WavAudioImporter/WavImporter.h index c393eb2f2..f8fb6ec9c 100644 --- a/src/MagnumPlugins/WavAudioImporter/WavImporter.h +++ b/src/MagnumPlugins/WavAudioImporter/WavImporter.h @@ -3,7 +3,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a @@ -26,7 +26,7 @@ */ /** @file - * @brief Class Magnum::Audio::WavImporter + * @brief Class @ref Magnum::Audio::WavImporter */ #include @@ -43,10 +43,10 @@ imported with @ref Buffer::Format::Mono8, @ref Buffer::Format::Mono16, @ref Buffer::Format::Stereo8 or @ref Buffer::Format::Stereo16, respectively. This plugin is built if `WITH_WAVAUDIOIMPORTER` is enabled when building -%Magnum. To use dynamic plugin, you need to load `%WavAudioImporter` plugin +Magnum. To use dynamic plugin, you need to load `WavAudioImporter` plugin from `MAGNUM_PLUGINS_AUDIOIMPORTER_DIR`. To use static plugin or use this as a -dependency of another plugin, you need to request `%WavAudioImporter` component -of `%Magnum` package in CMake and link to `${MAGNUM_WAVAUDIOIMPORTER_LIBRARIES}`. +dependency of another plugin, you need to request `WavAudioImporter` component +of `Magnum` package in CMake and link to `${MAGNUM_WAVAUDIOIMPORTER_LIBRARIES}`. See @ref building, @ref cmake and @ref plugins for more information. */ class WavImporter: public AbstractImporter { @@ -62,14 +62,14 @@ class WavImporter: public AbstractImporter { private: Features doFeatures() const override; bool doIsOpened() const override; - void doOpenData(Containers::ArrayReference data) override; + void doOpenData(Containers::ArrayReference data) override; void doClose() override; Buffer::Format doFormat() const override; UnsignedInt doFrequency() const override; - Containers::Array doData() override; + Containers::Array doData() override; - Containers::Array _data; + Containers::Array _data; Buffer::Format _format; UnsignedInt _frequency; }; diff --git a/src/MagnumPlugins/WavAudioImporter/pluginRegistration.cpp b/src/MagnumPlugins/WavAudioImporter/pluginRegistration.cpp index 073dbf428..514228b8c 100644 --- a/src/MagnumPlugins/WavAudioImporter/pluginRegistration.cpp +++ b/src/MagnumPlugins/WavAudioImporter/pluginRegistration.cpp @@ -1,7 +1,7 @@ /* This file is part of Magnum. - Copyright © 2010, 2011, 2012, 2013, 2014 + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Vladimír Vondruš Permission is hereby granted, free of charge, to any person obtaining a diff --git a/toolchains b/toolchains index 7380270cc..9108c58bf 160000 --- a/toolchains +++ b/toolchains @@ -1 +1 @@ -Subproject commit 7380270cc5d8e399cb06f463ac681adcbd591d54 +Subproject commit 9108c58bf70bcd39be7be886d9aa837f27743646