Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/Plugins/TgaImporter/TgaImporter.cpp
	src/Shader.cpp
	src/Text/Test/AbstractFontConverterTest.cpp
Vladimír Vondruš 13 years ago
parent
commit
17b0c6a915
  1. 25
      CMakeLists.txt
  2. 5
      PKGBUILD
  3. 15
      PKGBUILD-emscripten
  4. 13
      PKGBUILD-es2
  5. 13
      PKGBUILD-es2desktop
  6. 13
      PKGBUILD-es3
  7. 49
      PKGBUILD-gcc46
  8. 49
      PKGBUILD-gcc47
  9. 14
      PKGBUILD-mingw32
  10. 26
      PKGBUILD-nacl-glibc
  11. 26
      PKGBUILD-nacl-newlib
  12. 16
      PKGBUILD-release
  13. 16
      doc/best-practices.dox
  14. 89
      doc/building.dox
  15. 107
      doc/cmake.dox
  16. 4
      doc/namespaces.dox
  17. 98
      external/OpenGL/GL/gl_magnum.c
  18. 109
      modules/FindMagnum.cmake
  19. 36
      src/AbstractShaderProgram.h
  20. 1
      src/CMakeLists.txt
  21. 4
      src/ImageReference.h
  22. 66
      src/Math/Functions.h
  23. 5
      src/Math/Geometry/Rectangle.h
  24. 9
      src/Math/Geometry/Test/RectangleTest.cpp
  25. 25
      src/Math/Test/FunctionsTest.cpp
  26. 24
      src/Math/Test/VectorTest.cpp
  27. 79
      src/Math/Vector.h
  28. 8
      src/Math/instantiation.cpp
  29. 6
      src/Mesh.cpp
  30. 6
      src/Platform/AbstractXApplication.cpp
  31. 7
      src/Platform/AbstractXApplication.h
  32. 11
      src/Platform/CMakeLists.txt
  33. 11
      src/Platform/GlutApplication.cpp
  34. 20
      src/Platform/GlutApplication.h
  35. 4
      src/Platform/GlxApplication.cpp
  36. 3
      src/Platform/GlxApplication.h
  37. 10
      src/Platform/NaClApplication.cpp
  38. 10
      src/Platform/NaClApplication.h
  39. 38
      src/Platform/Platform.h
  40. 265
      src/Platform/Screen.h
  41. 199
      src/Platform/ScreenedApplication.h
  42. 136
      src/Platform/ScreenedApplication.hpp
  43. 10
      src/Platform/Sdl2Application.cpp
  44. 10
      src/Platform/Sdl2Application.h
  45. 4
      src/Platform/XEglApplication.cpp
  46. 3
      src/Platform/XEglApplication.h
  47. 54
      src/Plugins/CMakeLists.txt
  48. 12
      src/Plugins/MagnumFont/CMakeLists.txt
  49. 81
      src/Plugins/MagnumFont/MagnumFont.cpp
  50. 21
      src/Plugins/MagnumFont/MagnumFont.h
  51. 27
      src/Plugins/MagnumFont/Test/MagnumFontTest.cpp
  52. 1
      src/Plugins/MagnumFont/Test/font.conf
  53. 2
      src/Plugins/MagnumFont/pluginRegistrationMagnumFont.cpp
  54. 11
      src/Plugins/MagnumFontConverter/CMakeLists.txt
  55. 14
      src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp
  56. 8
      src/Plugins/MagnumFontConverter/MagnumFontConverter.h
  57. 4
      src/Plugins/MagnumFontConverter/Test/CMakeLists.txt
  58. 66
      src/Plugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp
  59. 2
      src/Plugins/MagnumFontConverter/pluginRegistrationMagnumFontConverter.cpp
  60. 4
      src/Plugins/TgaImageConverter/CMakeLists.txt
  61. 11
      src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp
  62. 18
      src/Plugins/TgaImageConverter/TgaImageConverter.cpp
  63. 6
      src/Plugins/TgaImageConverter/TgaImageConverter.h
  64. 4
      src/Plugins/TgaImporter/CMakeLists.txt
  65. 14
      src/Plugins/TgaImporter/Test/TgaImporterTest.cpp
  66. 16
      src/Plugins/TgaImporter/TgaImporter.cpp
  67. 4
      src/Plugins/TgaImporter/TgaImporter.h
  68. 8
      src/Plugins/WavAudioImporter/CMakeLists.txt
  69. 2
      src/Plugins/WavAudioImporter/WavHeader.h
  70. 7
      src/Plugins/WavAudioImporter/WavImporter.h
  71. 15
      src/ResourceManager.h
  72. 25
      src/SceneGraph/AbstractCamera.h
  73. 12
      src/SceneGraph/AbstractFeature.h
  74. 2
      src/SceneGraph/AbstractFeature.hpp
  75. 10
      src/SceneGraph/AbstractGroupedFeature.h
  76. 22
      src/SceneGraph/AbstractObject.h
  77. 10
      src/SceneGraph/AbstractTransformation.h
  78. 32
      src/SceneGraph/Animable.h
  79. 8
      src/SceneGraph/Animable.hpp
  80. 11
      src/SceneGraph/Camera2D.h
  81. 11
      src/SceneGraph/Camera3D.h
  82. 14
      src/SceneGraph/Drawable.h
  83. 4
      src/SceneGraph/FeatureGroup.h
  84. 2
      src/SceneGraph/FeatureGroup.hpp
  85. 42
      src/SceneGraph/Object.h
  86. 2
      src/SceneGraph/Object.hpp
  87. 2
      src/SceneGraph/instantiation.cpp
  88. 6
      src/Shader.cpp
  89. 2
      src/Shaders/Flat.cpp
  90. 1
      src/Shaders/Flat.frag
  91. 2
      src/Shaders/Flat.h
  92. 3
      src/Shaders/Vector.cpp
  93. 6
      src/Shaders/Vector.frag
  94. 15
      src/Shaders/Vector.h
  95. 2
      src/Test/AbstractOpenGLTester.h
  96. 70
      src/Text/AbstractFont.cpp
  97. 160
      src/Text/AbstractFont.h
  98. 24
      src/Text/AbstractFontConverter.cpp
  99. 39
      src/Text/AbstractFontConverter.h
  100. 131
      src/Text/Alignment.h
  101. Some files were not shown because too many files have changed in this diff Show More

25
CMakeLists.txt

