From 0424e249936a7af0d5bb6c4afcb74195b93ff359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 19:18:09 +0100 Subject: [PATCH 01/45] Reordered Renderer::Feature enum. --- src/Renderer.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Renderer.h b/src/Renderer.h index 5edbd0db2..e916fbc95 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,9 @@ class MAGNUM_EXPORT Renderer { * available in OpenGL ES. */ LogicOperation = GL_COLOR_LOGIC_OP, + #endif + #ifndef MAGNUM_TARGET_GLES /** * Depth clamping. If enabled, ignores near and far clipping plane. * @requires_gl32 %Extension @extension{ARB,depth_clamp} @@ -99,10 +106,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 */ }; /** From aa7bdc4b7a661ffc9ac0fc5be53e46e665c8ead9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 19:23:07 +0100 Subject: [PATCH 02/45] Added multisampling to Renderer::Feature enum. --- src/Renderer.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Renderer.h b/src/Renderer.h index e916fbc95..8726025ee 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -92,6 +92,14 @@ class MAGNUM_EXPORT Renderer { 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. From e8c7213d7ac6c0fa9e0f8d121d8ced2df3c622fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 19:32:28 +0100 Subject: [PATCH 03/45] Platform: multisampling support in Sdl2Application. --- src/Platform/Sdl2Application.cpp | 6 ++++++ src/Platform/Sdl2Application.h | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) 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; }; /** From b0336c240d006633d505b1e8e08bfbf05c22d1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 20:00:50 +0100 Subject: [PATCH 04/45] Platform: multisampling support in GlutApplication. --- src/Platform/GlutApplication.cpp | 8 +++++++- src/Platform/GlutApplication.h | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) 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; }; /** From f18297ab2bf09f49998a5e101ecbc69dcf38a73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 21:21:07 +0100 Subject: [PATCH 05/45] Define MAGNUM_TARGET_GLES3 if targetting ES and not ES2. Makes it easier to disable parts of the code than with this. And this would also not be future-proof: defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2) --- CMakeLists.txt | 8 +++++--- doc/cmake.dox | 1 + modules/FindMagnum.cmake | 5 +++++ src/Magnum.h | 17 +++++++++++++++-- src/magnumConfigure.h.cmake | 1 + 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ad8c561b..359a4b38e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,9 +86,11 @@ 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) diff --git a/doc/cmake.dox b/doc/cmake.dox index 6c3bcd853..342d67152 100644 --- a/doc/cmake.dox +++ b/doc/cmake.dox @@ -97,6 +97,7 @@ 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 diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 509e806e5..257d99612 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -47,6 +47,7 @@ # 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 @@ -119,6 +120,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) diff --git a/src/Magnum.h b/src/Magnum.h index c597594a1..837c6bb6e 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 diff --git a/src/magnumConfigure.h.cmake b/src/magnumConfigure.h.cmake index 303ffee2d..94fefcfd0 100644 --- a/src/magnumConfigure.h.cmake +++ b/src/magnumConfigure.h.cmake @@ -24,6 +24,7 @@ #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 From 76ac3529242b4b4f10775a743bbda989de1ff92a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 21:23:07 +0100 Subject: [PATCH 06/45] Added FindOpenGLES3.cmake module. Seems that Mesa has both ES2 and ES3 in the same libGLESv2.so. Weird. --- CMakeLists.txt | 4 +++- modules/FindOpenGLES3.cmake | 48 +++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 4 +++- 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 modules/FindOpenGLES3.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 359a4b38e..6c4383966 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,8 +76,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) diff --git a/modules/FindOpenGLES3.cmake b/modules/FindOpenGLES3.cmake new file mode 100644 index 000000000..d4b160162 --- /dev/null +++ b/modules/FindOpenGLES3.cmake @@ -0,0 +1,48 @@ +# - Find OpenGL ES 3 +# +# This module defines: +# +# OPENGLES3_FOUND - True if OpenGL ES 3 library is found +# OPENGLES3_LIBRARY - OpenGL ES 3 library +# OPENGLES3_INCLUDE_DIR - Include dir +# + +# +# 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. +# + +# Library +find_library(OPENGLES3_LIBRARY NAMES + GLESv2) # wtf? + +# Include dir +find_path(OPENGLES3_INCLUDE_DIR + NAMES gl3.h + PATH_SUFFIXES GLES3 +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args("OpenGLES3" DEFAULT_MSG + OPENGLES3_LIBRARY + OPENGLES3_INCLUDE_DIR +) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0d1df7c4d..7517288d5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -158,8 +158,10 @@ set(Magnum_LIBS ${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}) From 787e01940f98cb6723d3e653c8158c59e62b82fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 21:24:32 +0100 Subject: [PATCH 07/45] 16bit SNORM internal texture formats are not available in ES3. Don't know why I thought they were. --- src/AbstractTexture.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index da7c8d3eb..3935d69c8 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -314,39 +314,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. From 6b59c08c15db6790d80620c38ac4d0658847125f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 21:28:24 +0100 Subject: [PATCH 08/45] Some image & texture formats are available only through ES2 extensions. And ES3 has no extensions now. --- src/AbstractImage.cpp | 22 +++++++++++++++++++++- src/AbstractImage.h | 8 ++++++++ src/AbstractTexture.cpp | 2 ++ src/AbstractTexture.h | 8 ++++++++ src/Renderbuffer.h | 4 ++++ 5 files changed, 43 insertions(+), 1 deletion(-) 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 cdb5a305b..ab272feaf 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 3935d69c8..56b636c9f 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -653,6 +653,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 +664,7 @@ class MAGNUM_EXPORT AbstractTexture { #else RGB10 = GL_RGB10_EXT, #endif + #endif #ifndef MAGNUM_TARGET_GLES /** @@ -740,6 +742,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 +757,7 @@ class MAGNUM_EXPORT AbstractTexture { #else SRGB = GL_SRGB_EXT, #endif + #endif #ifndef MAGNUM_TARGET_GLES2 /** @@ -764,6 +768,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 +783,7 @@ class MAGNUM_EXPORT AbstractTexture { #else SRGBAlpha = GL_SRGB_ALPHA_EXT, #endif + #endif #ifndef MAGNUM_TARGET_GLES2 /** @@ -930,6 +936,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 +948,7 @@ class MAGNUM_EXPORT AbstractTexture { #else DepthComponent32 = GL_DEPTH_COMPONENT32_OES, #endif + #endif #ifndef MAGNUM_TARGET_GLES2 /** 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, From 59b6fb2904a81e65a7043aea0fb57b3b31b3d11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 21:28:58 +0100 Subject: [PATCH 09/45] Texture border & anisotropy is available only as ES2 extension. --- src/AbstractTexture.h | 6 ++++++ src/CubeMapTexture.h | 4 ++-- src/CubeMapTextureArray.h | 2 ++ src/Texture.h | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index 56b636c9f..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 }; /** @@ -995,6 +997,7 @@ class MAGNUM_EXPORT AbstractTexture { */ static Int maxSupportedLayerCount(); + #ifndef MAGNUM_TARGET_GLES3 /** * @brief Max supported anisotropy * @@ -1005,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) { @@ -1083,6 +1087,7 @@ class MAGNUM_EXPORT AbstractTexture { return this; } + #ifndef MAGNUM_TARGET_GLES3 /** * @brief Set border color * @return Pointer to self (for method chaining) @@ -1124,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/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/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; From deafd8f6eefe5aeb8dbd5f13bff1342161e27b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 21:31:39 +0100 Subject: [PATCH 10/45] No deprecated Buffer::map() in ES3. --- src/Buffer.cpp | 4 ++++ src/Buffer.h | 6 ++++++ 2 files changed, 10 insertions(+) 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); From cb067376402f5e53d79311825ef5d134856e92c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 21:39:00 +0100 Subject: [PATCH 11/45] glDrawBuffer() is not available in ES3. Using glDrawBuffers() also in this case. --- src/AbstractFramebuffer.cpp | 4 ++++ src/DefaultFramebuffer.h | 3 ++- src/Framebuffer.h | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) 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/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 26a2029ea..096d98752 100644 --- a/src/Framebuffer.h +++ b/src/Framebuffer.h @@ -262,7 +262,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) { From b55dba81683ef3ad90e9fb7d016cefc652d93c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 21:39:41 +0100 Subject: [PATCH 12/45] Platform: forgot to initialize variable. --- src/Platform/AbstractXApplication.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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); } From ab56470dec183446dfee52cc99a7d6f6b3569570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 22 Mar 2013 22:36:12 +0100 Subject: [PATCH 13/45] Updated PKGBUILDs and added ES2/ES3 variants. --- PKGBUILD | 9 ++++++--- PKGBUILD-es2 | 44 ++++++++++++++++++++++++++++++++++++++++++++ PKGBUILD-es2desktop | 45 +++++++++++++++++++++++++++++++++++++++++++++ PKGBUILD-es3 | 44 ++++++++++++++++++++++++++++++++++++++++++++ PKGBUILD-mingw32 | 7 ++++--- PKGBUILD-nacl | 2 +- PKGBUILD-release | 13 ++++++++----- 7 files changed, 152 insertions(+), 12 deletions(-) create mode 100644 PKGBUILD-es2 create mode 100644 PKGBUILD-es2desktop create mode 100644 PKGBUILD-es3 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() { From b1fcdf81af289e5a2610e1381995794782e77e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 26 Mar 2013 19:43:43 +0100 Subject: [PATCH 14/45] Trade: improved *Data constructors and destructors. * They are now deinlined into source files, as most of the classes have either heavy members (std::vector) or virtual methods. * All of them are explicit now (that should be already done, don't know why not). * Passing huge classes by value and using move constructors to avoid unnecessary copying. --- src/CMakeLists.txt | 7 ++++++- src/Trade/AbstractMaterialData.cpp | 33 ++++++++++++++++++++++++++++++ src/Trade/AbstractMaterialData.h | 8 +++----- src/Trade/ImageData.h | 2 +- src/Trade/MeshData2D.h | 2 +- src/Trade/MeshData3D.h | 2 +- src/Trade/MeshObjectData2D.cpp | 31 ++++++++++++++++++++++++++++ src/Trade/MeshObjectData2D.h | 4 ++-- src/Trade/MeshObjectData3D.cpp | 31 ++++++++++++++++++++++++++++ src/Trade/MeshObjectData3D.h | 4 ++-- src/Trade/ObjectData2D.cpp | 6 ++++++ src/Trade/ObjectData2D.h | 8 ++++---- src/Trade/ObjectData3D.cpp | 4 ++++ src/Trade/ObjectData3D.h | 6 +++--- src/Trade/PhongMaterialData.cpp | 31 ++++++++++++++++++++++++++++ src/Trade/PhongMaterialData.h | 4 ++-- src/Trade/SceneData.cpp | 31 ++++++++++++++++++++++++++++ src/Trade/SceneData.h | 3 ++- 18 files changed, 194 insertions(+), 23 deletions(-) create mode 100644 src/Trade/AbstractMaterialData.cpp create mode 100644 src/Trade/MeshObjectData2D.cpp create mode 100644 src/Trade/MeshObjectData3D.cpp create mode 100644 src/Trade/PhongMaterialData.cpp create mode 100644 src/Trade/SceneData.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7517288d5..589b97694 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -68,10 +68,15 @@ set(Magnum_SRCS Implementation/State.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) 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/ImageData.h b/src/Trade/ImageData.h index fbe6d8c4c..8fd76c525 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; } 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; } From 19cc27e2c00ae8cb13154a1236e9e92e35c9c73b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 12:57:42 +0100 Subject: [PATCH 15/45] Cleaned up OpenGL.h header. I didn't know that C preprocessor had `#elif` until now. Learning something new every day. --- src/OpenGL.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) 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 From 0f4e2f8a3719d8ffb62a2a47ac408f939cdaa89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 13:04:01 +0100 Subject: [PATCH 16/45] Text: made constructors explicit. --- src/Text/AbstractFont.h | 4 ++-- src/Text/FreeTypeFont.cpp | 2 +- src/Text/HarfBuzzFont.cpp | 2 +- src/Text/TextRenderer.h | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Text/AbstractFont.h b/src/Text/AbstractFont.h index aa22df3c1..631974f24 100644 --- a/src/Text/AbstractFont.h +++ b/src/Text/AbstractFont.h @@ -48,7 +48,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont { AbstractFont& operator=(const AbstractFont&&) = delete; public: - AbstractFont(); + explicit AbstractFont(); virtual ~AbstractFont() = 0; /** @brief %Font texture atlas */ @@ -81,7 +81,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/FreeTypeFont.cpp b/src/Text/FreeTypeFont.cpp index 4cd54b78c..c9d3e3f0a 100644 --- a/src/Text/FreeTypeFont.cpp +++ b/src/Text/FreeTypeFont.cpp @@ -40,7 +40,7 @@ namespace { class FreeTypeLayouter: public AbstractLayouter { public: - FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text); + explicit FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text); std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; diff --git a/src/Text/HarfBuzzFont.cpp b/src/Text/HarfBuzzFont.cpp index 6adf781e7..b3689017b 100644 --- a/src/Text/HarfBuzzFont.cpp +++ b/src/Text/HarfBuzzFont.cpp @@ -32,7 +32,7 @@ namespace { class HarfBuzzLayouter: public AbstractLayouter { public: - HarfBuzzLayouter(HarfBuzzFont& font, const Float size, const std::string& text); + explicit HarfBuzzLayouter(HarfBuzzFont& font, const Float size, const std::string& text); ~HarfBuzzLayouter(); std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; diff --git a/src/Text/TextRenderer.h b/src/Text/TextRenderer.h index 998c30bdb..bb38b5d89 100644 --- a/src/Text/TextRenderer.h +++ b/src/Text/TextRenderer.h @@ -66,7 +66,7 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { * @param font %Font to use * @param size %Font size */ - AbstractTextRenderer(AbstractFont& font, Float size); + explicit AbstractTextRenderer(AbstractFont& font, Float size); virtual ~AbstractTextRenderer() = 0; @@ -212,7 +212,7 @@ template class MAGNUM_TEXT_EXPORT TextRenderer: public A * @param font %Font to use * @param size %Font size */ - TextRenderer(AbstractFont& font, Float size); + explicit TextRenderer(AbstractFont& font, Float size); using AbstractTextRenderer::render; }; From 3c9c90ecf747e3df1fd51a3af00f395ce6a3e844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 13:05:21 +0100 Subject: [PATCH 17/45] Text: assert that also freeing up FreeType resources doesn't fail. --- src/Text/FreeTypeFont.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Text/FreeTypeFont.cpp b/src/Text/FreeTypeFont.cpp index c9d3e3f0a..f90a33fe4 100644 --- a/src/Text/FreeTypeFont.cpp +++ b/src/Text/FreeTypeFont.cpp @@ -57,7 +57,7 @@ FreeTypeFontRenderer::FreeTypeFontRenderer() { } FreeTypeFontRenderer::~FreeTypeFontRenderer() { - FT_Done_FreeType(_library); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_FreeType(_library) == 0); } FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): _size(size) { @@ -174,7 +174,7 @@ void FreeTypeFont::prerenderDistanceField(const std::string& characters, const V } FreeTypeFont::~FreeTypeFont() { - FT_Done_Face(_ftFont); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(_ftFont) == 0); } const std::tuple& FreeTypeFont::operator[](char32_t character) const { From 06971775cd0b5752f7bb718439563a613c52b8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 13:07:02 +0100 Subject: [PATCH 18/45] Text: properly compute glyph count in FreeTypeFont layouter. It was the same as byte count, thus working only for pure ASCII, not UTF-8. --- src/Text/FreeTypeFont.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Text/FreeTypeFont.cpp b/src/Text/FreeTypeFont.cpp index f90a33fe4..a5fd3c785 100644 --- a/src/Text/FreeTypeFont.cpp +++ b/src/Text/FreeTypeFont.cpp @@ -194,12 +194,12 @@ 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)); } + _glyphCount = glyphs.size(); } std::tuple FreeTypeLayouter::renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) { From da4ceb7cbcb7ada3e8223afae9c3af5460ccbaf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 13:09:45 +0100 Subject: [PATCH 19/45] Delete VAO in Mesh only if it is nonzero. glDeleteVertexArrays() was called even after the Mesh was moved out to another object. On my NVidia it was working but it might cause issues elsewhere. --- src/Mesh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 169a78ffd..d94e4d1a2 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 } From 28499ac9087e87f16bbd8303c30f81696969ce1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 13:11:25 +0100 Subject: [PATCH 20/45] Fixed outdated documentation. --- src/ImageWrapper.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageWrapper.h b/src/ImageWrapper.h index 132b2526f..3a20cfc6c 100644 --- a/src/ImageWrapper.h +++ b/src/ImageWrapper.h @@ -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) {} From 5c5c9d81d8bcc4673c468d4664b32358f15efaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 13:40:11 +0100 Subject: [PATCH 21/45] Added Renderer::flush() and Renderer::finish(). --- src/Renderer.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Renderer.h b/src/Renderer.h index 8726025ee..e6de10260 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -664,6 +664,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(); + } + + /*@}*/ }; } From 5ed38a37277ac75abd0a38c5de75d49ff792fdbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 14:00:50 +0100 Subject: [PATCH 22/45] Worked around Doxygen issues in Renderer documentation. The text was displayed as if it was code block. --- src/Renderer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Renderer.h b/src/Renderer.h index e6de10260..06f65be9b 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -394,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 */ From 6802b022eaa0fd3da2da4c7246cc6915e767dd9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 15:06:21 +0100 Subject: [PATCH 23/45] Added some TODOs. --- src/Math/Geometry/Rectangle.h | 2 ++ src/TextureTools/DistanceField.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) 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/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); From cc19e789830ea17e5b8606f137daee9321f9e515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 15:00:26 +0100 Subject: [PATCH 24/45] Text: moved glyph caching into separate classes. The API is similar for both basic and distance field caching. --- src/Text/AbstractFont.h | 28 ++--- src/Text/CMakeLists.txt | 4 + src/Text/DistanceFieldGlyphCache.cpp | 66 +++++++++++ src/Text/DistanceFieldGlyphCache.h | 92 ++++++++++++++++ src/Text/FreeTypeFont.cpp | 103 +++++------------- src/Text/FreeTypeFont.h | 85 +++------------ src/Text/GlyphCache.cpp | 91 ++++++++++++++++ src/Text/GlyphCache.h | 157 +++++++++++++++++++++++++++ src/Text/HarfBuzzFont.cpp | 21 +++- src/Text/HarfBuzzFont.h | 16 +-- src/Text/Text.h | 2 + src/Text/TextRenderer.cpp | 18 +-- src/Text/TextRenderer.h | 66 ++++++----- 13 files changed, 541 insertions(+), 208 deletions(-) create mode 100644 src/Text/DistanceFieldGlyphCache.cpp create mode 100644 src/Text/DistanceFieldGlyphCache.h create mode 100644 src/Text/GlyphCache.cpp create mode 100644 src/Text/GlyphCache.h diff --git a/src/Text/AbstractFont.h b/src/Text/AbstractFont.h index 631974f24..33456bfc4 100644 --- a/src/Text/AbstractFont.h +++ b/src/Text/AbstractFont.h @@ -51,22 +51,24 @@ class MAGNUM_TEXT_EXPORT AbstractFont { explicit AbstractFont(); virtual ~AbstractFont() = 0; - /** @brief %Font texture atlas */ - inline Texture2D& texture() { return _texture; } - /** - * @brief Layout the text using fon't own layouter - * @param size %Font size - * @param text Text to layout + * @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 AbstractLayouter* layout(const Float size, const std::string& text) = 0; + virtual void createGlyphCache(GlyphCache* const cache, const std::string& characters) = 0; - #ifdef DOXYGEN_GENERATING_OUTPUT - private: - #else - protected: - #endif - Texture2D _texture; + /** + * @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 GlyphCache* const cache, const Float size, const std::string& text) = 0; }; /** diff --git a/src/Text/CMakeLists.txt b/src/Text/CMakeLists.txt index 517ebbea2..127a32f06 100644 --- a/src/Text/CMakeLists.txt +++ b/src/Text/CMakeLists.txt @@ -27,10 +27,14 @@ include_directories(${FREETYPE_INCLUDE_DIRS}) set(MagnumText_SRCS AbstractFont.cpp + DistanceFieldGlyphCache.cpp + GlyphCache.cpp FreeTypeFont.cpp TextRenderer.cpp) set(MagnumText_HEADERS AbstractFont.h + DistanceFieldGlyphCache.h + GlyphCache.h FreeTypeFont.h Text.h TextRenderer.h 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 index a5fd3c785..d60d86f90 100644 --- a/src/Text/FreeTypeFont.cpp +++ b/src/Text/FreeTypeFont.cpp @@ -23,6 +23,7 @@ */ #include "FreeTypeFont.h" +#include "GlyphCache.h" #include #include @@ -40,14 +41,15 @@ namespace { class FreeTypeLayouter: public AbstractLayouter { public: - explicit FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text); + explicit FreeTypeLayouter(FreeTypeFont& font, const GlyphCache* const cache, const Float size, const std::string& text); std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; private: FreeTypeFont& font; - std::vector glyphs; + const GlyphCache* const cache; const Float size; + std::vector glyphs; }; } @@ -62,34 +64,15 @@ FreeTypeFontRenderer::~FreeTypeFontRenderer() { 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(); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, _size*64, 100, 100) == 0); } 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(); - +void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string& characters) { /** @bug Crash when atlas is too small */ /* Get glyph codes from characters */ @@ -107,7 +90,6 @@ void FreeTypeFont::prerenderInternal(const std::string& characters, const Vector 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(FT_UInt c: charIndices) { @@ -116,12 +98,11 @@ void FreeTypeFont::prerenderInternal(const std::string& characters, const Vector } /* Create texture atlas */ - const std::vector charPositions = TextureTools::atlas(atlasSize, charSizes, padding); + const std::vector charPositions = cache->reserve(charSizes); /* Render all characters to the atlas and create character map */ - glyphs.reserve(charPositions.size()); - unsigned char* pixmap = new unsigned char[atlasSize.product()](); - Image2D image(atlasSize, Image2D::Format::Red, Image2D::Type::UnsignedByte, pixmap); + unsigned char* pixmap = new unsigned char[cache->textureSize().product()](); + Image2D image(cache->textureSize(), 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 */ @@ -135,63 +116,29 @@ void FreeTypeFont::prerenderInternal(const std::string& characters, const Vector 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); -} + pixmap[yout*cache->textureSize().x() + xout] = bitmap.buffer[(bitmap.rows-yin-1)*bitmap.width + xin]; -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); + /* Insert glyph parameters into cache */ + cache->insert(charIndices[i], + Vector2i(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].height()), + charPositions[i]); + } - /* Create distance field from input texture */ - _texture.setStorage(1, Texture2D::InternalFormat::R8, atlasSize); - TextureTools::distanceField(&input, &_texture, Rectanglei::fromSize({}, atlasSize), radius); + /* Set cache image */ + cache->setImage({}, &image); } FreeTypeFont::~FreeTypeFont() { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(_ftFont) == 0); } -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); +AbstractLayouter* FreeTypeFont::layout(const GlyphCache* const cache, const Float size, const std::string& text) { + return new FreeTypeLayouter(*this, cache, size, text); } namespace { -FreeTypeLayouter::FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text): font(font), size(size) { +FreeTypeLayouter::FreeTypeLayouter(FreeTypeFont& font, const GlyphCache* const cache, const Float size, const std::string& text): font(font), cache(cache), size(size) { /* Get glyph codes from characters */ glyphs.reserve(text.size()); for(std::size_t i = 0; i != text.size(); ) { @@ -204,8 +151,14 @@ FreeTypeLayouter::FreeTypeLayouter(FreeTypeFont& font, const Float size, const s 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]]; + Vector2i position; + Rectanglei rectangle; + std::tie(position, rectangle) = (*cache)[glyphs[i]]; + + Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/font.size(), + Vector2(rectangle.size())/font.size()); + Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache->textureSize(), + Vector2(rectangle.topRight())/cache->textureSize()); /* Load glyph */ CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font.font(), glyphs[i], FT_LOAD_DEFAULT) == 0); diff --git a/src/Text/FreeTypeFont.h b/src/Text/FreeTypeFont.h index 223698995..faa4f1d50 100644 --- a/src/Text/FreeTypeFont.h +++ b/src/Text/FreeTypeFont.h @@ -66,97 +66,50 @@ class MAGNUM_TEXT_EXPORT FreeTypeFontRenderer { /** @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. +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. @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). +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. */ 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 + * @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 + * @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 */ + /** @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; + void createGlyphCache(GlyphCache* const cache, const std::string& characters) override; + AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) override; #ifdef DOXYGEN_GENERATING_OUTPUT private: @@ -166,10 +119,6 @@ class MAGNUM_TEXT_EXPORT FreeTypeFont: public AbstractFont { 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; }; 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 index b3689017b..4115cfee2 100644 --- a/src/Text/HarfBuzzFont.cpp +++ b/src/Text/HarfBuzzFont.cpp @@ -26,19 +26,22 @@ #include +#include "GlyphCache.h" + namespace Magnum { namespace Text { namespace { class HarfBuzzLayouter: public AbstractLayouter { public: - explicit HarfBuzzLayouter(HarfBuzzFont& font, const Float size, const std::string& text); + explicit HarfBuzzLayouter(HarfBuzzFont& font, const GlyphCache* const cache, const Float size, const std::string& text); ~HarfBuzzLayouter(); std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; private: const HarfBuzzFont& font; + const GlyphCache* const cache; hb_buffer_t* buffer; hb_glyph_info_t* glyphInfo; hb_glyph_position_t* glyphPositions; @@ -64,13 +67,13 @@ HarfBuzzFont::~HarfBuzzFont() { hb_font_destroy(_hbFont); } -AbstractLayouter* HarfBuzzFont::layout(const Float size, const std::string& text) { - return new HarfBuzzLayouter(*this, size, text); +AbstractLayouter* HarfBuzzFont::layout(const GlyphCache* const cache, const Float size, const std::string& text) { + return new HarfBuzzLayouter(*this, cache, size, text); } namespace { -HarfBuzzLayouter::HarfBuzzLayouter(HarfBuzzFont& font, const Float size, const std::string& text): font(font), size(size) { +HarfBuzzLayouter::HarfBuzzLayouter(HarfBuzzFont& font, const GlyphCache* const cache, const Float size, const std::string& text): font(font), cache(cache), size(size) { /* Prepare HarfBuzz buffer */ buffer = hb_buffer_create(); hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); @@ -92,8 +95,14 @@ HarfBuzzLayouter::~HarfBuzzLayouter() { 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]; + Vector2i position; + Rectanglei rectangle; + std::tie(position, rectangle) = (*cache)[glyphInfo[i].codepoint]; + + Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/font.size(), + Vector2(rectangle.size())/font.size()); + Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache->textureSize(), + Vector2(rectangle.topRight())/cache->textureSize()); /* Glyph offset and advance to next glyph in normalized coordinates */ Vector2 offset = Vector2(glyphPositions[i].x_offset, diff --git a/src/Text/HarfBuzzFont.h b/src/Text/HarfBuzzFont.h index b34b8ab77..d8e0277c6 100644 --- a/src/Text/HarfBuzzFont.h +++ b/src/Text/HarfBuzzFont.h @@ -51,18 +51,18 @@ 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 + * @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 + * @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); @@ -71,7 +71,7 @@ class MAGNUM_TEXT_EXPORT HarfBuzzFont: public FreeTypeFont { /** @brief HarfBuzz font handle */ inline hb_font_t* font() { return _hbFont; } - AbstractLayouter* layout(const Float size, const std::string& text) override; + AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) override; private: void MAGNUM_TEXT_LOCAL finishConstruction(); diff --git a/src/Text/Text.h b/src/Text/Text.h index 7f18557d9..85087ad11 100644 --- a/src/Text/Text.h +++ b/src/Text/Text.h @@ -36,6 +36,8 @@ namespace Magnum { namespace Text { class AbstractFont; class AbstractLayouter; +class DistanceFieldGlyphCache; +class GlyphCache; class FreeTypeFontRenderer; class FreeTypeFont; 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 bb38b5d89..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 */ - explicit 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 */ - explicit TextRenderer(AbstractFont& font, Float size); + explicit TextRenderer(AbstractFont* const font, const GlyphCache* const cache, Float size); using AbstractTextRenderer::render; }; From 57adfac002fe52b2095b65f5efaa11bd5fa7d57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 15:15:46 +0100 Subject: [PATCH 25/45] Text: moved font size to abstract base. --- src/Text/AbstractFont.cpp | 4 +++- src/Text/AbstractFont.h | 8 +++++++- src/Text/FreeTypeFont.cpp | 8 ++++---- src/Text/FreeTypeFont.h | 6 ------ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Text/AbstractFont.cpp b/src/Text/AbstractFont.cpp index 31214e636..049341ab9 100644 --- a/src/Text/AbstractFont.cpp +++ b/src/Text/AbstractFont.cpp @@ -26,10 +26,12 @@ namespace Magnum { namespace Text { -AbstractFont::AbstractFont() {} +AbstractFont::AbstractFont(Float size): _size(size) {} + AbstractFont::~AbstractFont() {} AbstractLayouter::AbstractLayouter(): _glyphCount(0) {} + AbstractLayouter::~AbstractLayouter() {} }} diff --git a/src/Text/AbstractFont.h b/src/Text/AbstractFont.h index 33456bfc4..cedfef2c9 100644 --- a/src/Text/AbstractFont.h +++ b/src/Text/AbstractFont.h @@ -48,9 +48,12 @@ class MAGNUM_TEXT_EXPORT AbstractFont { AbstractFont& operator=(const AbstractFont&&) = delete; public: - explicit AbstractFont(); + explicit AbstractFont(Float size); virtual ~AbstractFont() = 0; + /** @brief Font size */ + inline Float size() const { return _size; } + /** * @brief Create glyph cache for given character set * @param cache Glyph cache instance @@ -69,6 +72,9 @@ class MAGNUM_TEXT_EXPORT AbstractFont { * @see createGlyphCache() */ virtual AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) = 0; + + private: + Float _size; }; /** diff --git a/src/Text/FreeTypeFont.cpp b/src/Text/FreeTypeFont.cpp index d60d86f90..ba01446c9 100644 --- a/src/Text/FreeTypeFont.cpp +++ b/src/Text/FreeTypeFont.cpp @@ -62,14 +62,14 @@ FreeTypeFontRenderer::~FreeTypeFontRenderer() { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_FreeType(_library) == 0); } -FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): _size(size) { +FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): AbstractFont(size) { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &_ftFont) == 0); - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, _size*64, 100, 100) == 0); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, size*64, 100, 100) == 0); } -FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): _size(size) { +FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): AbstractFont(size) { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &_ftFont) == 0); - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, _size*64, 100, 100) == 0); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, size*64, 100, 100) == 0); } void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string& characters) { diff --git a/src/Text/FreeTypeFont.h b/src/Text/FreeTypeFont.h index faa4f1d50..e6d52c176 100644 --- a/src/Text/FreeTypeFont.h +++ b/src/Text/FreeTypeFont.h @@ -102,9 +102,6 @@ class MAGNUM_TEXT_EXPORT FreeTypeFont: public AbstractFont { ~FreeTypeFont(); - /** @brief Font size */ - inline Float size() const { return _size; } - /** @brief FreeType font handle */ inline FT_Face font() { return _ftFont; } @@ -117,9 +114,6 @@ class MAGNUM_TEXT_EXPORT FreeTypeFont: public AbstractFont { protected: #endif FT_Face _ftFont; - - private: - Float _size; }; }} From e222fc5eb83b2a3bd1b8ce0bc93c08f9f51070d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 16:26:39 +0100 Subject: [PATCH 26/45] Text: simplified font layouters, removed remaining public API. Now the font classes are prepared to be plugins. --- src/Text/FreeTypeFont.cpp | 46 +++++++++++++++++++-------------------- src/Text/FreeTypeFont.h | 5 +---- src/Text/HarfBuzzFont.cpp | 28 ++++++++++++------------ src/Text/HarfBuzzFont.h | 5 +---- 4 files changed, 39 insertions(+), 45 deletions(-) diff --git a/src/Text/FreeTypeFont.cpp b/src/Text/FreeTypeFont.cpp index ba01446c9..061bb3cbb 100644 --- a/src/Text/FreeTypeFont.cpp +++ b/src/Text/FreeTypeFont.cpp @@ -41,14 +41,14 @@ namespace { class FreeTypeLayouter: public AbstractLayouter { public: - explicit FreeTypeLayouter(FreeTypeFont& font, const GlyphCache* const cache, const Float size, const std::string& text); + explicit FreeTypeLayouter(FT_Face ftFont, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text); std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; private: - FreeTypeFont& font; + FT_Face font; const GlyphCache* const cache; - const Float size; + const Float fontSize, textSize; std::vector glyphs; }; @@ -63,13 +63,13 @@ FreeTypeFontRenderer::~FreeTypeFontRenderer() { } FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): AbstractFont(size) { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &_ftFont) == 0); - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, size*64, 100, 100) == 0); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &ftFont) == 0); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(ftFont, 0, size*64, 100, 100) == 0); } FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): AbstractFont(size) { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &_ftFont) == 0); - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, size*64, 100, 100) == 0); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &ftFont) == 0); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(ftFont, 0, size*64, 100, 100) == 0); } void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string& characters) { @@ -82,7 +82,7 @@ void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string& 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)); + charIndices.push_back(FT_Get_Char_Index(ftFont, codepoint)); } /* Remove duplicates (e.g. uppercase and lowercase mapped to same glyph) */ @@ -93,8 +93,8 @@ void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string& std::vector charSizes; charSizes.reserve(charIndices.size()); for(FT_UInt c: charIndices) { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(_ftFont, c, FT_LOAD_DEFAULT) == 0); - charSizes.push_back(Vector2i(_ftFont->glyph->metrics.width, _ftFont->glyph->metrics.height)/64); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(ftFont, c, FT_LOAD_DEFAULT) == 0); + charSizes.push_back(Vector2i(ftFont->glyph->metrics.width, ftFont->glyph->metrics.height)/64); } /* Create texture atlas */ @@ -106,8 +106,8 @@ void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string& 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); + 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 */ @@ -129,22 +129,22 @@ void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string& } FreeTypeFont::~FreeTypeFont() { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(_ftFont) == 0); + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(ftFont) == 0); } AbstractLayouter* FreeTypeFont::layout(const GlyphCache* const cache, const Float size, const std::string& text) { - return new FreeTypeLayouter(*this, cache, size, text); + return new FreeTypeLayouter(ftFont, cache, this->size(), size, text); } namespace { -FreeTypeLayouter::FreeTypeLayouter(FreeTypeFont& font, const GlyphCache* const cache, const Float size, const std::string& text): font(font), cache(cache), size(size) { +FreeTypeLayouter::FreeTypeLayouter(FT_Face font, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text): font(font), cache(cache), fontSize(fontSize), textSize(textSize) { /* Get glyph codes from characters */ glyphs.reserve(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)); + glyphs.push_back(FT_Get_Char_Index(font, codepoint)); } _glyphCount = glyphs.size(); } @@ -155,22 +155,22 @@ std::tuple FreeTypeLayouter::renderGlyph(const Ve Rectanglei rectangle; std::tie(position, rectangle) = (*cache)[glyphs[i]]; - Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/font.size(), - Vector2(rectangle.size())/font.size()); + Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/fontSize, + Vector2(rectangle.size())/fontSize); Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache->textureSize(), Vector2(rectangle.topRight())/cache->textureSize()); /* Load glyph */ - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font.font(), glyphs[i], FT_LOAD_DEFAULT) == 0); - const FT_GlyphSlot slot = font.font()->glyph; + CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font, glyphs[i], FT_LOAD_DEFAULT) == 0); + const FT_GlyphSlot slot = font->glyph; Vector2 offset = Vector2(0, 0); /** @todo really? */ - Vector2 advance = Vector2(slot->advance.x, slot->advance.y)/(64*font.size()); + Vector2 advance = Vector2(slot->advance.x, slot->advance.y)/(64*fontSize); /* 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); + (cursorPosition + offset + Vector2(texturePosition.left(), texturePosition.bottom()))*textSize, + texturePosition.size()*textSize); return std::make_tuple(quadPosition, textureCoordinates, advance); } diff --git a/src/Text/FreeTypeFont.h b/src/Text/FreeTypeFont.h index e6d52c176..273834739 100644 --- a/src/Text/FreeTypeFont.h +++ b/src/Text/FreeTypeFont.h @@ -102,9 +102,6 @@ class MAGNUM_TEXT_EXPORT FreeTypeFont: public AbstractFont { ~FreeTypeFont(); - /** @brief FreeType font handle */ - inline FT_Face font() { return _ftFont; } - void createGlyphCache(GlyphCache* const cache, const std::string& characters) override; AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) override; @@ -113,7 +110,7 @@ class MAGNUM_TEXT_EXPORT FreeTypeFont: public AbstractFont { #else protected: #endif - FT_Face _ftFont; + FT_Face ftFont; }; }} diff --git a/src/Text/HarfBuzzFont.cpp b/src/Text/HarfBuzzFont.cpp index 4115cfee2..8eb19c112 100644 --- a/src/Text/HarfBuzzFont.cpp +++ b/src/Text/HarfBuzzFont.cpp @@ -34,18 +34,18 @@ namespace { class HarfBuzzLayouter: public AbstractLayouter { public: - explicit HarfBuzzLayouter(HarfBuzzFont& font, const GlyphCache* const cache, const Float size, const std::string& text); + explicit HarfBuzzLayouter(hb_font_t* const font, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text); ~HarfBuzzLayouter(); std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; private: - const HarfBuzzFont& font; + const hb_font_t* const font; const GlyphCache* const cache; + const Float fontSize, textSize; hb_buffer_t* buffer; hb_glyph_info_t* glyphInfo; hb_glyph_position_t* glyphPositions; - const Float size; }; } @@ -60,20 +60,20 @@ HarfBuzzFont::HarfBuzzFont(FreeTypeFontRenderer& renderer, const unsigned char* void HarfBuzzFont::finishConstruction() { /* Create Harfbuzz font */ - _hbFont = hb_ft_font_create(_ftFont, nullptr); + hbFont = hb_ft_font_create(ftFont, nullptr); } HarfBuzzFont::~HarfBuzzFont() { - hb_font_destroy(_hbFont); + hb_font_destroy(hbFont); } AbstractLayouter* HarfBuzzFont::layout(const GlyphCache* const cache, const Float size, const std::string& text) { - return new HarfBuzzLayouter(*this, cache, size, text); + return new HarfBuzzLayouter(hbFont, cache, this->size(), size, text); } namespace { -HarfBuzzLayouter::HarfBuzzLayouter(HarfBuzzFont& font, const GlyphCache* const cache, const Float size, const std::string& text): font(font), cache(cache), size(size) { +HarfBuzzLayouter::HarfBuzzLayouter(hb_font_t* const font, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text): font(font), cache(cache), fontSize(fontSize), textSize(textSize) { /* Prepare HarfBuzz buffer */ buffer = hb_buffer_create(); hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); @@ -82,7 +82,7 @@ HarfBuzzLayouter::HarfBuzzLayouter(HarfBuzzFont& font, const GlyphCache* const c /* Layout the text */ hb_buffer_add_utf8(buffer, text.c_str(), -1, 0, -1); - hb_shape(font.font(), buffer, nullptr, 0); + hb_shape(font, buffer, nullptr, 0); glyphInfo = hb_buffer_get_glyph_infos(buffer, &_glyphCount); glyphPositions = hb_buffer_get_glyph_positions(buffer, &_glyphCount); @@ -99,22 +99,22 @@ std::tuple HarfBuzzLayouter::renderGlyph(const Ve Rectanglei rectangle; std::tie(position, rectangle) = (*cache)[glyphInfo[i].codepoint]; - Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/font.size(), - Vector2(rectangle.size())/font.size()); + Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/fontSize, + Vector2(rectangle.size())/fontSize); Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache->textureSize(), Vector2(rectangle.topRight())/cache->textureSize()); /* Glyph offset and advance to next glyph in normalized coordinates */ Vector2 offset = Vector2(glyphPositions[i].x_offset, - glyphPositions[i].y_offset)/(64*font.size()); + glyphPositions[i].y_offset)/(64*fontSize); Vector2 advance = Vector2(glyphPositions[i].x_advance, - glyphPositions[i].y_advance)/(64*font.size()); + glyphPositions[i].y_advance)/(64*fontSize); /* 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); + (cursorPosition + offset + Vector2(texturePosition.left(), texturePosition.bottom()))*textSize, + texturePosition.size()*textSize); return std::make_tuple(quadPosition, textureCoordinates, advance); } diff --git a/src/Text/HarfBuzzFont.h b/src/Text/HarfBuzzFont.h index d8e0277c6..96dd60ab7 100644 --- a/src/Text/HarfBuzzFont.h +++ b/src/Text/HarfBuzzFont.h @@ -68,15 +68,12 @@ class MAGNUM_TEXT_EXPORT HarfBuzzFont: public FreeTypeFont { ~HarfBuzzFont(); - /** @brief HarfBuzz font handle */ - inline hb_font_t* font() { return _hbFont; } - AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) override; private: void MAGNUM_TEXT_LOCAL finishConstruction(); - hb_font_t* _hbFont; + hb_font_t* hbFont; }; }} From cda51f3dd5e0e19b952ba551343035939f0ce500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 28 Mar 2013 23:57:14 +0100 Subject: [PATCH 27/45] Text: moved FreeType and HarfBuzz fonts into plugins. In next few commits AbstractFont will become plugin interface. Font implementations are now in magnum-plugins repository. Removed all traces of FreeType and HarfBuzz dependencies. --- CMakeLists.txt | 6 -- doc/building.dox | 7 -- doc/cmake.dox | 5 +- modules/FindHarfBuzz.cmake | 57 ----------- modules/FindMagnum.cmake | 22 +---- src/Magnum.h | 9 -- src/Platform/magnum-info.cpp | 3 - src/Text/CMakeLists.txt | 18 +--- src/Text/FreeTypeFont.cpp | 180 ----------------------------------- src/Text/FreeTypeFont.h | 118 ----------------------- src/Text/HarfBuzzFont.cpp | 124 ------------------------ src/Text/HarfBuzzFont.h | 81 ---------------- src/Text/Text.h | 6 -- src/magnumConfigure.h.cmake | 1 - 14 files changed, 3 insertions(+), 634 deletions(-) delete mode 100644 modules/FindHarfBuzz.cmake delete mode 100644 src/Text/FreeTypeFont.cpp delete mode 100644 src/Text/FreeTypeFont.h delete mode 100644 src/Text/HarfBuzzFont.cpp delete mode 100644 src/Text/HarfBuzzFont.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c4383966..d440600d3 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) @@ -97,9 +94,6 @@ endif() if(TARGET_DESKTOP_GLES) set(MAGNUM_TARGET_DESKTOP_GLES 1) endif() -if(USE_HARFBUZZ) - set(MAGNUM_USE_HARFBUZZ 1) -endif() # Installation paths include(CorradeLibSuffix) 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 342d67152..5a6907707 100644 --- a/doc/cmake.dox +++ b/doc/cmake.dox @@ -57,8 +57,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: @@ -101,8 +100,6 @@ are also available as preprocessor variables if including Magnum.h: - `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/FindHarfBuzz.cmake b/modules/FindHarfBuzz.cmake deleted file mode 100644 index f4b0139f5..000000000 --- a/modules/FindHarfBuzz.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# - Find HarfBuzz -# -# 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 -# -# Additionally these variables are defined for internal usage: -# HARFBUZZ_INCLUDE_DIR - Include dir (w/o dependencies) -# HARFBUZZ_LIBRARY - HarfBuzz library (w/o dependencies) -# - -# -# 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. -# - -# Library -find_library(HARFBUZZ_LIBRARY NAMES harfbuzz) - -# Include dir -find_path(HARFBUZZ_INCLUDE_DIR - NAMES hb.h - PATH_SUFFIXES harfbuzz -) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args("HarfBuzz" DEFAULT_MSG - HARFBUZZ_LIBRARY - HARFBUZZ_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/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 257d99612..9cc751b7b 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -19,9 +19,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) @@ -52,8 +50,6 @@ # 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 @@ -132,10 +128,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) @@ -255,18 +247,6 @@ 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() endif() # TextureTools library diff --git a/src/Magnum.h b/src/Magnum.h index 837c6bb6e..108df245e 100644 --- a/src/Magnum.h +++ b/src/Magnum.h @@ -124,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/Platform/magnum-info.cpp b/src/Platform/magnum-info.cpp index 7aa18126b..ab10e41a8 100644 --- a/src/Platform/magnum-info.cpp +++ b/src/Platform/magnum-info.cpp @@ -65,9 +65,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/Text/CMakeLists.txt b/src/Text/CMakeLists.txt index 127a32f06..4ae369cdc 100644 --- a/src/Text/CMakeLists.txt +++ b/src/Text/CMakeLists.txt @@ -22,38 +22,22 @@ # DEALINGS IN THE SOFTWARE. # -find_package(Freetype REQUIRED) -include_directories(${FREETYPE_INCLUDE_DIRS}) - set(MagnumText_SRCS AbstractFont.cpp DistanceFieldGlyphCache.cpp GlyphCache.cpp - FreeTypeFont.cpp TextRenderer.cpp) set(MagnumText_HEADERS AbstractFont.h DistanceFieldGlyphCache.h GlyphCache.h - FreeTypeFont.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}) -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/FreeTypeFont.cpp b/src/Text/FreeTypeFont.cpp deleted file mode 100644 index 061bb3cbb..000000000 --- a/src/Text/FreeTypeFont.cpp +++ /dev/null @@ -1,180 +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 "GlyphCache.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: - explicit FreeTypeLayouter(FT_Face ftFont, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text); - - std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; - - private: - FT_Face font; - const GlyphCache* const cache; - const Float fontSize, textSize; - std::vector glyphs; -}; - -} - -FreeTypeFontRenderer::FreeTypeFontRenderer() { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Init_FreeType(&_library) == 0); -} - -FreeTypeFontRenderer::~FreeTypeFontRenderer() { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_FreeType(_library) == 0); -} - -FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): AbstractFont(size) { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &ftFont) == 0); - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(ftFont, 0, size*64, 100, 100) == 0); -} - -FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): AbstractFont(size) { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &ftFont) == 0); - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(ftFont, 0, size*64, 100, 100) == 0); -} - -void FreeTypeFont::createGlyphCache(GlyphCache* const cache, const std::string& characters) { - /** @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 */ - std::vector charSizes; - charSizes.reserve(charIndices.size()); - for(FT_UInt c: charIndices) { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(ftFont, c, FT_LOAD_DEFAULT) == 0); - charSizes.push_back(Vector2i(ftFont->glyph->metrics.width, ftFont->glyph->metrics.height)/64); - } - - /* Create texture atlas */ - const std::vector charPositions = cache->reserve(charSizes); - - /* Render all characters to the atlas and create character map */ - unsigned char* pixmap = new unsigned char[cache->textureSize().product()](); - Image2D image(cache->textureSize(), 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*cache->textureSize().x() + xout] = bitmap.buffer[(bitmap.rows-yin-1)*bitmap.width + xin]; - - /* Insert glyph parameters into cache */ - cache->insert(charIndices[i], - Vector2i(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].height()), - charPositions[i]); - } - - /* Set cache image */ - cache->setImage({}, &image); -} - -FreeTypeFont::~FreeTypeFont() { - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(ftFont) == 0); -} - -AbstractLayouter* FreeTypeFont::layout(const GlyphCache* const cache, const Float size, const std::string& text) { - return new FreeTypeLayouter(ftFont, cache, this->size(), size, text); -} - -namespace { - -FreeTypeLayouter::FreeTypeLayouter(FT_Face font, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text): font(font), cache(cache), fontSize(fontSize), textSize(textSize) { - /* Get glyph codes from characters */ - glyphs.reserve(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, codepoint)); - } - _glyphCount = glyphs.size(); -} - -std::tuple FreeTypeLayouter::renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) { - /* Position of the texture in the resulting glyph, texture coordinates */ - Vector2i position; - Rectanglei rectangle; - std::tie(position, rectangle) = (*cache)[glyphs[i]]; - - Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/fontSize, - Vector2(rectangle.size())/fontSize); - Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache->textureSize(), - Vector2(rectangle.topRight())/cache->textureSize()); - - /* Load glyph */ - CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font, glyphs[i], FT_LOAD_DEFAULT) == 0); - const FT_GlyphSlot slot = font->glyph; - Vector2 offset = Vector2(0, 0); /** @todo really? */ - Vector2 advance = Vector2(slot->advance.x, slot->advance.y)/(64*fontSize); - - /* 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()))*textSize, - texturePosition.size()*textSize); - - return std::make_tuple(quadPosition, textureCoordinates, advance); -} - -} - -}} diff --git a/src/Text/FreeTypeFont.h b/src/Text/FreeTypeFont.h deleted file mode 100644 index 273834739..000000000 --- a/src/Text/FreeTypeFont.h +++ /dev/null @@ -1,118 +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 - -@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. -@code -Text::FreeTypeFontRenderer fontRenderer; - -Text::FreeTypeFont font(fontRenderer, "MyFreeTypeFont.ttf", 48.0f); -@endcode -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. -*/ -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); - - ~FreeTypeFont(); - - void createGlyphCache(GlyphCache* const cache, const std::string& characters) override; - AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) override; - - #ifdef DOXYGEN_GENERATING_OUTPUT - private: - #else - protected: - #endif - FT_Face ftFont; -}; - -}} - -#endif diff --git a/src/Text/HarfBuzzFont.cpp b/src/Text/HarfBuzzFont.cpp deleted file mode 100644 index 8eb19c112..000000000 --- a/src/Text/HarfBuzzFont.cpp +++ /dev/null @@ -1,124 +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 - -#include "GlyphCache.h" - -namespace Magnum { namespace Text { - -namespace { - -class HarfBuzzLayouter: public AbstractLayouter { - public: - explicit HarfBuzzLayouter(hb_font_t* const font, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text); - ~HarfBuzzLayouter(); - - std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override; - - private: - const hb_font_t* const font; - const GlyphCache* const cache; - const Float fontSize, textSize; - hb_buffer_t* buffer; - hb_glyph_info_t* glyphInfo; - hb_glyph_position_t* glyphPositions; -}; - -} - -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 GlyphCache* const cache, const Float size, const std::string& text) { - return new HarfBuzzLayouter(hbFont, cache, this->size(), size, text); -} - -namespace { - -HarfBuzzLayouter::HarfBuzzLayouter(hb_font_t* const font, const GlyphCache* const cache, const Float fontSize, const Float textSize, const std::string& text): font(font), cache(cache), fontSize(fontSize), textSize(textSize) { - /* 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, 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 */ - Vector2i position; - Rectanglei rectangle; - std::tie(position, rectangle) = (*cache)[glyphInfo[i].codepoint]; - - Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/fontSize, - Vector2(rectangle.size())/fontSize); - Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache->textureSize(), - Vector2(rectangle.topRight())/cache->textureSize()); - - /* Glyph offset and advance to next glyph in normalized coordinates */ - Vector2 offset = Vector2(glyphPositions[i].x_offset, - glyphPositions[i].y_offset)/(64*fontSize); - Vector2 advance = Vector2(glyphPositions[i].x_advance, - glyphPositions[i].y_advance)/(64*fontSize); - - /* 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()))*textSize, - texturePosition.size()*textSize); - - return std::make_tuple(quadPosition, textureCoordinates, advance); -} - -} - -}} diff --git a/src/Text/HarfBuzzFont.h b/src/Text/HarfBuzzFont.h deleted file mode 100644 index 96dd60ab7..000000000 --- a/src/Text/HarfBuzzFont.h +++ /dev/null @@ -1,81 +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(); - - AbstractLayouter* layout(const GlyphCache* const cache, 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 85087ad11..aae3a8ea5 100644 --- a/src/Text/Text.h +++ b/src/Text/Text.h @@ -39,12 +39,6 @@ class AbstractLayouter; class DistanceFieldGlyphCache; class GlyphCache; -class FreeTypeFontRenderer; -class FreeTypeFont; -#ifdef MAGNUM_USE_HARFBUZZ -class HarfBuzzFont; -#endif - class AbstractTextRenderer; template class TextRenderer; typedef TextRenderer<2> TextRenderer2D; diff --git a/src/magnumConfigure.h.cmake b/src/magnumConfigure.h.cmake index 94fefcfd0..b6fd0f9c0 100644 --- a/src/magnumConfigure.h.cmake +++ b/src/magnumConfigure.h.cmake @@ -27,4 +27,3 @@ #cmakedefine MAGNUM_TARGET_GLES3 #cmakedefine MAGNUM_TARGET_DESKTOP_GLES #cmakedefine MAGNUM_TARGET_NACL -#cmakedefine MAGNUM_USE_HARFBUZZ From c0b8e65d75216992bebbf6e358336bb02199baa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 29 Mar 2013 10:51:36 +0100 Subject: [PATCH 28/45] FindMagnum.cmake: fixed finding of Text library. --- modules/FindMagnum.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 9cc751b7b..0f815fc4a 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -246,7 +246,7 @@ foreach(component ${Magnum_FIND_COMPONENTS}) # Text library if(${component} STREQUAL Text) - set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Font.h) + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES AbstractFont.h) endif() # TextureTools library From 92c4a5a2ed61407e52a7b44fea42ccf71ff85f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 29 Mar 2013 10:55:01 +0100 Subject: [PATCH 29/45] Text: turned AbstractFont into plugin interface. --- doc/cmake.dox | 1 + modules/FindMagnum.cmake | 9 ++++++- src/Text/AbstractFont.cpp | 4 +-- src/Text/AbstractFont.h | 55 +++++++++++++++++++++++++++++++++------ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/doc/cmake.dox b/doc/cmake.dox index 5a6907707..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 diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 0f815fc4a..e1e9561ad 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -7,6 +7,7 @@ # MAGNUM_LIBRARIES - Magnum library and dependent libraries # MAGNUM_INCLUDE_DIRS - Root include dir and include dirs of # dependencies +# MAGNUM_PLUGINS_FONT_DIR - Directory with font 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 @@ -60,6 +61,8 @@ # 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_IMPORTER_INSTALL_DIR - Importer plugin installation # directory # MAGNUM_CMAKE_MODULE_INSTALL_DIR - Installation dir for CMake @@ -319,6 +322,7 @@ 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_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) @@ -328,14 +332,17 @@ mark_as_advanced(FORCE MAGNUM_INCLUDE_DIR MAGNUM_LIBRARY_INSTALL_DIR MAGNUM_PLUGINS_INSTALL_DIR + MAGNUM_PLUGINS_FONT_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_IMPORTER_DIR ${MAGNUM_PLUGINS_INSTALL_DIR}/importers) else() + set(MAGNUM_PLUGINS_FONT_DIR fonts) set(MAGNUM_PLUGINS_IMPORTER_DIR importers) endif() diff --git a/src/Text/AbstractFont.cpp b/src/Text/AbstractFont.cpp index 049341ab9..74f116ad3 100644 --- a/src/Text/AbstractFont.cpp +++ b/src/Text/AbstractFont.cpp @@ -26,9 +26,9 @@ namespace Magnum { namespace Text { -AbstractFont::AbstractFont(Float size): _size(size) {} +AbstractFont::AbstractFont(): _size(0.0f) {} -AbstractFont::~AbstractFont() {} +AbstractFont::AbstractFont(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin): AbstractPlugin(manager, std::move(plugin)), _size(0.0f) {} AbstractLayouter::AbstractLayouter(): _glyphCount(0) {} diff --git a/src/Text/AbstractFont.h b/src/Text/AbstractFont.h index cedfef2c9..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,17 +40,51 @@ 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: - explicit AbstractFont(Float size); - virtual ~AbstractFont() = 0; + /** @brief Default constructor */ + explicit AbstractFont(); + + /** @brief Plugin manager constructor */ + explicit AbstractFont(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin); + + /** + * @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 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; } @@ -73,7 +108,11 @@ class MAGNUM_TEXT_EXPORT AbstractFont { */ virtual AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) = 0; + #ifdef DOXYGEN_GENERATING_OUTPUT private: + #else + protected: + #endif Float _size; }; From d6f5560262bade9660457413fc1703d71e7e74d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 29 Mar 2013 14:26:39 +0100 Subject: [PATCH 30/45] Trade: got rid of opening input streams in AbstractImporter. Now it is possible to open either pure data arrays or arrays specified with filename. The function calls might be ambiguous now (i.e. open("image.tga") would open data array instead of handling it as filename), renamed them to avoid that. Default implementations now fire an assertion. Bumped plugin interface string version as this is pretty incompatible change. --- src/Trade/AbstractImporter.cpp | 20 +++++++------- src/Trade/AbstractImporter.h | 48 +++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/Trade/AbstractImporter.cpp b/src/Trade/AbstractImporter.cpp index 5d7dcf24d..46a6abc8e 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,18 @@ 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); } }} diff --git a/src/Trade/AbstractImporter.h b/src/Trade/AbstractImporter.h index 1c6f1f754..0af1e45db 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 open(const std::string& filename); + virtual bool openData(const void* const data, const std::size_t size); /** - * @brief Open stream - * @param in Input stream - * @return Whether the file was successfully opened + * @brief Open raw data + * @param data Data * - * See also open(const std::string&), @ref Feature - * "Feature::OpenStream". Default implementation prints message to - * error output and returns false. + * Convenience alternative to above function useful when array size is + * known at compile-time. + */ + template inline bool openData(const T(&data)[size]) { + return openData(data, size*sizeof(T)); + } + + /** + * @brief Open file + * @param filename Filename + * + * 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; From 2054cbf4473a54a17c82319f1cd1290916f87910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 29 Mar 2013 14:29:54 +0100 Subject: [PATCH 31/45] Trade: deinlined all AbstractImporter virtual functions. --- src/Trade/AbstractImporter.cpp | 37 +++++++++++++++++++++++++++++++++ src/Trade/AbstractImporter.h | 38 ---------------------------------- 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/Trade/AbstractImporter.cpp b/src/Trade/AbstractImporter.cpp index 46a6abc8e..ce792335c 100644 --- a/src/Trade/AbstractImporter.cpp +++ b/src/Trade/AbstractImporter.cpp @@ -46,4 +46,41 @@ bool AbstractImporter::openFile(const std::string&) { 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 0af1e45db..c885739c0 100644 --- a/src/Trade/AbstractImporter.h +++ b/src/Trade/AbstractImporter.h @@ -465,44 +465,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 From dc10235a96518c8a2072f717e249d175ec38a840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 29 Mar 2013 14:54:56 +0100 Subject: [PATCH 32/45] Trade: updated AbstractImporter documentation. Clearly state that deleting the data is user responsibility. --- src/Trade/AbstractImporter.h | 67 ++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/Trade/AbstractImporter.h b/src/Trade/AbstractImporter.h index c885739c0..54233c69b 100644 --- a/src/Trade/AbstractImporter.h +++ b/src/Trade/AbstractImporter.h @@ -124,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. @@ -137,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); @@ -154,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); @@ -164,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); @@ -181,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); @@ -191,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); @@ -208,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); @@ -219,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); @@ -236,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); @@ -247,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); @@ -264,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); @@ -275,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); @@ -292,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); @@ -302,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); @@ -319,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); @@ -329,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); @@ -346,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); @@ -357,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); @@ -374,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); @@ -385,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); @@ -402,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); @@ -412,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); @@ -429,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); @@ -439,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); @@ -456,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); From 872ef12ebd0276b3b54d0d9782444bd8e1733360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 29 Mar 2013 17:53:40 +0100 Subject: [PATCH 33/45] Treat image data as array of unsigned chars. Arithmetic on void* is not defined, this helps a little with various conversions. --- src/Image.cpp | 2 +- src/Image.h | 8 ++++---- src/ImageWrapper.h | 10 +++++----- src/Trade/ImageData.h | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) 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 3a20cfc6c..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 @@ -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/Trade/ImageData.h b/src/Trade/ImageData.h index 8fd76c525..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 explicit 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 */ From bbb764eff5167a519ba17c74984796c1a8aefee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 29 Mar 2013 17:56:53 +0100 Subject: [PATCH 34/45] Base for image converter plugins. --- modules/FindMagnum.cmake | 7 ++ src/CMakeLists.txt | 1 + src/Trade/AbstractImageConverter.cpp | 56 +++++++++++++ src/Trade/AbstractImageConverter.h | 119 +++++++++++++++++++++++++++ src/Trade/CMakeLists.txt | 1 + src/Trade/Trade.h | 1 + 6 files changed, 185 insertions(+) create mode 100644 src/Trade/AbstractImageConverter.cpp create mode 100644 src/Trade/AbstractImageConverter.h diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index e1e9561ad..cde956bc7 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -8,6 +8,7 @@ # 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 @@ -63,6 +64,8 @@ # 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 @@ -323,6 +326,7 @@ endif() 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) @@ -333,6 +337,7 @@ mark_as_advanced(FORCE 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 @@ -341,8 +346,10 @@ mark_as_advanced(FORCE # 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/src/CMakeLists.txt b/src/CMakeLists.txt index 589b97694..61c7a059b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,6 +67,7 @@ set(Magnum_SRCS Implementation/BufferState.cpp Implementation/State.cpp + Trade/AbstractImageConverter.cpp Trade/AbstractImporter.cpp Trade/AbstractMaterialData.cpp Trade/MeshData2D.cpp 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/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/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; From d95c44fcc824cf46a41918877025f7fa546b26e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 30 Mar 2013 19:24:17 +0100 Subject: [PATCH 35/45] Math: test that trigonometric functions work with Unit base class. The test fails. --- src/Math/Test/FunctionsTest.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) 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) From 2d71c86942844c913dc184076919ebe94810092f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 30 Mar 2013 19:25:28 +0100 Subject: [PATCH 36/45] Math: make trignometric functions working with Unit base class. The test now passes again. --- src/Math/Functions.h | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) 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 */ From 032827fc3d67b36b2ac7809f542ba0ba6b7f6e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 30 Mar 2013 19:18:08 +0100 Subject: [PATCH 37/45] Primitives: added 2D circle primitive. --- src/Primitives/CMakeLists.txt | 2 + src/Primitives/Circle.cpp | 66 +++++++++++++++++++++++++++ src/Primitives/Circle.h | 65 +++++++++++++++++++++++++++ src/Primitives/Test/CMakeLists.txt | 3 +- src/Primitives/Test/CircleTest.cpp | 71 ++++++++++++++++++++++++++++++ 5 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 src/Primitives/Circle.cpp create mode 100644 src/Primitives/Circle.h create mode 100644 src/Primitives/Test/CircleTest.cpp diff --git a/src/Primitives/CMakeLists.txt b/src/Primitives/CMakeLists.txt index a3c2efd95..24b978fa5 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 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) From c455955d5073614586bba5d16323f4cc6ee261b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 30 Mar 2013 19:18:47 +0100 Subject: [PATCH 38/45] DebugTools: render boxes with size as half extent, not full. Also clarified the documentation in Physics::Box and Physics::AxisAlignedBox classes. --- src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp | 6 ++---- src/DebugTools/Implementation/BoxRenderer.cpp | 4 +--- src/Physics/AxisAlignedBox.h | 2 ++ src/Physics/Box.h | 2 ++ 4 files changed, 7 insertions(+), 7 deletions(-) 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/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 From 79b4c0dbbdf4a2f3c6adcf4c5e89ae4f2f186a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 30 Mar 2013 19:22:13 +0100 Subject: [PATCH 39/45] DebugTools: take also object rotation into account in ForceRenderer. Currently the force was only translated, completely ignoring object translation. --- src/DebugTools/ForceRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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(); From 4f4e1230d7cc8d3ee491eed5eeba19f60f2fc8b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 30 Mar 2013 19:23:48 +0100 Subject: [PATCH 40/45] DebugTools: added support for 2D spheres into ShapeRenderer. --- src/DebugTools/CMakeLists.txt | 3 +- .../Implementation/SphereRenderer.cpp | 53 ++++++++++++++++++ .../Implementation/SphereRenderer.h | 54 +++++++++++++++++++ src/DebugTools/ShapeRenderer.cpp | 5 ++ 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/DebugTools/Implementation/SphereRenderer.cpp create mode 100644 src/DebugTools/Implementation/SphereRenderer.h diff --git a/src/DebugTools/CMakeLists.txt b/src/DebugTools/CMakeLists.txt index 55081223a..8d09c7346 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 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 1987e529b..38fbd46ce 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"; } From cc0d45ca7c8cd62acd5553011fe0c65ecc8a9ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 30 Mar 2013 23:12:15 +0100 Subject: [PATCH 41/45] Fixed building with static Corrade. Four tests (SceneGraph::Animable, Mesh, MeshTools::Tipsify, TextureTools::Atlas) however fail, not sure what the cause is, as they fail somewhere deep long after exiting from main(). --- src/CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 61c7a059b..0528e4ca5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -219,9 +219,7 @@ if(BUILD_TESTS) add_library(MagnumMathTestLib SHARED $) 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 $ From c79327ee43e419a33ce5f7ee2754ea9d370143b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 30 Mar 2013 23:36:53 +0100 Subject: [PATCH 42/45] Option to build Magnum as static library. And optionaly position-independent code. The tests now pass again, if both Corrade and Magnum is static. --- CMakeLists.txt | 8 ++++++++ src/CMakeLists.txt | 10 +++++++--- src/DebugTools/CMakeLists.txt | 6 +++++- src/MeshTools/CMakeLists.txt | 15 ++++++++++++--- src/Physics/CMakeLists.txt | 6 +++++- src/Primitives/CMakeLists.txt | 6 +++++- src/SceneGraph/CMakeLists.txt | 11 ++++++++--- src/Shaders/CMakeLists.txt | 6 +++++- src/Text/CMakeLists.txt | 6 +++++- src/TextureTools/CMakeLists.txt | 6 +++++- 10 files changed, 65 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d440600d3..470f2d2ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,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() @@ -95,6 +97,12 @@ if(TARGET_DESKTOP_GLES) set(MAGNUM_TARGET_DESKTOP_GLES 1) endif() +if(NOT BUILD_STATIC) + set(SHARED_OR_STATIC SHARED) +else() + set(SHARED_OR_STATIC STATIC) +endif() + # Installation paths include(CorradeLibSuffix) set(MAGNUM_BINARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0528e4ca5..0ae0fee42 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -156,9 +156,13 @@ 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}) @@ -216,12 +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) 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/DebugTools/CMakeLists.txt b/src/DebugTools/CMakeLists.txt index 8d09c7346..a80d6e435 100644 --- a/src/DebugTools/CMakeLists.txt +++ b/src/DebugTools/CMakeLists.txt @@ -46,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/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/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/Primitives/CMakeLists.txt b/src/Primitives/CMakeLists.txt index 24b978fa5..6c44f1c81 100644 --- a/src/Primitives/CMakeLists.txt +++ b/src/Primitives/CMakeLists.txt @@ -46,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/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/CMakeLists.txt b/src/Text/CMakeLists.txt index 4ae369cdc..fa28db8d1 100644 --- a/src/Text/CMakeLists.txt +++ b/src/Text/CMakeLists.txt @@ -36,7 +36,11 @@ set(MagnumText_HEADERS magnumTextVisibility.h) -add_library(MagnumText SHARED ${MagnumText_SRCS}) +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}) 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}) From c07b0f0b4ae78b8cb048550ff833880cc8e27885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 31 Mar 2013 19:13:26 +0200 Subject: [PATCH 43/45] Updated FindCorrade.cmake from Corrade repository. --- modules/FindCorrade.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/FindCorrade.cmake b/modules/FindCorrade.cmake index ef56feca3..e34de81bb 100644 --- a/modules/FindCorrade.cmake +++ b/modules/FindCorrade.cmake @@ -154,6 +154,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 From d66858074b9bc04bd2d6c093ea7659fdc4194112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 31 Mar 2013 19:13:46 +0200 Subject: [PATCH 44/45] FindMagnum.cmake: use CORRADE_*_LIBRARIES, not *_LIBRARY. --- modules/FindMagnum.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index cde956bc7..2074b14cb 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -311,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() From 64585ca4fdb2adeaaf17e0ede4a45b8ad5678684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 31 Mar 2013 19:41:10 +0200 Subject: [PATCH 45/45] GCC 4.6 compatibility: vector conversion is not constexpr. --- src/Math/Geometry/Test/RectangleTest.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 */