diff --git a/CMakeLists.txt b/CMakeLists.txt index 737e5c95e..afe35fa20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,9 +43,6 @@ option(WITH_TEXT "Build Text library" ON) cmake_dependent_option(WITH_TEXTURETOOLS "Build TextureTools library" ON "NOT WITH_TEXT" ON) option(WITH_MAGNUMINFO "Build magnum-info utility" ON) -# Library features -cmake_dependent_option(USE_HARFBUZZ "Use HarfBuzz in Text library" ON "WITH_TEXT" OFF) - # Application libraries if(${CMAKE_SYSTEM_NAME} STREQUAL NaCl) option(WITH_NACLAPPLICATION "Build NaClApplication library" OFF) @@ -57,6 +54,8 @@ else() option(WITH_SDL2APPLICATION "Build Sdl2Application library" OFF) endif() +option(BUILD_STATIC "Build static libraries (default are shared)" OFF) +cmake_dependent_option(BUILD_STATIC_PIC "Build static libraries with position-independent code" OFF "BUILD_STATIC" OFF) option(BUILD_TESTS "Build unit tests." OFF) if(BUILD_TESTS) enable_testing() @@ -84,8 +83,10 @@ endif() find_package(Corrade REQUIRED) if(NOT TARGET_GLES OR TARGET_DESKTOP_GLES) find_package(OpenGL REQUIRED) -else() +elseif(TARGET_GLES2) find_package(OpenGLES2 REQUIRED) +else() + find_package(OpenGLES3 REQUIRED) endif() if(NOT TARGET_GLES) find_package(GLEW REQUIRED) @@ -94,15 +95,20 @@ endif() # Configuration variables (saved later to corradeConfigure.h) if(TARGET_GLES) set(MAGNUM_TARGET_GLES 1) -endif() -if(TARGET_GLES2) - set(MAGNUM_TARGET_GLES2 1) + if(TARGET_GLES2) + set(MAGNUM_TARGET_GLES2 1) + else() + set(MAGNUM_TARGET_GLES3 1) + endif() endif() if(TARGET_DESKTOP_GLES) set(MAGNUM_TARGET_DESKTOP_GLES 1) endif() -if(USE_HARFBUZZ) - set(MAGNUM_USE_HARFBUZZ 1) + +if(NOT BUILD_STATIC) + set(SHARED_OR_STATIC SHARED) +else() + set(SHARED_OR_STATIC STATIC) endif() # Installation paths diff --git a/PKGBUILD b/PKGBUILD index ca4a64126..f0f8701c7 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -2,11 +2,11 @@ pkgname=magnum pkgver=dev pkgrel=1 -pkgdesc="OpenGL 3 graphics engine" +pkgdesc="OpenGL graphics engine" arch=('i686' 'x86_64') url="https://github.com/mosra/magnum" license=('MIT') -depends=('corrade' 'glew') +depends=('corrade' 'glew' 'sdl-hg' 'freeglut') makedepends=('cmake') options=(!strip) provides=('magnum-git') @@ -27,13 +27,16 @@ build() { cmake .. \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_INSTALL_PREFIX=/usr \ + -DWITH_GLUTAPPLICATION=ON \ + -DWITH_GLXAPPLICATION=ON \ + -DWITH_SDL2APPLICATION=ON \ -DBUILD_TESTS=TRUE make } check() { cd "$startdir/build" - ctest --output-on-failure -E Benchmark + ctest --output-on-failure } package() { diff --git a/PKGBUILD-es2 b/PKGBUILD-es2 new file mode 100644 index 000000000..e4c937d64 --- /dev/null +++ b/PKGBUILD-es2 @@ -0,0 +1,44 @@ +# Author: mosra +pkgname=magnum +pkgver=dev.es2 +pkgrel=1 +pkgdesc="OpenGL graphics engine (OpenGL ES 2.0 version)" +arch=('i686' 'x86_64') +url="https://github.com/mosra/magnum" +license=('MIT') +depends=('corrade' 'glew') +makedepends=('cmake') +options=(!strip) +provides=('magnum-git') + +build() { + mkdir -p "$startdir/build-es2" + cd "$startdir/build-es2" + + if [ "$CXX" = clang++ ] ; then + newcxxflags=$(echo $CXXFLAGS | sed s/--param=ssp-buffer-size=4//g) + export CXXFLAGS="$newcxxflags" + fi + + cmake .. \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DBUILD_TESTS=ON \ + -DTARGET_GLES=ON \ + -DTARGET_GLES2=ON \ + -DWITH_TEXT=OFF \ + -DWITH_TEXTURETOOLS=OFF \ + -DWITH_MAGNUMINFO=OFF \ + -DWITH_XEGLAPPLICATION=ON + make +} + +check() { + cd "$startdir/build-es2" + ctest --output-on-failure +} + +package() { + cd "$startdir/build-es2" + make DESTDIR="$pkgdir/" install +} diff --git a/PKGBUILD-es2desktop b/PKGBUILD-es2desktop new file mode 100644 index 000000000..55fa9ccb9 --- /dev/null +++ b/PKGBUILD-es2desktop @@ -0,0 +1,45 @@ +# Author: mosra +pkgname=magnum +pkgver=dev.es2desktop +pkgrel=1 +pkgdesc="OpenGL graphics engine (desktop OpenGL ES 2.0 version)" +arch=('i686' 'x86_64') +url="https://github.com/mosra/magnum" +license=('MIT') +depends=('corrade' 'glew') +makedepends=('cmake') +options=(!strip) +provides=('magnum-git') + +build() { + mkdir -p "$startdir/build-es2desktop" + cd "$startdir/build-es2desktop" + + if [ "$CXX" = clang++ ] ; then + newcxxflags=$(echo $CXXFLAGS | sed s/--param=ssp-buffer-size=4//g) + export CXXFLAGS="$newcxxflags" + fi + + cmake .. \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DBUILD_TESTS=ON \ + -DTARGET_GLES=ON \ + -DTARGET_GLES2=ON \ + -DTARGET_DESKTOP_GLES=ON \ + -DWITH_TEXT=OFF \ + -DWITH_TEXTURETOOLS=OFF \ + -DWITH_MAGNUMINFO=OFF \ + -DWITH_XEGLAPPLICATION=ON + make +} + +check() { + cd "$startdir/build-es2desktop" + ctest --output-on-failure +} + +package() { + cd "$startdir/build-es2desktop" + make DESTDIR="$pkgdir/" install +} diff --git a/PKGBUILD-es3 b/PKGBUILD-es3 new file mode 100644 index 000000000..e567c82a8 --- /dev/null +++ b/PKGBUILD-es3 @@ -0,0 +1,44 @@ +# Author: mosra +pkgname=magnum +pkgver=dev.es3 +pkgrel=1 +pkgdesc="OpenGL graphics engine (OpenGL ES 3.0 version)" +arch=('i686' 'x86_64') +url="https://github.com/mosra/magnum" +license=('MIT') +depends=('corrade' 'glew') +makedepends=('cmake') +options=(!strip) +provides=('magnum-git') + +build() { + mkdir -p "$startdir/build-es3" + cd "$startdir/build-es3" + + if [ "$CXX" = clang++ ] ; then + newcxxflags=$(echo $CXXFLAGS | sed s/--param=ssp-buffer-size=4//g) + export CXXFLAGS="$newcxxflags" + fi + + cmake .. \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DBUILD_TESTS=ON \ + -DTARGET_GLES=ON \ + -DTARGET_GLES2=OFF \ + -DWITH_TEXT=OFF \ + -DWITH_TEXTURETOOLS=OFF \ + -DWITH_MAGNUMINFO=OFF \ + -DWITH_XEGLAPPLICATION=ON + make +} + +check() { + cd "$startdir/build-es3" + ctest --output-on-failure +} + +package() { + cd "$startdir/build-es3" + make DESTDIR="$pkgdir/" install +} diff --git a/PKGBUILD-mingw32 b/PKGBUILD-mingw32 index 42b3835c3..7d9526c8f 100644 --- a/PKGBUILD-mingw32 +++ b/PKGBUILD-mingw32 @@ -2,11 +2,11 @@ pkgname=mingw32-magnum pkgver=dev pkgrel=1 -pkgdesc="OpenGL 3 graphics engine (mingw32)" +pkgdesc="OpenGL graphics engine (mingw32)" arch=('any') url="https://github.com/mosra/magnum" license=('MIT') -depends=('mingw32-runtime' 'mingw32-corrade' 'mingw32-glew') +depends=('mingw32-runtime' 'mingw32-corrade' 'mingw32-glew' 'mingw32-freeglut') makedepends=('mingw32-gcc' 'cmake' 'corrade') options=(!buildflags !strip) @@ -19,7 +19,8 @@ build() { cmake .. \ -DCMAKE_TOOLCHAIN_FILE=../toolchains/archlinux/basic-mingw32.cmake \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/usr/i486-mingw32 + -DCMAKE_INSTALL_PREFIX=/usr/i486-mingw32 \ + -DWITH_GLUTAPPLICATION=ON make } diff --git a/PKGBUILD-nacl b/PKGBUILD-nacl index 668cafd4c..22f79f985 100644 --- a/PKGBUILD-nacl +++ b/PKGBUILD-nacl @@ -2,7 +2,7 @@ pkgname=nacl-magnum pkgver=dev pkgrel=1 -pkgdesc="OpenGL 3 graphics engine (NaCl x86-64 version)" +pkgdesc="OpenGL graphics engine (NaCl version)" arch=('any') url="https://github.com/mosra/magnum" license=('MIT') diff --git a/PKGBUILD-release b/PKGBUILD-release index a09e48d39..80453d0f9 100644 --- a/PKGBUILD-release +++ b/PKGBUILD-release @@ -1,13 +1,13 @@ # Author: mosra pkgname=magnum -pkgver=dev_release +pkgver=dev.release pkgrel=1 -pkgdesc="OpenGL 3 graphics engine" +pkgdesc="OpenGL graphics engine" arch=('i686' 'x86_64') url="https://github.com/mosra/magnum" license=('MIT') -depends=('corrade' 'glew') -makedepends=('cmake' 'qt') +depends=('corrade' 'glew' 'sdl-hg' 'freeglut') +makedepends=('cmake') provides=('magnum-git') build() { @@ -22,13 +22,16 @@ build() { cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ + -DWITH_GLUTAPPLICATION=ON \ + -DWITH_GLXAPPLICATION=ON \ + -DWITH_SDL2APPLICATION=ON -DBUILD_TESTS=TRUE make } check() { cd "$startdir/build" - ctest --output-on-failure -E Benchmark + ctest --output-on-failure } package() { diff --git a/doc/building.dox b/doc/building.dox index e8bb33d3a..8eee27b50 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -106,18 +106,11 @@ and which not: - `WITH_SHADERS` - Shaders library. Enabled automatically if `WITH_DEBUGTOOLS` is enabled. - `WITH_TEXT` - Text library. Enables also building of TextureTools library. - Requires **FreeType** and possibly **HarfBuzz** library (see below). - `WITH_TEXTURETOOLS` - TextureTools library. Enabled automatically if `WITH_TEXT` is enabled. - `WITH_MAGNUMINFO` - `magnum-info` executable, provides information about the engine and OpenGL capabilities. -Some dependencies are optional, although disabling them might reduce some -functionality: - - - `USE_HARFBUZZ` - Defaults to `ON`, disabling it will result in worse text - rendering (no kerning & ligatures) and possible issues with non-Latin text. - 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: diff --git a/doc/cmake.dox b/doc/cmake.dox index 6c3bcd853..274ab26ce 100644 --- a/doc/cmake.dox +++ b/doc/cmake.dox @@ -43,6 +43,7 @@ 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 However, this command will try to find only the base library, not the optional @@ -57,8 +58,7 @@ The optional components are: - `%Primitives` -- Primitives library - `%SceneGraph` -- SceneGraph library - `%Shaders` -- Shaders library -- `%Text` -- Text library (depends on `%TextureTools` component, FreeType - library and possibly HarfBuzz library, see below) +- `%Text` -- Text library (depends on `%TextureTools` component) - `%TextureTools` -- TextureTools library Platform namespace is split into more components: @@ -97,11 +97,10 @@ are also available as preprocessor variables if including Magnum.h: - `MAGNUM_TARGET_GLES` -- Defined if compiled for OpenGL ES - `MAGNUM_TARGET_GLES2` -- Defined if compiled for OpenGL ES 2.0 +- `MAGNUM_TARGET_GLES3` -- Defined if compiled for OpenGL ES 3.0 - `MAGNUM_TARGET_DESKTOP_GLES` -- Defined if compiled with OpenGL ES emulation on desktop OpenGL - `MAGNUM_TARGET_NACL` -- Defined if compiled for Google Chrome Native Client -- `MAGNUM_USE_HARFBUZZ` -- Defined if HarfBuzz library is used for text - rendering %Corrade library provides also its own set of CMake macros and variables, see @ref corrade-cmake "its documentation" for more information. diff --git a/modules/FindCorrade.cmake b/modules/FindCorrade.cmake index 3e0fb9bf5..fc60051d8 100644 --- a/modules/FindCorrade.cmake +++ b/modules/FindCorrade.cmake @@ -162,6 +162,12 @@ set(CORRADE_UTILITY_LIBRARIES ${CORRADE_UTILITY_LIBRARY}) set(CORRADE_INTERCONNECT_LIBRARIES ${CORRADE_INTERCONNECT_LIBRARY} ${CORRADE_UTILITY_LIBRARIES}) set(CORRADE_PLUGINMANAGER_LIBRARIES ${CORRADE_PLUGINMANAGER_LIBRARY} ${CORRADE_UTILITY_LIBRARIES}) set(CORRADE_TESTSUITE_LIBRARIES ${CORRADE_TESTSUITE_LIBRARY} ${CORRADE_UTILITY_LIBRARIES}) + +# At least static build needs this +if(UNIX OR ${CMAKE_SYSTEM_NAME} STREQUAL NaCl) + set(CORRADE_PLUGINMANAGER_LIBRARIES ${CORRADE_PLUGINMANAGER_LIBRARIES} dl) +endif() + mark_as_advanced(CORRADE_UTILITY_LIBRARY CORRADE_INTERCONNECT_LIBRARY CORRADE_PLUGINMANAGER_LIBRARY diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 509e806e5..2074b14cb 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -7,6 +7,8 @@ # 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_IMAGECONVERTER_DIR - Directory with image converter plugins # MAGNUM_PLUGINS_IMPORTER_DIR - Directory with importer plugins # This command will try to find only the base library, not the optional # components. The base library depends on Corrade, OpenGL and GLEW @@ -19,9 +21,7 @@ # Primitives - Primitives library # SceneGraph - SceneGraph library # Shaders - Shaders library -# Text - Text library (depends on TextureTools component, -# FreeType library and possibly HarfBuzz library, -# see below) +# Text - Text library (depends on TextureTools component) # TextureTools - TextureTools library # GlutApplication - GLUT application (depends on GLUT library) # GlxApplication - GLX application (depends on GLX and X11 libraries) @@ -47,12 +47,11 @@ # Features of found Magnum library are exposed in these variables: # MAGNUM_TARGET_GLES - Defined if compiled for OpenGL ES # MAGNUM_TARGET_GLES2 - Defined if compiled for OpenGL ES 2.0 +# MAGNUM_TARGET_GLES3 - Defined if compiled for OpenGL ES 3.0 # MAGNUM_TARGET_DESKTOP_GLES - Defined if compiled with OpenGL ES # emulation on desktop OpenGL # MAGNUM_TARGET_NACL - Defined if compiled for Google Chrome Native # Client -# MAGNUM_USE_HARFBUZZ - Defined if HarfBuzz library is used for text -# rendering # # Additionally these variables are defined for internal usage: # MAGNUM_INCLUDE_DIR - Root include dir (w/o @@ -63,6 +62,10 @@ # dependencies) # MAGNUM_LIBRARY_INSTALL_DIR - Library installation directory # MAGNUM_PLUGINS_INSTALL_DIR - Plugin installation directory +# MAGNUM_PLUGINS_FONT_INSTALL_DIR - Font plugin installation +# directory +# MAGNUM_PLUGINS_IMAGECONVERTER_INSTALL_DIR - Image converter plugin +# installation directory # MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR - Importer plugin installation # directory # MAGNUM_CMAKE_MODULE_INSTALL_DIR - Installation dir for CMake @@ -119,6 +122,10 @@ string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_GLES2" _TARGET_GLES2) if(NOT _TARGET_GLES2 EQUAL -1) set(MAGNUM_TARGET_GLES2 1) endif() +string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_GLES3" _TARGET_GLES3) +if(NOT _TARGET_GLES3 EQUAL -1) + set(MAGNUM_TARGET_GLES3 1) +endif() string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_NACL" _TARGET_NACL) if(NOT _TARGET_NACL EQUAL -1) set(MAGNUM_TARGET_NACL 1) @@ -127,10 +134,6 @@ string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_DESKTOP_GLES" _TARGET_D if(NOT _TARGET_DESKTOP_GLES EQUAL -1) set(MAGNUM_TARGET_DESKTOP_GLES 1) endif() -string(FIND "${_magnumConfigure}" "#define MAGNUM_USE_HARFBUZZ" _USE_HARFBUZZ) -if(NOT _USE_HARFBUZZ EQUAL -1) - set(MAGNUM_USE_HARFBUZZ 1) -endif() if(NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES) find_package(OpenGL REQUIRED) @@ -249,19 +252,7 @@ foreach(component ${Magnum_FIND_COMPONENTS}) # Text library if(${component} STREQUAL Text) - set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Font.h) - - # Dependencies - find_package(Freetype) - if(NOT FREETYPE_FOUND) - unset(MAGNUM_${_COMPONENT}_LIBRARY) - endif() - if(MAGNUM_USE_HARFBUZZ) - find_package(HarfBuzz) - if(NOT HARFBUZZ_FOUND) - unset(MAGNUM_${_COMPONENT}_LIBRARY) - endif() - endif() + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES AbstractFont.h) endif() # TextureTools library @@ -320,8 +311,8 @@ set(MAGNUM_INCLUDE_DIRS ${MAGNUM_INCLUDE_DIR} ${MAGNUM_INCLUDE_DIR}/OpenGL ${CORRADE_INCLUDE_DIR}) set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARY} - ${CORRADE_UTILITY_LIBRARY} - ${CORRADE_PLUGINMANAGER_LIBRARY}) + ${CORRADE_UTILITY_LIBRARIES} + ${CORRADE_PLUGINMANAGER_LIBRARIES}) if(NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES) set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARIES} ${OPENGL_gl_LIBRARY}) else() @@ -334,6 +325,8 @@ endif() # Installation dirs 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_IMAGECONVERTER_INSTALL_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/imageconverters) set(MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/importers) set(MAGNUM_CMAKE_MODULE_INSTALL_DIR ${CMAKE_ROOT}/Modules) set(MAGNUM_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/Magnum) @@ -343,14 +336,20 @@ mark_as_advanced(FORCE MAGNUM_INCLUDE_DIR MAGNUM_LIBRARY_INSTALL_DIR MAGNUM_PLUGINS_INSTALL_DIR + MAGNUM_PLUGINS_FONT_INSTALL_DIR + MAGNUM_PLUGINS_IMAGECONVERTER_INSTALL_DIR MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR MAGNUM_CMAKE_MODULE_INSTALL_DIR MAGNUM_INCLUDE_INSTALL_DIR MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR) -# Importer plugins dir +# Plugin directories if(NOT WIN32) + set(MAGNUM_PLUGINS_FONT_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/fonts) + set(MAGNUM_PLUGINS_IMAGECONVERTER_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/imageconverters) set(MAGNUM_PLUGINS_IMPORTER_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/importers) else() + set(MAGNUM_PLUGINS_FONT_DIR fonts) + set(MAGNUM_PLUGINS_IMAGECONVERTER_DIR imageconverters) set(MAGNUM_PLUGINS_IMPORTER_DIR importers) endif() diff --git a/modules/FindHarfBuzz.cmake b/modules/FindOpenGLES3.cmake similarity index 61% rename from modules/FindHarfBuzz.cmake rename to modules/FindOpenGLES3.cmake index f4b0139f5..d4b160162 100644 --- a/modules/FindHarfBuzz.cmake +++ b/modules/FindOpenGLES3.cmake @@ -1,13 +1,10 @@ -# - Find HarfBuzz +# - Find OpenGL ES 3 # -# This module tries to find HarfBuzz library and then defines: -# HARFBUZZ_FOUND - True if HarfBuzz library is found -# HARFBUZZ_INCLUDE_DIRS - Include dirs -# HARFBUZZ_LIBRARIES - HarfBuzz libraries +# This module defines: # -# Additionally these variables are defined for internal usage: -# HARFBUZZ_INCLUDE_DIR - Include dir (w/o dependencies) -# HARFBUZZ_LIBRARY - HarfBuzz library (w/o dependencies) +# OPENGLES3_FOUND - True if OpenGL ES 3 library is found +# OPENGLES3_LIBRARY - OpenGL ES 3 library +# OPENGLES3_INCLUDE_DIR - Include dir # # @@ -35,23 +32,17 @@ # # Library -find_library(HARFBUZZ_LIBRARY NAMES harfbuzz) +find_library(OPENGLES3_LIBRARY NAMES + GLESv2) # wtf? # Include dir -find_path(HARFBUZZ_INCLUDE_DIR - NAMES hb.h - PATH_SUFFIXES harfbuzz +find_path(OPENGLES3_INCLUDE_DIR + NAMES gl3.h + PATH_SUFFIXES GLES3 ) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args("HarfBuzz" DEFAULT_MSG - HARFBUZZ_LIBRARY - HARFBUZZ_INCLUDE_DIR +find_package_handle_standard_args("OpenGLES3" DEFAULT_MSG + OPENGLES3_LIBRARY + OPENGLES3_INCLUDE_DIR ) - -set(HARFBUZZ_INCLUDE_DIRS ${HARFBUZZ_INCLUDE_DIR}) -set(HARFBUZZ_LIBRARIES ${HARFBUZZ_LIBRARY}) - -mark_as_advanced(FORCE - HARFBUZZ_LIBRARY - HARFBUZZ_INCLUDE_DIR) diff --git a/src/AbstractFramebuffer.cpp b/src/AbstractFramebuffer.cpp index ac57b4402..6fd62aab8 100644 --- a/src/AbstractFramebuffer.cpp +++ b/src/AbstractFramebuffer.cpp @@ -219,8 +219,12 @@ void AbstractFramebuffer::drawBufferImplementationDefault(GLenum buffer) { /** @todo Re-enable when extension wrangler is available for ES2 */ #ifndef MAGNUM_TARGET_GLES2 bindInternal(drawTarget); + #ifndef MAGNUM_TARGET_GLES3 glDrawBuffer(buffer); #else + glDrawBuffers(1, &buffer); + #endif + #else static_cast(buffer); #endif } diff --git a/src/AbstractImage.cpp b/src/AbstractImage.cpp index 6d34289e3..c7bd56b2d 100644 --- a/src/AbstractImage.cpp +++ b/src/AbstractImage.cpp @@ -59,9 +59,13 @@ std::size_t AbstractImage::pixelSize(Format format, Type type) { case Type::UnsignedShort565Rev: #endif case Type::UnsignedShort4444: + #ifndef MAGNUM_TARGET_GLES3 case Type::UnsignedShort4444Rev: + #endif case Type::UnsignedShort5551: + #ifndef MAGNUM_TARGET_GLES3 case Type::UnsignedShort1555Rev: + #endif return 2; #ifndef MAGNUM_TARGET_GLES case Type::UnsignedInt8888: @@ -111,7 +115,9 @@ std::size_t AbstractImage::pixelSize(Format format, Type type) { #ifndef MAGNUM_TARGET_GLES2 case Format::RGBAInteger: #endif + #ifndef MAGNUM_TARGET_GLES3 case Format::BGRA: + #endif #ifndef MAGNUM_TARGET_GLES case Format::BGRAInteger: #endif @@ -119,7 +125,9 @@ std::size_t AbstractImage::pixelSize(Format format, Type type) { /* Handled above */ case Format::DepthComponent: + #ifndef MAGNUM_TARGET_GLES3 case Format::StencilIndex: + #endif case Format::DepthStencil: CORRADE_INTERNAL_ASSERT(false); } @@ -143,19 +151,27 @@ Debug operator<<(Debug debug, AbstractImage::Format value) { #ifndef MAGNUM_TARGET_GLES _c(BGR) #endif + #ifndef MAGNUM_TARGET_GLES3 _c(BGRA) + #endif #ifndef MAGNUM_TARGET_GLES2 _c(RedInteger) + #ifndef MAGNUM_TARGET_GLES _c(GreenInteger) _c(BlueInteger) + #endif _c(RGInteger) _c(RGBInteger) _c(RGBAInteger) + #ifndef MAGNUM_TARGET_GLES _c(BGRInteger) _c(BGRAInteger) #endif + #endif _c(DepthComponent) + #ifndef MAGNUM_TARGET_GLES3 _c(StencilIndex) + #endif _c(DepthStencil) #undef _c } @@ -180,7 +196,7 @@ Debug operator<<(Debug debug, AbstractImage::Type value) { #endif _c(HalfFloat) _c(Float) - #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES _c(UnsignedByte332) _c(UnsignedByte233Rev) #endif @@ -189,9 +205,13 @@ Debug operator<<(Debug debug, AbstractImage::Type value) { _c(UnsignedShort565Rev) #endif _c(UnsignedShort4444) + #ifndef MAGNUM_TARGET_GLES3 _c(UnsignedShort4444Rev) + #endif _c(UnsignedShort5551) + #ifndef MAGNUM_TARGET_GLES3 _c(UnsignedShort1555Rev) + #endif #ifndef MAGNUM_TARGET_GLES _c(UnsignedInt8888) _c(UnsignedInt8888Rev) diff --git a/src/AbstractImage.h b/src/AbstractImage.h index ff6964bc9..5ba4002c6 100644 --- a/src/AbstractImage.h +++ b/src/AbstractImage.h @@ -131,6 +131,7 @@ class MAGNUM_EXPORT AbstractImage { BGR = GL_BGR, #endif + #ifndef MAGNUM_TARGET_GLES3 /** * Floating-point BGRA. * @requires_es_extension %Extension @es_extension{EXT,read_format_bgra} @@ -143,6 +144,7 @@ class MAGNUM_EXPORT AbstractImage { #else BGRA = GL_BGRA_EXT, #endif + #endif #ifndef MAGNUM_TARGET_GLES2 /** @@ -230,6 +232,7 @@ class MAGNUM_EXPORT AbstractImage { */ DepthComponent = GL_DEPTH_COMPONENT, + #ifndef MAGNUM_TARGET_GLES3 /** * Stencil index. For framebuffer reading only. * @requires_es_extension %Extension @es_extension2{NV,read_stencil,GL_NV_read_depth_stencil} @@ -240,6 +243,7 @@ class MAGNUM_EXPORT AbstractImage { #else StencilIndex = 0x1901, #endif + #endif /** * Depth and stencil. @@ -369,6 +373,7 @@ class MAGNUM_EXPORT AbstractImage { */ UnsignedShort4444 = GL_UNSIGNED_SHORT_4_4_4_4, + #ifndef MAGNUM_TARGET_GLES3 /** * ABGR, unsigned short, each component 4bit. * @requires_es_extension For framebuffer reading only, extension @@ -379,6 +384,7 @@ class MAGNUM_EXPORT AbstractImage { #else UnsignedShort4444Rev = GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, #endif + #endif /** * RGBA, unsigned short, each RGB component 5bit, alpha component @@ -387,6 +393,7 @@ class MAGNUM_EXPORT AbstractImage { */ UnsignedShort5551 = GL_UNSIGNED_SHORT_5_5_5_1, + #ifndef MAGNUM_TARGET_GLES3 /** * ABGR, unsigned short, each RGB component 5bit, alpha component * 1bit. @@ -398,6 +405,7 @@ class MAGNUM_EXPORT AbstractImage { #else UnsignedShort1555Rev = GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, #endif + #endif #ifndef MAGNUM_TARGET_GLES /** diff --git a/src/AbstractTexture.cpp b/src/AbstractTexture.cpp index 04bfef4de..d13609061 100644 --- a/src/AbstractTexture.cpp +++ b/src/AbstractTexture.cpp @@ -96,6 +96,7 @@ Int AbstractTexture::maxSupportedLayerCount() { return Context::current()->state()->texture->maxSupportedLayerCount; } +#ifndef MAGNUM_TARGET_GLES3 Float AbstractTexture::maxSupportedAnisotropy() { GLfloat& value = Context::current()->state()->texture->maxSupportedAnisotropy; @@ -108,6 +109,7 @@ Float AbstractTexture::maxSupportedAnisotropy() { return value; } +#endif void AbstractTexture::destroy() { /* Moved out */ diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index da7c8d3eb..a67b00430 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -152,6 +152,7 @@ class MAGNUM_EXPORT AbstractTexture { */ ClampToEdge = GL_CLAMP_TO_EDGE, + #ifndef MAGNUM_TARGET_GLES3 /** * Clamp to border color. Coordinates out of range will be clamped * to border color (set with setBorderColor()). @@ -162,6 +163,7 @@ class MAGNUM_EXPORT AbstractTexture { #else ClampToBorder = GL_CLAMP_TO_BORDER_NV #endif + #endif }; /** @@ -314,39 +316,39 @@ class MAGNUM_EXPORT AbstractTexture { * in OpenGL ES. */ RGBA16 = GL_RGBA16, - #endif /** * Red component, normalized signed short. * @requires_gl31 %Extension @extension{EXT,texture_snorm} - * @requires_gles30 Only unsigned normalized formats are available - * in OpenGL ES 2.0. + * @requires_gl Only byte-sized normalized formats are available + * in OpenGL ES. */ R16Snorm = GL_R16_SNORM, /** * Red and green component, each normalized signed short. * @requires_gl31 %Extension @extension{EXT,texture_snorm} - * @requires_gles30 Only unsigned normalized formats are available - * in OpenGL ES 2.0. + * @requires_gl Only byte-sized normalized formats are available + * in OpenGL ES. */ RG16Snorm = GL_RG16_SNORM, /** * RGB, each component normalized signed short. * @requires_gl31 %Extension @extension{EXT,texture_snorm} - * @requires_gles30 Only unsigned normalized formats are available - * in OpenGL ES 2.0. + * @requires_gl Only byte-sized normalized formats are available + * in OpenGL ES. */ RGB16Snorm = GL_RGB16_SNORM, /** * RGBA, each component normalized signed short. * @requires_gl31 %Extension @extension{EXT,texture_snorm} - * @requires_gles30 Only unsigned normalized formats are available - * in OpenGL ES 2.0. + * @requires_gl Only byte-sized normalized formats are available + * in OpenGL ES. */ RGBA16Snorm = GL_RGBA16_SNORM, + #endif /** * Red component, non-normalized unsigned byte. @@ -653,6 +655,7 @@ class MAGNUM_EXPORT AbstractTexture { RGB565 = GL_RGB565, #endif + #ifndef MAGNUM_TARGET_GLES3 /** * RGB, each component normalized unsigned 10bit. * @requires_es_extension %Extension @es_extension{OES,required_internalformat} @@ -663,6 +666,7 @@ class MAGNUM_EXPORT AbstractTexture { #else RGB10 = GL_RGB10_EXT, #endif + #endif #ifndef MAGNUM_TARGET_GLES /** @@ -740,6 +744,7 @@ class MAGNUM_EXPORT AbstractTexture { RGB9E5 = GL_RGB9_E5, #endif + #ifndef MAGNUM_TARGET_GLES3 /** * sRGB, normalized unsigned, size implementation-dependent. * @todo is this allowed in core? @@ -754,6 +759,7 @@ class MAGNUM_EXPORT AbstractTexture { #else SRGB = GL_SRGB_EXT, #endif + #endif #ifndef MAGNUM_TARGET_GLES2 /** @@ -764,6 +770,7 @@ class MAGNUM_EXPORT AbstractTexture { SRGB8 = GL_SRGB8, #endif + #ifndef MAGNUM_TARGET_GLES3 /** * sRGBA, normalized unsigned, size implementation-dependent. * @todo is this allowed in core? @@ -778,6 +785,7 @@ class MAGNUM_EXPORT AbstractTexture { #else SRGBAlpha = GL_SRGB_ALPHA_EXT, #endif + #endif #ifndef MAGNUM_TARGET_GLES2 /** @@ -930,6 +938,7 @@ class MAGNUM_EXPORT AbstractTexture { DepthComponent24 = GL_DEPTH_COMPONENT24_OES, #endif + #ifndef MAGNUM_TARGET_GLES3 /** * Depth component, 32bit. * @requires_es_extension %Extension (@es_extension{OES,required_internalformat}, @@ -941,6 +950,7 @@ class MAGNUM_EXPORT AbstractTexture { #else DepthComponent32 = GL_DEPTH_COMPONENT32_OES, #endif + #endif #ifndef MAGNUM_TARGET_GLES2 /** @@ -987,6 +997,7 @@ class MAGNUM_EXPORT AbstractTexture { */ static Int maxSupportedLayerCount(); + #ifndef MAGNUM_TARGET_GLES3 /** * @brief Max supported anisotropy * @@ -997,6 +1008,7 @@ class MAGNUM_EXPORT AbstractTexture { * @requires_es_extension %Extension @es_extension2{EXT,texture_filter_anisotropic,texture_filter_anisotropic} */ static Float maxSupportedAnisotropy(); + #endif #ifndef DOXYGEN_GENERATING_OUTPUT inline explicit AbstractTexture(GLenum target): _target(target) { @@ -1075,6 +1087,7 @@ class MAGNUM_EXPORT AbstractTexture { return this; } + #ifndef MAGNUM_TARGET_GLES3 /** * @brief Set border color * @return Pointer to self (for method chaining) @@ -1116,6 +1129,7 @@ class MAGNUM_EXPORT AbstractTexture { (this->*parameterfImplementation)(GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); return this; } + #endif /** * @brief Invalidate texture image diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 2fa92c0b2..4c2e18718 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -40,7 +40,9 @@ Buffer::SetDataImplementation Buffer::setDataImplementation = &Buffer::setDataIm Buffer::SetSubDataImplementation Buffer::setSubDataImplementation = &Buffer::setSubDataImplementationDefault; Buffer::InvalidateImplementation Buffer::invalidateImplementation = &Buffer::invalidateImplementationNoOp; Buffer::InvalidateSubImplementation Buffer::invalidateSubImplementation = &Buffer::invalidateSubImplementationNoOp; +#ifndef MAGNUM_TARGET_GLES3 Buffer::MapImplementation Buffer::mapImplementation = &Buffer::mapImplementationDefault; +#endif Buffer::MapRangeImplementation Buffer::mapRangeImplementation = &Buffer::mapRangeImplementationDefault; Buffer::FlushMappedRangeImplementation Buffer::flushMappedRangeImplementation = &Buffer::flushMappedRangeImplementationDefault; Buffer::UnmapImplementation Buffer::unmapImplementation = &Buffer::unmapImplementationDefault; @@ -156,6 +158,7 @@ void Buffer::invalidateSubImplementationARB(GLintptr offset, GLsizeiptr length) } #endif +#ifndef MAGNUM_TARGET_GLES3 void* Buffer::mapImplementationDefault(MapAccess access) { /** @todo Re-enable when extension wrangler is available for ES */ #ifndef MAGNUM_TARGET_GLES @@ -171,6 +174,7 @@ void* Buffer::mapImplementationDSA(MapAccess access) { return glMapNamedBufferEXT(_id, GLenum(access)); } #endif +#endif void* Buffer::mapRangeImplementationDefault(GLintptr offset, GLsizeiptr length, MapFlags access) { /** @todo Re-enable when extension wrangler is available for ES */ diff --git a/src/Buffer.h b/src/Buffer.h index 9d3e0c7e9..63be6124e 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -316,6 +316,7 @@ class MAGNUM_EXPORT Buffer { #endif }; + #ifndef MAGNUM_TARGET_GLES3 /** * @brief Memory mapping access * @@ -352,6 +353,7 @@ class MAGNUM_EXPORT Buffer { ReadWrite = GL_READ_WRITE #endif }; + #endif /** * @brief Memory mapping flag @@ -625,6 +627,7 @@ class MAGNUM_EXPORT Buffer { } #endif + #ifndef MAGNUM_TARGET_GLES3 /** * @brief Map buffer to client memory * @param access Access @@ -644,6 +647,7 @@ class MAGNUM_EXPORT Buffer { inline void* map(MapAccess access) { return (this->*mapImplementation)(access); } + #endif /** * @brief Map buffer to client memory @@ -747,12 +751,14 @@ class MAGNUM_EXPORT Buffer { #endif static InvalidateSubImplementation invalidateSubImplementation; + #ifndef MAGNUM_TARGET_GLES3 typedef void*(Buffer::*MapImplementation)(MapAccess); void MAGNUM_LOCAL * mapImplementationDefault(MapAccess access); #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL * mapImplementationDSA(MapAccess access); #endif static MapImplementation mapImplementation; + #endif typedef void*(Buffer::*MapRangeImplementation)(GLintptr, GLsizeiptr, MapFlags); void MAGNUM_LOCAL * mapRangeImplementationDefault(GLintptr offset, GLsizeiptr length, MapFlags access); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8b51fcf36..39dc033cb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,11 +67,17 @@ set(Magnum_SRCS Implementation/BufferState.cpp Implementation/State.cpp + Trade/AbstractImageConverter.cpp Trade/AbstractImporter.cpp + Trade/AbstractMaterialData.cpp Trade/MeshData2D.cpp Trade/MeshData3D.cpp + Trade/MeshObjectData2D.cpp + Trade/MeshObjectData3D.cpp Trade/ObjectData2D.cpp - Trade/ObjectData3D.cpp) + Trade/ObjectData3D.cpp + Trade/PhongMaterialData.cpp + Trade/SceneData.cpp) # Desktop-only code if(NOT TARGET_GLES) @@ -150,16 +156,22 @@ add_library(MagnumObjects OBJECT ${Magnum_SRCS}) set_target_properties(MagnumObjects MagnumMathObjects PROPERTIES COMPILE_FLAGS "-DMagnumObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") # Main library -add_library(Magnum SHARED +add_library(Magnum ${SHARED_OR_STATIC} $ $) +if(BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(Magnum PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +endif() set(Magnum_LIBS ${CORRADE_UTILITY_LIBRARY} ${CORRADE_PLUGINMANAGER_LIBRARY}) if(NOT TARGET_GLES OR TARGET_DESKTOP_GLES) set(Magnum_LIBS ${Magnum_LIBS} ${OPENGL_gl_LIBRARY}) -else() +elseif(TARGET_GLES2) set(Magnum_LIBS ${Magnum_LIBS} ${OPENGLES2_LIBRARY}) +else() + set(Magnum_LIBS ${Magnum_LIBS} ${OPENGLES3_LIBRARY}) endif() if(NOT TARGET_GLES) set(Magnum_LIBS ${Magnum_LIBS} ${GLEW_LIBRARIES}) @@ -208,14 +220,12 @@ endif() if(BUILD_TESTS) # Libraries with graceful assert for testing - add_library(MagnumMathTestLib SHARED + add_library(MagnumMathTestLib ${SHARED_OR_STATIC} $) set_target_properties(MagnumMathTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) - if(WIN32) - target_link_libraries(MagnumMathTestLib ${CORRADE_UTILITY_LIBRARY}) - endif() + target_link_libraries(MagnumMathTestLib ${CORRADE_UTILITY_LIBRARY}) - add_library(MagnumTestLib SHARED + add_library(MagnumTestLib ${SHARED_OR_STATIC} $ $) set_target_properties(MagnumTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) diff --git a/src/CubeMapTexture.h b/src/CubeMapTexture.h index 64d72cc99..2a515c686 100644 --- a/src/CubeMapTexture.h +++ b/src/CubeMapTexture.h @@ -201,16 +201,16 @@ class CubeMapTexture: public AbstractTexture { AbstractTexture::setMagnificationFilter(filter); return this; } - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES3 inline CubeMapTexture* setBorderColor(const Color4<>& color) { AbstractTexture::setBorderColor(color); return this; } - #endif inline CubeMapTexture* setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return this; } + #endif inline CubeMapTexture* generateMipmap() { AbstractTexture::generateMipmap(); return this; diff --git a/src/CubeMapTextureArray.h b/src/CubeMapTextureArray.h index 619e232cc..859621176 100644 --- a/src/CubeMapTextureArray.h +++ b/src/CubeMapTextureArray.h @@ -217,6 +217,7 @@ class CubeMapTextureArray: public AbstractTexture { AbstractTexture::setMagnificationFilter(filter); return this; } + #ifndef MAGNUM_TARGET_GLES3 inline CubeMapTextureArray* setBorderColor(const Color4<>& color) { AbstractTexture::setBorderColor(color); return this; @@ -225,6 +226,7 @@ class CubeMapTextureArray: public AbstractTexture { AbstractTexture::setMaxAnisotropy(anisotropy); return this; } + #endif inline CubeMapTextureArray* generateMipmap() { AbstractTexture::generateMipmap(); return this; diff --git a/src/DebugTools/CMakeLists.txt b/src/DebugTools/CMakeLists.txt index 55081223a..a80d6e435 100644 --- a/src/DebugTools/CMakeLists.txt +++ b/src/DebugTools/CMakeLists.txt @@ -33,7 +33,8 @@ set(MagnumDebugTools_SRCS Implementation/AbstractShapeRenderer.cpp Implementation/AxisAlignedBoxRenderer.cpp Implementation/BoxRenderer.cpp - Implementation/PointRenderer.cpp) + Implementation/PointRenderer.cpp + Implementation/SphereRenderer.cpp) set(MagnumDebugTools_HEADERS ForceRenderer.h @@ -45,7 +46,11 @@ set(MagnumDebugTools_HEADERS magnumDebugToolsVisibility.h) -add_library(MagnumDebugTools SHARED ${MagnumDebugTools_SRCS}) +add_library(MagnumDebugTools ${SHARED_OR_STATIC} ${MagnumDebugTools_SRCS}) +if(BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(MagnumDebugTools PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +endif() target_link_libraries(MagnumDebugTools Magnum MagnumMeshTools diff --git a/src/DebugTools/ForceRenderer.cpp b/src/DebugTools/ForceRenderer.cpp index 63583685a..618f97f9a 100644 --- a/src/DebugTools/ForceRenderer.cpp +++ b/src/DebugTools/ForceRenderer.cpp @@ -95,7 +95,7 @@ template ForceRenderer::ForceRenderer(SceneG } template void ForceRenderer::draw(const typename DimensionTraits::MatrixType& transformationMatrix, SceneGraph::AbstractCamera* camera) { - shader->setTransformationProjectionMatrix(camera->projectionMatrix()*Implementation::forceRendererTransformation(transformationMatrix.translation()+forcePosition, *force)*DimensionTraits::MatrixType::scaling(typename DimensionTraits::VectorType(options->scale()))) + shader->setTransformationProjectionMatrix(camera->projectionMatrix()*Implementation::forceRendererTransformation(transformationMatrix.transformPoint(forcePosition), *force)*DimensionTraits::MatrixType::scaling(typename DimensionTraits::VectorType(options->scale()))) ->setColor(options->color()) ->use(); mesh->draw(); diff --git a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp index 903cfbf57..9ef7904d5 100644 --- a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp @@ -34,11 +34,9 @@ namespace Magnum { namespace DebugTools { namespace Implementation { template AxisAlignedBoxRenderer::AxisAlignedBoxRenderer(Physics::AxisAlignedBox& axisAlignedBox): axisAlignedBox(axisAlignedBox) {} template void AxisAlignedBoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - /* Half scale, because the box is 2x2(x2) */ - typename DimensionTraits::MatrixType transformation = + this->shader->setTransformationProjectionMatrix(projectionMatrix* DimensionTraits::MatrixType::translation((axisAlignedBox.transformedMin()+axisAlignedBox.transformedMax())/2)* - DimensionTraits::MatrixType::scaling((axisAlignedBox.transformedMax()-axisAlignedBox.transformedMin())/2); - this->shader->setTransformationProjectionMatrix(projectionMatrix*transformation) + DimensionTraits::MatrixType::scaling(axisAlignedBox.transformedMax()-axisAlignedBox.transformedMin())) ->setColor(options->color()) ->use(); this->mesh->draw(); diff --git a/src/DebugTools/Implementation/BoxRenderer.cpp b/src/DebugTools/Implementation/BoxRenderer.cpp index e838b67f1..d9a34c62d 100644 --- a/src/DebugTools/Implementation/BoxRenderer.cpp +++ b/src/DebugTools/Implementation/BoxRenderer.cpp @@ -34,9 +34,7 @@ namespace Magnum { namespace DebugTools { namespace Implementation { template BoxRenderer::BoxRenderer(Physics::Box& box): box(box) {} template void BoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - /* Half scale, because the box is 2x2(x2) */ - this->shader->setTransformationProjectionMatrix(projectionMatrix*box.transformedTransformation()* - DimensionTraits::MatrixType::scaling(typename DimensionTraits::VectorType(0.5f))) + this->shader->setTransformationProjectionMatrix(projectionMatrix*box.transformedTransformation()) ->setColor(options->color()) ->use(); this->mesh->draw(); diff --git a/src/DebugTools/Implementation/SphereRenderer.cpp b/src/DebugTools/Implementation/SphereRenderer.cpp new file mode 100644 index 000000000..67a367c3a --- /dev/null +++ b/src/DebugTools/Implementation/SphereRenderer.cpp @@ -0,0 +1,53 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "SphereRenderer.h" + +#include "Mesh.h" +#include "DebugTools/ShapeRenderer.h" +#include "Physics/Sphere.h" +#include "Primitives/Circle.h" +#include "Shaders/FlatShader.h" +#include "Trade/MeshData2D.h" + +namespace Magnum { namespace DebugTools { namespace Implementation { + +AbstractSphereRenderer<2>::AbstractSphereRenderer(): AbstractShapeRenderer<2>("sphere2d", "sphere2d-vertices", {}) { + if(!mesh) this->createResources(Primitives::Circle::wireframe(40)); +} + +template SphereRenderer::SphereRenderer(Physics::Sphere& sphere): sphere(sphere) {} + +template void SphereRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { + this->shader->setTransformationProjectionMatrix(projectionMatrix* + DimensionTraits::MatrixType::translation(sphere.position())* + DimensionTraits::MatrixType::scaling(typename DimensionTraits::VectorType(sphere.radius()))) + ->setColor(options->color()) + ->use(); + this->mesh->draw(); +} + +template class SphereRenderer<2>; + +}}} diff --git a/src/DebugTools/Implementation/SphereRenderer.h b/src/DebugTools/Implementation/SphereRenderer.h new file mode 100644 index 000000000..e7cf52922 --- /dev/null +++ b/src/DebugTools/Implementation/SphereRenderer.h @@ -0,0 +1,54 @@ +#ifndef Magnum_DebugTools_Implementation_SphereRenderer_h +#define Magnum_DebugTools_Implementation_SphereRenderer_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "AbstractShapeRenderer.h" + +#include "Physics/Physics.h" + +#include "corradeCompatibility.h" + +namespace Magnum { namespace DebugTools { namespace Implementation { + +template class AbstractSphereRenderer; + +template<> class AbstractSphereRenderer<2>: public AbstractShapeRenderer<2> { + public: + AbstractSphereRenderer(); +}; + +template class SphereRenderer: public AbstractSphereRenderer { + public: + SphereRenderer(Physics::Sphere& sphere); + + void draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) override; + + private: + Physics::Sphere& sphere; +}; + +}}} + +#endif diff --git a/src/DebugTools/ShapeRenderer.cpp b/src/DebugTools/ShapeRenderer.cpp index 813bd317a..b9a072cc5 100644 --- a/src/DebugTools/ShapeRenderer.cpp +++ b/src/DebugTools/ShapeRenderer.cpp @@ -31,11 +31,13 @@ #include "Physics/ObjectShape.h" #include "Physics/Point.h" #include "Physics/ShapeGroup.h" +#include "Physics/Sphere.h" #include "SceneGraph/AbstractCamera.h" #include "Implementation/AxisAlignedBoxRenderer.h" #include "Implementation/BoxRenderer.h" #include "Implementation/PointRenderer.h" +#include "Implementation/SphereRenderer.h" namespace Magnum { namespace DebugTools { @@ -58,6 +60,9 @@ template<> void createDebugMesh(ShapeRenderer<2>* renderer, Physics::AbstractSha if(group->first()) createDebugMesh(renderer, group->first()); if(group->second()) createDebugMesh(renderer, group->second()); } break; + case Physics::AbstractShape2D::Type::Sphere: + renderer->renderers.push_back(new Implementation::SphereRenderer<2>(*static_cast(shape))); + break; default: Warning() << "DebugTools::ShapeRenderer2D::createShapeRenderer(): type" << shape->type() << "not implemented"; } diff --git a/src/DefaultFramebuffer.h b/src/DefaultFramebuffer.h index 3f37969cc..c7ae2effc 100644 --- a/src/DefaultFramebuffer.h +++ b/src/DefaultFramebuffer.h @@ -306,7 +306,8 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * framebufferbuffer is not currently bound, it is bound before the * operation. * @see mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffer} or - * @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access} + * @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access}, + * @fn_gl{DrawBuffers} in OpenGL ES 3.0 * @requires_gles30 Draw attachments for default framebuffer are * available only in OpenGL ES 3.0. */ diff --git a/src/Framebuffer.h b/src/Framebuffer.h index 2a8c6df8a..581b6211b 100644 --- a/src/Framebuffer.h +++ b/src/Framebuffer.h @@ -278,7 +278,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * framebufferbuffer is not currently bound, it is bound before the * operation. * @see mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffer} or - * @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access} + * @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access}, + * @fn_gl{DrawBuffers} in OpenGL ES 3.0 * @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} */ inline Framebuffer* mapForDraw(DrawAttachment attachment) { diff --git a/src/Image.cpp b/src/Image.cpp index 06f8cde86..a1c67a30a 100644 --- a/src/Image.cpp +++ b/src/Image.cpp @@ -31,7 +31,7 @@ template void Image::setData(const typename _format = format; _type = type; _size = size; - _data = reinterpret_cast(data); + _data = reinterpret_cast(data); } template class Image<1>; diff --git a/src/Image.h b/src/Image.h index 37e4d80bd..f0de0ad67 100644 --- a/src/Image.h +++ b/src/Image.h @@ -55,7 +55,7 @@ template class Image: public AbstractImage { * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - inline explicit Image(const typename DimensionTraits::VectorType& size, Format format, Type type, GLvoid* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} + inline explicit Image(const typename DimensionTraits::VectorType& size, Format format, Type type, GLvoid* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} /** * @brief Constructor @@ -74,8 +74,8 @@ template class Image: public AbstractImage { inline typename DimensionTraits::VectorType size() const { return _size; } /** @brief Pointer to raw data */ - inline void* data() { return _data; } - inline const void* data() const { return _data; } /**< @overload */ + inline unsigned char* data() { return _data; } + inline const unsigned char* data() const { return _data; } /**< @overload */ /** * @brief Set image data @@ -91,7 +91,7 @@ template class Image: public AbstractImage { private: Math::Vector _size; - char* _data; + unsigned char* _data; }; #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/ImageWrapper.h b/src/ImageWrapper.h index 132b2526f..e9e0b7f1d 100644 --- a/src/ImageWrapper.h +++ b/src/ImageWrapper.h @@ -62,7 +62,7 @@ template class ImageWrapper: public AbstractImage { * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - inline explicit ImageWrapper(const typename DimensionTraits::VectorType& size, Format format, Type type, GLvoid* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} + inline explicit ImageWrapper(const typename DimensionTraits::VectorType& size, Format format, Type type, GLvoid* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} /** * @brief Constructor @@ -70,8 +70,8 @@ template class ImageWrapper: public AbstractImage { * @param format Format of pixel data * @param type Data type of pixel data * - * Dimensions and data pointer are set to zero, call setData() to fill - * the image with data. + * Data pointer is set to zero, call setData() to fill the image with + * data. */ inline explicit ImageWrapper(const typename DimensionTraits::VectorType& size, Format format, Type type): AbstractImage(format, type), _size(size), _data(nullptr) {} @@ -79,8 +79,8 @@ template class ImageWrapper: public AbstractImage { inline typename DimensionTraits::VectorType size() const { return _size; } /** @brief Pointer to raw data */ - inline void* data() { return _data; } - inline const void* data() const { return _data; } /**< @overload */ + inline unsigned char* data() { return _data; } + inline const unsigned char* data() const { return _data; } /**< @overload */ /** * @brief Set image data @@ -91,12 +91,12 @@ template class ImageWrapper: public AbstractImage { * destruction. */ inline void setData(GLvoid* data) { - _data = reinterpret_cast(data); + _data = reinterpret_cast(data); } private: Math::Vector _size; - char* _data; + unsigned char* _data; }; /** @brief One-dimensional image wrapper */ diff --git a/src/Magnum.h b/src/Magnum.h index d1fdc7f02..8a57a85c5 100644 --- a/src/Magnum.h +++ b/src/Magnum.h @@ -74,7 +74,8 @@ using Corrade::Utility::Error; `MAGNUM_TARGET_GLES` is defined if the engine is built for OpenGL ES 3.0 or OpenGL ES 2.0. -@see @ref MAGNUM_TARGET_GLES_ "MAGNUM_TARGET_GLES", +@see @ref MAGNUM_TARGET_GLES2_ "MAGNUM_TARGET_GLES2", + @ref MAGNUM_TARGET_GLES3_ "MAGNUM_TARGET_GLES3", @ref MAGNUM_TARGET_DESKTOP_GLES_ "MAGNUM_TARGET_DESKTOP_GLES", @ref MAGNUM_TARGET_NACL_ "MAGNUM_TARGET_NACL", @ref building */ @@ -85,11 +86,23 @@ OpenGL ES 2.0. `MAGNUM_TARGET_GLES2` is defined if the engine is built for OpenGL ES 2.0. Implies also @ref MAGNUM_TARGET_GLES_ "MAGNUM_TARGET_GLES". -@see @ref MAGNUM_TARGET_DESKTOP_GLES_ "MAGNUM_TARGET_DESKTOP_GLES", +@see @ref MAGNUM_TARGET_GLES3_ "MAGNUM_TARGET_GLES3", + @ref MAGNUM_TARGET_DESKTOP_GLES_ "MAGNUM_TARGET_DESKTOP_GLES", @ref MAGNUM_TARGET_NACL_ "MAGNUM_TARGET_NACL", @ref building */ #define MAGNUM_TARGET_GLES2_ +/** +@brief OpenGL ES 3.0 target. + +`MAGNUM_TARGET_GLES3` is defined if the engine is built for OpenGL ES 3.0. +Implies also @ref MAGNUM_TARGET_GLES_ "MAGNUM_TARGET_GLES". +@see @ref MAGNUM_TARGET_GLES2_ "MAGNUM_TARGET_GLES2", + @ref MAGNUM_TARGET_DESKTOP_GLES_ "MAGNUM_TARGET_DESKTOP_GLES", + @ref MAGNUM_TARGET_NACL_ "MAGNUM_TARGET_NACL", @ref building +*/ +#define MAGNUM_TARGET_GLES3_ + /** @brief Desktop emulation of OpenGL ES target @@ -111,15 +124,6 @@ and @ref MAGNUM_TARGET_GLES2_ "MAGNUM_TARGET_GLES". */ #define MAGNUM_TARGET_NACL_ -/** -@brief HarfBuzz library usage - -`MAGNUM_USE_HARFBUZZ` is defined if HarfBuzz library is used for text -rendering. -@see Text::HarfBuzzFont -*/ -#define MAGNUM_USE_HARFBUZZ_ - #endif /** @{ @name Basic type definitions diff --git a/src/Math/Functions.h b/src/Math/Functions.h index 9d25668f6..cec7db9e5 100644 --- a/src/Math/Functions.h +++ b/src/Math/Functions.h @@ -80,20 +80,30 @@ UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number); */ UnsignedInt MAGNUM_EXPORT log(UnsignedInt base, UnsignedInt number); +/** @todo Can't trigonometric functions be done with only one overload? */ + /** @brief Sine */ +#ifdef DOXYGEN_GENERATING_OUTPUT template inline T sin(Rad angle) { return std::sin(T(angle)); } +#else +template inline T sin(Unit angle) { return std::sin(T(angle)); } +template inline T sin(Unit angle) { return sin(Rad(angle)); } +#endif /** @brief Cosine */ +#ifdef DOXYGEN_GENERATING_OUTPUT template inline T cos(Rad angle) { return std::cos(T(angle)); } +#else +template inline T cos(Unit angle) { return std::cos(T(angle)); } +template inline T cos(Unit angle) { return cos(Rad(angle)); } +#endif /** @brief Tangent */ +#ifdef DOXYGEN_GENERATING_OUTPUT template inline T tan(Rad angle) { return std::tan(T(angle)); } - -/** @todo Can't trigonometric functions be done with only one overload? */ -#ifndef DOXYGEN_GENERATING_OUTPUT -template inline T sin(Deg angle) { return sin(Rad(angle)); } -template inline T cos(Deg angle) { return cos(Rad(angle)); } -template inline T tan(Deg angle) { return tan(Rad(angle)); } +#else +template inline T tan(Unit angle) { return std::tan(T(angle)); } +template inline T tan(Unit angle) { return tan(Rad(angle)); } #endif /** @brief Arc sine */ diff --git a/src/Math/Geometry/Rectangle.h b/src/Math/Geometry/Rectangle.h index c832ecf36..ccf8ac019 100644 --- a/src/Math/Geometry/Rectangle.h +++ b/src/Math/Geometry/Rectangle.h @@ -39,6 +39,8 @@ Helper class for storing axis-aligned rectangles consisting of bottom left and top right corner positions with origin in bottom left. Bottom/left positions are inclusive, while top/right positions are exclusive. @see Magnum::Rectangle, Magnum::Rectanglei, Magnum::Rectangled +@todo rename to Range, make it generic for one, two and three dimensions, add translated(), padded()... +@todo move outside Math? */ template class Rectangle { template friend class Rectangle; diff --git a/src/Math/Geometry/Test/RectangleTest.cpp b/src/Math/Geometry/Test/RectangleTest.cpp index c53f35bc4..051f97670 100644 --- a/src/Math/Geometry/Test/RectangleTest.cpp +++ b/src/Math/Geometry/Test/RectangleTest.cpp @@ -80,7 +80,10 @@ void RectangleTest::constructFromSize() { void RectangleTest::constructConversion() { constexpr Rectangle a({1.3f, 2.7f}, {-15.0f, 7.0f}); - constexpr Rectanglei b(a); + #ifndef CORRADE_GCC46_COMPATIBILITY + constexpr /* Not constexpr under GCC < 4.7 */ + #endif + Rectanglei b(a); CORRADE_COMPARE(b, Rectanglei({1, 2}, {-15, 7})); /* Implicit conversion is not allowed */ diff --git a/src/Math/Test/FunctionsTest.cpp b/src/Math/Test/FunctionsTest.cpp index 6fd0b63d7..898df5ef8 100644 --- a/src/Math/Test/FunctionsTest.cpp +++ b/src/Math/Test/FunctionsTest.cpp @@ -52,6 +52,7 @@ class FunctionsTest: public Corrade::TestSuite::Tester { void log(); void log2(); void trigonometric(); + void trigonometricWithBase(); }; typedef Math::Constants Constants; @@ -81,7 +82,8 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::pow, &FunctionsTest::log, &FunctionsTest::log2, - &FunctionsTest::trigonometric}); + &FunctionsTest::trigonometric, + &FunctionsTest::trigonometricWithBase}); } void FunctionsTest::min() { @@ -296,6 +298,21 @@ void FunctionsTest::trigonometric() { CORRADE_COMPARE_AS(Math::atan(1.0f), Deg(45.0f), Deg); } +void FunctionsTest::trigonometricWithBase() { + /* Verify that the functions can be called with Unit and Unit */ + CORRADE_VERIFY((std::is_same>::value)); + CORRADE_VERIFY((std::is_same>::value)); + + CORRADE_COMPARE(Math::sin(2*Deg(15.0f)), 0.5f); + CORRADE_COMPARE(Math::sin(2*Rad(Constants::pi()/12)), 0.5f); + + CORRADE_COMPARE(Math::cos(2*Deg(30.0f)), 0.5f); + CORRADE_COMPARE(Math::cos(2*Rad(Constants::pi()/6)), 0.5f); + + CORRADE_COMPARE(Math::tan(2*Deg(22.5f)), 1.0f); + CORRADE_COMPARE(Math::tan(2*Rad(Constants::pi()/8)), 1.0f); +} + }}} CORRADE_TEST_MAIN(Magnum::Math::Test::FunctionsTest) diff --git a/src/Mesh.cpp b/src/Mesh.cpp index c9c28e39b..85cd97caa 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -230,7 +230,7 @@ void Mesh::destroyImplementationDefault() {} void Mesh::destroyImplementationVAO() { /** @todo Get some extension wrangler instead to avoid linker errors to glDeleteVertexArrays() on ES2 */ #ifndef MAGNUM_TARGET_GLES2 - glDeleteVertexArrays(1, &vao); + if(vao) glDeleteVertexArrays(1, &vao); #endif } diff --git a/src/MeshTools/CMakeLists.txt b/src/MeshTools/CMakeLists.txt index b28bd7c77..fc0b2cd15 100644 --- a/src/MeshTools/CMakeLists.txt +++ b/src/MeshTools/CMakeLists.txt @@ -48,12 +48,21 @@ set(MagnumMeshTools_HEADERS # Set shared library flags for the objects, as they will be part of shared lib # TODO: fix when CMake sets target_EXPORTS for OBJECT targets as well add_library(MagnumMeshToolsObjects OBJECT ${MagnumMeshTools_SRCS}) -set_target_properties(MagnumMeshToolsObjects PROPERTIES COMPILE_FLAGS "-DMagnumMeshToolsObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +if(NOT BUILD_SHARED OR BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(MagnumMeshToolsObjects PROPERTIES COMPILE_FLAGS "-DMagnumMeshToolsObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +else() + set_target_properties(MagnumMeshToolsObjects PROPERTIES COMPILE_FLAGS "-DMagnumMeshToolsObjects_EXPORTS") +endif() # Main library -add_library(MagnumMeshTools SHARED +add_library(MagnumMeshTools ${SHARED_OR_STATIC} $ ${MagnumMeshTools_GracefulAssert_SRCS}) +if(BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(MagnumMeshTools PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +endif() target_link_libraries(MagnumMeshTools Magnum) install(TARGETS MagnumMeshTools DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) @@ -61,7 +70,7 @@ install(FILES ${MagnumMeshTools_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DI if(BUILD_TESTS) # Library with graceful assert for testing - add_library(MagnumMeshToolsTestLib SHARED + add_library(MagnumMeshToolsTestLib ${SHARED_OR_STATIC} $ ${MagnumMeshTools_GracefulAssert_SRCS}) set_target_properties(MagnumMeshToolsTestLib PROPERTIES COMPILE_FLAGS "-DCORRADE_GRACEFUL_ASSERT -DMagnumMeshTools_EXPORTS") diff --git a/src/OpenGL.h b/src/OpenGL.h index 463ad9d6f..c19973805 100644 --- a/src/OpenGL.h +++ b/src/OpenGL.h @@ -30,12 +30,22 @@ #include "magnumConfigure.h" +/* Desktop OpenGL */ #ifndef MAGNUM_TARGET_GLES #include #include -#else -#ifndef MAGNUM_TARGET_NACL +/* NaCl has its own gl2.h, the official one causes linker issues. Additionaly + to NaCl's gl2ext.h we are including our own to prevent undeclared symbol + errors with some recent extensions. */ +#elif defined(MAGNUM_TARGET_NACL) +#include +#include +#undef __gl2ext_h_ +#include + +/* Generic OpenGL ES */ +#else #include #ifndef MAGNUM_TARGET_GLES2 #include @@ -45,16 +55,6 @@ #include #include #endif - -/* NaCl has its own gl2.h, the official one causes linker issues. Additionaly - to NaCl's gl2ext.h we are including our own to prevent undeclared symbol - errors with some recent extensions. */ -#else -#include -#include -#undef __gl2ext_h_ -#include #endif #endif -#endif diff --git a/src/Physics/AxisAlignedBox.h b/src/Physics/AxisAlignedBox.h index bcb164434..d987c8674 100644 --- a/src/Physics/AxisAlignedBox.h +++ b/src/Physics/AxisAlignedBox.h @@ -39,6 +39,8 @@ namespace Magnum { namespace Physics { /** @brief Axis-aligned box +Unit-size means that half extents are equal to 1, equivalent to e.g. sphere +radius. @see AxisAlignedBox2D, AxisAlignedBox3D @todo Assert for rotation */ diff --git a/src/Physics/Box.h b/src/Physics/Box.h index e442e915d..e0b79de96 100644 --- a/src/Physics/Box.h +++ b/src/Physics/Box.h @@ -39,6 +39,8 @@ namespace Magnum { namespace Physics { /** @brief Unit-size box with assigned transformation matrix +Unit-size means that half extents are equal to 1, equivalent to e.g. sphere +radius. @todo Use quat + position + size instead? @see Box2D, Box3D @todo Assert for skew diff --git a/src/Physics/CMakeLists.txt b/src/Physics/CMakeLists.txt index aa4a2afe2..ef1d51a51 100644 --- a/src/Physics/CMakeLists.txt +++ b/src/Physics/CMakeLists.txt @@ -52,7 +52,11 @@ set(MagnumPhysics_HEADERS magnumPhysicsVisibility.h) -add_library(MagnumPhysics SHARED ${MagnumPhysics_SRCS}) +add_library(MagnumPhysics ${SHARED_OR_STATIC} ${MagnumPhysics_SRCS}) +if(BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(MagnumPhysics PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +endif() target_link_libraries(MagnumPhysics Magnum MagnumSceneGraph) install(TARGETS MagnumPhysics DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) diff --git a/src/Platform/AbstractXApplication.cpp b/src/Platform/AbstractXApplication.cpp index 7442c6e85..6275abdd6 100644 --- a/src/Platform/AbstractXApplication.cpp +++ b/src/Platform/AbstractXApplication.cpp @@ -36,11 +36,11 @@ namespace Magnum { namespace Platform { -AbstractXApplication::AbstractXApplication(AbstractContextHandler* contextHandler, int&, char**): contextHandler(contextHandler), flags(Flag::Redraw) { +AbstractXApplication::AbstractXApplication(AbstractContextHandler* contextHandler, int&, char**): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) { createContext(new Configuration); } -AbstractXApplication::AbstractXApplication(AbstractContextHandler* contextHandler, int&, char**, Configuration* configuration): contextHandler(contextHandler), flags(Flag::Redraw) { +AbstractXApplication::AbstractXApplication(AbstractContextHandler* contextHandler, int&, char**, Configuration* configuration): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) { if(configuration) createContext(configuration); } diff --git a/src/Platform/GlutApplication.cpp b/src/Platform/GlutApplication.cpp index 2aa125759..3571c8a67 100644 --- a/src/Platform/GlutApplication.cpp +++ b/src/Platform/GlutApplication.cpp @@ -53,7 +53,13 @@ void GlutApplication::createContext(Configuration* configuration) { CORRADE_ASSERT(!c, "GlutApplication::createContext(): context already created", ); glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); - glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL); + + unsigned int flags = GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL; + + /* Multisampling */ + if(configuration->sampleCount()) flags |= GLUT_MULTISAMPLE; + + glutInitDisplayMode(flags); glutInitWindowSize(configuration->size().x(), configuration->size().y()); glutCreateWindow(configuration->title().c_str()); glutReshapeFunc(staticViewportEvent); diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 861376044..6dd8281a3 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -296,9 +296,26 @@ class GlutApplication::Configuration { return this; } + /** @brief Sample count */ + inline Int sampleCount() const { return _sampleCount; } + + /** + * @brief Set sample count + * @return Pointer to self (for method chaining) + * + * Default is `0`, thus no multisampling. The actual sample count is + * ignored, GLUT either enables it or disables. See also + * @ref Renderer::Feature "Renderer::Feature::Multisampling". + */ + inline Configuration* setSampleCount(Int count) { + _sampleCount = count; + return this; + } + private: std::string _title; Vector2i _size; + Int _sampleCount; }; /** diff --git a/src/Platform/Sdl2Application.cpp b/src/Platform/Sdl2Application.cpp index 9a39d9251..881ec5aab 100644 --- a/src/Platform/Sdl2Application.cpp +++ b/src/Platform/Sdl2Application.cpp @@ -69,6 +69,12 @@ void Sdl2Application::createContext(Configuration* configuration) { SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + /* Multisampling */ + if(configuration->sampleCount()) { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, configuration->sampleCount()); + } + window = SDL_CreateWindow(configuration->title().c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, configuration->size().x(), configuration->size().y(), SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); if(!window) { diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 9f36b90c4..860feda8f 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -219,9 +219,25 @@ class Sdl2Application::Configuration { return this; } + /** @brief Sample count */ + inline Int sampleCount() const { return _sampleCount; } + + /** + * @brief Set sample count + * @return Pointer to self (for method chaining) + * + * Default is `0`, thus no multisampling. See also + * @ref Renderer::Feature "Renderer::Feature::Multisampling". + */ + inline Configuration* setSampleCount(Int count) { + _sampleCount = count; + return this; + } + private: std::string _title; Vector2i _size; + Int _sampleCount; }; /** diff --git a/src/Platform/magnum-info.cpp b/src/Platform/magnum-info.cpp index fd30f1d14..6fde981c1 100644 --- a/src/Platform/magnum-info.cpp +++ b/src/Platform/magnum-info.cpp @@ -71,9 +71,6 @@ MagnumInfo::MagnumInfo(int& argc, char** argv): WindowlessGlxApplication(argc, a #ifdef MAGNUM_TARGET_NACL d << "MAGNUM_TARGET_NACL"; #endif - #ifdef MAGNUM_USE_HARFBUZZ - d << "MAGNUM_USE_HARFBUZZ"; - #endif } Debug() << ""; diff --git a/src/Primitives/CMakeLists.txt b/src/Primitives/CMakeLists.txt index a3c2efd95..6c44f1c81 100644 --- a/src/Primitives/CMakeLists.txt +++ b/src/Primitives/CMakeLists.txt @@ -24,6 +24,7 @@ set(MagnumPrimitives_SRCS Capsule.cpp + Circle.cpp Crosshair.cpp Cube.cpp Cylinder.cpp @@ -34,6 +35,7 @@ set(MagnumPrimitives_SRCS set(MagnumPrimitives_HEADERS Capsule.h + Circle.h Crosshair.h Cube.h Cylinder.h @@ -44,7 +46,11 @@ set(MagnumPrimitives_HEADERS magnumPrimitivesVisibility.h) -add_library(MagnumPrimitives SHARED ${MagnumPrimitives_SRCS}) +add_library(MagnumPrimitives ${SHARED_OR_STATIC} ${MagnumPrimitives_SRCS}) +if(BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(Magnum PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +endif() target_link_libraries(MagnumPrimitives Magnum) install(TARGETS MagnumPrimitives DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) diff --git a/src/Primitives/Circle.cpp b/src/Primitives/Circle.cpp new file mode 100644 index 000000000..170fcef89 --- /dev/null +++ b/src/Primitives/Circle.cpp @@ -0,0 +1,66 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Circle.h" + +#include "Math/Functions.h" +#include "Math/Vector2.h" +#include "Trade/MeshData2D.h" + +namespace Magnum { namespace Primitives { + +Trade::MeshData2D Circle::solid(UnsignedInt segments) { + CORRADE_ASSERT(segments >= 3, "Primitives::Circle::solid(): segments must be >= 3", + Trade::MeshData2D(Mesh::Primitive::TriangleFan, nullptr, {}, {})); + + auto positions = new std::vector; + positions->reserve(segments+1); + + /* Central point */ + positions->emplace_back(); + + /* Points on circle */ + const Rad angleIncrement(2*Constants::pi()/segments); + for(UnsignedInt i = 0; i != segments; ++i) + positions->emplace_back(Math::cos(i*angleIncrement), Math::sin(i*angleIncrement)); + + return Trade::MeshData2D(Mesh::Primitive::TriangleFan, nullptr, {positions}, {}); +} + +Trade::MeshData2D Circle::wireframe(UnsignedInt segments) { + CORRADE_ASSERT(segments >= 3, "Primitives::Circle::wireframe(): segments must be >= 3", + Trade::MeshData2D(Mesh::Primitive::LineLoop, nullptr, {}, {})); + + auto positions = new std::vector; + positions->reserve(segments); + + /* Points on circle */ + const Rad angleIncrement(2*Constants::pi()/segments); + for(UnsignedInt i = 0; i != segments; ++i) + positions->emplace_back(Math::cos(i*angleIncrement), Math::sin(i*angleIncrement)); + + return Trade::MeshData2D(Mesh::Primitive::LineLoop, nullptr, {positions}, {}); +} + +}} diff --git a/src/Primitives/Circle.h b/src/Primitives/Circle.h new file mode 100644 index 000000000..a27876e31 --- /dev/null +++ b/src/Primitives/Circle.h @@ -0,0 +1,65 @@ +#ifndef Magnum_Primitives_Circle_h +#define Magnum_Primitives_Circle_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class Magnum::Primitives::Circle + */ + +#include "Trade/Trade.h" + +#include "Primitives/magnumPrimitivesVisibility.h" + +namespace Magnum { namespace Primitives { + +/** +@brief 2D circle primitive + +Circle with radius 1. +*/ +class MAGNUM_PRIMITIVES_EXPORT Circle { + public: + /** + * @brief Solid circle + * @param segments Number of segments. Must be greater or equal to 3. + * + * Non-indexed @ref Mesh::Primitive "TriangleFan". + */ + static Trade::MeshData2D solid(UnsignedInt segments); + + /** + * @brief Wireframe circle + * @param segments Number of segments. Must be greater or equal to 3. + * + * Non-indexed @ref Mesh::Primitive "LineLoop". + */ + static Trade::MeshData2D wireframe(UnsignedInt segments); + + Circle() = delete; +}; + +}} + +#endif diff --git a/src/Primitives/Test/CMakeLists.txt b/src/Primitives/Test/CMakeLists.txt index 987d1e01e..b12e72032 100644 --- a/src/Primitives/Test/CMakeLists.txt +++ b/src/Primitives/Test/CMakeLists.txt @@ -23,5 +23,6 @@ # corrade_add_test(PrimitivesCapsuleTest CapsuleTest.cpp LIBRARIES MagnumPrimitives) -corrade_add_test(PrimitivesUVSphereTest UVSphereTest.cpp LIBRARIES MagnumPrimitives) +corrade_add_test(PrimitivesCircleTest CircleTest.cpp LIBRARIES MagnumPrimitives) corrade_add_test(PrimitivesCylinderTest CylinderTest.cpp LIBRARIES MagnumPrimitives) +corrade_add_test(PrimitivesUVSphereTest UVSphereTest.cpp LIBRARIES MagnumPrimitives) diff --git a/src/Primitives/Test/CircleTest.cpp b/src/Primitives/Test/CircleTest.cpp new file mode 100644 index 000000000..da396522f --- /dev/null +++ b/src/Primitives/Test/CircleTest.cpp @@ -0,0 +1,71 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Math/Vector2.h" +#include "Primitives/Circle.h" +#include "Trade/MeshData2D.h" + +namespace Magnum { namespace Primitives { namespace Test { + +class CircleTest: public Corrade::TestSuite::Tester { + public: + explicit CircleTest(); + + void solid(); + void wireframe(); +}; + +CircleTest::CircleTest() { + addTests({&CircleTest::solid, + &CircleTest::wireframe}); +} + +void CircleTest::solid() { + Trade::MeshData2D circle = Primitives::Circle::solid(8); + + CORRADE_COMPARE(*circle.positions(0), (std::vector{ + { 0.0f, 0.0f}, + { 1.0f, 0.0f}, { Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f}, + { 0.0f, 1.0f}, {-Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f}, + {-1.0f, 0.0f}, {-Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f}, + { 0.0f, -1.0f}, { Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f} + })); +} + +void CircleTest::wireframe() { + Trade::MeshData2D circle = Primitives::Circle::wireframe(8); + + CORRADE_COMPARE(*circle.positions(0), (std::vector{ + { 1.0f, 0.0f}, { Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f}, + { 0.0f, 1.0f}, {-Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f}, + {-1.0f, 0.0f}, {-Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f}, + { 0.0f, -1.0f}, { Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f} + })); +} + +}}} + +CORRADE_TEST_MAIN(Magnum::Primitives::Test::CircleTest) diff --git a/src/Renderbuffer.h b/src/Renderbuffer.h index 8c9cc8957..58f1bcd3e 100644 --- a/src/Renderbuffer.h +++ b/src/Renderbuffer.h @@ -436,6 +436,7 @@ class MAGNUM_EXPORT Renderbuffer { DepthComponent24 = GL_DEPTH_COMPONENT24_OES, #endif + #ifndef MAGNUM_TARGET_GLES3 /** * Depth component, 32bit. * @requires_es_extension %Extension @es_extension{OES,depth32} @@ -445,6 +446,7 @@ class MAGNUM_EXPORT Renderbuffer { #else DepthComponent32 = GL_DEPTH_COMPONENT32_OES, #endif + #endif #ifndef MAGNUM_TARGET_GLES2 /** @@ -466,6 +468,7 @@ class MAGNUM_EXPORT Renderbuffer { StencilIndex = GL_STENCIL_INDEX, #endif + #ifndef MAGNUM_TARGET_GLES3 /** * 1-bit stencil index. * @requires_es_extension %Extension @es_extension{OES,stencil1} @@ -485,6 +488,7 @@ class MAGNUM_EXPORT Renderbuffer { #else StencilIndex4 = GL_STENCIL_INDEX4_OES, #endif + #endif /** 8-bit stencil index. */ StencilIndex8 = GL_STENCIL_INDEX8, diff --git a/src/Renderer.h b/src/Renderer.h index 5edbd0db2..06f65be9b 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -77,6 +77,11 @@ class MAGNUM_EXPORT Renderer { */ Blending = GL_BLEND, + DepthTest = GL_DEPTH_TEST, /**< Depth test */ + Dithering = GL_DITHER, /**< Dithering (enabled by default) */ + + FaceCulling = GL_CULL_FACE, /**< Back face culling */ + #ifndef MAGNUM_TARGET_GLES /** * Logical operation @@ -85,7 +90,17 @@ class MAGNUM_EXPORT Renderer { * available in OpenGL ES. */ LogicOperation = GL_COLOR_LOGIC_OP, + #endif + #ifndef MAGNUM_TARGET_GLES + /** + * Multisampling (enabled by default) + * @requires_gl Always enabled in OpenGL ES. + */ + Multisampling = GL_MULTISAMPLE, + #endif + + #ifndef MAGNUM_TARGET_GLES /** * Depth clamping. If enabled, ignores near and far clipping plane. * @requires_gl32 %Extension @extension{ARB,depth_clamp} @@ -99,10 +114,8 @@ class MAGNUM_EXPORT Renderer { * @see setScissor() */ ScissorTest = GL_SCISSOR_TEST, - DepthTest = GL_DEPTH_TEST, /**< Depth test */ - StencilTest = GL_STENCIL_TEST, /**< Stencil test */ - Dithering = GL_DITHER, /**< Dithering (enabled by default) */ - FaceCulling = GL_CULL_FACE /**< Back face culling */ + + StencilTest = GL_STENCIL_TEST /**< Stencil test */ }; /** @@ -381,7 +394,9 @@ class MAGNUM_EXPORT Renderer { /*@}*/ - /** @{ @name Blending + /** + * @{ @name Blending + * * You have to enable blending with setFeature() first. * @todo Blending for given draw buffer */ @@ -651,6 +666,29 @@ class MAGNUM_EXPORT Renderer { /*@}*/ #endif + + /** @{ @name Renderer management */ + + /** + * @brief Flush the pipeline + * + * @see finish(), @fn_gl{Flush} + */ + inline static void flush() { + glFlush(); + } + + /** + * @brief Finish the pipeline + * + * Blocks until all commands in the pipeline are finished. + * @see flush(), @fn_gl{Finish} + */ + inline static void finish() { + glFinish(); + } + + /*@}*/ }; } diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 41bec81e3..e2658cd0f 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -73,10 +73,15 @@ set(MagnumSceneGraph_HEADERS # Set shared library flags for the objects, as they will be part of shared lib # TODO: fix when CMake sets target_EXPORTS for OBJECT targets as well add_library(MagnumSceneGraphObjects OBJECT ${MagnumSceneGraph_SRCS}) -set_target_properties(MagnumSceneGraphObjects PROPERTIES COMPILE_FLAGS "-DMagnumSceneGraphObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(MagnumSceneGraphObjects PROPERTIES COMPILE_FLAGS "-DMagnumSceneGraphObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +else() + set_target_properties(MagnumSceneGraphObjects PROPERTIES COMPILE_FLAGS "-DMagnumSceneGraphObjects_EXPORTS") +endif() # SceneGraph library -add_library(MagnumSceneGraph SHARED +add_library(MagnumSceneGraph ${SHARED_OR_STATIC} $ ${MagnumSceneGraph_GracefulAssert_SRCS}) target_link_libraries(MagnumSceneGraph Magnum) @@ -86,7 +91,7 @@ install(FILES ${MagnumSceneGraph_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_D if(BUILD_TESTS) # Library with graceful assert for testing - add_library(MagnumSceneGraphTestLib SHARED + add_library(MagnumSceneGraphTestLib ${SHARED_OR_STATIC} $ ${MagnumSceneGraph_GracefulAssert_SRCS}) set_target_properties(MagnumSceneGraphTestLib PROPERTIES COMPILE_FLAGS "-DCORRADE_GRACEFUL_ASSERT -DMagnumSceneGraph_EXPORTS") diff --git a/src/Shaders/CMakeLists.txt b/src/Shaders/CMakeLists.txt index 225b1b0c0..6d2a92cf0 100644 --- a/src/Shaders/CMakeLists.txt +++ b/src/Shaders/CMakeLists.txt @@ -49,7 +49,11 @@ set(MagnumShaders_HEADERS magnumShadersVisibility.h) -add_library(MagnumShaders SHARED ${MagnumShaders_SRCS}) +add_library(MagnumShaders ${SHARED_OR_STATIC} ${MagnumShaders_SRCS}) +if(BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(MagnumShaders PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +endif() target_link_libraries(MagnumShaders Magnum) install(TARGETS MagnumShaders DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) diff --git a/src/Text/AbstractFont.cpp b/src/Text/AbstractFont.cpp index 31214e636..74f116ad3 100644 --- a/src/Text/AbstractFont.cpp +++ b/src/Text/AbstractFont.cpp @@ -26,10 +26,12 @@ namespace Magnum { namespace Text { -AbstractFont::AbstractFont() {} -AbstractFont::~AbstractFont() {} +AbstractFont::AbstractFont(): _size(0.0f) {} + +AbstractFont::AbstractFont(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin): AbstractPlugin(manager, std::move(plugin)), _size(0.0f) {} AbstractLayouter::AbstractLayouter(): _glyphCount(0) {} + AbstractLayouter::~AbstractLayouter() {} }} diff --git a/src/Text/AbstractFont.h b/src/Text/AbstractFont.h index aa22df3c1..df2d06437 100644 --- a/src/Text/AbstractFont.h +++ b/src/Text/AbstractFont.h @@ -30,6 +30,7 @@ #include #include +#include #include "Magnum.h" #include "Texture.h" @@ -39,34 +40,80 @@ namespace Magnum { namespace Text { /** -@brief Base for fonts +@brief Base for font plugins + +@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. + +@section AbstractFont-subclassing Subclassing + +Plugin implements functions open(), close(), createGlyphCache() and layout(). */ -class MAGNUM_TEXT_EXPORT AbstractFont { - AbstractFont(const AbstractFont&) = delete; - AbstractFont(AbstractFont&&) = delete; - AbstractFont& operator=(const AbstractFont&) = delete; - AbstractFont& operator=(const AbstractFont&&) = delete; +class MAGNUM_TEXT_EXPORT AbstractFont: public Corrade::PluginManager::AbstractPlugin { + PLUGIN_INTERFACE("cz.mosra.magnum.Text.AbstractFont/0.1") public: - AbstractFont(); - virtual ~AbstractFont() = 0; + /** @brief Default constructor */ + explicit AbstractFont(); + + /** @brief Plugin manager constructor */ + explicit AbstractFont(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin); - /** @brief %Font texture atlas */ - inline Texture2D& texture() { return _texture; } + /** + * @brief Open font from file + * @param filename Font file + * @param size Font size + * + * Closes previous file, if it was opened, and tries to open given + * file. Returns `true` on success, `false` otherwise. + */ + virtual bool open(const std::string& filename, Float size) = 0; /** - * @brief Layout the text using fon't own layouter - * @param size %Font size - * @param text Text to layout + * @brief Open font from memory + * @param data Font data + * @param dataSize Font data size + * @param size Font size + * + * Closes previous file, if it was opened, and tries to open given + * file. Returns `true` on success, `false` otherwise. + */ + virtual bool open(const unsigned char* data, std::size_t dataSize, Float size) = 0; + + /** @brief Close font */ + virtual void close() = 0; + + /** @brief Font size */ + inline Float size() const { return _size; } + + /** + * @brief Create glyph cache for given character set + * @param cache Glyph cache instance + * @param characters UTF-8 characters to render + * + * Fills the cache with given characters. + */ + virtual void createGlyphCache(GlyphCache* const cache, const std::string& characters) = 0; + + /** + * @brief Layout the text using font own layouter + * @param cache Glyph cache + * @param size Font size + * @param text %Text to layout + * + * @see createGlyphCache() */ - virtual AbstractLayouter* layout(const Float size, const std::string& text) = 0; + virtual AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) = 0; #ifdef DOXYGEN_GENERATING_OUTPUT private: #else protected: #endif - Texture2D _texture; + Float _size; }; /** @@ -81,7 +128,7 @@ class MAGNUM_TEXT_EXPORT AbstractLayouter { AbstractLayouter& operator=(const AbstractLayouter&&) = delete; public: - AbstractLayouter(); + explicit AbstractLayouter(); virtual ~AbstractLayouter() = 0; /** @brief Count of glyphs in laid out text */ diff --git a/src/Text/CMakeLists.txt b/src/Text/CMakeLists.txt index 517ebbea2..fa28db8d1 100644 --- a/src/Text/CMakeLists.txt +++ b/src/Text/CMakeLists.txt @@ -22,34 +22,26 @@ # DEALINGS IN THE SOFTWARE. # -find_package(Freetype REQUIRED) -include_directories(${FREETYPE_INCLUDE_DIRS}) - set(MagnumText_SRCS AbstractFont.cpp - FreeTypeFont.cpp + DistanceFieldGlyphCache.cpp + GlyphCache.cpp TextRenderer.cpp) set(MagnumText_HEADERS AbstractFont.h - FreeTypeFont.h + DistanceFieldGlyphCache.h + GlyphCache.h Text.h TextRenderer.h magnumTextVisibility.h) -if(USE_HARFBUZZ) - find_package(HarfBuzz REQUIRED) - include_directories(${HARFBUZZ_INCLUDE_DIRS}) - - set(MagnumText_SRCS ${MagnumText_SRCS} HarfBuzzFont.cpp) - set(MagnumText_HEADERS ${MagnumText_HEADERS} HarfBuzzFont.h) -endif() - -add_library(MagnumText SHARED ${MagnumText_SRCS}) -target_link_libraries(MagnumText Magnum MagnumTextureTools ${FREETYPE_LIBRARIES}) -if(USE_HARFBUZZ) - target_link_libraries(MagnumText ${HARFBUZZ_LIBRARIES}) +add_library(MagnumText ${SHARED_OR_STATIC} ${MagnumText_SRCS}) +if(BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(MagnumText PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) endif() +target_link_libraries(MagnumText Magnum MagnumTextureTools) install(TARGETS MagnumText DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES ${MagnumText_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Text) diff --git a/src/Text/DistanceFieldGlyphCache.cpp b/src/Text/DistanceFieldGlyphCache.cpp new file mode 100644 index 000000000..af4a842d7 --- /dev/null +++ b/src/Text/DistanceFieldGlyphCache.cpp @@ -0,0 +1,66 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "DistanceFieldGlyphCache.h" + +#include "Extensions.h" +#include "Image.h" +#include "TextureTools/DistanceField.h" + +namespace Magnum { namespace Text { + +namespace { + #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES3) + const AbstractTexture::InternalFormat internalFormat = AbstractTexture::InternalFormat::R8; + #else + const AbstractTexture::InternalFormat internalFormat = AbstractTexture::InternalFormat::Red; + #endif +} + +DistanceFieldGlyphCache::DistanceFieldGlyphCache(const Vector2i& originalSize, const Vector2i& distanceFieldSize, UnsignedInt radius): GlyphCache(originalSize, Vector2i(radius)), scale(Vector2(distanceFieldSize)/originalSize), radius(radius) { + #ifndef MAGNUM_TARGET_GLES + MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg); + #else + MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::EXT::texture_rg); + #endif + + initialize(internalFormat, distanceFieldSize); +} + +void DistanceFieldGlyphCache::setImage(const Vector2i& offset, Image2D* const image) { + Texture2D input; + input.setWrapping(Texture2D::Wrapping::ClampToEdge) + ->setMinificationFilter(Texture2D::Filter::Linear) + ->setMagnificationFilter(Texture2D::Filter::Linear) + ->setImage(0, internalFormat, image); + + /* Create distance field from input texture */ + TextureTools::distanceField(&input, &_texture, Rectanglei::fromSize(offset*scale, image->size()*scale), radius); +} + +void DistanceFieldGlyphCache::setDistanceFieldImage(const Vector2i& offset, Image2D* const image) { + _texture.setSubImage(0, offset, image); +} + +}} diff --git a/src/Text/DistanceFieldGlyphCache.h b/src/Text/DistanceFieldGlyphCache.h new file mode 100644 index 000000000..80bcaceba --- /dev/null +++ b/src/Text/DistanceFieldGlyphCache.h @@ -0,0 +1,92 @@ +#ifndef Magnum_Text_DistanceFieldGlyphCache_h +#define Magnum_Text_DistanceFieldGlyphCache_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class Magnum::Text::DistanceFieldGlyphCache + */ + +#include "Text/GlyphCache.h" + +namespace Magnum { namespace Text { + +/** +@brief Glyph cache with distance field rendering + +Unlike original GlyphCache converts each binary image to distance field. It is +not possible to use non-binary colors with this cache, internal texture format +is red channel only. + +@section GlyphCache-usage Usage + +Usage is similar to GlyphCache, additionaly you need to specify size of +resulting distance field texture. +@code +Text::AbstractFont* font; +Text::GlyphCache* cache = new Text::DistanceFieldGlyphCache(Vector2i(2048), Vector2i(384)); +font->createGlyphCache(cache, "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789 "); +@endcode + +@see TextureTools::distanceField() +*/ +class MAGNUM_TEXT_EXPORT DistanceFieldGlyphCache: public GlyphCache { + public: + /** + * @brief Constructor + * @param originalSize Original cache texture size + * @param distanceFieldSize Size of computed distance field texture + * @param radius Distance field computation radius + * + * See TextureTools::distanceField() for more information about the + * parameters. + */ + explicit DistanceFieldGlyphCache(const Vector2i& originalSize, const Vector2i& distanceFieldSize, UnsignedInt radius); + + /** + * @brief Set cache image + * + * Uploads image for one or more glyphs to given offset in original + * cache texture. The texture is then converted to distance field. + */ + void setImage(const Vector2i& offset, Image2D* const image) override; + + /** + * @brief Set distance field cache image + * + * Uploads already computed distance field image to given offset in + * distance field texture. + */ + void setDistanceFieldImage(const Vector2i& offset, Image2D* const image); + + private: + const Vector2 scale; + const UnsignedInt radius; +}; + +}} + +#endif diff --git a/src/Text/FreeTypeFont.cpp b/src/Text/FreeTypeFont.cpp deleted file mode 100644 index 5fd3bda84..000000000 --- a/src/Text/FreeTypeFont.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "FreeTypeFont.h" - -#include -#include -#include FT_FREETYPE_H -#include - -#include "Extensions.h" -#include "Image.h" -#include "TextureTools/Atlas.h" -#include "TextureTools/DistanceField.h" - -namespace Magnum { namespace Text { - -namespace { - -class FreeTypeLayouter: public AbstractLayouter { - public: - FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text); - - std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; - - private: - FreeTypeFont& font; - std::vector glyphs; - const Float size; -}; - -} - -FreeTypeFontRenderer::FreeTypeFontRenderer() { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Init_FreeType(&_library) == 0); -} - -FreeTypeFontRenderer::~FreeTypeFontRenderer() { - FT_Done_FreeType(_library); -} - -FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): _size(size) { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &_ftFont) == 0); - - finishConstruction(); -} - -FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): _size(size) { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &_ftFont) == 0); - - finishConstruction(); -} - -void FreeTypeFont::finishConstruction() { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, _size*64, 100, 100) == 0); - - #ifndef MAGNUM_TARGET_GLES - MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg); - #else - MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::EXT::texture_rg); - #endif - - /* Set up the texture */ - _texture.setWrapping(Texture2D::Wrapping::ClampToEdge) - ->setMinificationFilter(Texture2D::Filter::Linear) - ->setMagnificationFilter(Texture2D::Filter::Linear); -} - -void FreeTypeFont::prerenderInternal(const std::string& characters, const Vector2i& atlasSize, const Int radius, Texture2D* output) { - glyphs.clear(); - - /** @bug Crash when atlas is too small */ - - /* Get glyph codes from characters */ - std::vector charIndices; - charIndices.reserve(characters.size()+1); - charIndices.push_back(0); - for(std::size_t i = 0; i != characters.size(); ) { - UnsignedInt codepoint; - std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(characters, i); - charIndices.push_back(FT_Get_Char_Index(_ftFont, codepoint)); - } - - /* Remove duplicates (e.g. uppercase and lowercase mapped to same glyph) */ - std::sort(charIndices.begin(), charIndices.end()); - charIndices.erase(std::unique(charIndices.begin(), charIndices.end()), charIndices.end()); - - /* Sizes of all characters */ - const Vector2i padding = Vector2i(radius); - std::vector charSizes; - charSizes.reserve(charIndices.size()); - for(auto it = charIndices.begin(); it != charIndices.end(); ++it) { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(_ftFont, *it, FT_LOAD_DEFAULT) == 0); - charSizes.push_back(Vector2i(_ftFont->glyph->metrics.width, _ftFont->glyph->metrics.height)/64); - } - - /* Create texture atlas */ - const std::vector charPositions = TextureTools::atlas(atlasSize, charSizes, padding); - - /* Render all characters to the atlas and create character map */ - #ifndef CORRADE_GCC44_COMPATIBILITY - glyphs.reserve(charPositions.size()); - #endif - unsigned char* pixmap = new unsigned char[atlasSize.product()](); - Image2D image(atlasSize, Image2D::Format::Red, Image2D::Type::UnsignedByte, pixmap); - for(std::size_t i = 0; i != charPositions.size(); ++i) { - /* Load and render glyph */ - /** @todo B&W only if radius != 0 */ - FT_GlyphSlot glyph = _ftFont->glyph; - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(_ftFont, charIndices[i], FT_LOAD_DEFAULT) == 0); - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) == 0); - - /* Copy rendered bitmap to texture image */ - const FT_Bitmap& bitmap = glyph->bitmap; - CORRADE_INTERNAL_ASSERT(std::abs(bitmap.width-charPositions[i].width()) <= 2); - CORRADE_INTERNAL_ASSERT(std::abs(bitmap.rows-charPositions[i].height()) <= 2); - for(Int yin = 0, yout = charPositions[i].bottom(), ymax = bitmap.rows; yin != ymax; ++yin, ++yout) - for(Int xin = 0, xout = charPositions[i].left(), xmax = bitmap.width; xin != xmax; ++xin, ++xout) - pixmap[yout*atlasSize.x() + xout] = bitmap.buffer[(bitmap.rows-yin-1)*bitmap.width + xin]; - - /* Save character texture position and texture coordinates for given character index */ - CORRADE_INTERNAL_ASSERT_OUTPUT(glyphs.insert({charIndices[i], std::make_tuple( - Rectangle::fromSize((Vector2(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].height()) - Vector2(radius))/_size, - Vector2(charPositions[i].size() + 2*padding)/_size), - Rectangle(Vector2(charPositions[i].bottomLeft() - padding)/atlasSize, - Vector2(charPositions[i].topRight() + padding)/atlasSize) - )}).second); - } - - /* Set texture data */ - #ifndef MAGNUM_TARGET_GLES - output->setImage(0, Texture2D::InternalFormat::R8, &image); - #else - output->setImage(0, Texture2D::InternalFormat::Red, &image); - #endif -} - -void FreeTypeFont::prerender(const std::string& characters, const Vector2i& atlasSize) { - prerenderInternal(characters, atlasSize, 0, &_texture); -} - -void FreeTypeFont::prerenderDistanceField(const std::string& characters, const Vector2i& sourceAtlasSize, const Vector2i& atlasSize, Int radius) { - MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_storage); - - /* Render input texture */ - Texture2D input; - input.setWrapping(Texture2D::Wrapping::ClampToEdge) - ->setMinificationFilter(Texture2D::Filter::Linear) - ->setMagnificationFilter(Texture2D::Filter::Linear); - prerenderInternal(characters, sourceAtlasSize, radius, &input); - - /* Create distance field from input texture */ - _texture.setStorage(1, Texture2D::InternalFormat::R8, atlasSize); - TextureTools::distanceField(&input, &_texture, Rectanglei::fromSize({}, atlasSize), radius); -} - -FreeTypeFont::~FreeTypeFont() { - FT_Done_Face(_ftFont); -} - -const std::tuple& FreeTypeFont::operator[](char32_t character) const { - auto it = glyphs.find(character); - - if(it == glyphs.end()) - return glyphs.at(0); - return it->second; -} - -AbstractLayouter* FreeTypeFont::layout(const Float size, const std::string& text) { - return new FreeTypeLayouter(*this, size, text); -} - -namespace { - -FreeTypeLayouter::FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text): font(font), size(size) { - /* Get glyph codes from characters */ - glyphs.reserve(text.size()); - _glyphCount = text.size(); - for(std::size_t i = 0; i != text.size(); ) { - UnsignedInt codepoint; - std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(text, i); - glyphs.push_back(FT_Get_Char_Index(font.font(), codepoint)); - } -} - -std::tuple FreeTypeLayouter::renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) { - /* Position of the texture in the resulting glyph, texture coordinates */ - Rectangle texturePosition, textureCoordinates; - std::tie(texturePosition, textureCoordinates) = font[glyphs[i]]; - - /* Load glyph */ - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font.font(), glyphs[i], FT_LOAD_DEFAULT) == 0); - const FT_GlyphSlot slot = font.font()->glyph; - Vector2 offset = Vector2(0, 0); /** @todo really? */ - Vector2 advance = Vector2(slot->advance.x, slot->advance.y)/(64*font.size()); - - /* Absolute quad position, composed from cursor position, glyph offset - and texture position, denormalized to requested text size */ - Rectangle quadPosition = Rectangle::fromSize( - (cursorPosition + offset + Vector2(texturePosition.left(), texturePosition.bottom()))*size, - texturePosition.size()*size); - - return std::make_tuple(quadPosition, textureCoordinates, advance); -} - -} - -}} diff --git a/src/Text/FreeTypeFont.h b/src/Text/FreeTypeFont.h deleted file mode 100644 index 223698995..000000000 --- a/src/Text/FreeTypeFont.h +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef Magnum_Text_FreeTypeFont_h -#define Magnum_Text_FreeTypeFont_h -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -/** @file - * @brief Class Magnum::Text::FreeTypeFontRenderer, Magnum::Text::FreeTypeFont - */ - -#include - -#include "Math/Geometry/Rectangle.h" -#include "Texture.h" -#include "Text/AbstractFont.h" -#include "Text/magnumTextVisibility.h" - -#ifndef DOXYGEN_GENERATING_OUTPUT -struct FT_LibraryRec_; -typedef FT_LibraryRec_* FT_Library; -struct FT_FaceRec_; -typedef FT_FaceRec_* FT_Face; -#endif - -namespace Magnum { namespace Text { - -/** -@brief FreeType font renderer - -Contains global instance of font renderer. See FreeTypeFont class documentation -for more information. -*/ -class MAGNUM_TEXT_EXPORT FreeTypeFontRenderer { - public: - explicit FreeTypeFontRenderer(); - - ~FreeTypeFontRenderer(); - - /** @brief FreeType library handle */ - inline FT_Library library() { return _library; } - - private: - FT_Library _library; -}; - -/** -@brief FreeType font - -Contains font with characters prerendered into texture atlas. - -@section FreeTypeFont-usage Usage - -You need to maintain instance of FreeTypeFontRenderer during the lifetime of all FreeTypeFont -instances. The font can be created either from file or from memory location of -format supported by [FreeType](http://www.freetype.org/) library. Next step is -to prerender all the glyphs which will be used in text rendering later. -@code -Text::FreeTypeFontRenderer fontRenderer; - -Text::FreeTypeFont font(fontRenderer, "MyFreeTypeFont.ttf", 48.0f); -font.prerender("abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789 ", Vector2i(512)); -@endcode -See TextRenderer for information about text rendering. - -@section FreeTypeFont-extensions Required OpenGL functionality - -%Font texture uses one-component internal format, which requires -@extension{ARB,texture_rg} (also part of OpenGL ES 3.0 or available as -@es_extension{EXT,texture_rg} in ES 2.0). -*/ -class MAGNUM_TEXT_EXPORT FreeTypeFont: public AbstractFont { - public: - /** - * @brief Create font from file - * @param renderer %Font renderer - * @param fontFile %Font file - * @param size %Font size - */ - explicit FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size); - - /** - * @brief Create font from memory - * @param renderer %Font renderer - * @param data %Font data - * @param dataSize %Font data size - * @param size %Font size - */ - explicit FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size); - - /** - * @brief Prerender given character set - * @param characters UTF-8 characters to render - * @param atlasSize Size of resulting atlas - * - * Creates new atlas with prerendered characters, replacing the - * previous one (if any). - * @attention @p atlasSize must be large enough to contain all - * rendered glyphs. - */ - void prerender(const std::string& characters, const Vector2i& atlasSize); - - /** - * @brief Prerender given character set for use with distance-field rendering - * @param characters UTF-8 characters to render - * @param sourceAtlasSize Size of distance field source atlas - * @param atlasSize Size of resulting atlas - * @param radius Max lookup radius for distance-field creation - * - * Creates new atlas with prerendered characters, replacing the - * previous one (if any). See TextureTools::distanceField() for more - * information. - * @attention @p sourceAtlasSize must be large enough to contain all - * rendered glyphs with padding given by @p radius. - */ - void prerenderDistanceField(const std::string& characters, const Vector2i& sourceAtlasSize, const Vector2i& atlasSize, Int radius); - - ~FreeTypeFont(); - - /** @brief %Font size */ - inline Float size() const { return _size; } - - /** @brief Count of prerendered glyphs in the font */ - inline std::size_t glyphCount() const { return glyphs.size(); } - - /** - * @brief Position of given character in the texture - * @param character Unicode character code (UTF-32) - * - * First returned rectangle is texture position relative to point on - * baseline, second is position of the texture in texture atlas. - */ - const std::tuple& operator[](char32_t character) const; - - /** @brief FreeType font handle */ - inline FT_Face font() { return _ftFont; } - - AbstractLayouter* layout(const Float size, const std::string& text) override; - - #ifdef DOXYGEN_GENERATING_OUTPUT - private: - #else - protected: - #endif - FT_Face _ftFont; - - private: - void MAGNUM_TEXT_LOCAL finishConstruction(); - void MAGNUM_TEXT_LOCAL prerenderInternal(const std::string& characters, const Vector2i& atlasSize, const Int radius, Texture2D* output); - - std::unordered_map> glyphs; - Float _size; -}; - -}} - -#endif diff --git a/src/Text/GlyphCache.cpp b/src/Text/GlyphCache.cpp new file mode 100644 index 000000000..ad6c81aee --- /dev/null +++ b/src/Text/GlyphCache.cpp @@ -0,0 +1,91 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "GlyphCache.h" + +#include "Extensions.h" +#include "Image.h" +#include "TextureTools/Atlas.h" + +namespace Magnum { namespace Text { + +namespace { + #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES3) + const AbstractTexture::InternalFormat internalFormat = AbstractTexture::InternalFormat::R8; + #else + const AbstractTexture::InternalFormat internalFormat = AbstractTexture::InternalFormat::Red; + #endif +} + +GlyphCache::GlyphCache(const Vector2i& size): _size(size) { + #ifndef MAGNUM_TARGET_GLES + MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg); + #else + MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::EXT::texture_rg); + #endif + + initialize(internalFormat, size); +} + +GlyphCache::GlyphCache(const Vector2i& size, const AbstractTexture::InternalFormat internalFormat): _size(size) { + initialize(internalFormat, size); +} + +GlyphCache::GlyphCache(const Vector2i& size, const Vector2i& padding): _size(size), _padding(padding) {} + +GlyphCache::~GlyphCache() = default; + +/** @todo Delegating constructor when support for GCC 4.6 is dropped */ +void GlyphCache::initialize(const AbstractTexture::InternalFormat internalFormat, const Vector2i& size) { + #ifndef MAGNUM_TARGET_GLES + MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_storage); + #else + MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::EXT::texture_storage); + #endif + + _texture.setWrapping(Texture2D::Wrapping::ClampToEdge) + ->setMinificationFilter(Texture2D::Filter::Linear) + ->setMagnificationFilter(Texture2D::Filter::Linear) + ->setStorage(1, internalFormat, size); +} + +std::vector GlyphCache::reserve(const std::vector& sizes) { + CORRADE_ASSERT(glyphs.empty(), "Text::GlyphCache::reserve(): reserving space in non-empty cache is not yet implemented", {}); + glyphs.reserve(glyphs.size() + sizes.size()); + return TextureTools::atlas(_size, sizes, _padding); +} + +void GlyphCache::insert(const UnsignedInt glyph, Vector2i position, Rectanglei rectangle) { + position -= _padding; + rectangle.bottomLeft() -= _padding; + rectangle.topRight() += _padding; + + glyphs.insert({glyph, {position, rectangle}}); +} + +void GlyphCache::setImage(const Vector2i& offset, Image2D* const image) { + _texture.setSubImage(0, offset, image); +} + +}} diff --git a/src/Text/GlyphCache.h b/src/Text/GlyphCache.h new file mode 100644 index 000000000..92f91544b --- /dev/null +++ b/src/Text/GlyphCache.h @@ -0,0 +1,157 @@ +#ifndef Magnum_Text_GlyphCache_h +#define Magnum_Text_GlyphCache_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class Magnum::Text::GlyphCache + */ + +#include + +#include "Math/Geometry/Rectangle.h" +#include "Texture.h" +#include "Text/magnumTextVisibility.h" + +namespace Magnum { namespace Text { + +/** +@brief Glyph cache + +Contains font glyphs prerendered into texture atlas. + +@section GlyphCache-usage Usage + +Create %GlyphCache object with sufficient size and then call +AbstractFont::createGlyphCache() to fill it with glyphs. +@code +Text::AbstractFont* font; +Text::GlyphCache* cache = new GlyphCache(Vector2i(512)); +font->createGlyphCache(cache, "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789 "); +@endcode + +See TextRenderer for information about text rendering. +*/ +class MAGNUM_TEXT_EXPORT GlyphCache { + public: + /** + * @brief Constructor + * @param size Glyph cache texture size + * @param internalFormat Internal texture format + */ + explicit GlyphCache(const Vector2i& size, const Texture2D::InternalFormat internalFormat); + + /** + * @brief Constructor + * @param size Glyph cache texture size + * + * Sets internal texture format to red channel only. Requires + * @extension{ARB,texture_rg} (also part of OpenGL ES 3.0 or available + * as @es_extension{EXT,texture_rg} in ES 2.0). + */ + explicit GlyphCache(const Vector2i& size); + + virtual ~GlyphCache(); + + /** + * @brief Cache size + * + * Size of unscaled glyph cache texture. + */ + inline Vector2i textureSize() const { return _size; } + + /** @brief Count of glyphs in the cache */ + inline std::size_t glyphCount() const { return glyphs.size(); } + + /** @brief Cache texture */ + inline Texture2D* texture() { return &_texture; } + + /** + * @brief Parameters of given glyph + * @param glyph Glyph ID + * + * First tuple element is glyph position relative to point on baseline, + * second element is glyph region in texture atlas. If no glyph is + * found, glyph on zero index is returned. + */ + inline std::pair operator[](const UnsignedInt glyph) const { + auto it = glyphs.find(glyph); + return it == glyphs.end() ? glyphs.at(0) : it->second; + } + + /** + * @brief Layout glyphs with given sizes to the cache + * + * Returns non-overlapping regions in cache texture to store glyphs. + * The reserved space is reused on next call to reserve() if no glyph + * was stored there, use insert() to store actual glyph on given + * position and setImage() to upload glyph image. + * + * @attention Cache size must be large enough to contain all rendered + * glyphs. + */ + std::vector reserve(const std::vector& sizes); + + /** + * @brief Insert glyph to cache + * @param glyph Glyph ID + * @param position Position relative to point on baseline + * @param rectangle Region in texture atlas + * + * You can obtain unused non-overlapping regions with reserve(). See + * also setImage() to upload glyph image. + */ + void insert(const UnsignedInt glyph, Vector2i position, Rectanglei rectangle); + + /** + * @brief Set cache image + * + * Uploads image for one or more glyphs to given offset in cache + * texture. + */ + virtual void setImage(const Vector2i& offset, Image2D* const image); + + #ifdef DOXYGEN_GENERATING_OUTPUT + private: + #else + protected: + #endif + /* Used from DistanceFieldGlyphCache */ + explicit MAGNUM_LOCAL GlyphCache(const Vector2i& size, const Vector2i& padding); + + void MAGNUM_LOCAL initialize(const Texture2D::InternalFormat internalFormat, const Vector2i& size); + + const Vector2i _size; + Texture2D _texture; + + private: + const Vector2i _padding; + std::unordered_map> glyphs; +}; + +}} + +#endif diff --git a/src/Text/HarfBuzzFont.cpp b/src/Text/HarfBuzzFont.cpp deleted file mode 100644 index 6adf781e7..000000000 --- a/src/Text/HarfBuzzFont.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "HarfBuzzFont.h" - -#include - -namespace Magnum { namespace Text { - -namespace { - -class HarfBuzzLayouter: public AbstractLayouter { - public: - HarfBuzzLayouter(HarfBuzzFont& font, const Float size, const std::string& text); - ~HarfBuzzLayouter(); - - std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; - - private: - const HarfBuzzFont& font; - hb_buffer_t* buffer; - hb_glyph_info_t* glyphInfo; - hb_glyph_position_t* glyphPositions; - const Float size; -}; - -} - -HarfBuzzFont::HarfBuzzFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): FreeTypeFont(renderer, fontFile, size) { - finishConstruction(); -} - -HarfBuzzFont::HarfBuzzFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): FreeTypeFont(renderer, data, dataSize, size) { - finishConstruction(); -} - -void HarfBuzzFont::finishConstruction() { - /* Create Harfbuzz font */ - _hbFont = hb_ft_font_create(_ftFont, nullptr); -} - -HarfBuzzFont::~HarfBuzzFont() { - hb_font_destroy(_hbFont); -} - -AbstractLayouter* HarfBuzzFont::layout(const Float size, const std::string& text) { - return new HarfBuzzLayouter(*this, size, text); -} - -namespace { - -HarfBuzzLayouter::HarfBuzzLayouter(HarfBuzzFont& font, const Float size, const std::string& text): font(font), size(size) { - /* Prepare HarfBuzz buffer */ - buffer = hb_buffer_create(); - hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); - hb_buffer_set_script(buffer, HB_SCRIPT_LATIN); - hb_buffer_set_language(buffer, hb_language_from_string("en", 2)); - - /* Layout the text */ - hb_buffer_add_utf8(buffer, text.c_str(), -1, 0, -1); - hb_shape(font.font(), buffer, nullptr, 0); - - glyphInfo = hb_buffer_get_glyph_infos(buffer, &_glyphCount); - glyphPositions = hb_buffer_get_glyph_positions(buffer, &_glyphCount); -} - -HarfBuzzLayouter::~HarfBuzzLayouter() { - /* Destroy HarfBuzz buffer */ - hb_buffer_destroy(buffer); -} - -std::tuple HarfBuzzLayouter::renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) { - /* Position of the texture in the resulting glyph, texture coordinates */ - Rectangle texturePosition, textureCoordinates; - std::tie(texturePosition, textureCoordinates) = font[glyphInfo[i].codepoint]; - - /* Glyph offset and advance to next glyph in normalized coordinates */ - Vector2 offset = Vector2(glyphPositions[i].x_offset, - glyphPositions[i].y_offset)/(64*font.size()); - Vector2 advance = Vector2(glyphPositions[i].x_advance, - glyphPositions[i].y_advance)/(64*font.size()); - - /* Absolute quad position, composed from cursor position, glyph offset - and texture position, denormalized to requested text size */ - Rectangle quadPosition = Rectangle::fromSize( - (cursorPosition + offset + Vector2(texturePosition.left(), texturePosition.bottom()))*size, - texturePosition.size()*size); - - return std::make_tuple(quadPosition, textureCoordinates, advance); -} - -} - -}} diff --git a/src/Text/HarfBuzzFont.h b/src/Text/HarfBuzzFont.h deleted file mode 100644 index b34b8ab77..000000000 --- a/src/Text/HarfBuzzFont.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef Magnum_Text_HarfBuzzFont_h -#define Magnum_Text_HarfBuzzFont_h -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -/** @file - * @brief Class Magnum::Text::HarfBuzzFont - */ - -#include "Text/FreeTypeFont.h" - -#ifndef DOXYGEN_GENERATING_OUTPUT -struct hb_font_t; -#endif - -#ifndef MAGNUM_USE_HARFBUZZ -#error Magnum is not compiled with HarfBuzz support -#endif - -namespace Magnum { namespace Text { - -/** -@brief HarfBuzz font - -Improves FreeTypeFont with [HarfBuzz](http://www.freedesktop.org/wiki/Software/HarfBuzz) -text layouting capabilities, such as kerning, ligatures etc. See FreeTypeFont -class documentation for more information about usage. -*/ -class MAGNUM_TEXT_EXPORT HarfBuzzFont: public FreeTypeFont { - public: - /** - * @brief Create font from file - * @param renderer %Font renderer - * @param fontFile %Font file - * @param size %Font size - */ - explicit HarfBuzzFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size); - - /** - * @brief Create font from memory - * @param renderer %Font renderer - * @param data %Font data - * @param dataSize %Font data size - * @param size %Font size - */ - explicit HarfBuzzFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size); - - ~HarfBuzzFont(); - - /** @brief HarfBuzz font handle */ - inline hb_font_t* font() { return _hbFont; } - - AbstractLayouter* layout(const Float size, const std::string& text) override; - - private: - void MAGNUM_TEXT_LOCAL finishConstruction(); - - hb_font_t* _hbFont; -}; - -}} - -#endif diff --git a/src/Text/Text.h b/src/Text/Text.h index 7f18557d9..aae3a8ea5 100644 --- a/src/Text/Text.h +++ b/src/Text/Text.h @@ -36,12 +36,8 @@ namespace Magnum { namespace Text { class AbstractFont; class AbstractLayouter; - -class FreeTypeFontRenderer; -class FreeTypeFont; -#ifdef MAGNUM_USE_HARFBUZZ -class HarfBuzzFont; -#endif +class DistanceFieldGlyphCache; +class GlyphCache; class AbstractTextRenderer; template class TextRenderer; diff --git a/src/Text/TextRenderer.cpp b/src/Text/TextRenderer.cpp index e471b968d..a0ee125d6 100644 --- a/src/Text/TextRenderer.cpp +++ b/src/Text/TextRenderer.cpp @@ -60,8 +60,8 @@ struct Vertex { } -std::tuple, std::vector, std::vector, Rectangle> AbstractTextRenderer::render(AbstractFont& font, Float size, const std::string& text) { - AbstractLayouter* const layouter = font.layout(size, text); +std::tuple, std::vector, std::vector, Rectangle> AbstractTextRenderer::render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text) { + AbstractLayouter* const layouter = font->layout(cache, size, text); const UnsignedInt vertexCount = layouter->glyphCount()*4; /* Output data */ @@ -106,8 +106,8 @@ std::tuple, std::vector, std::vector, return std::make_tuple(std::move(positions), std::move(texcoords), std::move(indices), rectangle); } -std::tuple AbstractTextRenderer::render(AbstractFont& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { - AbstractLayouter* const layouter = font.layout(size, text); +std::tuple AbstractTextRenderer::render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { + AbstractLayouter* const layouter = font->layout(cache, size, text); const UnsignedInt vertexCount = layouter->glyphCount()*4; const UnsignedInt indexCount = layouter->glyphCount()*6; @@ -174,9 +174,9 @@ std::tuple AbstractTextRenderer::render(AbstractFont& font, Flo return std::make_tuple(std::move(mesh), rectangle); } -template std::tuple TextRenderer::render(AbstractFont& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { +template std::tuple TextRenderer::render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { /* Finalize mesh configuration and return the result */ - auto r = AbstractTextRenderer::render(font, size, text, vertexBuffer, indexBuffer, usage); + auto r = AbstractTextRenderer::render(font, cache, size, text, vertexBuffer, indexBuffer, usage); Mesh& mesh = std::get<0>(r); mesh.addInterleavedVertexBuffer(vertexBuffer, 0, typename Shaders::AbstractVectorShader::Position( @@ -185,7 +185,7 @@ template std::tuple TextRenderer TextRenderer::TextRenderer(AbstractFont& font, const Float size): AbstractTextRenderer(font, size) { +template TextRenderer::TextRenderer(AbstractFont* const font, const GlyphCache* const cache, const Float size): AbstractTextRenderer(font, cache, size) { /* Finalize mesh configuration */ _mesh.addInterleavedVertexBuffer(&vertexBuffer, 0, typename Shaders::AbstractVectorShader::Position(Shaders::AbstractVectorShader::Position::Components::Two), @@ -246,7 +246,7 @@ void AbstractTextRenderer::reserve(const uint32_t glyphCount, const Buffer::Usag } void AbstractTextRenderer::render(const std::string& text) { - AbstractLayouter* layouter = font.layout(size, text); + AbstractLayouter* layouter = font->layout(cache, size, text); CORRADE_ASSERT(layouter->glyphCount() <= _capacity, "Text::TextRenderer::render(): capacity" << _capacity << "too small to render" << layouter->glyphCount() << "glyphs", ); diff --git a/src/Text/TextRenderer.h b/src/Text/TextRenderer.h index 998c30bdb..2d722f681 100644 --- a/src/Text/TextRenderer.h +++ b/src/Text/TextRenderer.h @@ -52,21 +52,23 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { public: /** * @brief Render text - * @param font %Font to use - * @param size %Font size - * @param text %Text to render + * @param font Font + * @param cache Glyph cache + * @param size Font size + * @param text Text to render * * Returns tuple with vertex positions, texture coordinates, indices * and rectangle spanning the rendered text. */ - static std::tuple, std::vector, std::vector, Rectangle> render(AbstractFont& font, Float size, const std::string& text); + static std::tuple, std::vector, std::vector, Rectangle> render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text); /** * @brief Constructor - * @param font %Font to use - * @param size %Font size + * @param font Font + * @param cache Glyph cache + * @param size Font size */ - AbstractTextRenderer(AbstractFont& font, Float size); + explicit AbstractTextRenderer(AbstractFont* const font, const GlyphCache* const cache, Float size); virtual ~AbstractTextRenderer() = 0; @@ -115,13 +117,14 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { #else private: #endif - static std::tuple MAGNUM_LOCAL render(AbstractFont& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); + static std::tuple MAGNUM_LOCAL render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); Mesh _mesh; Buffer vertexBuffer, indexBuffer; private: - AbstractFont& font; + AbstractFont* const font; + const GlyphCache* const cache; Float size; UnsignedInt _capacity; Rectangle _rectangle; @@ -140,46 +143,49 @@ methods, returning result either as data arrays or as fully configured mesh. The text can be then drawn by configuring text shader, binding font texture and drawing the mesh: @code -Text::Font font; -Shaders::VectorShader2D shader; -Buffer vertexBuffer, indexBuffer; +Text::AbstractFont* font; +Text::GlyphCache* cache; + +Shaders::VectorShader2D* shader; +Buffer *vertexBuffer, *indexBuffer; Mesh mesh; // Render the text Rectangle rectangle; -std::tie(mesh, rectangle) = Text::TextRenderer2D::render(font, 0.15f, - "Hello World!", &vertexBuffer, &indexBuffer, Buffer::Usage::StaticDraw); +std::tie(mesh, rectangle) = Text::TextRenderer2D::render(font, cache, 0.15f, + "Hello World!", vertexBuffer, indexBuffer, Buffer::Usage::StaticDraw); // Draw white text centered on the screen -shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-rectangle.width()/2.0f)) +shader->setTransformationProjectionMatrix(projection*Matrix3::translation(-rectangle.width()/2.0f)) ->setColor(Color3<>(1.0f)); ->use(); -font.texture()->bind(Shaders::VectorShader2D::FontTextureLayer); +glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer); mesh.draw(); @endcode -See render(Font&, Float, const std::string&) and -render(Font&, Float, const std::string&, Buffer*, Buffer*, Buffer::Usage) +See render(Font* const, const GlyphCache* const, Float, const std::string&) and +render(Font* const, const GlyphCache* const, Float, const std::string&, Buffer*, Buffer*, Buffer::Usage) for more information. While this method is sufficient for one-shot rendering of static texts, for mutable texts (e.g. FPS counters, chat messages) there is another approach that doesn't recreate everything on each text change: @code -Text::Font font; -Shaders::VectorShader2D shader; +Text::AbstractFont* font; +Text::GlyphCache* cache; +Shaders::VectorShader2D* shader; // Initialize renderer and reserve memory for enough glyphs -Text::TextRenderer2D renderer(font, 0.15f); +Text::TextRenderer2D renderer(font, cache, 0.15f); renderer.reserve(32, Buffer::Usage::DynamicDraw, Buffer::Usage::StaticDraw); // Update the text occasionally renderer.render("Hello World Countdown: 10"); // Draw the text centered on the screen -shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-renderer.rectangle().width()/2.0f)) +shader->setTransformationProjectionMatrix(projection*Matrix3::translation(-renderer.rectangle().width()/2.0f)) ->setColor(Color3<>(1.0f)); ->use(); -font.texture()->bind(Shaders::VectorShader2D::FontTextureLayer); +glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer); renderer.mesh().draw(); @endcode @@ -195,8 +201,9 @@ template class MAGNUM_TEXT_EXPORT TextRenderer: public A public: /** * @brief Render text - * @param font %Font to use - * @param size %Font size + * @param font Font + * @param cache Glyph cache + * @param size Font size * @param text %Text to render * @param vertexBuffer %Buffer where to store vertices * @param indexBuffer %Buffer where to store indices @@ -205,14 +212,15 @@ template class MAGNUM_TEXT_EXPORT TextRenderer: public A * Returns mesh prepared for use with Shaders::AbstractVectorShader * subclasses and rectangle spanning the rendered text. */ - static std::tuple render(AbstractFont& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); + static std::tuple render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); /** * @brief Constructor - * @param font %Font to use - * @param size %Font size + * @param font Font + * @param cache Glyph cache + * @param size Font size */ - TextRenderer(AbstractFont& font, Float size); + explicit TextRenderer(AbstractFont* const font, const GlyphCache* const cache, Float size); using AbstractTextRenderer::render; }; diff --git a/src/Texture.h b/src/Texture.h index e68ecaf56..9ab67c85b 100644 --- a/src/Texture.h +++ b/src/Texture.h @@ -331,7 +331,7 @@ template class Texture: public AbstractTexture { AbstractTexture::setMagnificationFilter(filter); return this; } - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES3 inline Texture* setBorderColor(const Color4<>& color) { AbstractTexture::setBorderColor(color); return this; diff --git a/src/TextureTools/CMakeLists.txt b/src/TextureTools/CMakeLists.txt index 701f299e5..01e7a6811 100644 --- a/src/TextureTools/CMakeLists.txt +++ b/src/TextureTools/CMakeLists.txt @@ -37,7 +37,11 @@ set(MagnumTextureTools_HEADERS magnumTextureToolsVisibility.h) -add_library(MagnumTextureTools SHARED ${MagnumTextureTools_SRCS}) +add_library(MagnumTextureTools ${SHARED_OR_STATIC} ${MagnumTextureTools_SRCS}) +if(BUILD_STATIC_PIC) + # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property + set_target_properties(MagnumTextureTools PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +endif() target_link_libraries(MagnumTextureTools Magnum) install(TARGETS MagnumTextureTools DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) diff --git a/src/TextureTools/DistanceField.cpp b/src/TextureTools/DistanceField.cpp index 7b5e0a6f6..c2804541c 100644 --- a/src/TextureTools/DistanceField.cpp +++ b/src/TextureTools/DistanceField.cpp @@ -84,7 +84,7 @@ DistanceFieldShader::DistanceFieldShader() { void distanceField(Texture2D* input, Texture2D* output, const Rectanglei& rectangle, const Int radius) { MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::EXT::framebuffer_object); - /** @todo Disable depth test and then enable it back (if was previously) */ + /** @todo Disable depth test, blending and then enable it back (if was previously) */ Framebuffer framebuffer(rectangle); framebuffer.attachTexture2D(Framebuffer::ColorAttachment(0), output, 0); diff --git a/src/Trade/AbstractImageConverter.cpp b/src/Trade/AbstractImageConverter.cpp new file mode 100644 index 000000000..23b3efeac --- /dev/null +++ b/src/Trade/AbstractImageConverter.cpp @@ -0,0 +1,56 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "AbstractImageConverter.h" + +#include + +namespace Magnum { namespace Trade { + +AbstractImageConverter::AbstractImageConverter() = default; + +AbstractImageConverter::AbstractImageConverter(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin): AbstractPlugin(manager, std::move(plugin)) {} + +Image2D* AbstractImageConverter::convertToImage(const Image2D* const) const { + CORRADE_ASSERT(features() & Feature::ConvertToImage, + "Trade::AbstractImageConverter::convertToImage(): feature advertised but not implemented", nullptr); + + CORRADE_ASSERT(false, "Trade::AbstractImageConverter::convertToImage(): feature not implemented", nullptr); +} + +std::pair AbstractImageConverter::convertToData(const Image2D* const) const { + CORRADE_ASSERT(features() & Feature::ConvertToData, + "Trade::AbstractImageConverter::convertToData(): feature advertised but not implemented", std::make_pair(nullptr, 0)); + + CORRADE_ASSERT(false, "Trade::AbstractImageConverter::convertToData(): feature not implemented", std::make_pair(nullptr, 0)); +} + +bool AbstractImageConverter::convertToFile(const Image2D* const, const std::string&) const { + CORRADE_ASSERT(features() & Feature::ConvertToFile, + "Trade::AbstractImageConverter::convertToFile(): feature advertised but not implemented", false); + + CORRADE_ASSERT(false, "Trade::AbstractImageConverter::convertToFile(): feature not implemented", false); +} + +}} diff --git a/src/Trade/AbstractImageConverter.h b/src/Trade/AbstractImageConverter.h new file mode 100644 index 000000000..5434618db --- /dev/null +++ b/src/Trade/AbstractImageConverter.h @@ -0,0 +1,119 @@ +#ifndef Magnum_Trade_AbstractImageConverter_h +#define Magnum_Trade_AbstractImageConverter_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class Magnum::Trade::AbstractImageConverter + */ + +#include + +#include "Magnum.h" +#include "Text/Text.h" +#include "magnumVisibility.h" + +namespace Magnum { namespace Trade { + +/** +@brief Base for image converter plugins + +Provides functionality for converting images between various internal formats +or compressing them. + +@section AbstractImageConverter-subclassing Subclassing + +Plugin implements function features() and one or more of convertToImage(), +convertToData() or convertToFile() functions based on what features are +supported. +*/ +class MAGNUM_EXPORT AbstractImageConverter: public Corrade::PluginManager::AbstractPlugin { + PLUGIN_INTERFACE("cz.mosra.magnum.Trade.AbstractImageConverter/0.1") + + public: + /** + * @brief Features supported by this converter + * + * @see Features, features() + */ + enum class Feature: UnsignedByte { + /** Converting to image with different format with convertToImage() */ + ConvertToImage = 1 << 0, + + /** Converting to data with convertToData() */ + ConvertToData = 1 << 1, + + /** Converting to file with convertToFile() */ + ConvertToFile = 1 << 2 + }; + + /** + * @brief Features supported by this converter + * + * @see features() + */ + typedef Corrade::Containers::EnumSet Features; + + /** @brief Default constructor */ + explicit AbstractImageConverter(); + + /** @brief Plugin manager constructor */ + explicit AbstractImageConverter(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin); + + /** @brief Features supported by this converter */ + virtual Features features() const = 0; + + /** + * @brief Convert image to different format + * + * Available only if @ref Feature "Feature::ConvertToImage" is supported. + * Returns converted image on success, `nullptr` otherwise. + * @see features(), convertToData(), convertToFile() + */ + virtual Image2D* convertToImage(const Image2D* const image) const; + + /** + * @brief Convert image to raw data + * + * Available only if @ref Feature "Feature::ConvertToData" is supported. + * Returns data pointer and size on success, `nullptr` otherwise. + * @see features(), convertToImage(), convertToFile() + */ + virtual std::pair convertToData(const Image2D* const image) const; + + /** + * @brief Convert image and save it to file + * + * Available only if @ref Feature "Feature::ConvertToFile" is supported. + * Returns `true` on success, `false` otherwise. + * @see features(), convertToImage(), convertToData() + */ + virtual bool convertToFile(const Image2D* const image, const std::string& filename) const; +}; + +CORRADE_ENUMSET_OPERATORS(AbstractImageConverter::Features) + +}} + +#endif diff --git a/src/Trade/AbstractImporter.cpp b/src/Trade/AbstractImporter.cpp index 5d7dcf24d..ce792335c 100644 --- a/src/Trade/AbstractImporter.cpp +++ b/src/Trade/AbstractImporter.cpp @@ -24,9 +24,7 @@ #include "AbstractImporter.h" -#include - -#include "Magnum.h" +#include namespace Magnum { namespace Trade { @@ -34,14 +32,55 @@ AbstractImporter::AbstractImporter() = default; AbstractImporter::AbstractImporter(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin): AbstractPlugin(manager, std::move(plugin)) {} -bool AbstractImporter::open(const std::string&) { - Error() << plugin() << "doesn't support opening files"; - return false; +bool AbstractImporter::openData(const void* const, const std::size_t) { + CORRADE_ASSERT(features() & Feature::OpenData, + "Trade::AbstractImporter::openData(): feature advertised but not implemented", nullptr); + + CORRADE_ASSERT(false, "Trade::AbstractImporter::openData(): feature not implemented", nullptr); } -bool AbstractImporter::open(std::istream&) { - Error() << plugin() << "doesn't support opening input streams"; - return false; +bool AbstractImporter::openFile(const std::string&) { + CORRADE_ASSERT(features() & Feature::OpenFile, + "Trade::AbstractImporter::openFile(): feature advertised but not implemented", nullptr); + + CORRADE_ASSERT(false, "Trade::AbstractImporter::openFile(): feature not implemented", nullptr); } +Int AbstractImporter::sceneForName(const std::string&) { return -1; } +std::string AbstractImporter::sceneName(UnsignedInt) { return {}; } +SceneData* AbstractImporter::scene(UnsignedInt) { return nullptr; } +Int AbstractImporter::lightForName(const std::string&) { return -1; } +std::string AbstractImporter::lightName(UnsignedInt) { return {}; } +LightData* AbstractImporter::light(UnsignedInt) { return nullptr; } +Int AbstractImporter::cameraForName(const std::string&) { return -1; } +std::string AbstractImporter::cameraName(UnsignedInt) { return {}; } +CameraData* AbstractImporter::camera(UnsignedInt) { return nullptr; } +Int AbstractImporter::object2DForName(const std::string&) { return -1; } +std::string AbstractImporter::object2DName(UnsignedInt) { return {}; } +ObjectData2D* AbstractImporter::object2D(UnsignedInt) { return nullptr; } +Int AbstractImporter::object3DForName(const std::string&) { return -1; } +std::string AbstractImporter::object3DName(UnsignedInt) { return {}; } +ObjectData3D* AbstractImporter::object3D(UnsignedInt) { return nullptr; } +Int AbstractImporter::mesh2DForName(const std::string&) { return -1; } +std::string AbstractImporter::mesh2DName(UnsignedInt) { return {}; } +MeshData2D* AbstractImporter::mesh2D(UnsignedInt) { return nullptr; } +Int AbstractImporter::mesh3DForName(const std::string&) { return -1; } +std::string AbstractImporter::mesh3DName(UnsignedInt) { return {}; } +MeshData3D* AbstractImporter::mesh3D(UnsignedInt) { return nullptr; } +Int AbstractImporter::materialForName(const std::string&) { return -1; } +std::string AbstractImporter::materialName(UnsignedInt) { return {}; } +AbstractMaterialData* AbstractImporter::material(UnsignedInt) { return nullptr; } +Int AbstractImporter::textureForName(const std::string&) { return -1; } +std::string AbstractImporter::textureName(UnsignedInt) { return {}; } +TextureData* AbstractImporter::texture(UnsignedInt) { return nullptr; } +Int AbstractImporter::image1DForName(const std::string&) { return -1; } +std::string AbstractImporter::image1DName(UnsignedInt) { return {}; } +ImageData1D* AbstractImporter::image1D(UnsignedInt) { return nullptr; } +Int AbstractImporter::image2DForName(const std::string&) { return -1; } +std::string AbstractImporter::image2DName(UnsignedInt) { return {}; } +ImageData2D* AbstractImporter::image2D(UnsignedInt) { return nullptr; } +Int AbstractImporter::image3DForName(const std::string&) { return -1; } +std::string AbstractImporter::image3DName(UnsignedInt) { return {}; } +ImageData3D* AbstractImporter::image3D(UnsignedInt) { return nullptr; } + }} diff --git a/src/Trade/AbstractImporter.h b/src/Trade/AbstractImporter.h index 1c6f1f754..54233c69b 100644 --- a/src/Trade/AbstractImporter.h +++ b/src/Trade/AbstractImporter.h @@ -54,7 +54,7 @@ some data. This is obviously not the case for single-data formats like images, as the file contains all data user wants to import. */ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlugin { - PLUGIN_INTERFACE("cz.mosra.magnum.Trade.AbstractImporter/0.2") + PLUGIN_INTERFACE("cz.mosra.magnum.Trade.AbstractImporter/0.2.1") public: /** @@ -62,13 +62,13 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * * @see Features, features() */ - enum class Feature { - OpenFile = 0x01, /**< Can open files specified by filename */ - OpenStream = 0x02 /**< Can open files from input streams */ + enum class Feature: UnsignedByte { + OpenData = 1 << 0, /**< Opening files from raw data */ + OpenFile = 1 << 1 /**< Opening files specified by filename */ }; /** @brief Set of features supported by this importer */ - typedef Corrade::Containers::EnumSet Features; + typedef Corrade::Containers::EnumSet Features; /** @brief Default constructor */ explicit AbstractImporter(); @@ -80,26 +80,38 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu virtual Features features() const = 0; /** - * @brief Open file - * @param filename Filename - * @return Whether the file was successfully opened + * @brief Open raw data + * @param data Data + * @param size Data size * * Closes previous file, if it was opened, and tries to open given - * file. See also @ref Feature "Feature::OpenFile". Default - * implementation prints message to error output and returns false. + * file. Available only if @ref Feature "Feature::OpenData" is + * supported. Returns `true` on success, `false` otherwise. + * @see features(), openFile() + */ + virtual bool openData(const void* const data, const std::size_t size); + + /** + * @brief Open raw data + * @param data Data + * + * Convenience alternative to above function useful when array size is + * known at compile-time. */ - virtual bool open(const std::string& filename); + template inline bool openData(const T(&data)[size]) { + return openData(data, size*sizeof(T)); + } /** - * @brief Open stream - * @param in Input stream - * @return Whether the file was successfully opened + * @brief Open file + * @param filename Filename * - * See also open(const std::string&), @ref Feature - * "Feature::OpenStream". Default implementation prints message to - * error output and returns false. + * Closes previous file, if it was opened, and tries to open given + * file. Available only if @ref Feature "Feature::OpenFile" is + * supported. Returns `true` on success, `false` otherwise. + * @see features(), openData() */ - virtual bool open(std::istream& in); + virtual bool openFile(const std::string& filename); /** @brief Close file */ virtual void close() = 0; @@ -112,7 +124,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief Default scene * * When there is more than one scene, returns ID of the default one. - * If there is no default scene, returns -1. + * If there is no default scene, returns `-1`. * * @note The function is not const, because the value will probably * be lazy-populated. @@ -125,7 +137,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief %Scene ID for given name * - * If no scene for given name exists, returns -1. + * If no scene for given name exists, returns `-1`. * @see sceneName() */ virtual Int sceneForName(const std::string& name); @@ -142,7 +154,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief %Scene * @param id %Scene ID, from range [0, sceneCount()). * - * Returns pointer to given scene or nullptr, if no such scene exists. + * Returns given scene or `nullptr` if import failed. Deleting the data + * is user responsibility. */ virtual SceneData* scene(UnsignedInt id); @@ -152,7 +165,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief %Light ID for given name * - * If no light for given name exists, returns -1. + * If no light for given name exists, returns `-1`. * @see lightName() */ virtual Int lightForName(const std::string& name); @@ -169,7 +182,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief %Light * @param id %Light ID, from range [0, lightCount()). * - * Returns pointer to given light or nullptr, if no such light exists. + * Returns given light or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual LightData* light(UnsignedInt id); @@ -179,7 +193,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief Camera ID for given name * - * If no camera for given name exists, returns -1. + * If no camera for given name exists, returns `-1`. * @see cameraName() */ virtual Int cameraForName(const std::string& name); @@ -196,8 +210,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief Camera * @param id Camera ID, from range [0, cameraCount()). * - * Returns pointer to given camera or nullptr, if no such camera - * exists. + * Returns given camera or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual CameraData* camera(UnsignedInt id); @@ -207,7 +221,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief Two-dimensional object ID for given name * - * If no scene for given name exists, returns -1. + * If no scene for given name exists, returns `-1`. * @see object2DName() */ virtual Int object2DForName(const std::string& name); @@ -224,8 +238,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief Two-dimensional object * @param id Object ID, from range [0, object2DCount()). * - * Returns pointer to given object or nullptr, if no such object - * exists. + * Returns given object or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual ObjectData2D* object2D(UnsignedInt id); @@ -235,7 +249,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief Three-dimensional object ID for given name * - * If no scene for given name exists, returns -1. + * If no scene for given name exists, returns `-1`. * @see object3DName() */ virtual Int object3DForName(const std::string& name); @@ -252,8 +266,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief Three-dimensional object * @param id Object ID, from range [0, object3DCount()). * - * Returns pointer to given object or nullptr, if no such object - * exists. + * Returns given object or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual ObjectData3D* object3D(UnsignedInt id); @@ -263,7 +277,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief Two-dimensional mesh ID for given name * - * If no mesh for given name exists, returns -1. + * If no mesh for given name exists, returns `-1`. * @see mesh2DName() */ virtual Int mesh2DForName(const std::string& name); @@ -280,7 +294,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief Two-dimensional mesh * @param id %Mesh ID, from range [0, mesh2DCount()). * - * Returns pointer to given mesh or nullptr, if no such mesh exists. + * Returns given mesh or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual MeshData2D* mesh2D(UnsignedInt id); @@ -290,7 +305,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief Three-dimensional mesh ID for given name * - * If no mesh for given name exists, returns -1. + * If no mesh for given name exists, returns `-1`. * @see mesh3DName() */ virtual Int mesh3DForName(const std::string& name); @@ -307,7 +322,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief Three-dimensional mesh * @param id %Mesh ID, from range [0, mesh3DCount()). * - * Returns pointer to given mesh or nullptr, if no such mesh exists. + * Returns given mesh or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual MeshData3D* mesh3D(UnsignedInt id); @@ -317,7 +333,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief Material ID for given name * - * If no material for given name exists, returns -1. + * If no material for given name exists, returns `-1`. * @see materialName() */ virtual Int materialForName(const std::string& name); @@ -334,8 +350,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief Material * @param id Material ID, from range [0, materialCount()). * - * Returns pointer to given material or nullptr, if no such material - * exists. + * Returns given material or `nullptr` if importing failed. Deleting + * the data is user responsibility. */ virtual AbstractMaterialData* material(UnsignedInt id); @@ -345,7 +361,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief %Texture ID for given name * - * If no texture for given name exists, returns -1. + * If no texture for given name exists, returns `-1`. * @see textureName() */ virtual Int textureForName(const std::string& name); @@ -362,8 +378,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief %Texture * @param id %Texture ID, from range [0, textureCount()). * - * Returns pointer to given texture or nullptr, if no such texture - * exists. + * Returns given texture or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual TextureData* texture(UnsignedInt id); @@ -373,7 +389,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief One-dimensional image ID for given name * - * If no image for given name exists, returns -1. + * If no image for given name exists, returns `-1`. * @see image1Dname() */ virtual Int image1DForName(const std::string& name); @@ -390,7 +406,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief One-dimensional image * @param id %Image ID, from range [0, image1DCount()). * - * Returns pointer to given image or nullptr, if no such image exists. + * Returns given image or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual ImageData1D* image1D(UnsignedInt id); @@ -400,7 +417,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief Two-dimensional image ID for given name * - * If no image for given name exists, returns -1. + * If no image for given name exists, returns `-1`. * @see image2DName() */ virtual Int image2DForName(const std::string& name); @@ -417,7 +434,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief Two-dimensional image * @param id %Image ID, from range [0, image2DCount()). * - * Returns pointer to given image or nullptr, if no such image exists. + * Returns given image or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual ImageData2D* image2D(UnsignedInt id); @@ -427,7 +445,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu /** * @brief Three-dimensional image ID for given name * - * If no image for given name exists, returns -1. + * If no image for given name exists, returns `-1`. * @see image3DName() */ virtual Int image3DForName(const std::string& name); @@ -444,7 +462,8 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu * @brief Three-dimensional image * @param id %Image ID, from range [0, image3DCount()). * - * Returns pointer to given image or nullptr, if no such image exists. + * Returns given image or `nullptr` if importing failed. Deleting the + * data is user responsibility. */ virtual ImageData3D* image3D(UnsignedInt id); @@ -453,44 +472,6 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::AbstractPlu CORRADE_ENUMSET_OPERATORS(AbstractImporter::Features) -/* Implementations for inline functions with unused parameters */ -inline Int AbstractImporter::sceneForName(const std::string&) { return -1; } -inline std::string AbstractImporter::sceneName(UnsignedInt) { return {}; } -inline SceneData* AbstractImporter::scene(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::lightForName(const std::string&) { return -1; } -inline std::string AbstractImporter::lightName(UnsignedInt) { return {}; } -inline LightData* AbstractImporter::light(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::cameraForName(const std::string&) { return -1; } -inline std::string AbstractImporter::cameraName(UnsignedInt) { return {}; } -inline CameraData* AbstractImporter::camera(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::object2DForName(const std::string&) { return -1; } -inline std::string AbstractImporter::object2DName(UnsignedInt) { return {}; } -inline ObjectData2D* AbstractImporter::object2D(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::object3DForName(const std::string&) { return -1; } -inline std::string AbstractImporter::object3DName(UnsignedInt) { return {}; } -inline ObjectData3D* AbstractImporter::object3D(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::mesh2DForName(const std::string&) { return -1; } -inline std::string AbstractImporter::mesh2DName(UnsignedInt) { return {}; } -inline MeshData2D* AbstractImporter::mesh2D(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::mesh3DForName(const std::string&) { return -1; } -inline std::string AbstractImporter::mesh3DName(UnsignedInt) { return {}; } -inline MeshData3D* AbstractImporter::mesh3D(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::materialForName(const std::string&) { return -1; } -inline std::string AbstractImporter::materialName(UnsignedInt) { return {}; } -inline AbstractMaterialData* AbstractImporter::material(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::textureForName(const std::string&) { return -1; } -inline std::string AbstractImporter::textureName(UnsignedInt) { return {}; } -inline TextureData* AbstractImporter::texture(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::image1DForName(const std::string&) { return -1; } -inline std::string AbstractImporter::image1DName(UnsignedInt) { return {}; } -inline ImageData1D* AbstractImporter::image1D(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::image2DForName(const std::string&) { return -1; } -inline std::string AbstractImporter::image2DName(UnsignedInt) { return {}; } -inline ImageData2D* AbstractImporter::image2D(UnsignedInt) { return nullptr; } -inline Int AbstractImporter::image3DForName(const std::string&) { return -1; } -inline std::string AbstractImporter::image3DName(UnsignedInt) { return {}; } -inline ImageData3D* AbstractImporter::image3D(UnsignedInt) { return nullptr; } - }} #endif diff --git a/src/Trade/AbstractMaterialData.cpp b/src/Trade/AbstractMaterialData.cpp new file mode 100644 index 000000000..39135072c --- /dev/null +++ b/src/Trade/AbstractMaterialData.cpp @@ -0,0 +1,33 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "AbstractMaterialData.h" + +namespace Magnum { namespace Trade { + +AbstractMaterialData::AbstractMaterialData(AbstractMaterialData::Type type): _type(type) {} + +AbstractMaterialData::~AbstractMaterialData() {} + +}} diff --git a/src/Trade/AbstractMaterialData.h b/src/Trade/AbstractMaterialData.h index 92630b427..7b26ee0b8 100644 --- a/src/Trade/AbstractMaterialData.h +++ b/src/Trade/AbstractMaterialData.h @@ -28,7 +28,7 @@ * @brief Class Magnum::Trade::AbstractMaterialData */ -#include +#include "magnumVisibility.h" namespace Magnum { namespace Trade { @@ -37,7 +37,7 @@ namespace Magnum { namespace Trade { Subclasses provide access to parameters for given material type. */ -class AbstractMaterialData { +class MAGNUM_EXPORT AbstractMaterialData { AbstractMaterialData(const AbstractMaterialData&) = delete; AbstractMaterialData(AbstractMaterialData&&) = delete; AbstractMaterialData& operator=(const AbstractMaterialData&) = delete; @@ -53,7 +53,7 @@ class AbstractMaterialData { * @brief Constructor * @param type Material type */ - inline AbstractMaterialData(Type type): _type(type) {} + explicit AbstractMaterialData(Type type); /** @brief Destructor */ virtual ~AbstractMaterialData() = 0; @@ -65,8 +65,6 @@ class AbstractMaterialData { Type _type; }; -inline AbstractMaterialData::~AbstractMaterialData() {} - }} #endif diff --git a/src/Trade/CMakeLists.txt b/src/Trade/CMakeLists.txt index 3e541fe28..954527c36 100644 --- a/src/Trade/CMakeLists.txt +++ b/src/Trade/CMakeLists.txt @@ -24,6 +24,7 @@ set(MagnumTrade_HEADERS AbstractImporter.h + AbstractImageConverter.h AbstractMaterialData.h CameraData.h ImageData.h diff --git a/src/Trade/ImageData.h b/src/Trade/ImageData.h index fbe6d8c4c..dbc6a548b 100644 --- a/src/Trade/ImageData.h +++ b/src/Trade/ImageData.h @@ -55,7 +55,7 @@ template class ImageData: public AbstractImage { * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - inline ImageData(const typename DimensionTraits::VectorType& size, Format format, Type type, GLvoid* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} + inline explicit ImageData(const typename DimensionTraits::VectorType& size, Format format, Type type, GLvoid* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} /** @brief Destructor */ inline ~ImageData() { delete[] _data; } @@ -64,12 +64,12 @@ template class ImageData: public AbstractImage { inline typename DimensionTraits::VectorType size() const { return _size; } /** @brief Pointer to raw data */ - inline void* data() { return _data; } - inline const void* data() const { return _data; } /**< @overload */ + inline unsigned char* data() { return _data; } + inline const unsigned char* data() const { return _data; } /**< @overload */ private: Math::Vector _size; - char* _data; + unsigned char* _data; }; /** @brief One-dimensional image */ diff --git a/src/Trade/MeshData2D.h b/src/Trade/MeshData2D.h index 696a3bd70..97369a79e 100644 --- a/src/Trade/MeshData2D.h +++ b/src/Trade/MeshData2D.h @@ -56,7 +56,7 @@ class MAGNUM_EXPORT MeshData2D { * @param textureCoords2D Array with two-dimensional texture * coordinate arrays or empty array */ - MeshData2D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> textureCoords2D); + explicit MeshData2D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> textureCoords2D); /** @brief Move constructor */ MeshData2D(MeshData2D&&); diff --git a/src/Trade/MeshData3D.h b/src/Trade/MeshData3D.h index 54fef49aa..61e02e807 100644 --- a/src/Trade/MeshData3D.h +++ b/src/Trade/MeshData3D.h @@ -57,7 +57,7 @@ class MAGNUM_EXPORT MeshData3D { * @param textureCoords2D Array with two-dimensional texture * coordinate arrays or empty array */ - MeshData3D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> normals, std::vector*> textureCoords2D); + explicit MeshData3D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> normals, std::vector*> textureCoords2D); /** @brief Move constructor */ MeshData3D(MeshData3D&&); diff --git a/src/Trade/MeshObjectData2D.cpp b/src/Trade/MeshObjectData2D.cpp new file mode 100644 index 000000000..bc52d77fe --- /dev/null +++ b/src/Trade/MeshObjectData2D.cpp @@ -0,0 +1,31 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "MeshObjectData2D.h" + +namespace Magnum { namespace Trade { + +MeshObjectData2D::MeshObjectData2D(std::vector children, const Matrix3& transformation, UnsignedInt instance, UnsignedInt material): ObjectData2D(std::move(children), transformation, InstanceType::Mesh, instance), _material(material) {} + +}} diff --git a/src/Trade/MeshObjectData2D.h b/src/Trade/MeshObjectData2D.h index d6137fffc..bbe38cd0c 100644 --- a/src/Trade/MeshObjectData2D.h +++ b/src/Trade/MeshObjectData2D.h @@ -38,7 +38,7 @@ namespace Magnum { namespace Trade { Provides access to material information for given mesh instance. @see MeshObjectData3D */ -class MeshObjectData2D: public ObjectData2D { +class MAGNUM_EXPORT MeshObjectData2D: public ObjectData2D { MeshObjectData2D(const MeshObjectData2D&) = delete; MeshObjectData2D(MeshObjectData2D&&) = delete; MeshObjectData2D& operator=(const MeshObjectData2D&) = delete; @@ -54,7 +54,7 @@ class MeshObjectData2D: public ObjectData2D { * * Creates object with mesh instance type. */ - inline MeshObjectData2D(const std::vector& children, const Matrix4& transformation, UnsignedInt instance, UnsignedInt material): ObjectData2D(children, transformation, InstanceType::Mesh, instance), _material(material) {} + explicit MeshObjectData2D(std::vector children, const Matrix3& transformation, UnsignedInt instance, UnsignedInt material); /** @brief Material ID */ inline UnsignedInt material() const { return _material; } diff --git a/src/Trade/MeshObjectData3D.cpp b/src/Trade/MeshObjectData3D.cpp new file mode 100644 index 000000000..dfd6e766b --- /dev/null +++ b/src/Trade/MeshObjectData3D.cpp @@ -0,0 +1,31 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "MeshObjectData3D.h" + +namespace Magnum { namespace Trade { + +MeshObjectData3D::MeshObjectData3D(std::vector< UnsignedInt > children, const Matrix4& transformation, UnsignedInt instance, UnsignedInt material): ObjectData3D(children, transformation, InstanceType::Mesh, instance), _material(material) {} + +}} diff --git a/src/Trade/MeshObjectData3D.h b/src/Trade/MeshObjectData3D.h index b692b51e2..636ad52b1 100644 --- a/src/Trade/MeshObjectData3D.h +++ b/src/Trade/MeshObjectData3D.h @@ -38,7 +38,7 @@ namespace Magnum { namespace Trade { Provides access to material information for given mesh instance. @see MeshObjectData2D */ -class MeshObjectData3D: public ObjectData3D { +class MAGNUM_EXPORT MeshObjectData3D: public ObjectData3D { MeshObjectData3D(const MeshObjectData3D&) = delete; MeshObjectData3D(MeshObjectData3D&&) = delete; MeshObjectData3D& operator=(const MeshObjectData3D&) = delete; @@ -54,7 +54,7 @@ class MeshObjectData3D: public ObjectData3D { * * Creates object with mesh instance type. */ - inline MeshObjectData3D(const std::vector& children, const Matrix4& transformation, UnsignedInt instance, UnsignedInt material): ObjectData3D(children, transformation, InstanceType::Mesh, instance), _material(material) {} + explicit MeshObjectData3D(std::vector children, const Matrix4& transformation, UnsignedInt instance, UnsignedInt material); /** @brief Material ID */ inline UnsignedInt material() const { return _material; } diff --git a/src/Trade/ObjectData2D.cpp b/src/Trade/ObjectData2D.cpp index 4c44c12f6..e4d8413b9 100644 --- a/src/Trade/ObjectData2D.cpp +++ b/src/Trade/ObjectData2D.cpp @@ -26,6 +26,12 @@ namespace Magnum { namespace Trade { +ObjectData2D::ObjectData2D(std::vector children, const Matrix3& transformation, ObjectData2D::InstanceType instanceType, UnsignedInt instanceId): _children(std::move(children)), _transformation(transformation), _instanceType(instanceType), _instanceId(instanceId) {} + +ObjectData2D::ObjectData2D(std::vector children, const Matrix3& transformation): _children(children), _transformation(transformation), _instanceType(InstanceType::Empty), _instanceId(-1) {} + +ObjectData2D::~ObjectData2D() = default; + #ifndef DOXYGEN_GENERATING_OUTPUT Debug operator<<(Debug debug, ObjectData2D::InstanceType value) { switch(value) { diff --git a/src/Trade/ObjectData2D.h b/src/Trade/ObjectData2D.h index 466b8d18e..46d2305f3 100644 --- a/src/Trade/ObjectData2D.h +++ b/src/Trade/ObjectData2D.h @@ -42,7 +42,7 @@ Provides access to object transformation and hierarchy. See also MeshObjectData2D, which is specialized for objects with mesh instance type. @see ObjectData3D */ -class ObjectData2D { +class MAGNUM_EXPORT ObjectData2D { ObjectData2D(const ObjectData2D&) = delete; ObjectData2D(ObjectData2D&&) = delete; ObjectData2D& operator=(const ObjectData2D&) = delete; @@ -63,17 +63,17 @@ class ObjectData2D { * @param instanceType Instance type * @param instanceId Instance ID */ - inline ObjectData2D(const std::vector& children, const Matrix3& transformation, InstanceType instanceType, UnsignedInt instanceId): _children(children), _transformation(transformation), _instanceType(instanceType), _instanceId(instanceId) {} + explicit ObjectData2D(std::vector children, const Matrix3& transformation, InstanceType instanceType, UnsignedInt instanceId); /** * @brief Constructor for empty instance * @param children Child objects * @param transformation Transformation (relative to parent) */ - inline ObjectData2D(const std::vector& children, const Matrix3& transformation): _children(children), _transformation(transformation), _instanceType(InstanceType::Empty), _instanceId(-1) {} + explicit ObjectData2D(std::vector children, const Matrix3& transformation); /** @brief Destructor */ - inline virtual ~ObjectData2D() {} + virtual ~ObjectData2D(); /** @brief Child objects */ inline std::vector& children() { return _children; } diff --git a/src/Trade/ObjectData3D.cpp b/src/Trade/ObjectData3D.cpp index b021b4305..81b5e2dde 100644 --- a/src/Trade/ObjectData3D.cpp +++ b/src/Trade/ObjectData3D.cpp @@ -26,6 +26,10 @@ namespace Magnum { namespace Trade { +ObjectData3D::ObjectData3D(std::vector children, const Matrix4& transformation, ObjectData3D::InstanceType instanceType, UnsignedInt instanceId): _children(std::move(children)), _transformation(transformation), _instanceType(instanceType), _instanceId(instanceId) {} + +ObjectData3D::ObjectData3D(std::vector children, const Matrix4& transformation): _children(std::move(children)), _transformation(transformation), _instanceType(InstanceType::Empty), _instanceId(-1) {} + #ifndef DOXYGEN_GENERATING_OUTPUT Debug operator<<(Debug debug, ObjectData3D::InstanceType value) { switch(value) { diff --git a/src/Trade/ObjectData3D.h b/src/Trade/ObjectData3D.h index 8b5be8a68..f6ac02923 100644 --- a/src/Trade/ObjectData3D.h +++ b/src/Trade/ObjectData3D.h @@ -42,7 +42,7 @@ Provides access to object transformation and hierarchy. See also MeshObjectData3D, which is specialized for objects with mesh instance type. @see ObjectData2D */ -class ObjectData3D { +class MAGNUM_EXPORT ObjectData3D { ObjectData3D(const ObjectData3D&) = delete; ObjectData3D(ObjectData3D&&) = delete; ObjectData3D& operator=(const ObjectData3D&) = delete; @@ -64,14 +64,14 @@ class ObjectData3D { * @param instanceType Instance type * @param instanceId Instance ID */ - inline ObjectData3D(const std::vector& children, const Matrix4& transformation, InstanceType instanceType, UnsignedInt instanceId): _children(children), _transformation(transformation), _instanceType(instanceType), _instanceId(instanceId) {} + explicit ObjectData3D(std::vector children, const Matrix4& transformation, InstanceType instanceType, UnsignedInt instanceId); /** * @brief Constructor for empty instance * @param children Child objects * @param transformation Transformation (relative to parent) */ - inline ObjectData3D(const std::vector& children, const Matrix4& transformation): _children(children), _transformation(transformation), _instanceType(InstanceType::Empty), _instanceId(-1) {} + explicit ObjectData3D(std::vector children, const Matrix4& transformation); /** @brief Destructor */ inline virtual ~ObjectData3D() {} diff --git a/src/Trade/PhongMaterialData.cpp b/src/Trade/PhongMaterialData.cpp new file mode 100644 index 000000000..5f640a4fa --- /dev/null +++ b/src/Trade/PhongMaterialData.cpp @@ -0,0 +1,31 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "PhongMaterialData.h" + +namespace Magnum { namespace Trade { + +PhongMaterialData::PhongMaterialData(const Vector3& ambientColor, const Vector3& diffuseColor, const Vector3& specularColor, Float shininess): AbstractMaterialData(Phong), _ambientColor(ambientColor), _diffuseColor(diffuseColor), _specularColor(specularColor), _shininess(shininess) {} + +}} diff --git a/src/Trade/PhongMaterialData.h b/src/Trade/PhongMaterialData.h index fed9fd310..dec88b406 100644 --- a/src/Trade/PhongMaterialData.h +++ b/src/Trade/PhongMaterialData.h @@ -37,7 +37,7 @@ namespace Magnum { namespace Trade { /** @brief Phong material data */ -class PhongMaterialData: public AbstractMaterialData { +class MAGNUM_EXPORT PhongMaterialData: public AbstractMaterialData { public: /** * @brief Constructor @@ -46,7 +46,7 @@ class PhongMaterialData: public AbstractMaterialData { * @param specularColor Specular color * @param shininess Shininess */ - PhongMaterialData(const Vector3& ambientColor, const Vector3& diffuseColor, const Vector3& specularColor, Float shininess): AbstractMaterialData(Phong), _ambientColor(ambientColor), _diffuseColor(diffuseColor), _specularColor(specularColor), _shininess(shininess) {} + explicit PhongMaterialData(const Vector3& ambientColor, const Vector3& diffuseColor, const Vector3& specularColor, Float shininess); /** @brief Ambient color */ inline Vector3 ambientColor() const { return _ambientColor; } diff --git a/src/Trade/SceneData.cpp b/src/Trade/SceneData.cpp new file mode 100644 index 000000000..889085bb0 --- /dev/null +++ b/src/Trade/SceneData.cpp @@ -0,0 +1,31 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "SceneData.h" + +namespace Magnum { namespace Trade { + +SceneData::SceneData(std::vector children2D, std::vector children3D): _children2D(std::move(children2D)), _children3D(std::move(children3D)) {} + +}} diff --git a/src/Trade/SceneData.h b/src/Trade/SceneData.h index 519573fb9..66b33c21a 100644 --- a/src/Trade/SceneData.h +++ b/src/Trade/SceneData.h @@ -32,6 +32,7 @@ #include #include "Types.h" +#include "magnumVisibility.h" namespace Magnum { namespace Trade { @@ -50,7 +51,7 @@ class MAGNUM_EXPORT SceneData { * @param children2D Two-dimensional child objects * @param children3D Three-dimensional child objects */ - inline SceneData(const std::vector& children2D, const std::vector& children3D): _children2D(children2D), _children3D(children3D) {} + explicit SceneData(std::vector children2D, std::vector children3D); /** @brief Two-dimensional child objects */ inline const std::vector& children2D() const { return _children2D; } diff --git a/src/Trade/Trade.h b/src/Trade/Trade.h index 37dc2ba1a..a12b47f79 100644 --- a/src/Trade/Trade.h +++ b/src/Trade/Trade.h @@ -34,6 +34,7 @@ namespace Magnum { namespace Trade { /** @todoc Remove `ifndef` when Doxygen is sane again */ #ifndef DOXYGEN_GENERATING_OUTPUT +class AbstractImageConverter; class AbstractImporter; class AbstractMaterialData; class CameraData; diff --git a/src/magnumConfigure.h.cmake b/src/magnumConfigure.h.cmake index 303ffee2d..b6fd0f9c0 100644 --- a/src/magnumConfigure.h.cmake +++ b/src/magnumConfigure.h.cmake @@ -24,6 +24,6 @@ #cmakedefine MAGNUM_TARGET_GLES #cmakedefine MAGNUM_TARGET_GLES2 +#cmakedefine MAGNUM_TARGET_GLES3 #cmakedefine MAGNUM_TARGET_DESKTOP_GLES #cmakedefine MAGNUM_TARGET_NACL -#cmakedefine MAGNUM_USE_HARFBUZZ