@ -48,8 +48,6 @@ cmake_dependent_option(WITH_SHADERS "Build Shaders library" ON "NOT WITH_DEBUGTO
cmake_dependent_option(WITH_SHAPES "Build Shapes library" ON "NOT WITH_DEBUGTOOLS" ON)
option(WITH_TEXT "Build Text library" ON)
cmake_dependent_option(WITH_TEXTURETOOLS "Build TextureTools library" ON "NOT WITH_TEXT;NOT WITH_DISTANCEFIELDCONVERTER" ON)
option(WITH_MAGNUMINFO "Build magnum-info utility" OFF)
cmake_dependent_option(WITH_DISTANCEFIELDCONVERTER "Build magnum-distancefield utility" OFF "NOT TARGET_GLES" OFF)
# Application libraries
if(CORRADE_TARGET_NACL)
@ -63,6 +61,22 @@ else()
option(WITH_SDL2APPLICATION "Build Sdl2Application library" OFF)
endif()
# Utilities (currently depending on WindowlessGlxApplication)
if(UNIX OR CORRADE_TARGET_NACL)
option(WITH_MAGNUMINFO "Build magnum-info utility" OFF)
endif()
if(UNIX)
cmake_dependent_option(WITH_FONTCONVERTER "Build magnum-fontconverter utility" OFF "NOT TARGET_GLES" OFF)
cmake_dependent_option(WITH_DISTANCEFIELDCONVERTER "Build magnum-distancefieldconverter utility" OFF "NOT TARGET_GLES" OFF)
endif()
# Plugins
cmake_dependent_option(WITH_MAGNUMFONT "Build MagnumFont plugin" OFF "WITH_TEXT" OFF)
cmake_dependent_option(WITH_MAGNUMFONTCONVERTER "Build MagnumFontConverter plugin" OFF "NOT MAGNUM_TARGET_GLES;WITH_TEXT" OFF)
cmake_dependent_option(WITH_TGAIMAGECONVERTER "Build TgaImageConverter plugin" OFF "NOT WITH_MAGNUMFONTCONVERTER" ON)
cmake_dependent_option(WITH_TGAIMPORTER "Build TgaImporter plugin" OFF "NOT WITH_MAGNUMFONT" ON)
cmake_dependent_option(WITH_WAVAUDIOIMPORTER "Build WavAudioImporter plugin" OFF "WITH_AUDIO" OFF)
option(BUILD_DEPRECATED "Include deprecated API in the build" ON)
if(BUILD_DEPRECATED)
set(MAGNUM_BUILD_DEPRECATED 1)
@ -142,9 +156,16 @@ endif()
include(CorradeLibSuffix)
set(MAGNUM_BINARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin)
set(MAGNUM_LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
set(MAGNUM_PLUGINS_INSTALL_DIR ${MAGNUM_LIBRARY_INSTALL_DIR}/magnum)
set(MAGNUM_PLUGINS_FONT_INSTALL_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/fonts)
set(MAGNUM_PLUGINS_FONTCONVERTER_INSTALL_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/fontconverters)
set(MAGNUM_PLUGINS_IMAGECONVERTER_INSTALL_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/imageconverters)
set(MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/importers)
set(MAGNUM_PLUGINS_AUDIOIMPORTER_INSTALL_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/audioimporters)
set(MAGNUM_DATA_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/magnum)
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/Magnum/Plugins)
add_subdirectory(external)
add_subdirectory(modules)

5
PKGBUILD

@ -30,6 +30,11 @@ build() {
-DWITH_GLUTAPPLICATION=ON \
-DWITH_GLXAPPLICATION=ON \
-DWITH_SDL2APPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-DBUILD_TESTS=TRUE \
-G Ninja
ninja

15
PKGBUILD-emscripten

@ -7,7 +7,7 @@ arch=('any')
url="http://mosra.cz/blog/magnum.php"
license=('MIT')
depends=('emscripten-corrade')
makedepends=('cmake')
makedepends=('cmake' 'ninja')
options=(!strip !buildflags)
build() {
@ -18,7 +18,8 @@ build() {
cmake .. \
-DCMAKE_MODULE_PATH="$startdir/toolchains/modules" \
-DCMAKE_TOOLCHAIN_FILE="$startdir/toolchains/generic/Emscripten.cmake" \
-DWITH_AUDIO=OFF
-DWITH_AUDIO=OFF \
-G Ninja
fi
cd "$startdir/build-emscripten"
@ -27,11 +28,15 @@ build() {
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/emscripten/system \
-DWITH_AUDIO=OFF \
-DWITH_SDL2APPLICATION=ON
make
-DWITH_SDL2APPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON
ninja
}
package() {
cd "$startdir/build-emscripten"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
}

13
PKGBUILD-es2

@ -7,7 +7,7 @@ arch=('i686' 'x86_64')
url="https://github.com/mosra/magnum"
license=('MIT')
depends=('corrade' 'openal')
makedepends=('cmake')
makedepends=('cmake' 'ninja')
options=(!strip)
provides=('magnum-git')
@ -27,8 +27,13 @@ build() {
-DTARGET_GLES=ON \
-DTARGET_GLES2=ON \
-DWITH_MAGNUMINFO=OFF \
-DWITH_XEGLAPPLICATION=ON
make
-DWITH_XEGLAPPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-G Ninja
ninja
}
check() {
@ -38,5 +43,5 @@ check() {
package() {
cd "$startdir/build-es2"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
}

13
PKGBUILD-es2desktop

@ -7,7 +7,7 @@ arch=('i686' 'x86_64')
url="https://github.com/mosra/magnum"
license=('MIT')
depends=('corrade' 'openal')
makedepends=('cmake')
makedepends=('cmake' 'ninja')
options=(!strip)
provides=('magnum-git')
@ -29,8 +29,13 @@ build() {
-DTARGET_DESKTOP_GLES=ON \
-DWITH_MAGNUMINFO=ON \
-DWITH_GLXAPPLICATION=ON \
-DWITH_WINDOWLESSGLXAPPLICATION=ON
make
-DWITH_WINDOWLESSGLXAPPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-G Ninja
ninja
}
check() {
@ -40,5 +45,5 @@ check() {
package() {
cd "$startdir/build-es2desktop"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
}

13
PKGBUILD-es3

@ -7,7 +7,7 @@ arch=('i686' 'x86_64')
url="https://github.com/mosra/magnum"
license=('MIT')
depends=('corrade' 'openal')
makedepends=('cmake')
makedepends=('cmake' 'ninja')
options=(!strip)
provides=('magnum-git')
@ -27,8 +27,13 @@ build() {
-DTARGET_GLES=ON \
-DTARGET_GLES2=OFF \
-DWITH_MAGNUMINFO=OFF \
-DWITH_XEGLAPPLICATION=ON
make
-DWITH_XEGLAPPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-G Ninja
ninja
}
check() {
@ -38,5 +43,5 @@ check() {
package() {
cd "$startdir/build-es3"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
}

49
PKGBUILD-gcc46

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

49
PKGBUILD-gcc47

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

14
PKGBUILD-mingw32

@ -7,7 +7,7 @@ arch=('any')
url="https://github.com/mosra/magnum"
license=('MIT')
depends=('mingw32-runtime' 'mingw32-corrade' 'mingw32-freeglut' 'mingw32-openal')
makedepends=('mingw32-gcc' 'cmake' 'corrade')
makedepends=('mingw32-gcc' 'cmake' 'ninja' 'corrade')
options=(!buildflags !strip)
build() {
@ -20,11 +20,17 @@ build() {
-DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw32.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/i486-mingw32 \
-DWITH_GLUTAPPLICATION=ON
make
-DWITH_GLUTAPPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-G Ninja
ninja
}
package() {
cd "$startdir/build-win"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
}

26
PKGBUILD-nacl-glibc

@ -7,7 +7,7 @@ arch=('any')
url="https://github.com/mosra/magnum"
license=('MIT')
depends=('nacl-corrade')
makedepends=('nacl-sdk' 'cmake')
makedepends=('nacl-sdk' 'cmake' 'corrade' 'ninja')
options=(!buildflags !strip)
build() {
@ -22,8 +22,14 @@ build() {
-DCMAKE_INSTALL_PREFIX=/usr/nacl \
-DWITH_MAGNUMINFO=OFF \
-DWITH_NACLAPPLICATION=ON \
-DLIB_SUFFIX=/32
make
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-DLIB_SUFFIX=/32 \
-G Ninja
ninja
# Build 64bit
mkdir -p "$startdir/build-nacl-glibc-x86-64"
@ -35,17 +41,23 @@ build() {
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/nacl \
-DWITH_MAGNUMINFO=OFF \
-DWITH_NACLAPPLICATION=ON
make
-DWITH_NACLAPPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-G Ninja
ninja
}
package() {
# Install 32bit
cd "$startdir/build-nacl-glibc-x86-32"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
# 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"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
}

26
PKGBUILD-nacl-newlib

@ -7,7 +7,7 @@ arch=('any')
url="https://github.com/mosra/magnum"
license=('MIT')
depends=('nacl-corrade')
makedepends=('nacl-sdk' 'cmake')
makedepends=('nacl-sdk' 'cmake' 'corrade' 'ninja')
options=(!buildflags !strip)
build() {
@ -24,8 +24,14 @@ build() {
-DWITH_MAGNUMINFO=ON \
-DWITH_NACLAPPLICATION=ON \
-DWITH_WINDOWLESSNACLAPPLICATION=ON \
-DLIB_SUFFIX=/32
make
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-DLIB_SUFFIX=/32 \
-G Ninja
ninja
# Build 64bit
mkdir -p "$startdir/build-nacl-newlib-x86-64"
@ -39,14 +45,20 @@ build() {
-DWITH_AUDIO=OFF \
-DWITH_MAGNUMINFO=ON \
-DWITH_NACLAPPLICATION=ON \
-DWITH_WINDOWLESSNACLAPPLICATION=ON
make
-DWITH_WINDOWLESSNACLAPPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-G Ninja
ninja
}
package() {
# Install 32bit
cd "$startdir/build-nacl-newlib-x86-32"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
# Strip 32bit binaries
/usr/nacl/toolchain/linux_x86_newlib/bin/i686-nacl-strip ${pkgdir}/usr/nacl/bin/*x86-32.nexe
@ -54,7 +66,7 @@ package() {
# 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"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
# Strip 64bit binaries
/usr/nacl/toolchain/linux_x86_newlib/bin/x86_64-nacl-strip ${pkgdir}/usr/nacl/bin/*x86-64.nexe

16
PKGBUILD-release

@ -7,7 +7,7 @@ arch=('i686' 'x86_64')
url="https://github.com/mosra/magnum"
license=('MIT')
depends=('corrade' 'openal' 'sdl2' 'freeglut')
makedepends=('cmake')
makedepends=('cmake' 'ninja')
provides=('magnum-git')
build() {
@ -24,9 +24,15 @@ build() {
-DCMAKE_INSTALL_PREFIX=/usr \
-DWITH_GLUTAPPLICATION=ON \
-DWITH_GLXAPPLICATION=ON \
-DWITH_SDL2APPLICATION=ON
-DBUILD_TESTS=TRUE
make
-DWITH_SDL2APPLICATION=ON \
-DWITH_MAGNUMFONT=ON \
-DWITH_MAGNUMFONTCONVERTER=ON \
-DWITH_TGAIMAGECONVERTER=ON \
-DWITH_TGAIMPORTER=ON \
-DWITH_WAVAUDIOIMPORTER=ON \
-DBUILD_TESTS=TRUE \
-G Ninja
ninja
}
check() {
@ -36,5 +42,5 @@ check() {
package() {
cd "$startdir/build"
make DESTDIR="$pkgdir/" install
DESTDIR="$pkgdir/" ninja install
}

16
doc/best-practices.dox

@ -57,17 +57,17 @@ information.
- [Best practices for 3D graphics](https://developers.google.com/native-client/beta/devguide/coding/3D-graphics#best-practices)
@subsubsection best-practices-nacl-buffer-types Native Client requires unique buffer binding
@subsection best-practices-web-buffer-types Native Client and Emscripten require unique buffer binding
As noted in the above link, buffers in NaCl implementation 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 sufficient target when binding the buffer internally (e.g.
for setting data or copying). To avoid this, set target hint to desired target,
either in constructor or using @ref Buffer::setTargetHint().
As noted in the above link, buffers in NaCl implementation and and also in
WebGL 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 sufficient target when binding the buffer
internally (e.g. for setting data or copying). To avoid this, set target hint
to desired target, either in constructor or using @ref Buffer::setTargetHint().
To ease up the development, @ref Mesh checks proper target hint when adding
vertex and index buffers.
vertex and index buffers in both Native Client and Emscripten.
@section best-practices-hw Hardware-specific

89
doc/building.dox

@ -136,44 +136,67 @@ CMake and C++ sources, see @ref cmake and @ref src/Magnum.h for more
information. See also @ref corrade-cmake and @ref src/Corrade.h for additional
information.
By default the engine is built with nearly everything except Audio library and
application libraries (see below). Using `WITH_*` CMake parameters you can
specify which parts will be built and which not:
- `WITH_AUDIO` - Audio library. Depends on **OpenAL** library, not built by
default.
- `WITH_DEBUGTOOLS` - DebugTools library. Enables also building of MeshTools,
Primitives, SceneGraph, Shaders and Shapes libraries.
- `WITH_MESHTOOLS` - MeshTools library. Enabled automatically if `WITH_DEBUGTOOLS`
is enabled.
- `WITH_PRIMITIVES` - Primitives library. Enabled automatically if `WITH_DEBUGTOOLS`
is enabled.
- `WITH_SCENEGRAPH` - SceneGraph library. Enabled automatically if `WITH_DEBUGTOOLS`
or `WITH_SHAPES` is enabled.
- `WITH_SHADERS` - Shaders library. Enabled automatically if `WITH_DEBUGTOOLS`
is enabled.
- `WITH_SHAPES` - Shapes library. Enables also building of SceneGraph library.
Enabled automatically if `WITH_DEBUGTOOLS` is enabled.
- `WITH_TEXT` - Text library. Enables also building of TextureTools library.
- `WITH_TEXTURETOOLS` - TextureTools library. Enabled automatically if `WITH_TEXT`
or `WITH_DISTANCEFIELDCONVERTER` is enabled.
- `WITH_MAGNUMINFO` - `magnum-info` executable, provides information about the
engine and OpenGL capabilities.
- `WITH_DISTANCEFIELDCONVERTER` - `magnum-distancefield` executable for
converting black&white images to distance field textures. Enables also
building of TextureTools library.
By default the engine is built with nearly everything except Audio library,
plugins and application libraries (see below). Using `WITH_*` CMake parameters
you can specify which parts will be built and which not:
- `WITH_AUDIO` - Audio library. Depends on **OpenAL** library, not built by
default.
- `WITH_DEBUGTOOLS` - DebugTools library. Enables also building of MeshTools,
Primitives, SceneGraph, Shaders and Shapes libraries.
- `WITH_MESHTOOLS` - MeshTools library. Enabled automatically if
`WITH_DEBUGTOOLS` is enabled.
- `WITH_PRIMITIVES` - Primitives library. Enabled automatically if
`WITH_DEBUGTOOLS` is enabled.
- `WITH_SCENEGRAPH` - SceneGraph library. Enabled automatically if
`WITH_DEBUGTOOLS` or `WITH_SHAPES` is enabled.
- `WITH_SHADERS` - Shaders library. Enabled automatically if `WITH_DEBUGTOOLS`
is enabled.
- `WITH_SHAPES` - Shapes library. Enables also building of SceneGraph
library. Enabled automatically if `WITH_DEBUGTOOLS` is enabled.
- `WITH_TEXT` - Text library. Enables also building of TextureTools library.
- `WITH_TEXTURETOOLS` - TextureTools library. Enabled automatically if
`WITH_TEXT` or `WITH_DISTANCEFIELDCONVERTER` is enabled.
None of the @ref Platform "application libraries" is built by default (and you
need at least one). Choose the one which suits your requirements and your
platform best:
- `WITH_GLUTAPPLICATION` - @ref Platform::GlutApplication "GlutApplication"
- `WITH_GLXAPPLICATION` - @ref Platform::GlxApplication "GlxApplication"
- `WITH_NACLAPPLICATION` - @ref Platform::NaClApplication "NaClApplication"
- `WITH_SDL2APPLICATION` - @ref Platform::Sdl2Application "Sdl2Application"
- `WITH_XEGLAPPLICATION` - @ref Platform::XEglApplication "XEglApplication"
- `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `WITH_WINDOWLESSNACLAPPLICATION` - @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication"
- `WITH_GLUTAPPLICATION` - @ref Platform::GlutApplication "GlutApplication"
- `WITH_GLXAPPLICATION` - @ref Platform::GlxApplication "GlxApplication"
- `WITH_NACLAPPLICATION` - @ref Platform::NaClApplication "NaClApplication"
- `WITH_SDL2APPLICATION` - @ref Platform::Sdl2Application "Sdl2Application"
- `WITH_XEGLAPPLICATION` - @ref Platform::XEglApplication "XEglApplication"
- `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `WITH_WINDOWLESSNACLAPPLICATION` - @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication"
There are also a few command-line utilities. They are currently available only
on Linux and are disabled by default:
- `WITH_MAGNUMINFO` - `magnum-info` executable, provides information about
the engine and OpenGL capabilities.
- `WITH_FONTCONVERTER` - `magnum-fontconverter` executable for converting
fonts to raster ones. Enables also building of Text library.
- `WITH_DISTANCEFIELDCONVERTER` - `magnum-distancefieldconverter` executable
for converting black&white images to distance field textures. Enables also
building of TextureTools library.
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.
- `WITH_MAGNUMFONT` -- @ref Text::MagnumFont "MagnumFont" plugin. Available
only if `WITH_TEXT` is enabled. Enables also building of
@ref Trade::TgaImporter "TgaImporter" plugin.
- `WITH_MAGNUMFONTCONVERTER` -- @ref Text::MagnumFontConverter "MagnumFontConverter"
plugin. Available only if `WITH_TEXT` is enabled. Enables also building of
@ref Trade::TgaImageConverter "TgaImageConverter" plugin.
- `WITH_TGAIMPORTER` -- @ref Trade::TgaImporter "TgaImporter" plugin.
- `WITH_TGAIMAGECONVERTER` -- @ref Trade::TgaImageConverter "TgaImageConverter"
plugin.
- `WITH_WAVAUDIOIMPORTER` -- @ref Audio::WavImporter "WavAudioImporter"
plugin. Available only if `WITH_AUDIO` is enabled.
Note that [each namespace](namespaces.html) and all @ref Platform libraries
contain more detailed information about dependencies, availability on

107
doc/cmake.dox

@ -40,42 +40,71 @@ Basic usage is:
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_INCLUDE_DIRS` -- Root include dir and include dirs of dependencies
- `MAGNUM_PLUGINS_FONT_DIR` -- Directory with font plugins
- `MAGNUM_PLUGINS_IMPORTER_DIR` -- Directory with importer plugins
- `MAGNUM_FOUND` -- Whether the library was found
- `MAGNUM_LIBRARIES` -- %Magnum library and dependent libraries
- `MAGNUM_INCLUDE_DIRS` -- Root include dir and include dirs of dependencies
- `MAGNUM_PLUGINS_DIR` -- Base directory with plugins. You can modify it
(e.g. set it to `.` when deploying on Windows with plugins stored
relatively to the executable), the following `MAGNUM_PLUGINS_*_DIR`
variables depend on it.
- `MAGNUM_PLUGINS_INCLUDE_DIR -- Include dir with plugins
- `MAGNUM_PLUGINS_FONT_DIR` -- Directory with font plugins
- `MAGNUM_PLUGINS_FONTCONVERTER_DIR` -- Directory with font converter plugins
- `MAGNUM_PLUGINS_IMAGECONVERTER_DIR` -- Directory with image converter
plugins
- `MAGNUM_PLUGINS_IMPORTER_DIR` -- Directory with importer plugins
- `MAGNUM_PLUGINS_AUDIOIMPORTER_DIR` -- Directory with audio importer plugins
However, this command will try to find only the base library, not the optional
components. The base library depends on %Corrade and OpenGL libraries (or
OpenGL ES libraries). Additional dependencies are specified by the components.
The optional components are:
- `%Audio` -- Audio library
- `%DebugTools` -- DebugTools library (depends on `%MeshTools`,
`%Primitives`, `%SceneGraph`, `%Shaders` and `%Shapes` components)
- `%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)
- `%TextureTools` -- TextureTools library
- `%Audio` -- Audio library
- `%DebugTools` -- DebugTools library (depends on `%MeshTools`,
`%Primitives`, `%SceneGraph`, `%Shaders` and `%Shapes` components)
- `%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)
- `%TextureTools` -- 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"
- `%WindowlessNaClApplication` -- @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication"
- `%WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
Note that [each namespace](namespaces.html) and all @ref Platform libraries
contain more detailed information about dependencies, availability on
particular platform and also guide how to enable given library in build and use
it with CMake.
- `%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"
- `%WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `%WindowlessNaClApplication` -- @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication"
The library also contains a set of plugins for importing essential file
formats. Additional plugins are provided in separate plugin repository, see
@ref cmake-plugins for more information. If you are going to use dynamic
plugins (the default) via plugin manager, they don't need to be handled via
CMake. The manager will look for them at runtime at specified location and
loads them dynamically. However, if they are built as static (see
@ref building-plugins for more information), they need to be linked into the
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)
- `MagnumFontConverter` -- @ref Text::MagnumFontConverter "MagnumFontConverter"
plugin (depends on `%Text` component and `%TgaImageConverter` 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,
availability on particular platform and also guide how to enable given library
in build and use it with CMake.
Example usage with specifying additional components is:
@ -83,9 +112,9 @@ Example usage with specifying additional components is:
For each component is then defined:
- `MAGNUM_*_FOUND` -- Whether the component was found
- `MAGNUM_*_LIBRARIES` -- Component library and dependent libraries
- `MAGNUM_*_INCLUDE_DIRS` -- Include dirs of module dependencies
- `MAGNUM_*_FOUND` -- Whether the component was found
- `MAGNUM_*_LIBRARIES` -- Component library and dependent libraries
- `MAGNUM_*_INCLUDE_DIRS` -- Include dirs of module dependencies
If exactly one `*Application` or exactly one `Windowless*Application` component
is requested and found, its libraries and include dirs are available in
@ -96,15 +125,15 @@ convenience aliases `MAGNUM_APPLICATION_LIBRARIES` /
Features of found %Magnum library are exposed in these CMake variables, they
are also available as preprocessor variables if including Magnum.h:
- `MAGNUM_BUILD_DEPRECATED` -- Defined if compiled with deprecated APIs
included
- `MAGNUM_BUILD_STATIC` -- Defined if built as static libraries. Default are
shared libraries.
- `MAGNUM_TARGET_GLES` -- Defined if compiled for OpenGL ES
- `MAGNUM_TARGET_GLES2` -- Defined if compiled for OpenGL ES 2.0
- `MAGNUM_TARGET_GLES3` -- Defined if compiled for OpenGL ES 3.0
- `MAGNUM_TARGET_DESKTOP_GLES` -- Defined if compiled with OpenGL ES emulation
on desktop OpenGL
- `MAGNUM_BUILD_DEPRECATED` -- Defined if compiled with deprecated APIs
included
- `MAGNUM_BUILD_STATIC` -- Defined if built as static libraries. Default are
shared libraries.
- `MAGNUM_TARGET_GLES` -- Defined if compiled for OpenGL ES
- `MAGNUM_TARGET_GLES2` -- Defined if compiled for OpenGL ES 2.0
- `MAGNUM_TARGET_GLES3` -- Defined if compiled for OpenGL ES 3.0
- `MAGNUM_TARGET_DESKTOP_GLES` -- Defined if compiled with OpenGL ES
emulation on desktop OpenGL
%Corrade library provides also its own set of CMake macros and variables, see
@ref corrade-cmake "its documentation" for more information.

4
doc/namespaces.dox

@ -139,6 +139,10 @@ library, you need to request `%MeshTools` component in CMake and link to
information.
*/
/** @dir Plugins
* @brief Basic plugins
*/
/** @dir Primitives
* @brief Namespace Magnum::Primitives
*/

98
external/OpenGL/GL/gl_magnum.c vendored

@ -2605,19 +2605,6 @@ static ogl_StrToExtMap ExtensionMap[8] = {
static int g_extensionMapSize = 8;
static ogl_StrToExtMap *FindExtEntry(const char *extensionName)
{
int loop;
ogl_StrToExtMap *currLoc = ExtensionMap;
for(loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
{
if(strcmp(extensionName, currLoc->extensionName) == 0)
return currLoc;
}
return NULL;
}
static void ClearExtensionVars()
{
ogl_ext_AMD_vertex_shader_layer = ogl_LOAD_FAILED;
@ -2630,65 +2617,29 @@ static void ClearExtensionVars()
ogl_ext_GREMEDY_string_marker = ogl_LOAD_FAILED;
}
static void LoadExtByName(const char *extensionName)
{
ogl_StrToExtMap *entry = NULL;
entry = FindExtEntry(extensionName);
if(entry)
{
if(entry->LoadExtension)
{
int numFailed = entry->LoadExtension();
if(numFailed == 0)
{
*(entry->extensionVariable) = ogl_LOAD_SUCCEEDED;
}
else
{
*(entry->extensionVariable) = ogl_LOAD_SUCCEEDED + numFailed;
}
}
else
{
*(entry->extensionVariable) = ogl_LOAD_SUCCEEDED;
}
}
}
static void ProcExtsFromExtString(const char *strExtList)
static void LoadExts()
{
size_t iExtListLen = strlen(strExtList);
const char *strExtListEnd = strExtList + iExtListLen;
const char *strCurrPos = strExtList;
char strWorkBuff[256];
while(*strCurrPos)
{
/*Get the extension at our position.*/
int iStrLen = 0;
const char *strEndStr = strchr(strCurrPos, ' ');
int iStop = 0;
if(strEndStr == NULL)
{
strEndStr = strExtListEnd;
iStop = 1;
}
iStrLen = (int)((ptrdiff_t)strEndStr - (ptrdiff_t)strCurrPos);
if(iStrLen > 255)
return;
strncpy(strWorkBuff, strCurrPos, iStrLen);
strWorkBuff[iStrLen] = '\0';
LoadExtByName(strWorkBuff);
strCurrPos = strEndStr + 1;
if(iStop) break;
}
int loop;
ogl_StrToExtMap *entry = ExtensionMap;
for(loop = 0; loop < g_extensionMapSize; ++loop, ++entry)
{
if(entry->LoadExtension)
{
int numFailed = entry->LoadExtension();
if(numFailed == 0)
{
*(entry->extensionVariable) = ogl_LOAD_SUCCEEDED;
}
else
{
*(entry->extensionVariable) = ogl_LOAD_SUCCEEDED + numFailed;
}
}
else
{
*(entry->extensionVariable) = ogl_LOAD_SUCCEEDED;
}
}
}
int ogl_LoadFunctions()
@ -2696,10 +2647,7 @@ int ogl_LoadFunctions()
int numFailed = 0;
ClearExtensionVars();
_ptrc_glGetString = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glGetString");
if(!_ptrc_glGetString) return ogl_LOAD_FAILED;
ProcExtsFromExtString((const char *)_ptrc_glGetString(GL_EXTENSIONS));
LoadExts();
numFailed = Load_Version_4_4();
if(numFailed == 0)

109
modules/FindMagnum.cmake

@ -7,6 +7,7 @@
# MAGNUM_LIBRARIES - Magnum library and dependent libraries
# MAGNUM_INCLUDE_DIRS - Root include dir and include dirs of
# dependencies
# MAGNUM_PLUGINS_INCLUDE_DIR - Include dir with plugins
# MAGNUM_PLUGINS_DIR - Base directory with plugins. You can modify
# it (e.g. set it to `.` when deploying on Windows with plugins stored
# relatively to the executable), the following MAGNUM_PLUGINS_*_DIR
@ -30,13 +31,20 @@
# Shapes - Shapes library (depends on SceneGraph component)
# Text - Text library (depends on TextureTools component)
# 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)
# TgaImageConverter - TGA image converter plugin
# TgaImporter - TGA importer plugin
# WavAudioImporter - WAV audio importer plugin (depends on Audio component)
# GlutApplication - GLUT application
# GlxApplication - GLX application
# NaClApplication - NaCl application
# Sdl2Application - SDL2 application
# XEglApplication - X/EGL application
# WindowlessNaClApplication - Windowless NaCl application
# WindowlessGlxApplication - Windowless GLX application
# WindowlessNaClApplication - Windowless NaCl application
# Example usage with specifying additional components is:
# find_package(Magnum [REQUIRED|COMPONENTS]
# MeshTools Primitives GlutApplication)
@ -167,15 +175,66 @@ endif()
foreach(component ${Magnum_FIND_COMPONENTS})
string(TOUPPER ${component} _COMPONENT)
# Find the library
find_library(MAGNUM_${_COMPONENT}_LIBRARY Magnum${component})
# AudioImporter plugin specific name suffixes
if(${component} MATCHES ".+AudioImporter$")
set(_MAGNUM_${_COMPONENT}_IS_PLUGIN 1)
set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX audioimporters)
# Audio importer class is Audio::*Importer, thus we need to convert
# *AudioImporter.h to *Importer.h
string(REPLACE "AudioImporter" "Importer" _MAGNUM_${_COMPONENT}_HEADER_NAME "${component}")
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES ${_MAGNUM_${_COMPONENT}_HEADER_NAME}.h)
# Importer plugin specific name suffixes
elseif(${component} MATCHES ".+Importer$")
set(_MAGNUM_${_COMPONENT}_IS_PLUGIN 1)
set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX importers)
# Font plugin specific name suffixes
elseif(${component} MATCHES ".+Font$")
set(_MAGNUM_${_COMPONENT}_IS_PLUGIN 1)
set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX fonts)
# ImageConverter plugin specific name suffixes
elseif(${component} MATCHES ".+ImageConverter$")
set(_MAGNUM_${_COMPONENT}_IS_PLUGIN 1)
set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX imageconverters)
# FontConverter plugin specific name suffixes
elseif(${component} MATCHES ".+FontConverter$")
set(_MAGNUM_${_COMPONENT}_IS_PLUGIN 1)
set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX fontconverters)
endif()
# Set plugin defaults, find the plugin
if(_MAGNUM_${_COMPONENT}_IS_PLUGIN)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Plugins/${component})
# Don't override the one for *AudioImporter plugins
if(NOT _MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES ${component}.h)
endif()
# Dynamic plugins don't have any prefix (e.g. `lib` on Linux), search
# with empty prefix and then reset that back so we don't accidentaly
# break something else
set(_tmp_prefixes ${CMAKE_FIND_LIBRARY_PREFIXES})
set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} "")
find_library(MAGNUM_${_COMPONENT}_LIBRARY ${component}
PATH_SUFFIXES magnum/${_MAGNUM_${_COMPONENT}_PATH_SUFFIX})
set(CMAKE_FIND_LIBRARY_PREFIXES ${_tmp_prefixes})
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX ${component})
# Set library defaults, find the library
else()
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX ${component})
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES ${component}.h)
find_library(MAGNUM_${_COMPONENT}_LIBRARY Magnum${component})
endif()
# Applications
if(${component} MATCHES .+Application)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Platform)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES ${component}.h)
# GLUT application dependencies
if(${component} STREQUAL GlutApplication)
@ -223,12 +282,9 @@ foreach(component ${Magnum_FIND_COMPONENTS})
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
endif()
endif()
# Audio library
if(${component} STREQUAL Audio)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Audio.h)
elseif(${component} STREQUAL Audio)
find_package(OpenAL)
if(OPENAL_FOUND)
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${OPENAL_LIBRARY})
@ -236,45 +292,17 @@ foreach(component ${Magnum_FIND_COMPONENTS})
else()
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
endif()
# DebugTools library
if(${component} STREQUAL DebugTools)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES DebugTools.h)
endif()
# Mesh tools library
if(${component} STREQUAL MeshTools)
elseif(${component} STREQUAL MeshTools)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES CompressIndices.h)
endif()
# Primitives library
if(${component} STREQUAL Primitives)
elseif(${component} STREQUAL Primitives)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Cube.h)
endif()
# Scene graph library
if(${component} STREQUAL SceneGraph)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES SceneGraph.h)
endif()
# Shaders library
if(${component} STREQUAL Shaders)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Shaders.h)
endif()
# Shapes library
if(${component} STREQUAL Shapes)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Shapes.h)
endif()
# Text library
if(${component} STREQUAL Text)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Text.h)
endif()
# TextureTools library
if(${component} STREQUAL TextureTools)
elseif(${component} STREQUAL TextureTools)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Atlas.h)
endif()
@ -367,6 +395,7 @@ set(MAGNUM_PLUGINS_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}
CACHE PATH "Base directory where to look for Magnum plugins")
# Plugin directories
set(MAGNUM_PLUGINS_INCLUDE_DIR ${MAGNUM_INCLUDE_DIR}/Plugins)
set(MAGNUM_PLUGINS_FONT_DIR ${MAGNUM_PLUGINS_DIR}/fonts)
set(MAGNUM_PLUGINS_FONTCONVERTER_DIR ${MAGNUM_PLUGINS_DIR}/fontconverters)
set(MAGNUM_PLUGINS_IMAGECONVERTER_DIR ${MAGNUM_PLUGINS_DIR}/imageconverters)

36
src/AbstractShaderProgram.h

@ -132,10 +132,20 @@ layout(location = 0, index = 0) out vec4 color;
layout(location = 1, index = 1) out vec3 normal;
@endcode
If you don't have the required extension, you can use functions
bindAttributeLocation() and bindFragmentDataLocation() /
bindFragmentDataLocationIndexed() between attaching the shaders and linking
the program:
If you don't have the required extension, declare the attributes without
`layout()` qualifier and use functions @ref bindAttributeLocation() and
@ref bindFragmentDataLocation() / @ref bindFragmentDataLocationIndexed() between
attaching the shaders and linking the program. Note that additional syntax
changes may be needed for GLSL 1.20 and GLSL ES 1.0.
@code
in vec4 position;
in vec3 normal;
in vec2 textureCoordinates;
@endcode
@code
out vec4 color;
out vec3 normal;
@endcode
@code
// Shaders attached...
@ -174,8 +184,14 @@ layout(location = 0) uniform mat4 transformation;
layout(location = 1) uniform mat4 projection;
@endcode
If you don't have the required extension, you can get uniform location using
uniformLocation() after linking stage:
If you don't have the required extension, declare the uniforms without the
`layout()` qualifier and get uniform location using @ref uniformLocation()
*after* linking stage. Note that additional syntax changes may be needed for
GLSL 1.20 and GLSL ES 1.0.
@code
uniform mat4 transformation;
uniform mat4 projection;
@endcode
@code
Int transformationUniform = uniformLocation("transformation");
Int projectionUniform = uniformLocation("projection");
@ -199,7 +215,13 @@ layout(binding = 1) uniform sampler2D specularTexture;
@endcode
If you don't have the required extension (or if you want to change the layer
later), you can set the texture layer uniform using setUniform(Int, Int):
later), declare the uniforms without the `layout()` qualifier and set the
texture layer uniform using @ref setUniform(Int, Int). Note that additional
syntax changes may be needed for GLSL 1.20 and GLSL ES 1.0.
@code
uniform sampler2D diffuseTexture;
uniform sampler2D specularTexture;
@endcode
@code
setUniform(DiffuseTextureUniform, DiffuseTextureLayer);
setUniform(SpecularTextureUniform, SpecularTextureLayer);

1
src/CMakeLists.txt

@ -205,6 +205,7 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/magnumConfigure.h DESTINATION ${MAGNUM
add_subdirectory(Math)
add_subdirectory(Platform)
add_subdirectory(Plugins)
add_subdirectory(Trade)
if(WITH_AUDIO)

4
src/ImageReference.h

@ -48,6 +48,7 @@ to change image properties, only data pointer.
Interchangeable with Image, BufferImage or Trade::ImageData.
@see ImageReference1D, ImageReference2D, ImageReference3D
@todo Provide const version somewhat
*/
template<UnsignedInt dimensions> class ImageReference: public AbstractImage {
public:
@ -59,9 +60,6 @@ template<UnsignedInt dimensions> class ImageReference: public AbstractImage {
* @param type Data type of pixel 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.
*/
constexpr explicit ImageReference(ColorFormat format, ColorType type, const typename DimensionTraits<Dimensions, Int>::VectorType& size, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {}

66
src/Math/Functions.h

@ -211,6 +211,51 @@ template<std::size_t size, class T> Vector<size, T> abs(const Vector<size, T>& a
}
#endif
/** @brief Nearest not larger integer */
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T floor(const T& a);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type floor(T a) {
return std::floor(a);
}
template<std::size_t size, class T> Vector<size, T> floor(const Vector<size, T>& a) {
Vector<size, T> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = std::floor(a[i]);
return out;
}
#endif
/** @brief Round value to nearest integer */
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T round(const T& a);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type round(T a) {
return std::round(a);
}
template<std::size_t size, class T> Vector<size, T> round(const Vector<size, T>& a) {
Vector<size, T> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = std::round(a[i]);
return out;
}
#endif
/** @brief Nearest not smaller integer */
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T ceil(const T& a);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type ceil(T a) {
return std::ceil(a);
}
template<std::size_t size, class T> Vector<size, T> ceil(const Vector<size, T>& a) {
Vector<size, T> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = std::ceil(a[i]);
return out;
}
#endif
/**
@brief Square root
@ -242,10 +287,7 @@ template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T
return T(1)/std::sqrt(a);
}
template<std::size_t size, class T> Vector<size, T> sqrtInverted(const Vector<size, T>& a) {
Vector<size, T> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = T(1)/std::sqrt(a[i]);
return out;
return Vector<size, T>(T(1))/sqrt(a);
}
#endif
@ -265,7 +307,7 @@ template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T
template<std::size_t size, class T> Vector<size, T> clamp(const Vector<size, T>& value, T min, T max) {
Vector<size, T> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = std::min(std::max(value[i], min), max);
out[i] = clamp(value[i], min, max);
return out;
}
#endif
@ -344,8 +386,9 @@ Converts integral value from full range of given *unsigned* integral type to
value in range @f$ [0, 1] @f$ or from *signed* integral to range @f$ [-1, 1] @f$.
@note For best precision, resulting `FloatingPoint` type should be always
larger that `Integral` type (e.g. Double from Int, LongDouble from Long and
similarly for vector types).
larger that `Integral` type (e.g. @ref Magnum::Float "Float" from
@ref Magnum::Short "Short", @ref Magnum::Double "Double" from
@ref Magnum::Int "Int" and similarly for vector types).
@attention To ensure the integral type is correctly detected when using
literals, this function should be called with both template parameters
@ -358,7 +401,7 @@ Float a = normalize<Float>('\xFF');
Float b = normalize<Float, UnsignedByte>('\xFF');
@endcode
@see denormalize()
@see @ref denormalize()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class FloatingPoint, class Integral> inline FloatingPoint normalize(const Integral& value);
@ -393,13 +436,14 @@ Converts floating-point value in range @f$ [0, 1] @f$ to full range of given
integral type.
@note For best precision, `FloatingPoint` type should be always larger that
resulting `Integral` type (e.g. Double to Int, LongDouble to Long and
similarly for vector types).
resulting `Integral` type (e.g. @ref Magnum::Float "Float" to
@ref Magnum::Short "Short", @ref Magnum::Double "Double" to @ref Magnum::Int "Int"
and similarly for vector types).
@attention Return value for floating point numbers outside the normalized
range is undefined.
@see normalize()
@see @ref normalize()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class Integral, class FloatingPoint> inline Integral denormalize(const FloatingPoint& value);

5
src/Math/Geometry/Rectangle.h

@ -132,6 +132,11 @@ template<class T> class Rectangle {
/** @brief %Rectangle height */
constexpr T height() const { return _topRight.y() - _bottomLeft.y(); }
/** @brief Translated rectangle */
Rectangle<T> translated(const Vector2<T>& vec) {
return {_bottomLeft + vec, _topRight + vec};
};
private:
Vector2<T> _bottomLeft;
Vector2<T> _topRight;

9
src/Math/Geometry/Test/RectangleTest.cpp

@ -44,6 +44,8 @@ class RectangleTest: public Corrade::TestSuite::Tester {
void compare();
void size();
void translated();
void debug();
void configuration();
};
@ -63,6 +65,8 @@ RectangleTest::RectangleTest() {
&RectangleTest::compare,
&RectangleTest::size,
&RectangleTest::translated,
&RectangleTest::debug,
&RectangleTest::configuration});
}
@ -144,6 +148,11 @@ void RectangleTest::size() {
CORRADE_COMPARE(rect.height(), 7);
}
void RectangleTest::translated() {
CORRADE_COMPARE(Rectanglei({34, 23}, {47, 30}).translated({-17, 40}),
Rectanglei({17, 63}, {30, 70}));
}
void RectangleTest::debug() {
std::ostringstream o;
Debug(&o) << Rectanglei({34, 23}, {47, 30});

25
src/Math/Test/FunctionsTest.cpp

@ -39,6 +39,11 @@ class FunctionsTest: public Corrade::TestSuite::Tester {
void maxList();
void sign();
void abs();
void floor();
void round();
void ceil();
void sqrt();
void sqrtInverted();
void clamp();
@ -76,6 +81,11 @@ FunctionsTest::FunctionsTest() {
&FunctionsTest::maxList,
&FunctionsTest::sign,
&FunctionsTest::abs,
&FunctionsTest::floor,
&FunctionsTest::round,
&FunctionsTest::ceil,
&FunctionsTest::sqrt,
&FunctionsTest::sqrtInverted,
&FunctionsTest::clamp,
@ -135,6 +145,21 @@ void FunctionsTest::abs() {
CORRADE_COMPARE(Math::abs(Vector3i(5, -3, 2)), Vector3i(5, 3, 2));
}
void FunctionsTest::floor() {
CORRADE_COMPARE(Math::floor(0.7f), 0.0f);
CORRADE_COMPARE(Math::floor(Vector3(2.3f, 0.7f, 1.5f)), Vector3(2.0f, 0.0f, 1.0f));
}
void FunctionsTest::round() {
CORRADE_COMPARE(Math::round(2.3f), 2.0f);
CORRADE_COMPARE(Math::round(Vector3(2.3f, 0.7f, 1.5f)), Vector3(2.0f, 1.0f, 2.0f));
}
void FunctionsTest::ceil() {
CORRADE_COMPARE(Math::ceil(2.3f), 3.0f);
CORRADE_COMPARE(Math::ceil(Vector3(2.3f, 0.7f, 1.5f)), Vector3(3.0f, 1.0f, 2.0f));
}
void FunctionsTest::sqrt() {
CORRADE_COMPARE(Math::sqrt(16), 4);
CORRADE_COMPARE(Math::sqrt(Vector3i(256, 1, 0)), Vector3i(16, 1, 0));

24
src/Math/Test/VectorTest.cpp

@ -74,6 +74,7 @@ class VectorTest: public Corrade::TestSuite::Tester {
void multiplyDivideIntegral();
void multiplyDivideComponentWise();
void multiplyDivideComponentWiseIntegral();
void modulo();
void bitwise();
void compare();
@ -128,6 +129,7 @@ VectorTest::VectorTest() {
&VectorTest::multiplyDivideIntegral,
&VectorTest::multiplyDivideComponentWise,
&VectorTest::multiplyDivideComponentWiseIntegral,
&VectorTest::modulo,
&VectorTest::bitwise,
&VectorTest::compare,
@ -342,6 +344,15 @@ void VectorTest::multiplyDivideComponentWiseIntegral() {
/* Using integer vector as divisor is not supported */
}
void VectorTest::modulo() {
typedef Math::Vector<2, Int> Vector2i;
const Vector2i a(4, 13);
const Vector2i b(2, 5);
CORRADE_COMPARE(a % 2, Vector2i(0, 1));
CORRADE_COMPARE(a % b, Vector2i(0, 3));
}
void VectorTest::bitwise() {
typedef Math::Vector<2, Int> Vector2i;
@ -484,9 +495,16 @@ void VectorTest::subclassTypes() {
CORRADE_VERIFY((std::is_same<decltype(a *= c), Vec2&>::value));
CORRADE_VERIFY((std::is_same<decltype(a /= c), Vec2&>::value));
/* Bitwise operations */
/* Modulo operations */
const Vec2i ci;
Vec2i i;
const Int j = {};
CORRADE_VERIFY((std::is_same<decltype(ci % j), Vec2i>::value));
CORRADE_VERIFY((std::is_same<decltype(i %= j), Vec2i&>::value));
CORRADE_VERIFY((std::is_same<decltype(ci % ci), Vec2i>::value));
CORRADE_VERIFY((std::is_same<decltype(i %= ci), Vec2i&>::value));
/* Bitwise operations */
CORRADE_VERIFY((std::is_same<decltype(~ci), Vec2i>::value));
CORRADE_VERIFY((std::is_same<decltype(ci & ci), Vec2i>::value));
CORRADE_VERIFY((std::is_same<decltype(ci | ci), Vec2i>::value));
@ -533,6 +551,10 @@ void VectorTest::subclass() {
CORRADE_COMPARE(Vec2(-2.0f, 5.0f)*Vec2(1.5f, -2.0f), Vec2(-3.0f, -10.0f));
CORRADE_COMPARE(Vec2(-2.0f, 5.0f)/Vec2(2.0f/3.0f, -0.5f), Vec2(-3.0f, -10.0f));
/* Modulo operations */
CORRADE_COMPARE(Vec2i(4, 13) % 2, Vec2i(0, 1));
CORRADE_COMPARE(Vec2i(4, 13) % Vec2i(2, 5), Vec2i(0, 3));
/* Bitwise operations */
CORRADE_COMPARE(~Vec2i(85, 240), Vec2i(-86, -241));
CORRADE_COMPARE(Vec2i(85, 240) & Vec2i(170, 85), Vec2i(0, 80));

79
src/Math/Vector.h

@ -573,6 +573,70 @@ template<std::size_t size, class T> inline Vector<size, T> operator/(
return out;
}
/** @relates Vector
@brief Do modulo of integral vector and assign
The computation is done in-place.
*/
template<std::size_t size, class Integral> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
typename std::enable_if<std::is_integral<Integral>::value, Vector<size, Integral>&>::type
#endif
operator%=(Vector<size, Integral>& a, Integral b) {
for(std::size_t i = 0; i != size; ++i)
a[i] %= b;
return a;
}
/** @relates Vector
@brief Modulo of integral vector
*/
template<std::size_t size, class Integral> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
typename std::enable_if<std::is_integral<Integral>::value, Vector<size, Integral>>::type
#endif
operator%(const Vector<size, Integral>& a, Integral b) {
Vector<size, Integral> copy(a);
return copy %= b;
}
/** @relates Vector
@brief Do modulo of two integral vectors and assign
The computation is done in-place.
*/
template<std::size_t size, class Integral> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
typename std::enable_if<std::is_integral<Integral>::value, Vector<size, Integral>&>::type
#endif
operator%=(Vector<size, Integral>& a, const Vector<size, Integral>& b) {
for(std::size_t i = 0; i != size; ++i)
a[i] %= b[i];
return a;
}
/** @relates Vector
@brief Modulo of two integral vectors
*/
template<std::size_t size, class Integral> inline
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
typename std::enable_if<std::is_integral<Integral>::value, Vector<size, Integral>>::type
#endif
operator%(const Vector<size, Integral>& a, const Vector<size, Integral>& b) {
Vector<size, Integral> copy(a);
return copy %= b;
}
/** @relates Vector
@brief Bitwise NOT of integral vector
*/
@ -1067,6 +1131,21 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit
return number/static_cast<const Math::Vector<size, T>&>(vector); \
} \
\
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator%=(Type<Integral>& a, Integral b) { \
static_cast<Math::Vector<size, Integral>&>(a) %= b; \
return a; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator%(const Type<Integral>& a, Integral b) { \
return static_cast<const Math::Vector<size, Integral>&>(a) % b; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator%=(Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
static_cast<Math::Vector<size, Integral>&>(a) %= b; \
return a; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator%(const Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
return static_cast<const Math::Vector<size, Integral>&>(a) % b; \
} \
\
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator~(const Type<Integral>& vector) { \
return ~static_cast<const Math::Vector<size, Integral>&>(vector); \
} \

8
src/Math/instantiation.cpp

@ -58,23 +58,23 @@ template struct ConfigurationValue<Magnum::Math::RectangularMatrix<4, 3, Magnum:
template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::Float>>;
template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::Float>>;
#ifndef _WIN32
#ifndef __MINGW32__
template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::Float>>;
#endif
template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::Int>>;
template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::Int>>;
#ifndef _WIN32
#ifndef __MINGW32__
template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::Int>>;
#endif
template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::UnsignedInt>>;
template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::UnsignedInt>>;
#ifndef _WIN32
#ifndef __MINGW32__
template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::UnsignedInt>>;
#endif
#ifndef MAGNUM_TARGET_GLES
template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::Double>>;
template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::Double>>;
#ifndef _WIN32
#ifndef __MINGW32__
template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::Double>>;
#endif
#endif

6
src/Mesh.cpp

@ -138,7 +138,7 @@ Mesh& Mesh::operator=(Mesh&& other) noexcept {
}
Mesh& Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end) {
#ifdef CORRADE_TARGET_NACL
#if defined(CORRADE_TARGET_NACL) || defined(CORRADE_TARGET_EMSCRIPTEN)
CORRADE_ASSERT(buffer.targetHint() == Buffer::Target::ElementArray,
"Mesh::setIndexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::ElementArray << "but got" << buffer.targetHint(), *this);
#endif
@ -265,7 +265,7 @@ void Mesh::destroyImplementationVAO() {
}
void Mesh::attributePointerImplementationDefault(const Attribute& attribute) {
#ifdef CORRADE_TARGET_NACL
#if defined(CORRADE_TARGET_NACL) || defined(CORRADE_TARGET_EMSCRIPTEN)
CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::Target::Array,
"Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::Array << "but got" << attribute.buffer->targetHint(), );
#endif
@ -274,7 +274,7 @@ void Mesh::attributePointerImplementationDefault(const Attribute& attribute) {
}
void Mesh::attributePointerImplementationVAO(const Attribute& attribute) {
#ifdef CORRADE_TARGET_NACL
#if defined(CORRADE_TARGET_NACL) || defined(CORRADE_TARGET_EMSCRIPTEN)
CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::Target::Array,
"Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::Array << "but got" << attribute.buffer->targetHint(), );
#endif

6
src/Platform/AbstractXApplication.cpp

@ -174,6 +174,12 @@ int AbstractXApplication::exec() {
return 0;
}
void AbstractXApplication::keyPressEvent(KeyEvent&) {}
void AbstractXApplication::keyReleaseEvent(KeyEvent&) {}
void AbstractXApplication::mousePressEvent(MouseEvent&) {}
void AbstractXApplication::mouseReleaseEvent(MouseEvent&) {}
void AbstractXApplication::mouseMoveEvent(MouseMoveEvent&) {}
AbstractXApplication::Configuration::Configuration(): _title("Magnum X Application"), _size(800, 600) {}
AbstractXApplication::Configuration::~Configuration() = default;

7
src/Platform/AbstractXApplication.h

@ -493,13 +493,6 @@ class AbstractXApplication::MouseMoveEvent: public AbstractXApplication::InputEv
const Vector2i _position;
};
/* Implementations for inline functions with unused parameters */
inline void AbstractXApplication::keyPressEvent(KeyEvent&) {}
inline void AbstractXApplication::keyReleaseEvent(KeyEvent&) {}
inline void AbstractXApplication::mousePressEvent(MouseEvent&) {}
inline void AbstractXApplication::mouseReleaseEvent(MouseEvent&) {}
inline void AbstractXApplication::mouseMoveEvent(MouseMoveEvent&) {}
}}
#endif

11
src/Platform/CMakeLists.txt

@ -22,6 +22,15 @@
# DEALINGS IN THE SOFTWARE.
#
# Headers
set(Platform_HEADERS
Platform.h
Screen.h
ScreenedApplication.h
ScreenedApplication.hpp)
install(FILES ${Platform_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform)
# GLUT application
if(WITH_GLUTAPPLICATION)
find_package(GLUT)
@ -169,7 +178,7 @@ endif()
# Magnum Info
if(WITH_MAGNUMINFO)
if(NOT UNIX AND NOT CORRADE_TARGET_NACL)
message(FATAL_ERROR "magnum-info is not available on this platform. Set WITH_MAGNUMINFO to OFF to suppress this warning.")
message(FATAL_ERROR "magnum-info is not available on this platform. Set WITH_MAGNUMINFO to OFF to skip building it.")
endif()
add_executable(magnum-info magnum-info.cpp)

11
src/Platform/GlutApplication.cpp

@ -26,6 +26,8 @@
#include "Context.h"
#include "Platform/ScreenedApplication.hpp"
namespace Magnum { namespace Platform {
GlutApplication* GlutApplication::instance = nullptr;
@ -115,7 +117,16 @@ void GlutApplication::staticMouseMoveEvent(int x, int y) {
instance->mouseMoveEvent(e);
}
void GlutApplication::keyPressEvent(KeyEvent&) {}
void GlutApplication::keyReleaseEvent(KeyEvent&) {}
void GlutApplication::mousePressEvent(MouseEvent&) {}
void GlutApplication::mouseReleaseEvent(MouseEvent&) {}
void GlutApplication::mouseMoveEvent(MouseMoveEvent&) {}
GlutApplication::Configuration::Configuration(): _title("Magnum GLUT Application"), _size(800, 600), _sampleCount(0) {}
GlutApplication::Configuration::~Configuration() = default;
template class BasicScreen<GlutApplication>;
template class BasicScreenedApplication<GlutApplication>;
}}

20
src/Platform/GlutApplication.h

@ -30,10 +30,12 @@
#include <string>
#include "Platform/Platform.h"
#include "Math/Vector2.h"
#include "Magnum.h"
#include "OpenGL.h"
/* We must include our own GL headers first to avoid conflicts */
#include "OpenGL.h"
#include <GL/freeglut.h>
namespace Magnum {
@ -202,6 +204,14 @@ class GlutApplication {
*/
virtual void keyPressEvent(KeyEvent& event);
/**
* @brief Key release event
*
* Included only for compatibility with other toolkits, doesn't get
* called at all.
*/
virtual void keyReleaseEvent(KeyEvent& event);
/*@}*/
/** @{ @name Mouse handling */
@ -546,6 +556,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef GlutApplication Application;
typedef BasicScreen<GlutApplication> Screen;
typedef BasicScreenedApplication<GlutApplication> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_GLUTAPPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN
@ -554,12 +566,6 @@ typedef GlutApplication Application;
CORRADE_ENUMSET_OPERATORS(GlutApplication::MouseMoveEvent::Buttons)
/* Implementations for inline functions with unused parameters */
inline void GlutApplication::keyPressEvent(KeyEvent&) {}
inline void GlutApplication::mousePressEvent(MouseEvent&) {}
inline void GlutApplication::mouseReleaseEvent(MouseEvent&) {}
inline void GlutApplication::mouseMoveEvent(MouseMoveEvent&) {}
}}
#endif

4
src/Platform/GlxApplication.cpp

@ -24,6 +24,7 @@
#include "GlxApplication.h"
#include "Platform/ScreenedApplication.hpp"
#include "Platform/Implementation/GlxContextHandler.h"
namespace Magnum { namespace Platform {
@ -37,4 +38,7 @@ GlxApplication::GlxApplication(const Arguments& arguments, void*)
#endif
: AbstractXApplication(new Implementation::GlxContextHandler, arguments, nullptr) {}
template class BasicScreen<GlxApplication>;
template class BasicScreenedApplication<GlxApplication>;
}}

3
src/Platform/GlxApplication.h

@ -29,6 +29,7 @@
*/
#include "Platform/AbstractXApplication.h"
#include "Platform/Platform.h"
namespace Magnum { namespace Platform {
@ -108,6 +109,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef GlxApplication Application;
typedef BasicScreen<GlxApplication> Screen;
typedef BasicScreenedApplication<GlxApplication> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_GLXAPPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN

10
src/Platform/NaClApplication.cpp

@ -30,6 +30,7 @@
#include <Utility/NaClStreamBuffer.h>
#include "Context.h"
#include "Platform/ScreenedApplication.hpp"
namespace Magnum { namespace Platform {
@ -255,4 +256,13 @@ void NaClApplication::mouseLockCallback(void* applicationInstance, std::int32_t)
instance->flags |= Flag::MouseLocked;
}
void NaClApplication::keyPressEvent(KeyEvent&) {}
void NaClApplication::keyReleaseEvent(KeyEvent&) {}
void NaClApplication::mousePressEvent(MouseEvent&) {}
void NaClApplication::mouseReleaseEvent(MouseEvent&) {}
void NaClApplication::mouseMoveEvent(MouseMoveEvent&) {}
template class BasicScreen<NaClApplication>;
template class BasicScreenedApplication<NaClApplication>;
}}

10
src/Platform/NaClApplication.h

@ -37,6 +37,7 @@
#include <ppapi/cpp/graphics_3d_client.h>
#include <ppapi/gles2/gl2ext_ppapi.h>
#include "Platform/Platform.h"
#include "Math/Vector2.h"
#include "Magnum.h"
@ -669,6 +670,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef NaClApplication Application;
typedef BasicScreen<NaClApplication> Screen;
typedef BasicScreenedApplication<NaClApplication> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_NACLAPPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN
@ -678,13 +681,6 @@ typedef NaClApplication Application;
CORRADE_ENUMSET_OPERATORS(NaClApplication::InputEvent::Modifiers)
CORRADE_ENUMSET_OPERATORS(NaClApplication::InputEvent::Buttons)
/* Implementations for inline functions with unused parameters */
inline void NaClApplication::keyPressEvent(KeyEvent&) {}
inline void NaClApplication::keyReleaseEvent(KeyEvent&) {}
inline void NaClApplication::mousePressEvent(MouseEvent&) {}
inline void NaClApplication::mouseReleaseEvent(MouseEvent&) {}
inline void NaClApplication::mouseMoveEvent(MouseMoveEvent&) {}
}}
#endif

38
src/Platform/Platform.h

@ -0,0 +1,38 @@
#ifndef Magnum_Platform_Platform_h
#define Magnum_Platform_Platform_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
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 Forward declarations for @ref Magnum::Platform namespace
*/
namespace Magnum { namespace Platform {
template<class> class BasicScreen;
template<class> class BasicScreenedApplication;
}}
#endif

265
src/Platform/Screen.h

@ -0,0 +1,265 @@
#ifndef Magnum_Platform_AbstractScreen_h
#define Magnum_Platform_AbstractScreen_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
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::Platform::BasicScreen
*/
#include <Containers/EnumSet.h>
#include "Platform/ScreenedApplication.h"
namespace Magnum { namespace Platform {
namespace Implementation {
enum class PropagatedScreenEvent: UnsignedByte {
Draw = 1 << 0,
Input = 1 << 1
};
typedef Containers::EnumSet<PropagatedScreenEvent, UnsignedByte> PropagatedScreenEvents;
CORRADE_ENUMSET_OPERATORS(PropagatedScreenEvents)
}
/**
@brief Base for application screens
See @ref BasicScreenedApplication for more information.
If exactly one application header is included, this class is also aliased to
`Platform::Screen`.
@section Screen-explicit-specializations Explicit template specializations
The following specialization are explicitly compiled into each particular
`*Application` library. For other specializations you have to use
@ref ScreenedApplication.hpp implementation file to avoid linker errors. See
@ref compilation-speedup-hpp for more information.
- @ref GlutApplication "BasicScreen<GlutApplication>"
- @ref GlxApplication "BasicScreen<GlxApplication>"
- @ref NaClApplication "BasicScreen<NaClApplication>"
- @ref Sdl2Application "BasicScreen<Sdl2Application>"
- @ref XEglApplication "BasicScreen<XEglApplication>"
*/
template<class Application> class BasicScreen: private Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>> {
friend class Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>;
friend class Containers::LinkedList<BasicScreen<Application>>;
friend class BasicScreenedApplication<Application>;
public:
#ifdef DOXYGEN_GENERATING_OUTPUT
/**
* @brief Event propagated to given screen
*
* @see @ref PropagatedEvents, @ref BasicScreen::setPropagatedEvents()
*/
enum class PropagatedEvent: UnsignedByte {
/**
* Draw event.
*
* When enabled, drawEvent() is propagated to this screen.
*/
Draw = 1 << 0,
/**
* Input events.
*
* When enabled, keyPressEvent(), keyReleaseEvent(), mousePressEvent(),
* mouseReleaseEvent() and mouseMoveEvent() are propagated to this
* screen.
*/
Input = 1 << 1
};
/**
* @brief Events propagated to given screen
*
* @see @ref setPropagatedEvents()
*/
typedef Containers::EnumSet<PropagatedEvent, UnsignedByte> PropagatedEvents;
#else
typedef Implementation::PropagatedScreenEvent PropagatedEvent;
typedef Implementation::PropagatedScreenEvents PropagatedEvents;
#endif
/** @brief Input event */
typedef typename BasicScreenedApplication<Application>::InputEvent InputEvent;
/** @brief Key event */
typedef typename BasicScreenedApplication<Application>::KeyEvent KeyEvent;
/** @brief Mouse event */
typedef typename BasicScreenedApplication<Application>::MouseEvent MouseEvent;
/** @brief Mouse move event */
typedef typename BasicScreenedApplication<Application>::MouseMoveEvent MouseMoveEvent;
explicit BasicScreen();
~BasicScreen();
/** @brief Events propagated to this screen */
PropagatedEvents propagatedEvents() const { return _propagatedEvents; }
/**
* @brief Set events propagated to this screen
*
* For non-propagated events related event functions are not called.
* No events are propagated by default, call this function in
* @ref focusEvent() and @ref blurEvent() to reflect focus changes.
*/
void setPropagatedEvents(PropagatedEvents events) { _propagatedEvents = events; }
/** @brief %Application holding this screen */
template<class T = BasicScreenedApplication<Application>> T* application() {
return static_cast<T*>(Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::list());
}
/** @overload */
template<class T = BasicScreenedApplication<Application>> const T* application() const {
return static_cast<const T*>(Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::list());
}
/**
* @brief Next nearer screen
*
* @see @ref BasicScreenedApplication::frontScreen(),
* @ref BasicScreenedApplication::backScreen()
*/
BasicScreen<Application>* nextNearerScreen() {
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::previous();
}
/** @overload */
const BasicScreen<Application>* nextNearerScreen() const {
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::previous();
}
/**
* @brief Next farther screen
*
* @see @ref BasicScreenedApplication::frontScreen(),
* @ref BasicScreenedApplication::backScreen()
*/
BasicScreen<Application>* nextFartherScreen() {
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::next();
}
/** @overload */
const BasicScreen<Application>* nextFartherScreen() const {
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::next();
}
protected:
/** @brief Request redraw */
virtual void redraw() { application()->redraw(); }
/**
* @brief Focus event
*
* Called when screen is focused using @ref BasicScreenedApplication::focusScreen()
* or @ref BasicScreenedApplication::addScreen().
*/
virtual void focusEvent() = 0;
/**
* @brief Blur event
*
* Called when another screen is focused using @ref BasicScreenedApplication::focusScreen(),
* @ref BasicScreenedApplication::addScreen() or before the screen is
* removed from application using @ref BasicScreenedApplication::removeScreen().
*/
virtual void blurEvent() = 0;
/**
* @brief Viewport event
*
* Called from holder application when viewport size changes. See
* @ref Sdl2Application::viewportEvent() "*Application::viewportEvent()"
* for more information. Setting viewport on default framebuffer should
* be done by the holder application.
*/
virtual void viewportEvent(const Vector2i& size) = 0;
/**
* @brief Draw event
*
* Called when @ref PropagatedEvent::Draw is enabled and the screen is
* redrawn. See @ref Sdl2Application::viewportEvent() "*Application::viewportEvent()"
* for more information. Buffer swapping and clearing of default
* framebufer should be done by the holder application.
*/
virtual void drawEvent() = 0;
/**
* @brief Key press event
*
* Called when @ref PropagatedEvent::Input is enabled and an key is
* pressed. See @ref Sdl2Application::keyPressEvent() "*Application::keyPressEvent()"
* for more information.
*/
virtual void keyPressEvent(KeyEvent& event);
/**
* @brief Key release event
*
* Called when @ref PropagatedEvent::Input is enabled and an key is
* released. See @ref Sdl2Application::keyReleaseEvent() "*Application::keyReleaseEvent()"
* for more information.
*/
virtual void keyReleaseEvent(KeyEvent& event);
/**
* @brief Mouse press event
*
* Called when @ref PropagatedEvent::Input is enabled and mouse button
* is pressed. See @ref Sdl2Application::mousePressEvent() "*Application::mousePressEvent()"
* for more information.
*/
virtual void mousePressEvent(MouseEvent& event);
/**
* @brief Mouse release event
*
* Called when @ref PropagatedEvent::Input is enabled and mouse button
* is released. See @ref Sdl2Application::mouseReleaseEvent() "*Application::mouseReleaseEvent()"
* for more information.
*/
virtual void mouseReleaseEvent(MouseEvent& event);
/**
* @brief Mouse move event
*
* Called when @ref PropagatedEvent::Input is enabled and mouse is
* moved. See @ref Sdl2Application::mouseMoveEvent() "*Application::mouseMoveEvent()"
* for more information.
*/
virtual void mouseMoveEvent(MouseMoveEvent& event);
private:
PropagatedEvents _propagatedEvents;
};
}}
#endif

199
src/Platform/ScreenedApplication.h

@ -0,0 +1,199 @@
#ifndef Magnum_Platform_ScreenedApplication_h
#define Magnum_Platform_ScreenedApplication_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
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::Platform::BasicScreenedApplication
*/
#include <Containers/LinkedList.h>
#include <Magnum.h>
#include "Platform/Platform.h"
namespace Magnum { namespace Platform {
/**
@brief Base for applications with screen management
Manages list of screens and propagates events to them.
If exactly one application header is included, this class is also aliased to
`Platform::ScreenedApplication`.
Each @ref BasicScreen "Screen" specifies which set of events should be
propagated to it using @ref BasicScreen::setPropagatedEvents(). When
application gets an event, they are propagated to the screens:
- @ref Sdl2Application::viewportEvent() "viewportEvent()" is propagated to
all screens.
- @ref Sdl2Application::drawEvent() "drawEvent()" is propagated in
back-to-front order to screens which have @ref BasicScreen::PropagatedEvent::Draw
enabled.
- Input events (@ref Sdl2Application::keyPressEvent() "keyPressEvent()",
@ref Sdl2Application::keyReleaseEvent() "keyReleaseEvent()",
@ref Sdl2Application::mousePressEvent() "mousePressEvent()",
@ref Sdl2Application::mouseReleaseEvent() "mouseReleaseEvent()"
and @ref Sdl2Application::mouseMoveEvent() "mouseMoveEvent()")
are propagated in front-to-back order to screens which have
@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:
@code
// front-to-back
for(Screen* s = app.frontScreen(); s; s = s->nextFartherScreen()) {
// ...
}
// back-to-front
for(Screen* s = app.backScreen(); s; s = s->nextNearerScreen()) {
// ...
}
@endcode
@section ScreenedApplication-explicit-specializations Explicit template specializations
The following specialization are explicitly compiled into each particular
`*Application` library. For other specializations you have to use
@ref ScreenedApplication.hpp implementation file to avoid linker errors. See
@ref compilation-speedup-hpp for more information.
- @ref GlutApplication "BasicScreenedApplication<GlutApplication>"
- @ref GlxApplication "BasicScreenedApplication<GlxApplication>"
- @ref NaClApplication "BasicScreenedApplication<NaClApplication>"
- @ref Sdl2Application "BasicScreenedApplication<Sdl2Application>"
- @ref XEglApplication "BasicScreenedApplication<XEglApplication>"
*/
template<class Application> class BasicScreenedApplication: public Application, private Containers::LinkedList<BasicScreen<Application>> {
friend class Containers::LinkedList<BasicScreen<Application>>;
friend class Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>;
friend class BasicScreen<Application>;
public:
/** @copydoc Sdl2Application::Sdl2Application(const Arguments, const Configuration&) */
BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration = Application::Configuration()): Application(arguments, configuration) {}
/** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */
BasicScreenedApplication(const typename Application::Arguments& arguments, std::nullptr_t): Application(arguments, nullptr) {}
/**
* @brief Add screen to application
* @return Reference to self (for method chaining)
*
* The new screen is added as backmost. If this is the first screen
* added, @ref BasicScreen::focusEvent() is called. If not, neither
* @ref BasicScreen::blurEvent() nor @ref BasicScreen::focusEvent() is
* called (i.e. the screen default state is used).
*/
BasicScreenedApplication<Application>& addScreen(BasicScreen<Application>& screen);
/**
* @brief Remove screen from application
* @return Reference to self (for method chaining)
*
* The screen is blurred before removing. Deleting the object is left
* up to the user.
* @see @ref BasicScreen::blurEvent()
*/
BasicScreenedApplication<Application>& removeScreen(BasicScreen<Application>& screen);
/**
* @brief Focus screen
* @return Reference to self (for method chaining)
*
* Moves the screen to front. Previously focused screen is blurred and
* this screen is focused.
* @see @ref BasicScreen::blurEvent(), @ref BasicScreen::focusEvent()
*/
BasicScreenedApplication<Application>& focusScreen(BasicScreen<Application>& screen);
/**
* @brief Front screen
*
* @see @ref BasicScreen::nextFartherScreen(), @ref BasicScreen::nextNearerScreen()
*/
BasicScreen<Application>* frontScreen() {
return Containers::LinkedList<BasicScreen<Application>>::first();
}
/** @overload */
const BasicScreen<Application>* frontScreen() const {
return Containers::LinkedList<BasicScreen<Application>>::first();
}
/**
* @brief Back screen
*
* @see @ref BasicScreen::nextFartherScreen(), @ref BasicScreen::nextNearerScreen()
*/
BasicScreen<Application>* backScreen() {
return Containers::LinkedList<BasicScreen<Application>>::last();
}
/** @overload */
const BasicScreen<Application>* backScreen() const {
return Containers::LinkedList<BasicScreen<Application>>::last();
}
protected:
/**
* @brief Global viewport event
*
* Called when window size changes, *before* all screens'
* @ref BasicScreen::viewportEvent() "viewportEvent()". You should at
* least pass the new size to @ref DefaultFramebuffer::setViewport().
*
* Note that this function might not get called at all if the window
* size doesn't change. You are responsible for configuring the initial
* state yourself, viewport of default framebuffer can be retrieved
* from @ref DefaultFramebuffer::viewport().
*/
virtual void globalViewportEvent(const Vector2i& size) = 0;
/**
* @brief Draw event
*
* Called *after* all screens' @ref BasicScreen::drawEvent() "drawEvent()".
* You should call at least @ref Sdl2Application::swapBuffers() "swapBuffers()".
* If you want to draw immediately again, call also
* @ref Sdl2Application::redraw() "redraw()".
*/
virtual void globalDrawEvent() = 0;
private:
/* The user is supposed to override only globalViewportEvent() and
globalDrawEvent(), these implementations are dispatching the events
to attached screens. */
void viewportEvent(const Vector2i& size) override final;
void drawEvent() override final;
void keyPressEvent(typename Application::KeyEvent& event) override final;
void keyReleaseEvent(typename Application::KeyEvent& event) override final;
void mousePressEvent(typename Application::MouseEvent& event) override final;
void mouseReleaseEvent(typename Application::MouseEvent& event) override final;
void mouseMoveEvent(typename Application::MouseMoveEvent& event) override final;
};
}}
#endif

136
src/Platform/ScreenedApplication.hpp

@ -0,0 +1,136 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
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 @ref compilation-speedup-hpp "Template implementation" for @ref ScreenedApplication.h and @ref Screen.h
*/
#include "ScreenedApplication.h"
#include "Platform/Screen.h"
namespace Magnum { namespace Platform {
template<class Application> BasicScreen<Application>::BasicScreen() = default;
template<class Application> BasicScreen<Application>::~BasicScreen() = default;
template<class Application> void BasicScreen<Application>::keyPressEvent(KeyEvent&) {}
template<class Application> void BasicScreen<Application>::keyReleaseEvent(KeyEvent&) {}
template<class Application> void BasicScreen<Application>::mousePressEvent(MouseEvent&) {}
template<class Application> void BasicScreen<Application>::mouseReleaseEvent(MouseEvent&) {}
template<class Application> void BasicScreen<Application>::mouseMoveEvent(MouseMoveEvent&) {}
template<class Application> BasicScreenedApplication<Application>& BasicScreenedApplication<Application>::addScreen(BasicScreen<Application>& screen) {
Containers::LinkedList<BasicScreen<Application>>::insert(&screen);
if(frontScreen() == &screen) screen.focusEvent();
Application::redraw();
return *this;
}
template<class Application> BasicScreenedApplication<Application>& BasicScreenedApplication<Application>::removeScreen(BasicScreen<Application>& screen) {
screen.blurEvent();
Containers::LinkedList<BasicScreen<Application>>::erase(&screen);
Application::redraw();
return *this;
}
template<class Application> BasicScreenedApplication<Application>& BasicScreenedApplication<Application>::focusScreen(BasicScreen<Application>& screen) {
/* Already focused, nothing to do */
if(frontScreen() == &screen) return *this;
frontScreen()->blurEvent();
Containers::LinkedList<BasicScreen<Application>>::move(&screen, frontScreen());
screen.focusEvent();
Application::redraw();
return *this;
}
template<class Application> void BasicScreenedApplication<Application>::viewportEvent(const Vector2i& size) {
/* Call viewport event after all other (because of framebuffer resizing) */
globalViewportEvent(size);
for(BasicScreen<Application>* s = Containers::LinkedList<BasicScreen<Application>>::first(); s; s = s->next())
s->viewportEvent(size);
}
template<class Application> void BasicScreenedApplication<Application>::drawEvent() {
/* Back-to-front rendering */
for(BasicScreen<Application>* s = backScreen(); s; s = s->nextNearerScreen())
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Draw) s->drawEvent();
/* Call global event after all other (because of buffer swapping) */
globalDrawEvent();
}
template<class Application> void BasicScreenedApplication<Application>::keyPressEvent(typename Application::KeyEvent& event) {
/* Front-to-back event propagation, stop when the event gets accepted */
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) {
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) {
s->keyPressEvent(event);
if(event.isAccepted()) break;
}
}
}
template<class Application> void BasicScreenedApplication<Application>::keyReleaseEvent(typename Application::KeyEvent& event) {
/* Front-to-back event propagation, stop when the event gets accepted */
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) {
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) {
s->keyReleaseEvent(event);
if(event.isAccepted()) break;
}
}
}
template<class Application> void BasicScreenedApplication<Application>::mousePressEvent(typename Application::MouseEvent& event) {
/* Front-to-back event propagation, stop when the event gets accepted */
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) {
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) {
s->mousePressEvent(event);
if(event.isAccepted()) break;
}
}
}
template<class Application> void BasicScreenedApplication<Application>::mouseReleaseEvent(typename Application::MouseEvent& event) {
/* Front-to-back event propagation, stop when the event gets accepted */
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) {
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) {
s->mouseReleaseEvent(event);
if(event.isAccepted()) break;
}
}
}
template<class Application> void BasicScreenedApplication<Application>::mouseMoveEvent(typename Application::MouseMoveEvent& event) {
/* Front-to-back event propagation, stop when the event gets accepted */
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) {
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) {
s->mouseMoveEvent(event);
if(event.isAccepted()) break;
}
}
}
}}

10
src/Platform/Sdl2Application.cpp

@ -29,6 +29,7 @@
#endif
#include "Context.h"
#include "Platform/ScreenedApplication.hpp"
namespace Magnum { namespace Platform {
@ -248,6 +249,12 @@ void Sdl2Application::setMouseLocked(bool enabled) {
#endif
}
void Sdl2Application::keyPressEvent(KeyEvent&) {}
void Sdl2Application::keyReleaseEvent(KeyEvent&) {}
void Sdl2Application::mousePressEvent(MouseEvent&) {}
void Sdl2Application::mouseReleaseEvent(MouseEvent&) {}
void Sdl2Application::mouseMoveEvent(MouseMoveEvent&) {}
Sdl2Application::Configuration::Configuration(): _title("Magnum SDL2 Application"), _size(800, 600), _flags(Flag::Resizable), _sampleCount(0) {}
Sdl2Application::Configuration::~Configuration() = default;
@ -263,4 +270,7 @@ Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseMoveEvent::modifier
return _modifiers = fixedModifiers(SDL_GetModState());
}
template class BasicScreen<Sdl2Application>;
template class BasicScreenedApplication<Sdl2Application>;
}}

10
src/Platform/Sdl2Application.h

@ -30,6 +30,7 @@
#include <Containers/EnumSet.h>
#include "Platform/Platform.h"
#include "Math/Vector2.h"
#include "Magnum.h"
@ -656,6 +657,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef Sdl2Application Application;
typedef BasicScreen<Sdl2Application> Screen;
typedef BasicScreenedApplication<Sdl2Application> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_SDL2APPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN
@ -665,13 +668,6 @@ typedef Sdl2Application Application;
CORRADE_ENUMSET_OPERATORS(Sdl2Application::InputEvent::Modifiers)
CORRADE_ENUMSET_OPERATORS(Sdl2Application::MouseMoveEvent::Buttons)
/* Implementations for inline functions with unused parameters */
inline void Sdl2Application::keyPressEvent(KeyEvent&) {}
inline void Sdl2Application::keyReleaseEvent(KeyEvent&) {}
inline void Sdl2Application::mousePressEvent(MouseEvent&) {}
inline void Sdl2Application::mouseReleaseEvent(MouseEvent&) {}
inline void Sdl2Application::mouseMoveEvent(MouseMoveEvent&) {}
}}
#endif

4
src/Platform/XEglApplication.cpp

@ -24,6 +24,7 @@
#include "XEglApplication.h"
#include "Platform/ScreenedApplication.hpp"
#include "Platform/Implementation/EglContextHandler.h"
namespace Magnum { namespace Platform {
@ -37,4 +38,7 @@ XEglApplication::XEglApplication(const Arguments& arguments, void*)
#endif
: AbstractXApplication(new Implementation::EglContextHandler, arguments, nullptr) {}
template class BasicScreen<XEglApplication>;
template class BasicScreenedApplication<XEglApplication>;
}}

3
src/Platform/XEglApplication.h

@ -28,6 +28,7 @@
* @brief Class @ref Magnum::Platform::XEglApplication
*/
#include "Platform/Platform.h"
#include "Platform/AbstractXApplication.h"
namespace Magnum { namespace Platform {
@ -109,6 +110,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef XEglApplication Application;
typedef BasicScreen<XEglApplication> Screen;
typedef BasicScreenedApplication<XEglApplication> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_XEGLAPPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN

54
src/Plugins/CMakeLists.txt

@ -0,0 +1,54 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
#
# 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_directories(${CMAKE_CURRENT_SOURCE_DIR})
# Wrapper for creating given plugin type
macro(add_plugin)
if(NOT BUILD_STATIC)
corrade_add_plugin(${ARGN})
else()
corrade_add_static_plugin(${ARGN})
endif()
endmacro()
if(WITH_TEXT AND WITH_MAGNUMFONT)
add_subdirectory(MagnumFont)
endif()
if(WITH_TEXT AND WITH_MAGNUMFONTCONVERTER AND NOT MAGNUM_TARGET_GLES)
add_subdirectory(MagnumFontConverter)
endif()
if(WITH_TGAIMAGECONVERTER)
add_subdirectory(TgaImageConverter)
endif()
if(WITH_TGAIMPORTER)
add_subdirectory(TgaImporter)
endif()
if(WITH_AUDIO AND WITH_WAVAUDIOIMPORTER)
add_subdirectory(WavAudioImporter)
endif()

12
src/Plugins/MagnumFont/CMakeLists.txt

@ -22,8 +22,6 @@
# DEALINGS IN THE SOFTWARE.
#
find_package(Magnum REQUIRED Text)
set(MagnumFont_SOURCES
MagnumFont.cpp)
@ -37,9 +35,7 @@ add_plugin(MagnumFont ${MAGNUM_PLUGINS_FONT_INSTALL_DIR}
MagnumFont.conf
$<TARGET_OBJECTS:MagnumFontObjects>
pluginRegistrationMagnumFont.cpp)
target_link_libraries(MagnumFont
${MAGNUM_LIBRARIES}
${MAGNUM_TEXT_LIBRARIES})
target_link_libraries(MagnumFont Magnum MagnumText)
if(WIN32)
target_link_libraries(MagnumFont TgaImporter)
@ -49,10 +45,6 @@ install(FILES ${MagnumFont_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL
if(BUILD_GL_TESTS)
add_library(MagnumFontTestLib STATIC $<TARGET_OBJECTS:MagnumFontObjects>)
target_link_libraries(MagnumFontTestLib
${MAGNUM_LIBRARIES}
${MAGNUM_TEXT_LIBRARIES}
TgaImporterTestLib)
target_link_libraries(MagnumFontTestLib Magnum MagnumText TgaImporterTestLib)
add_subdirectory(Test)
endif()

81
src/Plugins/MagnumFont/MagnumFont.cpp

@ -25,11 +25,11 @@
#include "MagnumFont.h"
#include <sstream>
#include <Containers/Array.h>
#include <Utility/Directory.h>
#include <Utility/Unicode.h>
#include <Text/GlyphCache.h>
#include <Trade/ImageData.h>
#include "Containers/Array.h"
#include "Utility/Directory.h"
#include "Utility/Unicode.h"
#include "Text/GlyphCache.h"
#include "Trade/ImageData.h"
#include "TgaImporter/TgaImporter.h"
@ -49,15 +49,15 @@ struct MagnumFont::Data {
namespace {
class MagnumFontLayouter: public AbstractLayouter {
public:
explicit MagnumFontLayouter(const std::unordered_map<char32_t, UnsignedInt>& glyphId, const std::vector<Vector2>& glyphAdvance, const GlyphCache& cache, Float fontSize, Float textSize, const std::string& text);
std::tuple<Rectangle, Rectangle, Vector2> renderGlyph(UnsignedInt i) override;
explicit MagnumFontLayouter(const std::vector<Vector2>& glyphAdvance, const GlyphCache& cache, Float fontSize, Float textSize, std::vector<UnsignedInt>&& glyphs);
private:
std::tuple<Rectangle, Rectangle, Vector2> doRenderGlyph(UnsignedInt i) override;
const std::vector<Vector2>& glyphAdvance;
const GlyphCache& cache;
const Float fontSize, textSize;
std::vector<UnsignedInt> glyphs;
const std::vector<UnsignedInt> glyphs;
};
}
@ -71,63 +71,63 @@ auto MagnumFont::doFeatures() const -> Features { return Feature::OpenData|Featu
bool MagnumFont::doIsOpened() const { return _opened; }
void MagnumFont::doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, const Float) {
std::pair<Float, Float> MagnumFont::doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& 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();
return;
return {};
}
/* Open the configuration file */
std::istringstream in(std::string(reinterpret_cast<const char*>(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 << conf.isValid();
return;
Error() << "Text::MagnumFont::openData(): cannot open file" << data[0].first;
return {};
}
/* Check version */
if(conf.value<UnsignedInt>("version") != 1) {
Error() << "Text::MagnumFont::openData(): unsupported file version, expected 1 but got"
<< conf.value<UnsignedInt>("version");
return;
return {};
}
/* Check that we have also the image file */
if(conf.value("image") != data[1].first) {
Error() << "Text::MagnumFont::openData(): expected file"
<< conf.value("image") << "but got" << data[1].first;
return;
return {};
}
/* Open and load image file */
Trade::TgaImporter importer;
if(!importer.openData(data[1].second)) {
Error() << "Text::MagnumFont::openData(): cannot open image file";
return;
return {};
}
std::optional<Trade::ImageData2D> image = importer.image2D(0);
if(!image) {
Error() << "Text::MagnumFont::openData(): cannot load image file";
return;
return {};
}
openInternal(std::move(conf), std::move(*image));
return openInternal(std::move(conf), std::move(*image));
}
void MagnumFont::doOpenFile(const std::string& filename, Float) {
std::pair<Float, Float> MagnumFont::doOpenFile(const std::string& filename, Float) {
/* Open the configuration file */
Utility::Configuration conf(filename, Utility::Configuration::Flag::ReadOnly|Utility::Configuration::Flag::SkipComments);
if(!conf.isValid() || conf.isEmpty()) {
Error() << "Text::MagnumFont::openFile(): cannot open file" << filename << conf.isValid();
return;
return {};
}
/* Check version */
if(conf.value<UnsignedInt>("version") != 1) {
Error() << "Text::MagnumFont::openFile(): unsupported file version, expected 1 but got"
<< conf.value<UnsignedInt>("version");
return;
return {};
}
/* Open and load image file */
@ -135,21 +135,20 @@ void MagnumFont::doOpenFile(const std::string& filename, Float) {
Trade::TgaImporter importer;
if(!importer.openFile(imageFilename)) {
Error() << "Text::MagnumFont::openFile(): cannot open image file" << imageFilename;
return;
return {};
}
std::optional<Trade::ImageData2D> image = importer.image2D(0);
if(!image) {
Error() << "Text::MagnumFont::openFile(): cannot load image file";
return;
return {};
}
openInternal(std::move(conf), std::move(*image));
return openInternal(std::move(conf), std::move(*image));
}
void MagnumFont::openInternal(Utility::Configuration&& conf, Trade::ImageData2D&& image) {
std::pair<Float, Float> MagnumFont::openInternal(Utility::Configuration&& conf, Trade::ImageData2D&& image) {
/* Everything okay, save the data internally */
_opened = new Data{std::move(conf), std::move(image), {}, {}};
_size = _opened->conf.value<Float>("fontSize");
/* Glyph advances */
const std::vector<Utility::ConfigurationGroup*> glyphs = _opened->conf.groups("glyph");
@ -169,6 +168,8 @@ void MagnumFont::openInternal(Utility::Configuration&& conf, Trade::ImageData2D&
_opened->glyphId.insert({c->value<char32_t>("unicode"), glyphId});
#endif
}
return {_opened->conf.value<Float>("fontSize"), _opened->conf.value<Float>("lineHeight")};
}
void MagnumFont::doClose() {
@ -185,12 +186,12 @@ Vector2 MagnumFont::doGlyphAdvance(const UnsignedInt glyph) {
return glyph < _opened->glyphAdvance.size() ? _opened->glyphAdvance[glyph] : Vector2();
}
GlyphCache* MagnumFont::doCreateGlyphCache() {
std::unique_ptr<GlyphCache> MagnumFont::doCreateGlyphCache() {
/* Set cache image */
auto cache = new Text::GlyphCache(
std::unique_ptr<GlyphCache> cache(new Text::GlyphCache(
_opened->conf.value<Vector2i>("originalImageSize"),
_opened->image.size(),
_opened->conf.value<Vector2i>("padding"));
_opened->conf.value<Vector2i>("padding")));
cache->setImage({}, _opened->image);
/* Fill glyph map */
@ -201,25 +202,25 @@ GlyphCache* MagnumFont::doCreateGlyphCache() {
return cache;
}
AbstractLayouter* MagnumFont::doLayout(const GlyphCache& cache, Float size, const std::string& text) {
return new MagnumFontLayouter(_opened->glyphId, _opened->glyphAdvance, cache, this->size(), size, text);
}
namespace {
MagnumFontLayouter::MagnumFontLayouter(const std::unordered_map<char32_t, UnsignedInt>& glyphId, const std::vector<Vector2>& glyphAdvance, const GlyphCache& cache, Float fontSize, Float textSize, const std::string& text): glyphAdvance(glyphAdvance), cache(cache), fontSize(fontSize), textSize(textSize) {
std::unique_ptr<AbstractLayouter> MagnumFont::doLayout(const GlyphCache& cache, Float size, const std::string& text) {
/* Get glyph codes from characters */
std::vector<UnsignedInt> glyphs;
glyphs.reserve(text.size());
for(std::size_t i = 0; i != text.size(); ) {
UnsignedInt codepoint;
std::tie(codepoint, i) = Utility::Unicode::nextChar(text, i);
const auto it = glyphId.find(codepoint);
glyphs.push_back(it == glyphId.end() ? 0 : it->second);
const auto it = _opened->glyphId.find(codepoint);
glyphs.push_back(it == _opened->glyphId.end() ? 0 : it->second);
}
_glyphCount = glyphs.size();
return std::unique_ptr<MagnumFontLayouter>(new MagnumFontLayouter(_opened->glyphAdvance, cache, this->size(), size, std::move(glyphs)));
}
std::tuple<Rectangle, Rectangle, Vector2> MagnumFontLayouter::renderGlyph(UnsignedInt i) {
namespace {
MagnumFontLayouter::MagnumFontLayouter(const std::vector<Vector2>& glyphAdvance, const GlyphCache& cache, const Float fontSize, const Float textSize, std::vector<UnsignedInt>&& glyphs): AbstractLayouter(glyphs.size()), glyphAdvance(glyphAdvance), cache(cache), fontSize(fontSize), textSize(textSize), glyphs(std::move(glyphs)) {}
std::tuple<Rectangle, Rectangle, Vector2> MagnumFontLayouter::doRenderGlyph(const UnsignedInt i) {
/* Position of the texture in the resulting glyph, texture coordinates */
Vector2i position;
Rectanglei rectangle;

21
src/Plugins/MagnumFont/MagnumFont.h

@ -28,8 +28,8 @@
* @brief Class Magnum::Text::MagnumFont
*/
#include <Text/AbstractFont.h>
#include <Trade/Trade.h>
#include "Text/AbstractFont.h"
#include "Trade/Trade.h"
namespace Magnum { namespace Text {
@ -40,9 +40,8 @@ This plugin depends on @ref Trade::TgaImporter "TgaImporter" plugin and is
built if `WITH_MAGNUMFONT` is enabled in CMake. To use dynamic plugin, you need
to load `%MagnumFont` plugin from `fonts/` subdirectory of your plugin dir. To
use static plugin or use this as a dependency of another plugin, you need to
request `%MagnumFont` component in CMake and link to
`${MAGNUMPLUGINS_MAGNUMFONT_LIBRARIES}`. See @ref building-plugins and
@ref cmake-plugins for more information.
request `%MagnumFont` component in CMake and link to `${MAGNUM_MAGNUMFONT_LIBRARIES}`.
See @ref building and @ref cmake for more information.
The font consists of two files, one text file containing character and glyph
info and one TGA file containing the glyphs in distance field format. The font
@ -116,9 +115,9 @@ class MagnumFont: public AbstractFont {
bool doIsOpened() const override;
void doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, Float) override;
std::pair<Float, Float> doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, Float) override;
void doOpenFile(const std::string& filename, Float) override;
std::pair<Float, Float> doOpenFile(const std::string& filename, Float) override;
void doClose() override;
@ -126,13 +125,13 @@ class MagnumFont: public AbstractFont {
Vector2 doGlyphAdvance(UnsignedInt glyph) override;
GlyphCache* doCreateGlyphCache() override;
std::unique_ptr<GlyphCache> doCreateGlyphCache() override;
AbstractLayouter* doLayout(const GlyphCache& cache, Float size, const std::string& text) override;
std::unique_ptr<AbstractLayouter> doLayout(const GlyphCache& cache, Float size, const std::string& text) override;
Data* _opened;
std::pair<Float, Float> openInternal(Utility::Configuration&& conf, Trade::ImageData2D&& image);
void openInternal(Utility::Configuration&& conf, Trade::ImageData2D&& image);
Data* _opened;
};
}}

27
src/Plugins/MagnumFont/Test/MagnumFontTest.cpp

@ -22,10 +22,10 @@
DEALINGS IN THE SOFTWARE.
*/
#include <Test/AbstractOpenGLTester.h>
#include <Text/GlyphCache.h>
#include <Utility/Directory.h>
#include "Test/AbstractOpenGLTester.h"
#include "Text/GlyphCache.h"
#include "MagnumFont/MagnumFont.h"
#include "magnumFontTestConfigure.h"
@ -51,6 +51,7 @@ void MagnumFontTest::properties() {
MagnumFont font;
CORRADE_VERIFY(font.openFile(Utility::Directory::join(MAGNUMFONT_TEST_DIR, "font.conf"), 0.0f));
CORRADE_COMPARE(font.size(), 16.0f);
CORRADE_COMPARE(font.lineHeight(), 39.7333f);
CORRADE_COMPARE(font.glyphAdvance(font.glyphId(U'W')), Vector2(23.0f, 0.0f));
}
@ -63,41 +64,43 @@ void MagnumFontTest::layout() {
cache.insert(font.glyphId(U'W'), {25, 34}, {{0, 8}, {16, 128}});
cache.insert(font.glyphId(U'e'), {25, 12}, {{16, 4}, {64, 32}});
AbstractLayouter* layouter = font.layout(cache, 0.5f, "Wave");
auto layouter = font.layout(cache, 0.5f, "Wave");
CORRADE_VERIFY(layouter);
CORRADE_COMPARE(layouter->glyphCount(), 4);
Rectangle rectangle;
Rectangle position;
Rectangle textureCoordinates;
Vector2 advance;
/* 'W' */
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(0);
Vector2 cursorPosition;
std::tie(position, textureCoordinates) = layouter->renderGlyph(0, cursorPosition = {}, rectangle);
CORRADE_COMPARE(position, Rectangle({0.78125f, 1.0625f}, {1.28125f, 4.8125f}));
CORRADE_COMPARE(textureCoordinates, Rectangle({0, 0.03125f}, {0.0625f, 0.5f}));
CORRADE_COMPARE(advance, Vector2(0.71875f, 0.0f));
CORRADE_COMPARE(cursorPosition, Vector2(0.71875f, 0.0f));
/* 'a' (not found) */
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(1);
std::tie(position, textureCoordinates) = layouter->renderGlyph(1, cursorPosition = {}, rectangle);
CORRADE_COMPARE(position, Rectangle());
CORRADE_COMPARE(textureCoordinates, Rectangle());
CORRADE_COMPARE(advance, Vector2(0.25f, 0.0f));
CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f));
/* 'v' (not found) */
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(2);
std::tie(position, textureCoordinates) = layouter->renderGlyph(2, cursorPosition = {}, rectangle);
CORRADE_COMPARE(position, Rectangle());
CORRADE_COMPARE(textureCoordinates, Rectangle());
CORRADE_COMPARE(advance, Vector2(0.25f, 0.0f));
CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f));
/* 'e' */
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(3);
std::tie(position, textureCoordinates) = layouter->renderGlyph(3, cursorPosition = {}, rectangle);
CORRADE_COMPARE(position, Rectangle({0.78125f, 0.375f}, {2.28125f, 1.25f}));
CORRADE_COMPARE(textureCoordinates, Rectangle({0.0625f, 0.015625f}, {0.25f, 0.125f}));
CORRADE_COMPARE(advance, Vector2(0.375f, 0.0f));
CORRADE_COMPARE(cursorPosition, Vector2(0.375f, 0.0f));
}
void MagnumFontTest::createGlyphCache() {
/** @todo */
CORRADE_SKIP("Not yet implemented");
}
}}}

1
src/Plugins/MagnumFont/Test/font.conf

@ -3,6 +3,7 @@ image=font.tga
originalImageSize=1536 1536
padding=24 24
fontSize=16
lineHeight=39.7333
[char]
unicode=57
glyph=2

2
src/Plugins/MagnumFont/pluginRegistrationMagnumFont.cpp

@ -25,4 +25,4 @@
#include "MagnumFont/MagnumFont.h"
CORRADE_PLUGIN_REGISTER(MagnumFont, Magnum::Text::MagnumFont,
"cz.mosra.magnum.Text.AbstractFont/0.2")
"cz.mosra.magnum.Text.AbstractFont/0.2.3")

11
src/Plugins/MagnumFontConverter/CMakeLists.txt

@ -22,8 +22,6 @@
# DEALINGS IN THE SOFTWARE.
#
find_package(Magnum REQUIRED Text)
set(MagnumFontConverter_SOURCES
MagnumFontConverter.cpp)
@ -37,9 +35,7 @@ add_plugin(MagnumFontConverter ${MAGNUM_PLUGINS_FONTCONVERTER_INSTALL_DIR}
MagnumFontConverter.conf
$<TARGET_OBJECTS:MagnumFontConverterObjects>
pluginRegistrationMagnumFontConverter.cpp)
target_link_libraries(MagnumFontConverter
${MAGNUM_LIBRARIES}
${MAGNUM_TEXT_LIBRARIES})
target_link_libraries(MagnumFontConverter Magnum MagnumText)
if(WIN32)
target_link_libraries(MagnumFontConverter TgaImageConverter)
@ -49,9 +45,6 @@ install(FILES ${MagnumFontConverter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUD
if(BUILD_GL_TESTS)
add_library(MagnumFontConverterTestLib STATIC $<TARGET_OBJECTS:MagnumFontConverterObjects>)
target_link_libraries(MagnumFontConverterTestLib
${MAGNUM_LIBRARIES}
${MAGNUM_TEXT_LIBRARIES}
TgaImageConverterTestLib)
target_link_libraries(MagnumFontConverterTestLib Magnum MagnumText TgaImageConverterTestLib)
add_subdirectory(Test)
endif()

14
src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp

@ -27,11 +27,12 @@
#include <sstream>
#include <Containers/Array.h>
#include <Utility/Directory.h>
#include <ColorFormat.h>
#include <Image.h>
#include <Text/GlyphCache.h>
#include <Text/AbstractFont.h>
#include <TgaImageConverter/TgaImageConverter.h>
#include "ColorFormat.h"
#include "Image.h"
#include "Text/GlyphCache.h"
#include "Text/AbstractFont.h"
#include "TgaImageConverter/TgaImageConverter.h"
namespace Magnum { namespace Text {
@ -43,7 +44,7 @@ auto MagnumFontConverter::doFeatures() const -> Features {
return Feature::ExportFont|Feature::ConvertData|Feature::MultiFile;
}
#ifndef _WIN32
#ifndef __MINGW32__
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const
#else
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const
@ -56,6 +57,7 @@ std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFont
configuration.setValue("originalImageSize", cache.textureSize());
configuration.setValue("padding", cache.padding());
configuration.setValue("fontSize", font.size());
configuration.setValue("lineHeight", font.lineHeight());
/* Compress glyph IDs so the glyphs are in consecutive array, glyph 0
should stay at position 0 */

8
src/Plugins/MagnumFontConverter/MagnumFontConverter.h

@ -28,7 +28,7 @@
* @brief Class Magnum::Text::MagnumFontConverter
*/
#include <Text/AbstractFontConverter.h>
#include "Text/AbstractFontConverter.h"
namespace Magnum { namespace Text {
@ -45,8 +45,8 @@ to read back the generated data. It depends on
to load `%MagnumFontConverter` plugin from `fontconverters/` subdirectory of
your plugin dir. To use static plugin or use this as a dependency of another
plugin, you need to request `%MagnumFontConverter` component in CMake and link
to `${MAGNUMPLUGINS_MAGNUMFONTCONVERTER_LIBRARIES}`. See @ref building-plugins
and @ref cmake-plugins for more information.
to `${MAGNUM_MAGNUMFONTCONVERTER_LIBRARIES}`. See @ref building and @ref cmake
for more information.
*/
class MagnumFontConverter: public Text::AbstractFontConverter {
public:
@ -58,7 +58,7 @@ class MagnumFontConverter: public Text::AbstractFontConverter {
private:
Features doFeatures() const override;
#ifndef _WIN32
#ifndef __MINGW32__
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const override;
#else
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const override;

4
src/Plugins/MagnumFontConverter/Test/CMakeLists.txt

@ -25,12 +25,10 @@
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/magnumFontConverterTestConfigure.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/magnumFontConverterTestConfigure.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../FreeTypeFont/Test/
${CMAKE_CURRENT_BINARY_DIR}/../../MagnumFont/Test/
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../MagnumFont/Test/
${CMAKE_CURRENT_BINARY_DIR})
corrade_add_test(MagnumFontConverterTest MagnumFontConverterTest.cpp LIBRARIES
MagnumFontConverterTestLib
FreeTypeFontTestLib
TgaImporterTestLib
${GL_TEST_LIBRARIES})

66
src/Plugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp

@ -24,18 +24,18 @@
#include <Utility/Directory.h>
#include <TestSuite/Compare/File.h>
#include <ColorFormat.h>
#include <Extensions.h>
#include <TextureFormat.h>
#include <Test/AbstractOpenGLTester.h>
#include <Text/GlyphCache.h>
#include <Trade/ImageData.h>
#include "FreeTypeFont/FreeTypeFont.h"
#include "ColorFormat.h"
#include "Extensions.h"
#include "TextureFormat.h"
#include "Test/AbstractOpenGLTester.h"
#include "Text/GlyphCache.h"
#include "Trade/ImageData.h"
#include "Text/AbstractFont.h"
#include "MagnumFontConverter/MagnumFontConverter.h"
#include "TgaImporter/TgaImporter.h"
#include "freeTypeFontTestConfigure.h"
#include "magnumFontTestConfigure.h"
#include "magnumFontConverterTestConfigure.h"
@ -45,19 +45,11 @@ class MagnumFontConverterTest: public Magnum::Test::AbstractOpenGLTester {
public:
explicit MagnumFontConverterTest();
~MagnumFontConverterTest();
void exportFont();
};
MagnumFontConverterTest::MagnumFontConverterTest() {
addTests({&MagnumFontConverterTest::exportFont});
FreeTypeFont::initialize();
}
MagnumFontConverterTest::~MagnumFontConverterTest() {
FreeTypeFont::finalize();
}
void MagnumFontConverterTest::exportFont() {
@ -65,9 +57,43 @@ void MagnumFontConverterTest::exportFont() {
Utility::Directory::rm(Utility::Directory::join(MAGNUMFONTCONVERTER_TEST_WRITE_DIR, "font.conf"));
Utility::Directory::rm(Utility::Directory::join(MAGNUMFONTCONVERTER_TEST_WRITE_DIR, "font.tga"));
/* Open font */
FreeTypeFont font;
CORRADE_VERIFY(font.openFile(Utility::Directory::join(FREETYPEFONT_TEST_DIR, "Oxygen.ttf"), 16.0f));
/* Fake font with fake cache */
class FakeFont: public Text::AbstractFont {
public:
explicit FakeFont(): _opened(false) {}
private:
void doClose() { _opened = false; }
bool doIsOpened() const { return _opened; }
std::pair<Float, Float> doOpenFile(const std::string&, Float) {
_opened = true;
return {16.0f, 39.7333f};
}
Features doFeatures() const { return {}; }
std::unique_ptr<AbstractLayouter> doLayout(const GlyphCache&, Float, const std::string&) { return nullptr; }
UnsignedInt doGlyphId(const char32_t character) {
switch(character) {
case 'W': return 2;
case 'e': return 1;
}
return 0;
}
Vector2 doGlyphAdvance(const UnsignedInt glyph) {
switch(glyph) {
case 0: return {8, 0};
case 1: return {12, 0};
case 2: return {23, 0};
}
CORRADE_ASSERT_UNREACHABLE();
}
bool _opened;
} font;
font.openFile({}, {});
/* Create fake cache */
MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg);

2
src/Plugins/MagnumFontConverter/pluginRegistrationMagnumFontConverter.cpp

@ -25,4 +25,4 @@
#include "MagnumFontConverter/MagnumFontConverter.h"
CORRADE_PLUGIN_REGISTER(MagnumFontConverter, Magnum::Text::MagnumFontConverter,
"cz.mosra.magnum.Text.AbstractFontConverter/0.1")
"cz.mosra.magnum.Text.AbstractFontConverter/0.1.1")

4
src/Plugins/TgaImageConverter/CMakeLists.txt

@ -35,12 +35,12 @@ add_plugin(TgaImageConverter ${MAGNUM_PLUGINS_IMAGECONVERTER_INSTALL_DIR}
TgaImageConverter.conf
$<TARGET_OBJECTS:TgaImageConverterObjects>
pluginRegistrationTgaImageConverter.cpp)
target_link_libraries(TgaImageConverter ${MAGNUM_LIBRARIES})
target_link_libraries(TgaImageConverter Magnum)
install(FILES ${TgaImageConverter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImageConverter)
if(BUILD_TESTS)
add_library(TgaImageConverterTestLib SHARED $<TARGET_OBJECTS:TgaImageConverterObjects>)
target_link_libraries(TgaImageConverterTestLib ${MAGNUM_LIBRARIES})
target_link_libraries(TgaImageConverterTestLib Magnum)
add_subdirectory(Test)
endif()

11
src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp

@ -27,11 +27,12 @@
#include <Containers/Array.h>
#include <TestSuite/Tester.h>
#include <Utility/Directory.h>
#include <ColorFormat.h>
#include <Image.h>
#include <Trade/ImageData.h>
#include <TgaImageConverter/TgaImageConverter.h>
#include <TgaImporter/TgaImporter.h>
#include "ColorFormat.h"
#include "Image.h"
#include "Trade/ImageData.h"
#include "TgaImageConverter/TgaImageConverter.h"
#include "TgaImporter/TgaImporter.h"
#include "configure.h"

18
src/Plugins/TgaImageConverter/TgaImageConverter.cpp

@ -26,14 +26,16 @@
#include <fstream>
#include <tuple>
#include <Containers/Array.h>
#include <Utility/Endianness.h>
#include <ColorFormat.h>
#include <Image.h>
#include "Containers/Array.h"
#include "Utility/Endianness.h"
#include "ColorFormat.h"
#include "Image.h"
#ifdef MAGNUM_TARGET_GLES
#include <algorithm>
#include <Swizzle.h>
#include "Math/Swizzle.h"
#include "Math/Vector4.h"
#endif
#include "TgaImporter/TgaHeader.h"
@ -81,14 +83,14 @@ Containers::Array<unsigned char> TgaImageConverter::doExportToData(const ImageRe
std::copy(image.data(), image.data()+pixelSize*image.size().product(), data.begin()+sizeof(TgaHeader));
#ifdef MAGNUM_TARGET_GLES
if(image->format() == ColorFormat::RGB) {
if(image.format() == ColorFormat::RGB) {
auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.begin()+sizeof(TgaHeader));
std::transform(pixels, pixels + image.size().product(), pixels,
[](Math::Vector3<UnsignedByte> pixel) { return swizzle<'b', 'g', 'r'>(pixel); });
[](Math::Vector3<UnsignedByte> pixel) { return Math::swizzle<'b', 'g', 'r'>(pixel); });
} else if(image.format() == ColorFormat::RGBA) {
auto pixels = reinterpret_cast<Math::Vector4<UnsignedByte>*>(data.begin()+sizeof(TgaHeader));
std::transform(pixels, pixels + image.size().product(), pixels,
[](Math::Vector4<UnsignedByte> pixel) { return swizzle<'b', 'g', 'r', 'a'>(pixel); });
[](Math::Vector4<UnsignedByte> pixel) { return Math::swizzle<'b', 'g', 'r', 'a'>(pixel); });
}
#endif

6
src/Plugins/TgaImageConverter/TgaImageConverter.h

@ -28,7 +28,7 @@
* @brief Class Magnum::Trade::TgaImageConverter
*/
#include <Trade/AbstractImageConverter.h>
#include "Trade/AbstractImageConverter.h"
#ifndef DOXYGEN_GENERATING_OUTPUT
#if defined(TgaImageConverter_EXPORTS) || defined(TgaImageConverterObjects_EXPORTS)
@ -51,8 +51,8 @@ This plugin is built if `WITH_TGAIMAGECONVERTER` is enabled in CMake. To use
dynamic plugin, you need to load `%TgaImageConverter` plugin from
`imageconverters/` subdirectory of your plugin dir. To use static plugin or use
this as a dependency of another plugin, you need to request `%TgaImageConverter`
component in CMake and link to `${MAGNUMPLUGINS_TGAIMAGECONVERTER_LIBRARIES}`.
See @ref building-plugins and @ref cmake-plugins for more information.
component in CMake and link to `${MAGNUM_TGAIMAGECONVERTER_LIBRARIES}`. See
@ref building and @ref cmake for more information.
*/
class MAGNUM_TRADE_TGAIMAGECONVERTER_EXPORT TgaImageConverter: public AbstractImageConverter {
public:

4
src/Plugins/TgaImporter/CMakeLists.txt

@ -36,12 +36,12 @@ add_plugin(TgaImporter ${MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR}
TgaImporter.conf
$<TARGET_OBJECTS:TgaImporterObjects>
pluginRegistrationTgaImporter.cpp)
target_link_libraries(TgaImporter ${MAGNUM_LIBRARIES})
target_link_libraries(TgaImporter Magnum)
install(FILES ${TgaImporter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImporter)
if(BUILD_TESTS)
add_library(TgaImporterTestLib SHARED $<TARGET_OBJECTS:TgaImporterObjects>)
target_link_libraries(TgaImporterTestLib ${MAGNUM_LIBRARIES})
target_link_libraries(TgaImporterTestLib Magnum)
add_subdirectory(Test)
endif()

14
src/Plugins/TgaImporter/Test/TgaImporterTest.cpp

@ -26,9 +26,9 @@
#include <Containers/Array.h>
#include <TestSuite/Tester.h>
#include <Utility/Directory.h>
#include <ColorFormat.h>
#include <Trade/ImageData.h>
#include "ColorFormat.h"
#include "Trade/ImageData.h"
#include "TgaImporter/TgaImporter.h"
#include "configure.h"
@ -39,7 +39,7 @@ class TgaImporterTest: public TestSuite::Tester {
public:
TgaImporterTest();
void openInexistent();
void openNonexistent();
void openShort();
void paletted();
void compressed();
@ -55,7 +55,7 @@ class TgaImporterTest: public TestSuite::Tester {
};
TgaImporterTest::TgaImporterTest() {
addTests({&TgaImporterTest::openInexistent,
addTests({&TgaImporterTest::openNonexistent,
&TgaImporterTest::openShort,
&TgaImporterTest::paletted,
&TgaImporterTest::compressed,
@ -70,13 +70,13 @@ TgaImporterTest::TgaImporterTest() {
&TgaImporterTest::file});
}
void TgaImporterTest::openInexistent() {
void TgaImporterTest::openNonexistent() {
std::ostringstream debug;
Error::setOutput(&debug);
TgaImporter importer;
CORRADE_VERIFY(!importer.openFile("inexistent.file"));
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::openFile(): cannot open file inexistent.file\n");
CORRADE_VERIFY(!importer.openFile("nonexistent.file"));
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::openFile(): cannot open file nonexistent.file\n");
}
void TgaImporterTest::openShort() {

16
src/Plugins/TgaImporter/TgaImporter.cpp

@ -28,14 +28,16 @@
#include <sstream>
#include <Utility/Endianness.h>
#include <Containers/Array.h>
#include <ColorFormat.h>
#include <Trade/ImageData.h>
#include "ColorFormat.h"
#include "Trade/ImageData.h"
#ifdef MAGNUM_TARGET_GLES
#include <algorithm>
#include <Context.h>
#include <Extensions.h>
#include <Swizzle.h>
#include "Math/Swizzle.h"
#include "Math/Vector4.h"
#include "Context.h"
#include "Extensions.h"
#endif
#include "TgaHeader.h"
@ -44,11 +46,11 @@ namespace Magnum { namespace Trade {
namespace {
constexpr Math::Vector3<UnsignedByte> bgr(const Math::Vector3<UnsignedByte>& vec) {
return swizzle<'b', 'g', 'r'>(vec);
return Math::swizzle<'b', 'g', 'r'>(vec);
}
constexpr Math::Vector4<UnsignedByte> bgra(const Math::Vector4<UnsignedByte>& vec) {
return swizzle<'b', 'g', 'r', 'a'>(vec);
return Math::swizzle<'b', 'g', 'r', 'a'>(vec);
}
}

4
src/Plugins/TgaImporter/TgaImporter.h

@ -51,8 +51,8 @@ This plugin is built if `WITH_TGAIMPORTER` is enabled in CMake. To use dynamic
plugin, you need to load `%TgaImporter` plugin from `importers/` subdirectory
of your plugin dir. To use static plugin or use this as a dependency of another
plugin, you need to request `%TgaImporter` component in CMake and link to
`${MAGNUMPLUGINS_TGAIMPORTER_LIBRARIES}`. See @ref building-plugins and
@ref cmake-plugins for more information.
`${MAGNUM_TGAIMPORTER_LIBRARIES}`. See @ref building and @ref cmake for more
information.
The images are imported with @ref ColorType::UnsignedByte and @ref ColorFormat::BGR,
@ref ColorFormat::BGRA or @ref ColorFormat::Red, respectively. Grayscale images

8
src/Plugins/WavAudioImporter/CMakeLists.txt

@ -22,9 +22,7 @@
# DEALINGS IN THE SOFTWARE.
#
find_package(Magnum REQUIRED Audio)
include_directories(${MAGNUM_AUDIO_INCLUDE_DIRS})
include_directories(${OPENAL_INCLUDE_DIR})
set(WavAudioImporter_SRCS
WavImporter.cpp)
@ -40,12 +38,12 @@ add_plugin(WavAudioImporter ${MAGNUM_PLUGINS_AUDIOIMPORTER_INSTALL_DIR}
WavAudioImporter.conf
$<TARGET_OBJECTS:WavAudioImporterObjects>
pluginRegistrationWavAudioImporter.cpp)
target_link_libraries(WavAudioImporter ${MAGNUM_LIBRARIES} ${MAGNUM_AUDIO_LIBRARIES})
target_link_libraries(WavAudioImporter Magnum MagnumAudio)
install(FILES ${WavAudioImporter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/WavAudioImporter)
if(BUILD_TESTS)
add_library(WavAudioImporterTestLib STATIC $<TARGET_OBJECTS:WavAudioImporterObjects>)
target_link_libraries(WavAudioImporterTestLib ${MAGNUM_LIBRARIES} ${MAGNUM_AUDIO_LIBRARIES})
target_link_libraries(WavAudioImporterTestLib Magnum MagnumAudio)
add_subdirectory(Test)
endif()

2
src/Plugins/WavAudioImporter/WavHeader.h

@ -28,7 +28,7 @@
* @brief Struct Magnum::Audio::WavHeader
*/
#include <Types.h>
#include "Types.h"
namespace Magnum { namespace Audio {

7
src/Plugins/WavAudioImporter/WavImporter.h

@ -30,7 +30,8 @@
#include <Containers/Array.h>
#include <Utility/Visibility.h>
#include <Audio/AbstractImporter.h>
#include "Audio/AbstractImporter.h"
namespace Magnum { namespace Audio {
@ -45,8 +46,8 @@ This plugin is built if `WITH_WAVAUDIOIMPORTER` is enabled in CMake. To use
dynamic plugin, you need to load `%WavAudioImporter` plugin from `audioimporters/`
subdirectory of your plugin dir. To use static plugin or or use this as a
dependency of another plugin, you need to request `%WavAudioImporter` component
in CMake and link to `${MAGNUMPLUGINS_WAVAUDIOIMPORTER_LIBRARIES}`. See
@ref building-plugins and @ref cmake-plugins for more information.
in CMake and link to `${MAGNUM_WAVAUDIOIMPORTER_LIBRARIES}`. See @ref building
and @ref cmake for more information.
*/
class WavImporter: public AbstractImporter {
public:

15
src/ResourceManager.h

@ -453,9 +453,14 @@ template<class ...Types> ResourceManager<Types...>*& ResourceManager<Types...>::
namespace Implementation {
template<class T> void safeDelete(T* data) {
static_assert(sizeof(T) > 0, "Cannot delete pointer to incomplete type");
delete data;
}
template<class T> ResourceManagerData<T>::~ResourceManagerData() {
/* Loaders are already deleted via freeLoaders() from ResourceManager */
delete _fallback;
safeDelete(_fallback);
}
template<class T> std::size_t ResourceManagerData<T>::referenceCount(const ResourceKey key) const {
@ -509,7 +514,7 @@ template<class T> void ResourceManagerData<T>::set(const ResourceKey key, T* con
/* 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";
delete data;
safeDelete(data);
/* Delete also already present resource (it could be here
because previous policy could be other than
@ -527,7 +532,7 @@ template<class T> void ResourceManagerData<T>::set(const ResourceKey key, T* con
#endif
/* Replace previous data */
delete it->second.data;
safeDelete(it->second.data);
it->second.data = data;
it->second.state = state;
it->second.policy = policy;
@ -535,7 +540,7 @@ template<class T> void ResourceManagerData<T>::set(const ResourceKey key, T* con
}
template<class T> void ResourceManagerData<T>::setFallback(T* const data) {
delete _fallback;
safeDelete(_fallback);
_fallback = data;
}
@ -604,7 +609,7 @@ template<class T> struct ResourceManagerData<T>::Data {
template<class T> inline ResourceManagerData<T>::Data::~Data() {
CORRADE_ASSERT(referenceCount == 0,
"ResourceManager: cleared/destroyed while data are still referenced", );
delete data;
safeDelete(data);
}
}

25
src/SceneGraph/AbstractCamera.h

@ -25,7 +25,7 @@
*/
/** @file
* @brief Class Magnum::SceneGraph::AbstractCamera, enum Magnum::SceneGraph::AspectRatioPolicy, alias Magnum::SceneGraph::AbstractBasicCamera2D, Magnum::SceneGraph::AbstractBasicCamera3D, typedef Magnum::SceneGraph::AbstractCamera2D, Magnum::SceneGraph::AbstractCamera3D
* @brief Class @ref Magnum::SceneGraph::AbstractCamera, enum @ref Magnum::SceneGraph::AspectRatioPolicy, alias @ref Magnum::SceneGraph::AbstractBasicCamera2D, @ref Magnum::SceneGraph::AbstractBasicCamera3D, typedef @ref Magnum::SceneGraph::AbstractCamera2D, @ref Magnum::SceneGraph::AbstractCamera3D
*/
#include "Math/Matrix3.h"
@ -39,7 +39,7 @@ namespace Magnum { namespace SceneGraph {
/**
@brief Camera aspect ratio policy
@see AbstractCamera::setAspectRatioPolicy()
@see @ref AbstractCamera::setAspectRatioPolicy()
*/
enum class AspectRatioPolicy: UnsignedByte {
NotPreserved, /**< Don't preserve aspect ratio (default) */
@ -60,16 +60,15 @@ instead.
@section AbstractCamera-explicit-specializations Explicit template specializations
The following specialization are explicitly compiled into SceneGraph library.
For other specializations (e.g. using Double type) you have to use
AbstractCamera.hpp implementation file to avoid linker errors. See also
relevant sections in
@ref Camera2D-explicit-specializations "Camera2D" and
@ref Camera3D-explicit-specializations "Camera3D" class documentation or
The following specialization 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 Camera2D-explicit-specializations "Camera2D"
and @ref Camera3D-explicit-specializations "Camera3D" class documentation or
@ref compilation-speedup-hpp for more information.
- @ref AbstractCamera "AbstractCamera<2, Float>"
- @ref AbstractCamera "AbstractCamera<3, Float>"
- @ref AbstractCamera2D
- @ref AbstractCamera3D
@see @ref scenegraph, @ref AbstractBasicCamera2D, @ref AbstractBasicCamera3D,
@ref Drawable, @ref DrawableGroup
@ -101,7 +100,7 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Abstrac
*
* Projection matrix handles e.g. perspective distortion and is applied
* as last.
* @see projectionSize()
* @see @ref projectionSize()
*/
typename DimensionTraits<dimensions, T>::MatrixType projectionMatrix() const { return _projectionMatrix; }
@ -109,7 +108,7 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Abstrac
* @brief Size of (near) XY plane in current projection
*
* Returns size of near XY plane computed from projection matrix.
* @see projectionMatrix()
* @see @ref projectionMatrix()
*/
Math::Vector2<T> projectionSize() const {
return {T(2.0)/_projectionMatrix[0].x(), T(2.0)/_projectionMatrix[1].y()};
@ -123,7 +122,7 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Abstrac
*
* Stores viewport size internally and recalculates projection matrix
* according to aspect ratio policy.
* @see setAspectRatioPolicy()
* @see @ref setAspectRatioPolicy()
*/
virtual void setViewport(const Vector2i& size);

12
src/SceneGraph/AbstractFeature.h

@ -149,13 +149,13 @@ which is automatically extracted from the reference in our constructor.
@section AbstractFeature-explicit-specializations Explicit template specializations
The following specialization are explicitly compiled into %SceneGraph library.
For other specializations (e.g. using Double type) you have to use
AbstractFeature.hpp implementation file to avoid linker errors. See also
@ref compilation-speedup-hpp for more information.
The following specialization 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.
- @ref AbstractFeature "AbstractFeature<2, Float>"
- @ref AbstractFeature "AbstractFeature<3, Float>"
- @ref AbstractFeature2D
- @ref AbstractFeature3D
@see @ref AbstractBasicFeature2D, @ref AbstractBasicFeature3D,
@ref AbstractFeature2D, @ref AbstractFeature3D

2
src/SceneGraph/AbstractFeature.hpp

@ -25,7 +25,7 @@
*/
/** @file
* @brief @ref compilation-speedup-hpp "Template implementation" for AbstractFeature.h
* @brief @ref compilation-speedup-hpp "Template implementation" for @ref AbstractFeature.h
*/
#include "AbstractFeature.h"

10
src/SceneGraph/AbstractGroupedFeature.h

@ -54,13 +54,13 @@ typedef SceneGraph::FeatureGroup3D<Drawable> DrawableGroup;
@section AbstractGroupedFeature-explicit-specializations Explicit template specializations
The following specialization are explicitly compiled into %SceneGraph library.
For other specializations (e.g. using Double type) you have to use
AbstractGroupedFeature.hpp implementation file to avoid linker errors. See also
The following specialization 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.
- @ref AbstractFeatureGroup "AbstractFeatureGroup<2, Float>"
- @ref AbstractFeatureGroup "AbstractFeatureGroup<3, Float>"
- @ref FeatureGroup2D
- @ref FeatureGroup3D
@see @ref scenegraph, @ref AbstractBasicGroupedFeature2D,
@ref AbstractBasicGroupedFeature3D, @ref AbstractGroupedFeature2D,

22
src/SceneGraph/AbstractObject.h

@ -42,18 +42,30 @@ namespace Magnum { namespace SceneGraph {
@brief Base for objects
Provides minimal interface for features, not depending on object transformation
implementation. This class is not directly instantiatable, use Object subclass
instead. See also @ref scenegraph for more information.
implementation. This class is not directly instantiatable, use @ref Object
subclass instead. See also @ref scenegraph for more information.
Uses 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 lastFeature() and AbstractFeature::previousFeature().
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().
@code
for(AbstractFeature* feature = o->firstFeature(); feature; feature = feature->nextFeature()) {
// ...
}
@endcode
@section AbstractObject-explicit-specializations Explicit template specializations
The following specialization 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 Object-explicit-specializations "Object" and
@ref AbstractTransformation-explicit-specializations "AbstractTransformation"
class documentation or @ref compilation-speedup-hpp for more information.
- @ref AbstractObject2D
- @ref AbstractObject3D
@see @ref AbstractBasicObject2D, @ref AbstractBasicObject3D,
@ref AbstractObject2D, @ref AbstractObject3D
*/

10
src/SceneGraph/AbstractTransformation.h

@ -38,6 +38,16 @@ namespace Magnum { namespace SceneGraph {
Provides transformation implementation for @ref Object instances.
@section AbstractTransformation-explicit-specializations Explicit template specializations
The following specialization 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.
- @ref AbstractTransformation2D
- @ref AbstractTransformation3D
@see @ref scenegraph, @ref AbstractBasicTransformation2D,
@ref AbstractBasicTransformation3D, @ref AbstractTransformation2D,
@ref AbstractTransformation3D

32
src/SceneGraph/Animable.h

@ -129,13 +129,13 @@ calling @ref AnimableGroup::step(), saving precious frame time.
@section Animable-explicit-specializations Explicit template specializations
The following specialization are explicitly compiled into %SceneGraph library.
For other specializations (e.g. using Double type) you have to use
Animable.hpp implementation file to avoid linker errors. See also
The following specialization 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.
- @ref Animable "Animable<2, Float>", @ref AnimableGroup "AnimableGroup<2, Float>"
- @ref Animable "Animable<3, Float>", @ref AnimableGroup "AnimableGroup<3, Float>"
- @ref Animable2D, @ref AnimableGroup2D
- @ref Animable3D, @ref AnimableGroup3D
@see @ref scenegraph, @ref BasicAnimable2D, @ref BasicAnimable3D,
@ref Animable2D, @ref Animable3D, @ref AnimableGroup
@ -216,12 +216,28 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Animabl
}
/**
* @brief %Animable group containing this animable
* @brief Group containing this animable
*
* If the animable doesn't belong to any group, returns `nullptr`.
*/
AnimableGroup<dimensions, T>* group();
const AnimableGroup<dimensions, T>* group() const; /**< @overload */
AnimableGroup<dimensions, T>* animables();
const AnimableGroup<dimensions, T>* animables() const; /**< @overload */
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @copydoc animables()
* @deprecated Use @ref Magnum::SceneGraph::Animable::animables() "animables()"
* instead.
*/
AnimableGroup<dimensions, T>* group() { return animables(); }
/**
* @copydoc animables()
* @deprecated Use @ref Magnum::SceneGraph::Animable::animables() "animables()"
* instead.
*/
const AnimableGroup<dimensions, T>* group() const { return animables(); }
#endif
protected:
/**

8
src/SceneGraph/Animable.hpp

@ -25,7 +25,7 @@
*/
/** @file
* @brief @ref compilation-speedup-hpp "Template implementation" for Animable.h and AnimableGroup.h
* @brief @ref compilation-speedup-hpp "Template implementation" for @ref Animable.h and @ref AnimableGroup.h
*/
#include "AnimableGroup.h"
@ -47,16 +47,16 @@ template<UnsignedInt dimensions, class T> Animable<dimensions, T>& Animable<dime
return *this;
/* Wake up the group in case no animations are running */
group()->wakeUp = true;
animables()->wakeUp = true;
currentState = state;
return *this;
}
template<UnsignedInt dimensions, class T> AnimableGroup<dimensions, T>* Animable<dimensions, T>::group() {
template<UnsignedInt dimensions, class T> AnimableGroup<dimensions, T>* Animable<dimensions, T>::animables() {
return static_cast<AnimableGroup<dimensions, T>*>(AbstractGroupedFeature<dimensions, Animable<dimensions, T>, T>::group());
}
template<UnsignedInt dimensions, class T> const AnimableGroup<dimensions, T>* Animable<dimensions, T>::group() const {
template<UnsignedInt dimensions, class T> const AnimableGroup<dimensions, T>* Animable<dimensions, T>::animables() const {
return static_cast<const AnimableGroup<dimensions, T>*>(AbstractGroupedFeature<dimensions, Animable<dimensions, T>, T>::group());
}

11
src/SceneGraph/Camera2D.h

@ -46,12 +46,13 @@ camera.setProjection({4.0f/3.0f, 1.0f})
@section Camera2D-explicit-specializations Explicit template specializations
The following specialization are explicitly compiled into SceneGraph library.
For other specializations (e.g. using Double type) you have to use Camera2D.hpp
implementation file to avoid linker errors. See @ref compilation-speedup-hpp
for more information.
The following specialization are 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 AbstractCamera-explicit-specializations "AbstractCamera"
class documentation or @ref compilation-speedup-hpp for more information.
- @ref BasicCamera2D "BasicCamera2D<Float>"
- @ref Camera2D
@see @ref scenegraph, @ref Camera2D, @ref BasicCamera3D, @ref Drawable,
@ref DrawableGroup

11
src/SceneGraph/Camera3D.h

@ -51,12 +51,13 @@ camera.setPerspective({}, 0.001f, 100.0f)
@section Camera3D-explicit-specializations Explicit template specializations
The following specialization are explicitly compiled into SceneGraph library.
For other specializations (e.g. using Double type) you have to use Camera3D.hpp
implementation file to avoid linker errors. See @ref compilation-speedup-hpp
for more information.
The following specialization are 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 AbstractCamera-explicit-specializations "AbstractCamera"
class documentation or @ref compilation-speedup-hpp for more information.
- @ref BasicCamera3D "BasicCamera3D<Float>"
- @ref Camera3D
@see @ref scenegraph, @ref Camera3D, @ref BasicCamera2D, @ref Drawable,
@ref DrawableGroup

14
src/SceneGraph/Drawable.h

@ -129,6 +129,20 @@ template<UnsignedInt dimensions, class T> class Drawable: public AbstractGrouped
*/
explicit Drawable(AbstractObject<dimensions, T>& object, DrawableGroup<dimensions, T>* drawables = nullptr): AbstractGroupedFeature<dimensions, Drawable<dimensions, T>, T>(object, drawables) {}
/**
* @brief Group containing this drawable
*
* If the drawable doesn't belong to any group, returns `nullptr`.
*/
DrawableGroup<dimensions, T>* drawables() {
return AbstractGroupedFeature<dimensions, Drawable<dimensions, T>, T>::group();
}
/** @overload */
const DrawableGroup<dimensions, T>* drawables() const {
return AbstractGroupedFeature<dimensions, Drawable<dimensions, T>, T>::group();
}
/**
* @brief Draw the object using given camera
* @param transformationMatrix %Object transformation relative

4
src/SceneGraph/FeatureGroup.h

@ -39,7 +39,7 @@ namespace Magnum { namespace SceneGraph {
/**
@brief Base for group of features
See FeatureGroup.
See @ref FeatureGroup.
*/
template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT AbstractFeatureGroup {
template<UnsignedInt, class, class> friend class FeatureGroup;
@ -56,7 +56,7 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Abstrac
/**
@brief Group of features
See AbstractGroupedFeature for more information.
See @ref AbstractGroupedFeature for more information.
@see @ref scenegraph, @ref BasicFeatureGroup2D, @ref BasicFeatureGroup3D,
@ref FeatureGroup2D, @ref FeatureGroup3D
*/

2
src/SceneGraph/FeatureGroup.hpp

@ -25,7 +25,7 @@
*/
/** @file
* @brief @ref compilation-speedup-hpp "Template implementation" for FeatureGroup.h
* @brief @ref compilation-speedup-hpp "Template implementation" for @ref FeatureGroup.h
*/
#include "FeatureGroup.h"

42
src/SceneGraph/Object.h

@ -56,16 +56,16 @@ Base of scene graph. Contains specific transformation implementation, takes
care of parent/children relationship and contains features. See @ref scenegraph
for introduction.
Common usage is to typedef Object with desired transformation type to save
unnecessary typing later, along with Scene and possibly other types, e.g.:
Common usage is to typedef @ref Object with desired transformation type to save
unnecessary typing later, along with @ref Scene and possibly other types, e.g.:
@code
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
@endcode
Uses Corrade::Containers::LinkedList for parent/children relationship.
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 lastChild() and previousSibling().
possible to go in reverse order using @ref lastChild() and @ref previousSibling().
@code
for(Object* child = o->firstChild(); child; child = child->nextSibling()) {
// ...
@ -74,21 +74,25 @@ for(Object* child = o->firstChild(); child; child = child->nextSibling()) {
@section Object-explicit-specializations Explicit template specializations
The following specialization are explicitly compiled into SceneGraph library.
For other specializations (e.g. using Double type or special transformation
class) you have to use Object.hpp implementation file to avoid linker errors.
See @ref compilation-speedup-hpp for more information.
- @ref DualComplexTransformation "Object<DualComplexTransformation<Float>>"
- @ref DualQuaternionTransformation "Object<DualQuaternionTransformation<Float>>"
- @ref MatrixTransformation2D "Object<MatrixTransformation2D<Float>>"
- @ref MatrixTransformation3D "Object<MatrixTransformation3D<Float>>"
- @ref RigidMatrixTransformation2D "Object<RigidMatrixTransformation2D<Float>>"
- @ref RigidMatrixTransformation3D "Object<RigidMatrixTransformation3D<Float>>"
- @ref TranslationTransformation2D "Object<TranslationTransformation2D<Float>>"
- @ref TranslationTransformation3D "Object<TranslationTransformation3D<Float>>"
@see Scene, AbstractFeature, AbstractTransformation, DebugTools::ObjectRenderer
The following specialization 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
@ref AbstractObject-explicit-specializations "AbstractObject" and
@ref AbstractTransformation-explicit-specializations "AbstractTransformation"
class documentation or @ref compilation-speedup-hpp for more information.
- @ref DualComplexTransformation "Object<DualComplexTransformation>"
- @ref DualQuaternionTransformation "Object<DualQuaternionTransformation>"
- @ref MatrixTransformation2D "Object<MatrixTransformation2D>"
- @ref MatrixTransformation3D "Object<MatrixTransformation3D>"
- @ref RigidMatrixTransformation2D "Object<RigidMatrixTransformation2D>"
- @ref RigidMatrixTransformation3D "Object<RigidMatrixTransformation3D>"
- @ref TranslationTransformation2D "Object<TranslationTransformation2D>"
- @ref TranslationTransformation3D "Object<TranslationTransformation3D>"
@see @ref Scene, @ref AbstractFeature, @ref AbstractTransformation,
@ref DebugTools::ObjectRenderer
*/
template<class Transformation> class MAGNUM_SCENEGRAPH_EXPORT Object: public AbstractObject<Transformation::Dimensions, typename Transformation::Type>, public Transformation
#ifndef DOXYGEN_GENERATING_OUTPUT

2
src/SceneGraph/Object.hpp

@ -25,7 +25,7 @@
*/
/** @file
* @brief @ref compilation-speedup-hpp "Template implementation" for Object.h
* @brief @ref compilation-speedup-hpp "Template implementation" for @ref AbstractObject.h, @ref AbstractTransformation.h and @ref Object.h
*/
#include "AbstractTransformation.h"

2
src/SceneGraph/instantiation.cpp

@ -61,6 +61,8 @@ template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicRigidMatrixTransformation2D<
template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicRigidMatrixTransformation3D<Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<TranslationTransformation<2, Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<TranslationTransformation<3, Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<TranslationTransformation<2, Float, Int>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<TranslationTransformation<3, Float, Int>>;
#endif
}}

6
src/Shader.cpp

@ -31,7 +31,7 @@
#include "Implementation/State.h"
#include "Implementation/ShaderState.h"
#if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(_WIN32)
#if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(__MINGW32__)
#include <sstream>
#endif
@ -582,7 +582,7 @@ Shader& Shader::operator=(Shader&& other) {
Shader& Shader::addSource(std::string source) {
if(!source.empty()) {
#if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(_WIN32)
#if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(__MINGW32__)
std::ostringstream converter;
converter << (sources.size()+1)/2;
#endif
@ -591,7 +591,7 @@ Shader& Shader::addSource(std::string source) {
Source 0 is the #version string added in constructor. */
sources.push_back("#line 1 " +
/* This shouldn't be ambiguous. But is. */
#if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(_WIN32)
#if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(__MINGW32__)
#ifndef CORRADE_GCC44_COMPATIBILITY
std::to_string((sources.size()+1)/2) +
#else

2
src/Shaders/Flat.cpp

@ -84,7 +84,7 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): tran
}
#ifndef MAGNUM_TARGET_GLES
if(flags && !Context::current()->isExtensionSupported<Extensions::GL::ARB::shading_language_420pack>(version))
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shading_language_420pack>(version))
#endif
{
if(flags & Flag::Textured) setUniform(uniformLocation("textureData"), TextureLayer);

1
src/Shaders/Flat.frag

@ -25,6 +25,7 @@
#ifndef NEW_GLSL
#define fragmentColor gl_FragColor
#define texture texture2D
#define in varying
#endif
#ifdef TEXTURED

2
src/Shaders/Flat.h

@ -74,7 +74,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public Abstra
*
* Used only if @ref Flag::Textured is set.
*/
typedef Attribute<2, Vector2> TextureCoordinates;
typedef Attribute<1, Vector2> TextureCoordinates;
enum: Int {
/** Layer for color texture. Used only if @ref Flag::Textured is set. */

3
src/Shaders/Vector.cpp

@ -38,7 +38,7 @@ namespace {
template<> constexpr const char* vertexShaderName<3>() { return "AbstractVector3D.vert"; }
}
template<UnsignedInt dimensions> Vector<dimensions>::Vector(): transformationProjectionMatrixUniform(0), colorUniform(1) {
template<UnsignedInt dimensions> Vector<dimensions>::Vector(): transformationProjectionMatrixUniform(0), backgroundColorUniform(1), colorUniform(2) {
Utility::Resource rs("MagnumShaders");
/* Weird bug in GCC 4.5 - cannot use initializer list here, although the
@ -79,6 +79,7 @@ template<UnsignedInt dimensions> Vector<dimensions>::Vector(): transformationPro
#endif
{
transformationProjectionMatrixUniform = AbstractShaderProgram::uniformLocation("transformationProjectionMatrix");
backgroundColorUniform = AbstractShaderProgram::uniformLocation("backgroundColor");
colorUniform = AbstractShaderProgram::uniformLocation("color");
}

6
src/Shaders/Vector.frag

@ -29,8 +29,10 @@
#endif
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 1) uniform vec4 color;
layout(location = 1) uniform vec4 backgroundColor;
layout(location = 2) uniform vec4 color;
#else
uniform lowp vec4 backgroundColor;
uniform lowp vec4 color;
#endif
@ -48,5 +50,5 @@ out lowp vec4 fragmentColor;
void main() {
lowp float intensity = texture(vectorTexture, fragmentTextureCoordinates).r;
fragmentColor = intensity*color;
fragmentColor = mix(backgroundColor, color, intensity);
}

15
src/Shaders/Vector.h

@ -56,9 +56,23 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Vector: public Abst
return *this;
}
/**
* @brief Set background color
* @return Reference to self (for method chaining)
*
* Default is transparent black.
* @see @ref setColor()
*/
Vector& setBackgroundColor(const Color4& color) {
AbstractShaderProgram::setUniform(backgroundColorUniform, color);
return *this;
}
/**
* @brief Set fill color
* @return Reference to self (for method chaining)
*
* @see @ref setBackgroundColor()
*/
Vector& setColor(const Color4& color) {
AbstractShaderProgram::setUniform(colorUniform, color);
@ -67,6 +81,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Vector: public Abst
private:
Int transformationProjectionMatrixUniform,
backgroundColorUniform,
colorUniform;
};

2
src/Test/AbstractOpenGLTester.h

@ -50,7 +50,7 @@ class AbstractOpenGLTester: public TestSuite::Tester, public Platform::Windowles
int AbstractOpenGLTester::zero = 0;
#define MAGNUM_VERIFY_NO_ERROR() CORRADE_COMPARE(Renderer::error(), Renderer::Error::NoError)
#define MAGNUM_VERIFY_NO_ERROR() CORRADE_COMPARE(Magnum::Renderer::error(), Magnum::Renderer::Error::NoError)
}}

70
src/Text/AbstractFont.cpp

@ -28,11 +28,13 @@
#include <Containers/Array.h>
#include <Utility/Unicode.h>
#include "Text/GlyphCache.h"
namespace Magnum { namespace Text {
AbstractFont::AbstractFont(): _size(0.0f) {}
AbstractFont::AbstractFont(PluginManager::AbstractManager* manager, std::string plugin): AbstractPlugin(manager, std::move(plugin)), _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<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, const Float size) {
CORRADE_ASSERT(features() & Feature::OpenData,
@ -41,18 +43,19 @@ bool AbstractFont::openData(const std::vector<std::pair<std::string, Containers:
"Text::AbstractFont::openData(): no data passed", false);
close();
doOpenData(data, size);
std::tie(_size, _lineHeight) = doOpenData(data, size);
CORRADE_INTERNAL_ASSERT(isOpened() || (_size == 0.0f && _lineHeight == 0.0f));
return isOpened();
}
void AbstractFont::doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, const Float size) {
std::pair<Float, Float> AbstractFont::doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, const Float size) {
CORRADE_ASSERT(!(features() & Feature::MultiFile),
"Text::AbstractFont::openData(): feature advertised but not implemented", );
"Text::AbstractFont::openData(): feature advertised but not implemented", {});
CORRADE_ASSERT(data.size() == 1,
"Text::AbstractFont::openData(): expected just one file for single-file format", );
"Text::AbstractFont::openData(): expected just one file for single-file format", {});
close();
doOpenSingleData(data[0].second, size);
return doOpenSingleData(data[0].second, size);
}
bool AbstractFont::openSingleData(const Containers::ArrayReference<const unsigned char> data, const Float size) {
@ -62,29 +65,31 @@ bool AbstractFont::openSingleData(const Containers::ArrayReference<const unsigne
"Text::AbstractFont::openSingleData(): the format is not single-file", false);
close();
doOpenSingleData(data, size);
std::tie(_size, _lineHeight) = doOpenSingleData(data, size);
CORRADE_INTERNAL_ASSERT(isOpened() || (_size == 0.0f && _lineHeight == 0.0f));
return isOpened();
}
void AbstractFont::doOpenSingleData(Containers::ArrayReference<const unsigned char>, Float) {
CORRADE_ASSERT(false, "Text::AbstractFont::openSingleData(): feature advertised but not implemented", );
std::pair<Float, Float> AbstractFont::doOpenSingleData(Containers::ArrayReference<const unsigned char>, Float) {
CORRADE_ASSERT(false, "Text::AbstractFont::openSingleData(): feature advertised but not implemented", {});
}
bool AbstractFont::openFile(const std::string& filename, const Float size) {
close();
doOpenFile(filename, size);
std::tie(_size, _lineHeight) = doOpenFile(filename, size);
CORRADE_INTERNAL_ASSERT(isOpened() || (_size == 0.0f && _lineHeight == 0.0f));
return isOpened();
}
void AbstractFont::doOpenFile(const std::string& filename, const Float size) {
std::pair<Float, Float> AbstractFont::doOpenFile(const std::string& filename, const Float size) {
CORRADE_ASSERT(features() & Feature::OpenData && !(features() & Feature::MultiFile),
"Text::AbstractFont::openFile(): not implemented", );
"Text::AbstractFont::openFile(): not implemented", {});
/* Open file */
std::ifstream in(filename.data(), std::ios::binary);
if(!in.good()) {
Error() << "Trade::AbstractFont::openFile(): cannot open file" << filename;
return;
return {};
}
/* Create array to hold file contents */
@ -96,12 +101,14 @@ void AbstractFont::doOpenFile(const std::string& filename, const Float size) {
in.read(reinterpret_cast<char*>(data.begin()), data.size());
in.close();
doOpenSingleData(data, size);
return doOpenSingleData(data, size);
}
void AbstractFont::close() {
if(isOpened()) {
doClose();
_size = 0.0f;
_lineHeight = 0.0f;
CORRADE_INTERNAL_ASSERT(!isOpened());
}
}
@ -127,7 +134,7 @@ void AbstractFont::fillGlyphCache(GlyphCache& cache, const std::string& characte
doFillGlyphCache(cache, Utility::Unicode::utf32(characters));
}
#ifndef _WIN32
#ifndef __MINGW32__
void AbstractFont::doFillGlyphCache(GlyphCache&, const std::u32string&)
#else
void AbstractFont::doFillGlyphCache(GlyphCache&, const std::vector<char32_t>&)
@ -136,7 +143,7 @@ void AbstractFont::doFillGlyphCache(GlyphCache&, const std::vector<char32_t>&)
CORRADE_ASSERT(false, "Text::AbstractFont::fillGlyphCache(): feature advertised but not implemented", );
}
GlyphCache* AbstractFont::createGlyphCache() {
std::unique_ptr<GlyphCache> AbstractFont::createGlyphCache() {
CORRADE_ASSERT(isOpened(),
"Text::AbstractFont::createGlyphCache(): no font opened", nullptr);
CORRADE_ASSERT(features() & Feature::PreparedGlyphCache,
@ -145,18 +152,43 @@ GlyphCache* AbstractFont::createGlyphCache() {
return doCreateGlyphCache();
}
GlyphCache* AbstractFont::doCreateGlyphCache() {
std::unique_ptr<GlyphCache> AbstractFont::doCreateGlyphCache() {
CORRADE_ASSERT(false, "Text::AbstractFont::createGlyphCache(): feature advertised but not implemented", nullptr);
}
AbstractLayouter* AbstractFont::layout(const GlyphCache& cache, const Float size, const std::string& text) {
std::unique_ptr<AbstractLayouter> AbstractFont::layout(const GlyphCache& cache, const Float size, const std::string& text) {
CORRADE_ASSERT(isOpened(), "Text::AbstractFont::layout(): no font opened", nullptr);
return doLayout(cache, size, text);
}
AbstractLayouter::AbstractLayouter(): _glyphCount(0) {}
AbstractLayouter::AbstractLayouter(UnsignedInt glyphCount): _glyphCount(glyphCount) {}
AbstractLayouter::~AbstractLayouter() {}
std::pair<Rectangle, Rectangle> AbstractLayouter::renderGlyph(const UnsignedInt i, Vector2& cursorPosition, Rectangle& rectangle) {
CORRADE_ASSERT(i < glyphCount(), "Text::AbstractLayouter::renderGlyph(): glyph index out of bounds", {});
/* Render the glyph */
Rectangle quadPosition, textureCoordinates;
Vector2 advance;
std::tie(quadPosition, textureCoordinates, advance) = doRenderGlyph(i);
/* Move the quad to cursor */
quadPosition.bottomLeft() += cursorPosition;
quadPosition.topRight() += cursorPosition;
/* Extend rectangle with current quad bounds. If zero size, replace it. */
if(!rectangle.size().isZero()) {
rectangle.bottomLeft() = Math::min(rectangle.bottomLeft(), quadPosition.bottomLeft());
rectangle.topRight() = Math::max(rectangle.topRight(), quadPosition.topRight());
} else rectangle = quadPosition;
/* Advance cursor position to next character */
cursorPosition += advance;
/* Return moved quad and unchanged texture coordinates */
return {quadPosition, textureCoordinates};
}
}}

160
src/Text/AbstractFont.h

@ -25,11 +25,12 @@
*/
/** @file
* @brief Class Magnum::Text::AbstractFont, Magnum::Text::AbstractLayouter
* @brief Class @ref Magnum::Text::AbstractFont, @ref Magnum::Text::AbstractLayouter
*/
#include <tuple>
#include <memory>
#include <string>
#include <tuple>
#include <PluginManager/AbstractPlugin.h>
#include "Magnum.h"
@ -44,41 +45,43 @@ namespace Magnum { namespace Text {
@section AbstractFont-usage Usage
First step is to open the font using open(), next step is to prerender all the
glyphs which will be used in text rendering later, see GlyphCache for more
information. See TextRenderer for information about text rendering.
First step is to open the font using @ref openData(), @ref openSingleData() or
@ref openFile(). Next step is to prerender all the glyphs which will be used in
text rendering later, see @ref GlyphCache for more information. See
@ref Renderer for information about text rendering.
@section AbstractFont-subclassing Subclassing
Plugin implements doFeatures(), doClose(), doCreateGlyphCache(), doLayout() and
one or more of `doOpen*()` functions.
Plugin implements @ref doFeatures(), @ref doClose(), @ref doLayout(), either
@ref doCreateGlyphCache() or @ref doFillGlyphCache() and one or more of
`doOpen*()` functions. See also @ref AbstractLayouter for more information.
You don't need to do most of the redundant sanity checks, these things are
checked by the implementation:
- Functions doOpenData(), doOpenSingleData() and doOpenFile() are called
after the previous file was closed, function doClose() is called only if
there is any file opened.
- Functions doOpenData() and doOpenSingleData() are called only if
- Functions @ref doOpenData(), @ref doOpenSingleData() and @ref doOpenFile()
are called after the previous file was closed, function @ref doClose() is
called only if there is any file opened.
- Functions @ref doOpenData() and @ref doOpenSingleData() are called only if
@ref Feature::OpenData is supported.
- All `do*()` implementations working on opened file are called only if
there is any file opened.
*/
class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
CORRADE_PLUGIN_INTERFACE("cz.mosra.magnum.Text.AbstractFont/0.2")
CORRADE_PLUGIN_INTERFACE("cz.mosra.magnum.Text.AbstractFont/0.2.3")
public:
/**
* @brief Features supported by this importer
*
* @see Features, features()
* @see @ref Features, @ref features()
*/
enum class Feature: UnsignedByte {
/** Opening fonts from raw data using openData() */
/** Opening fonts from raw data using @ref openData() */
OpenData = 1 << 0,
/**
* The format is multi-file, thus openSingleData() convenience
* The format is multi-file, thus @ref openSingleData() convenience
* function cannot be used.
*/
MultiFile = 1 << 1,
@ -86,7 +89,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
/**
* The font contains prepared glyph cache.
*
* @see fillGlyphCache(), createGlyphCache()
* @see @ref fillGlyphCache(), @ref createGlyphCache()
*/
PreparedGlyphCache = 1 << 2
};
@ -148,6 +151,9 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
/** @brief Font size */
Float size() const { return _size; }
/** @brief Line height */
Float lineHeight() const { return _lineHeight; }
/**
* @brief Glyph ID for given character
*
@ -162,7 +168,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
*
* @note This function is not meant to be used in performance-critical
* code, only for font observations and conversions.
* @see glyphId()
* @see @ref glyphId()
*/
Vector2 glyphAdvance(UnsignedInt glyph);
@ -185,7 +191,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* Other fonts support only partial glyph cache filling, see
* @ref fillGlyphCache().
*/
GlyphCache* createGlyphCache();
std::unique_ptr<GlyphCache> createGlyphCache();
/**
* @brief Layout the text using font's own layouter
@ -193,59 +199,61 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* @param size Font size
* @param text %Text to layout
*
* @see fillGlyphCache(), createGlyphCache()
* Note that the layouters support rendering of single-line text only.
* See @ref Renderer class for more advanced text layouting.
* @see @ref fillGlyphCache(), @ref createGlyphCache()
*/
AbstractLayouter* layout(const GlyphCache& cache, Float size, const std::string& text);
#ifdef DOXYGEN_GENERATING_OUTPUT
private:
#else
protected:
#endif
Float _size;
std::unique_ptr<AbstractLayouter> layout(const GlyphCache& cache, Float size, const std::string& text);
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/** @brief Implementation for features() */
/** @brief Implementation for @ref features() */
virtual Features doFeatures() const = 0;
/** @brief Implementation for isOpened() */
/** @brief Implementation for @ref isOpened() */
virtual bool doIsOpened() const = 0;
/**
* @brief Implementation for openData()
* @brief Implementation for @ref openData()
*
* If the plugin doesn't have @ref Feature::MultiFile, default
* implementation calls @ref doOpenSingleData().
* Return size and line height of opened font on successful opening,
* zeros otherwise. If the plugin doesn't have @ref Feature::MultiFile,
* default implementation calls @ref doOpenSingleData().
*/
virtual void doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, Float size);
virtual std::pair<Float, Float> doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, Float size);
/** @brief Implementation for openSingleData() */
virtual void doOpenSingleData(Containers::ArrayReference<const unsigned char> data, Float size);
/**
* @brief Implementation for @ref openSingleData()
*
* Return size and line height of opened font on successful opening,
* zeros otherwise.
*/
virtual std::pair<Float, Float> doOpenSingleData(Containers::ArrayReference<const unsigned char> data, Float size);
/**
* @brief Implementation for openFile()
* @brief Implementation for @ref openFile()
*
* If @ref Feature::OpenData is supported and the plugin doesn't have
* @ref Feature::MultiFile, default implementation opens the file and
* calls @ref doOpenSingleData() with its contents.
* Return size and line height of opened font on successful opening,
* zeros otherwise. If @ref Feature::OpenData is supported and the
* plugin doesn't have @ref Feature::MultiFile, default implementation
* opens the file and calls @ref doOpenSingleData() with its contents.
*/
virtual void doOpenFile(const std::string& filename, Float size);
virtual std::pair<Float, Float> doOpenFile(const std::string& filename, Float size);
/** @brief Implementation for close() */
/** @brief Implementation for @ref close() */
virtual void doClose() = 0;
/** @brief Implementation for glyphId() */
/** @brief Implementation for @ref glyphId() */
virtual UnsignedInt doGlyphId(char32_t character) = 0;
/** @brief Implementation for glyphAdvance() */
/** @brief Implementation for @ref glyphAdvance() */
virtual Vector2 doGlyphAdvance(UnsignedInt glyph) = 0;
/**
* @brief Implementation for createGlyphCache()
* @brief Implementation for @ref fillGlyphCache()
*
* The string is converted from UTF-8 to UTF-32, unique characters are
* *not* removed.
@ -253,19 +261,22 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* `std::u32string`. See @ref Corrade::Utility::Unicode::utf32()
* for more information.
*/
#ifndef _WIN32
#ifndef __MINGW32__
virtual void doFillGlyphCache(GlyphCache& cache, const std::u32string& characters);
#else
virtual void doFillGlyphCache(GlyphCache& cache, const std::vector<char32_t>& characters);
#endif
/**
* @brief Implementation for createGlyphCache()
*/
virtual GlyphCache* doCreateGlyphCache();
/** @brief Implementation for @ref createGlyphCache() */
virtual std::unique_ptr<GlyphCache> doCreateGlyphCache();
/** @brief Implementation for layout() */
virtual AbstractLayouter* doLayout(const GlyphCache& cache, Float size, const std::string& text) = 0;
/** @brief Implementation for @ref layout() */
virtual std::unique_ptr<AbstractLayouter> doLayout(const GlyphCache& cache, Float size, const std::string& text) = 0;
#ifdef DOXYGEN_GENERATING_OUTPUT
private:
#endif
Float _size, _lineHeight;
};
CORRADE_ENUMSET_OPERATORS(AbstractFont::Features)
@ -273,7 +284,13 @@ CORRADE_ENUMSET_OPERATORS(AbstractFont::Features)
/**
@brief Base for text layouters
Returned by AbstractFont::layout().
Returned by @ref AbstractFont::layout().
@section TextAbstractLayouter-subclassing Subclassing
Plugin creates private subclass (no need to expose it to end users) and
implements @ref doRenderGlyph(). Bounds checking on @p i is done automatically
in the wrapping @ref renderGlyph() function.
*/
class MAGNUM_TEXT_EXPORT AbstractLayouter {
AbstractLayouter(const AbstractLayouter&) = delete;
@ -282,27 +299,46 @@ class MAGNUM_TEXT_EXPORT AbstractLayouter {
AbstractLayouter& operator=(const AbstractLayouter&&) = delete;
public:
explicit AbstractLayouter();
virtual ~AbstractLayouter() = 0;
~AbstractLayouter();
/** @brief Count of glyphs in laid out text */
UnsignedInt glyphCount() const {
return _glyphCount;
}
UnsignedInt glyphCount() const { return _glyphCount; }
/**
* @brief Render glyph
* @param i Glyph index
* @param cursorPosition Cursor position
* @param rectangle Bounding rectangle
*
* Returns quad position, texture coordinates and advance to next
* glyph.
* The function returns pair of quad position and texture coordinates,
* advances @p cursorPosition to next character and updates @p rectangle
* with extended bounds.
*/
virtual std::tuple<Rectangle, Rectangle, Vector2> renderGlyph(UnsignedInt i) = 0;
std::pair<Rectangle, Rectangle> renderGlyph(UnsignedInt i, Vector2& cursorPosition, Rectangle& rectangle);
protected:
/**
* @brief Constructor
* @param glyphCount Count of glyphs in laid out text
*/
explicit AbstractLayouter(UnsignedInt glyphCount);
#ifdef DOXYGEN_GENERATING_OUTPUT
private:
#else
protected:
#else
private:
#endif
/**
* @brief Implementation for @ref renderGlyph()
* @param i Glyph index
*
* Return quad position (relative to current cursor position), texture
* coordinates and advance to next glyph.
*/
virtual std::tuple<Rectangle, Rectangle, Vector2> doRenderGlyph(UnsignedInt i) = 0;
#ifdef DOXYGEN_GENERATING_OUTPUT
private:
#endif
UnsignedInt _glyphCount;
};

24
src/Text/AbstractFontConverter.cpp

@ -30,6 +30,8 @@
#include <Utility/Assert.h>
#include <Utility/Unicode.h>
#include "Text/GlyphCache.h"
namespace Magnum { namespace Text {
AbstractFontConverter::AbstractFontConverter() = default;
@ -43,7 +45,7 @@ std::vector<std::pair<std::string, Containers::Array<unsigned char>>> AbstractFo
return doExportFontToData(font, cache, filename, uniqueUnicode(characters));
}
#ifndef _WIN32
#ifndef __MINGW32__
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> AbstractFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const
#else
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> AbstractFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const
@ -73,7 +75,7 @@ Containers::Array<unsigned char> AbstractFontConverter::exportFontToSingleData(A
return doExportFontToSingleData(font, cache, uniqueUnicode(characters));
}
#ifndef _WIN32
#ifndef __MINGW32__
Containers::Array<unsigned char> AbstractFontConverter::doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string&) const
#else
Containers::Array<unsigned char> AbstractFontConverter::doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector<char32_t>&) const
@ -95,7 +97,7 @@ bool AbstractFontConverter::exportFontToFile(AbstractFont& font, GlyphCache& cac
return doExportFontToFile(font, cache, filename, uniqueUnicode(characters));
}
#ifndef _WIN32
#ifndef __MINGW32__
bool AbstractFontConverter::doExportFontToFile(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const
#else
bool AbstractFontConverter::doExportFontToFile(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const
@ -195,7 +197,7 @@ bool AbstractFontConverter::doExportGlyphCacheToFile(GlyphCache& cache, const st
return true;
}
GlyphCache* AbstractFontConverter::importGlyphCacheFromData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data) const {
std::unique_ptr<GlyphCache> AbstractFontConverter::importGlyphCacheFromData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data) const {
CORRADE_ASSERT(features() >= (Feature::ImportGlyphCache|Feature::ConvertData),
"Text::AbstractFontConverter::importGlyphCacheFromData(): feature not supported", nullptr);
CORRADE_ASSERT(!data.empty(),
@ -204,7 +206,7 @@ GlyphCache* AbstractFontConverter::importGlyphCacheFromData(const std::vector<st
return doImportGlyphCacheFromData(data);
}
GlyphCache* AbstractFontConverter::doImportGlyphCacheFromData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data) const {
std::unique_ptr<GlyphCache> AbstractFontConverter::doImportGlyphCacheFromData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data) const {
CORRADE_ASSERT(!(features() & Feature::MultiFile),
"Text::AbstractFontConverter::importGlyphCacheFromData(): feature advertised but not implemented", nullptr);
CORRADE_ASSERT(data.size() == 1,
@ -213,7 +215,7 @@ GlyphCache* AbstractFontConverter::doImportGlyphCacheFromData(const std::vector<
return doImportGlyphCacheFromSingleData(data[0].second);
}
GlyphCache* AbstractFontConverter::importGlyphCacheFromSingleData(Containers::ArrayReference<const unsigned char> data) const {
std::unique_ptr<GlyphCache> AbstractFontConverter::importGlyphCacheFromSingleData(Containers::ArrayReference<const unsigned char> data) const {
CORRADE_ASSERT(features() >= (Feature::ImportGlyphCache|Feature::ConvertData),
"Text::AbstractFontConverter::importGlyphCacheFromSingleData(): feature not supported", nullptr);
CORRADE_ASSERT(!(features() & Feature::MultiFile),
@ -222,19 +224,19 @@ GlyphCache* AbstractFontConverter::importGlyphCacheFromSingleData(Containers::Ar
return doImportGlyphCacheFromSingleData(data);
}
GlyphCache* AbstractFontConverter::doImportGlyphCacheFromSingleData(Containers::ArrayReference<const unsigned char>) const {
std::unique_ptr<GlyphCache> AbstractFontConverter::doImportGlyphCacheFromSingleData(Containers::ArrayReference<const unsigned char>) const {
CORRADE_ASSERT(false,
"Text::AbstractFontConverter::importGlyphCacheFromSingleData(): feature advertised but not implemented", nullptr);
}
GlyphCache* AbstractFontConverter::importGlyphCacheFromFile(const std::string& filename) const {
std::unique_ptr<GlyphCache> AbstractFontConverter::importGlyphCacheFromFile(const std::string& filename) const {
CORRADE_ASSERT(features() & Feature::ImportGlyphCache,
"Text::AbstractFontConverter::importGlyphCacheFromFile(): feature not supported", nullptr);
return doImportGlyphCacheFromFile(filename);
}
GlyphCache* AbstractFontConverter::doImportGlyphCacheFromFile(const std::string& filename) const {
std::unique_ptr<GlyphCache> AbstractFontConverter::doImportGlyphCacheFromFile(const std::string& filename) const {
CORRADE_ASSERT(features() & Feature::ConvertData && !(features() & Feature::MultiFile),
"Text::AbstractFontConverter::importGlyphCacheFromFile(): not implemented", nullptr);
@ -257,14 +259,14 @@ GlyphCache* AbstractFontConverter::doImportGlyphCacheFromFile(const std::string&
return doImportGlyphCacheFromSingleData(data);
}
#ifndef _WIN32
#ifndef __MINGW32__
std::u32string AbstractFontConverter::uniqueUnicode(const std::string& characters)
#else
std::vector<char32_t> AbstractFontConverter::uniqueUnicode(const std::string& characters)
#endif
{
/* Convert UTF-8 to UTF-32 */
#ifndef _WIN32
#ifndef __MINGW32__
std::u32string result = Utility::Unicode::utf32(characters);
#else
std::vector<char32_t> result = Utility::Unicode::utf32(characters);

39
src/Text/AbstractFontConverter.h

@ -25,9 +25,10 @@
*/
/** @file
* @brief Class Magnum::Text::AbstractFontConverter
* @brief Class @ref Magnum::Text::AbstractFontConverter
*/
#include <memory>
#include <PluginManager/AbstractPlugin.h>
#include "Magnum.h"
@ -43,9 +44,10 @@ Provides functionality for converting arbitrary font to different format.
@section AbstractFontConverter-subclassing Subclassing
Plugin implements doFeatures() and one or more of `exportTo*()` / `importFrom*()`
functions based on what features are supported. Characters passed to font
exporting functions are converted to list of unique UTF-32 characters.
Plugin implements @ref doFeatures() and one or more of `exportTo*()` /
`importFrom*()` functions based on what features are supported. Characters
passed to font exporting functions are converted to list of unique UTF-32
characters.
You don't need to do most of the redundant sanity checks, these things are
checked by the implementation:
@ -61,7 +63,7 @@ checked by the implementation:
array passed.
*/
class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPlugin {
CORRADE_PLUGIN_INTERFACE("cz.mosra.magnum.Text.AbstractFontConverter/0.1")
CORRADE_PLUGIN_INTERFACE("cz.mosra.magnum.Text.AbstractFontConverter/0.1.1")
public:
/**
@ -222,7 +224,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
* @see @ref features(), @ref importGlyphCacheFromFile(),
* @ref exportGlyphCacheToData()
*/
GlyphCache* importGlyphCacheFromData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data) const;
std::unique_ptr<GlyphCache> importGlyphCacheFromData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data) const;
/**
* @brief Import glyph cache from single raw data
@ -234,7 +236,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
* @see @ref features(), @ref importGlyphCacheFromFile(),
* @ref exportFontToSingleData()
*/
GlyphCache* importGlyphCacheFromSingleData(Containers::ArrayReference<const unsigned char> data) const;
std::unique_ptr<GlyphCache> importGlyphCacheFromSingleData(Containers::ArrayReference<const unsigned char> data) const;
/**
* @brief Import glyph cache from file
@ -247,7 +249,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
* @see @ref features(), @ref importGlyphCacheFromData(),
* @ref exportGlyphCacheToFile()
*/
GlyphCache* importGlyphCacheFromFile(const std::string& filename) const;
std::unique_ptr<GlyphCache> importGlyphCacheFromFile(const std::string& filename) const;
#ifndef DOXYGEN_GENERATING_OUTPUT
private:
@ -266,7 +268,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
* `std::u32string`. See @ref Corrade::Utility::Unicode::utf32()
* for more information.
*/
#ifndef _WIN32
#ifndef __MINGW32__
virtual std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const;
#else
virtual std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const;
@ -279,7 +281,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
* `std::u32string`. See @ref Corrade::Utility::Unicode::utf32()
* for more information.
*/
#ifndef _WIN32
#ifndef __MINGW32__
virtual Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::u32string& characters) const;
#else
virtual Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::vector<char32_t>& characters) const;
@ -289,12 +291,13 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
* @brief Implementation for @ref exportFontToFile()
*
* If @ref Feature::ConvertData is supported, default implementation
* calls doExportFontToData() and saves the result to given file(s).
* calls @ref doExportFontToData() and saves the result to given
* file(s).
* @note On Windows uses `std::vector<char32_t>` instead of
* `std::u32string`. See @ref Corrade::Utility::Unicode::utf32()
* for more information.
*/
#ifndef _WIN32
#ifndef __MINGW32__
virtual bool doExportFontToFile(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const;
#else
virtual bool doExportFontToFile(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const;
@ -308,7 +311,7 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
*/
virtual std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportGlyphCacheToData(GlyphCache& cache, const std::string& filename) const;
/** @brief Implementation for exportGlyphCacheToSingleData() */
/** @brief Implementation for @ref exportGlyphCacheToSingleData() */
virtual Containers::Array<unsigned char> doExportGlyphCacheToSingleData(GlyphCache& cache) const;
/**
@ -326,10 +329,10 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
* If the plugin doesn't have @ref Feature::MultiFile, default
* implementation calls @ref doImportGlyphCacheFromSingleData().
*/
virtual GlyphCache* doImportGlyphCacheFromData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data) const;
virtual std::unique_ptr<GlyphCache> doImportGlyphCacheFromData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data) const;
/** @brief Implementation for importGlyphCacheFromSingleData() */
virtual GlyphCache* doImportGlyphCacheFromSingleData(Containers::ArrayReference<const unsigned char> data) const;
/** @brief Implementation for @ref importGlyphCacheFromSingleData() */
virtual std::unique_ptr<GlyphCache> doImportGlyphCacheFromSingleData(Containers::ArrayReference<const unsigned char> data) const;
/**
* @brief Implementation for @ref importGlyphCacheFromFile()
@ -338,10 +341,10 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
* have @ref Feature::MultiFile, default implementation opens the file
* and calls @ref doImportGlyphCacheFromSingleData() with its contents.
*/
virtual GlyphCache* doImportGlyphCacheFromFile(const std::string& filename) const;
virtual std::unique_ptr<GlyphCache> doImportGlyphCacheFromFile(const std::string& filename) const;
private:
#ifndef _WIN32
#ifndef __MINGW32__
MAGNUM_TEXT_LOCAL static std::u32string uniqueUnicode(const std::string& characters);
#else
MAGNUM_TEXT_LOCAL static std::vector<char32_t> uniqueUnicode(const std::string& characters);

131
src/Text/Alignment.h

@ -0,0 +1,131 @@
#ifndef Magnum_Text_Alignment_h
#define Magnum_Text_Alignment_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
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 Enum @ref Magnum::Text::Alignment
*/
#include "Types.h"
namespace Magnum { namespace Text {
namespace Implementation {
enum: UnsignedByte {
AlignmentLeft = 1,
AlignmentCenter = 2,
AlignmentRight = 3,
AlignmentLine = 1 << 3,
AlignmentMiddle = 2 << 3,
AlignmentTop = 3 << 3,
AlignmentHorizontal = 3,
AlignmentVertical = 3 << 3,
AlignmentIntegral = 1 << 6
};
}
/**
@brief Text rendering alignment
@see @ref Renderer::render(), @ref Renderer::Renderer()
*/
enum class Alignment: UnsignedByte {
/** Text start and line is at origin */
LineLeft = Implementation::AlignmentLine|Implementation::AlignmentLeft,
/**
* Text center and line is at origin
*
* @see @ref Alignment::LineCenterIntegral
*/
LineCenter = Implementation::AlignmentLine|Implementation::AlignmentCenter,
/** Text end and line is at origin */
LineRight = Implementation::AlignmentLine|Implementation::AlignmentRight,
/**
* 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
*
* @see @ref Alignment::MiddleRightIntegral
*/
MiddleCenter = Implementation::AlignmentMiddle|Implementation::AlignmentCenter,
/**
* Text end and vertical middle is at origin
*
* @see @ref Alignment::MiddleRightIntegral
*/
MiddleRight = Implementation::AlignmentMiddle|Implementation::AlignmentRight,
/** Text start and top is at origin */
TopLeft = Implementation::AlignmentTop|Implementation::AlignmentLeft,
/** Text center and top is at origin */
TopCenter = Implementation::AlignmentTop|Implementation::AlignmentCenter,
/** Text end and top is at origin */
TopRight = Implementation::AlignmentTop|Implementation::AlignmentRight,
/**
* 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
*
* @see @ref Alignment::MiddleLeft
*/
MiddleLeftIntegral = Implementation::AlignmentMiddle|Implementation::AlignmentLeft|Implementation::AlignmentIntegral,
/**
* 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
*
* @see @ref Alignment::MiddleRight
*/
MiddleRightIntegral = Implementation::AlignmentMiddle|Implementation::AlignmentRight|Implementation::AlignmentIntegral
};
}}
#endif

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

Loading…
Cancel
Save