diff --git a/src/AbstractResourceLoader.h b/src/AbstractResourceLoader.h new file mode 100644 index 000000000..038054604 --- /dev/null +++ b/src/AbstractResourceLoader.h @@ -0,0 +1,137 @@ +#ifndef Magnum_AbstractResourceLoader_h +#define Magnum_AbstractResourceLoader_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::AbstractResourceLoader + */ + +#include "Magnum.h" + +#include + +#include "ResourceManager.h" + +namespace Magnum { + +/** +@brief Base for resource loaders + +Provides asynchronous resource loading for ResourceManager. +*/ +template class AbstractResourceLoader { + friend class Implementation::ResourceManagerData; + + public: + inline AbstractResourceLoader(): manager(nullptr), _requestedCount(0), _loadedCount(0), _notFoundCount(0) {} + + inline virtual ~AbstractResourceLoader() { + if(manager) manager->_loader = nullptr; + } + + /** + * @brief Count of requested resources + * + * Count of resources requested by calling load(). + */ + inline std::size_t requestedCount() const { return _requestedCount; } + + /** + * @brief Count of not found resources + * + * Count of resources requested by calling load(), but not found by + * the loader. + */ + inline std::size_t notFountCount() const { return _notFoundCount; } + + /** + * @brief Count of loaded resources + * + * Count of resources requested by calling load(), but not found by + * the loader. + */ + inline std::size_t loadedCount() const { return _loadedCount; } + + /** + * @brief %Resource name corresponding to given key + * + * If no such resource exists or the resource name is not available, + * returns empty string. Default implementation returns empty string. + */ + virtual std::string name(ResourceKey key) const; + + /** + * @brief Request resource to be loaded + * + * If the resource isn't yet loaded or loading, state of the resource + * is set to @ref Resource::ResourceState "ResourceState::Loading" and count of + * requested features is incremented. + * + * The resource might be loaded asynchronously and added to + * ResourceManager when loading is done. + * @see ResourceManager::state(), requestedCount(), notFountCount(), + * loadedCount() + */ + virtual void load(ResourceKey key) = 0; + + protected: + /** + * @brief Set loaded resource to resource manager + * + * Also increments count of loaded resources. Parameter @p state + * must be either @ref ResourceManager::ResourceDataState "ResourceDataState::Mutable" + * or @ref ResourceManager::ResourceDataState "ResourceDataState::Final". See + * ResourceManager::set() for more information. + * @see loadedCount() + */ + inline void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) { + CORRADE_ASSERT(state == ResourceDataState::Mutable || state == ResourceDataState::Final, + "AbstractResourceLoader::set(): state must be either Mutable or Final", ); + ++_loadedCount; + manager->set(key, data, state, policy); + } + + /** + * @brief Mark resource as not found + * + * Also increments count of not found resources. See + * ResourceManager::setNotFound() for more information. + * @see notFountCount() + */ + inline void setNotFound(ResourceKey key) { + ++_notFoundCount; + /** @todo What policy for notfound resources? */ + manager->set(key, nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident); + } + + private: + Implementation::ResourceManagerData* manager; + std::size_t _requestedCount; + std::size_t _loadedCount; + std::size_t _notFoundCount; +}; + +template inline std::string AbstractResourceLoader::name(ResourceKey) const { return {}; } + +template inline void AbstractResourceLoader::load(ResourceKey key) { + ++_requestedCount; + /** @todo What policy for loading resources? */ + manager->set(key, nullptr, ResourceDataState::Loading, ResourcePolicy::Resident); +} + +} + +#endif diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index 7729a25cb..19653753c 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -53,9 +53,9 @@ functions and properties: - %Attribute definitions with location and type for configuring meshes, for example: @code -static const Attribute<0, Point3D> Position; -static const Attribute<1, Vector3> Normal; -static const Attribute<2, Vector2> TextureCoordinates; +typedef Attribute<0, Point3D> Position; +typedef Attribute<1, Vector3> Normal; +typedef Attribute<2, Vector2> TextureCoordinates; @endcode @todoc Output attribute location (for bindFragmentDataLocationIndexed(), referenced also from Framebuffer::mapDefaultForDraw() / Framebuffer::mapForDraw()) @@ -127,9 +127,9 @@ the program: @code // Shaders attached... -bindAttributeLocation(Position.Location, "position"); -bindAttributeLocation(Normal.Location, "normal"); -bindAttributeLocation(TextureCoords.Location, "textureCoordinates"); +bindAttributeLocation(Position::Location, "position"); +bindAttributeLocation(Normal::Location, "normal"); +bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates"); bindFragmentDataLocationIndexed(0, 0, "color"); bindFragmentDataLocationIndexed(1, 1, "ambient"); diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index ae43129c7..038e4ad5d 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -29,10 +29,12 @@ namespace Magnum { @brief Base for textures @attention Don't forget to call @ref Texture::setWrapping() "setWrapping()", -setMinificationFilter() and setMagnificationFilter() after creating the -texture, otherwise the texture will be incomplete. If you specified mipmap -filtering in setMinificationFilter(), be sure to also either explicitly set -all mip levels or call generateMipmap(). + setMinificationFilter() and setMagnificationFilter() after creating the + texture, otherwise the texture will be incomplete. If you specified + @ref Wrapping "Wrapping::ClampToBorder" in @ref Texture::setWrapping() "setWrapping()", + be sure to also call setBorderColor(). If you specified mipmap filtering + in setMinificationFilter(), be sure to also either explicitly set all mip + levels or call generateMipmap(). The texture is bound to shader via bind(). Texture uniform on the shader must also be set to particular texture layer using diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5a6e78c37..3c1fef6ec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,7 @@ set(Magnum_SRCS Profiler.cpp Query.cpp Renderbuffer.cpp + Resource.cpp Shader.cpp SizeTraits.cpp Timeline.cpp @@ -58,6 +59,7 @@ endif() set(Magnum_HEADERS AbstractImage.h + AbstractResourceLoader.h AbstractShaderProgram.h AbstractTexture.h Buffer.h @@ -76,6 +78,7 @@ set(Magnum_HEADERS Profiler.h Query.h Renderbuffer.h + Resource.h ResourceManager.h Shader.h SizeTraits.h diff --git a/src/Context.cpp b/src/Context.cpp index 120538853..4b8ad07ef 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "AbstractShaderProgram.h" #include "AbstractTexture.h" diff --git a/src/Magnum.h b/src/Magnum.h index 8d74ce976..18458f416 100644 --- a/src/Magnum.h +++ b/src/Magnum.h @@ -120,8 +120,8 @@ typedef BufferedImage<3> BufferedImage3D; class BufferedTexture; #endif -template class Color3; -template class Color4; +template class Color3; +template class Color4; #ifndef CORRADE_GCC45_COMPATIBILITY enum class Version: GLint; @@ -160,7 +160,8 @@ enum class ResourceState: std::uint8_t; enum class ResourceDataState: std::uint8_t; enum class ResourcePolicy: std::uint8_t; #endif -template class Resource; +template class Resource; +class ResourceKey; template class ResourceManager; class Shader; diff --git a/src/Math/RectangularMatrix.h b/src/Math/RectangularMatrix.h index 2dd862b2b..bc4822323 100644 --- a/src/Math/RectangularMatrix.h +++ b/src/Math/RectangularMatrix.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include "MathTypeTraits.h" @@ -508,7 +508,7 @@ namespace Corrade { namespace Utility { /** @configurationvalue{Magnum::Math::RectangularMatrix} */ template struct ConfigurationValue> { /** @brief Writes elements separated with spaces */ - static std::string toString(const Magnum::Math::RectangularMatrix& value, int flags = 0) { + static std::string toString(const Magnum::Math::RectangularMatrix& value, ConfigurationValueFlags flags) { std::string output; for(std::size_t row = 0; row != rows; ++row) { @@ -522,7 +522,7 @@ template struct ConfigurationValue< } /** @brief Reads elements separated with whitespace */ - static Magnum::Math::RectangularMatrix fromString(const std::string& stringValue, int flags = 0) { + static Magnum::Math::RectangularMatrix fromString(const std::string& stringValue, ConfigurationValueFlags flags) { Magnum::Math::RectangularMatrix result; std::istringstream in(stringValue); diff --git a/src/Math/Test/Matrix3Test.cpp b/src/Math/Test/Matrix3Test.cpp index 6df43a7ca..e25c020b0 100644 --- a/src/Math/Test/Matrix3Test.cpp +++ b/src/Math/Test/Matrix3Test.cpp @@ -15,7 +15,7 @@ #include "Matrix3Test.h" -#include +#include #include "Constants.h" #include "Matrix3.h" @@ -148,14 +148,18 @@ void Matrix3Test::debug() { } void Matrix3Test::configuration() { + Configuration c; + Matrix3 m( 5.0f, 8.0f, 4.0f, 4.0f, 7.0f, 3.125f, 4.0f, 5.0f, 9.55f ); string value("5 4 4 8 7 5 4 3.125 9.55"); - CORRADE_COMPARE(ConfigurationValue::toString(m), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), m); + + c.setValue("matrix", m); + CORRADE_COMPARE(c.value("matrix"), value); + CORRADE_COMPARE(c.value("matrix"), m); } }}} diff --git a/src/Math/Test/Matrix4Test.cpp b/src/Math/Test/Matrix4Test.cpp index 89792fa4c..a1e8c4cbc 100644 --- a/src/Math/Test/Matrix4Test.cpp +++ b/src/Math/Test/Matrix4Test.cpp @@ -15,7 +15,7 @@ #include "Matrix4Test.h" -#include +#include #include "Constants.h" #include "Matrix4.h" @@ -195,6 +195,8 @@ void Matrix4Test::debug() { } void Matrix4Test::configuration() { + Configuration c; + Matrix4 m( 3.0f, 5.0f, 8.0f, 4.0f, 4.0f, 4.0f, 7.0f, 3.125f, @@ -202,8 +204,10 @@ void Matrix4Test::configuration() { 9.0f, 4.0f, 5.0f, 9.55f ); string value("3 4 7 9 5 4 -1 4 8 7 8 5 4 3.125 0 9.55"); - CORRADE_COMPARE(ConfigurationValue::toString(m), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), m); + + c.setValue("matrix", m); + CORRADE_COMPARE(c.value("matrix"), value); + CORRADE_COMPARE(c.value("matrix"), m); } }}} diff --git a/src/Math/Test/MatrixTest.cpp b/src/Math/Test/MatrixTest.cpp index 6a015b328..cc902f199 100644 --- a/src/Math/Test/MatrixTest.cpp +++ b/src/Math/Test/MatrixTest.cpp @@ -15,7 +15,7 @@ #include "MatrixTest.h" -#include +#include #include "Matrix.h" @@ -186,6 +186,8 @@ void MatrixTest::debug() { } void MatrixTest::configuration() { + Configuration c; + Matrix4 m( 3.0f, 5.0f, 8.0f, 4.0f, 4.0f, 4.0f, 7.0f, 3.125f, @@ -193,8 +195,10 @@ void MatrixTest::configuration() { 9.0f, 4.0f, 5.0f, 9.55f ); string value("3 4 7 9 5 4 -1 4 8 7 8 5 4 3.125 0 9.55"); - CORRADE_COMPARE(ConfigurationValue::toString(m), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), m); + + c.setValue("matrix", m); + CORRADE_COMPARE(c.value("matrix"), value); + CORRADE_COMPARE(c.value("matrix"), m); } }}} diff --git a/src/Math/Test/Point2DTest.cpp b/src/Math/Test/Point2DTest.cpp index 64d5540bc..63a93c345 100644 --- a/src/Math/Test/Point2DTest.cpp +++ b/src/Math/Test/Point2DTest.cpp @@ -15,7 +15,7 @@ #include "Point2DTest.h" -#include +#include #include "Point2D.h" @@ -47,10 +47,14 @@ void Point2DTest::debug() { } void Point2DTest::configuration() { + Configuration c; + Point2D vec(3.0f, 3.125f, 9.55f); string value("3 3.125 9.55"); - CORRADE_COMPARE(ConfigurationValue::toString(vec), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), vec); + + c.setValue("point", vec); + CORRADE_COMPARE(c.value("point"), value); + CORRADE_COMPARE(c.value("point"), vec); } }}} diff --git a/src/Math/Test/Point3DTest.cpp b/src/Math/Test/Point3DTest.cpp index 092f5a0f0..e4f24920f 100644 --- a/src/Math/Test/Point3DTest.cpp +++ b/src/Math/Test/Point3DTest.cpp @@ -15,7 +15,7 @@ #include "Point3DTest.h" -#include +#include #include "Point3D.h" @@ -47,10 +47,14 @@ void Point3DTest::debug() { } void Point3DTest::configuration() { + Configuration c; + Point3D vec(3.0f, 3.125f, 9.0f, 9.55f); string value("3 3.125 9 9.55"); - CORRADE_COMPARE(ConfigurationValue::toString(vec), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), vec); + + c.setValue("point", vec); + CORRADE_COMPARE(c.value("point"), value); + CORRADE_COMPARE(c.value("point"), vec); } }}} diff --git a/src/Math/Test/RectangularMatrixTest.cpp b/src/Math/Test/RectangularMatrixTest.cpp index e43c6e5e2..344e2fcd1 100644 --- a/src/Math/Test/RectangularMatrixTest.cpp +++ b/src/Math/Test/RectangularMatrixTest.cpp @@ -15,7 +15,7 @@ #include "RectangularMatrixTest.h" -#include +#include #include "RectangularMatrix.h" @@ -242,8 +242,12 @@ void RectangularMatrixTest::configuration() { 7.0f, -1.0f, 8.0f, 9.55f ); string value("3 4 7 5 4 -1 8 7 8 4 3.125 9.55"); - CORRADE_COMPARE(ConfigurationValue::toString(m), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), m); + + Configuration c; + c.setValue("matrix", m); + + CORRADE_COMPARE(c.value("matrix"), value); + CORRADE_COMPARE(c.value("matrix"), m); } }}} diff --git a/src/Math/Test/Vector2Test.cpp b/src/Math/Test/Vector2Test.cpp index a60a253d7..297e0e67a 100644 --- a/src/Math/Test/Vector2Test.cpp +++ b/src/Math/Test/Vector2Test.cpp @@ -15,7 +15,7 @@ #include "Vector2Test.h" -#include +#include #include "Vector2.h" @@ -57,10 +57,14 @@ void Vector2Test::debug() { } void Vector2Test::configuration() { + Configuration c; + Vector2 vec(3.125f, 9.0f); string value("3.125 9"); - CORRADE_COMPARE(ConfigurationValue::toString(vec), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), vec); + + c.setValue("vector", vec); + CORRADE_COMPARE(c.value("vector"), value); + CORRADE_COMPARE(c.value("vector"), vec); } }}} diff --git a/src/Math/Test/Vector3Test.cpp b/src/Math/Test/Vector3Test.cpp index 6ffdc267d..7ef022ff7 100644 --- a/src/Math/Test/Vector3Test.cpp +++ b/src/Math/Test/Vector3Test.cpp @@ -15,7 +15,7 @@ #include "Vector3Test.h" -#include +#include #include "Vector3.h" @@ -75,10 +75,14 @@ void Vector3Test::debug() { } void Vector3Test::configuration() { + Configuration c; + Vector3 vec(3.0f, 3.125f, 9.55f); string value("3 3.125 9.55"); - CORRADE_COMPARE(ConfigurationValue::toString(vec), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), vec); + + c.setValue("vector", vec); + CORRADE_COMPARE(c.value("vector"), value); + CORRADE_COMPARE(c.value("vector"), vec); } }}} diff --git a/src/Math/Test/Vector4Test.cpp b/src/Math/Test/Vector4Test.cpp index c12838a20..33d52deb0 100644 --- a/src/Math/Test/Vector4Test.cpp +++ b/src/Math/Test/Vector4Test.cpp @@ -15,7 +15,7 @@ #include "Vector4Test.h" -#include +#include #include "Vector4.h" @@ -59,10 +59,14 @@ void Vector4Test::debug() { } void Vector4Test::configuration() { + Configuration c; + Vector4 vec(3.0f, 3.125f, 9.0f, 9.55f); string value("3 3.125 9 9.55"); - CORRADE_COMPARE(ConfigurationValue::toString(vec), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), vec); + + c.setValue("vector", vec); + CORRADE_COMPARE(c.value("vector"), value); + CORRADE_COMPARE(c.value("vector"), vec); } }}} diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 5bd824c16..e89907bf4 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -15,7 +15,7 @@ #include "VectorTest.h" -#include +#include #include "Constants.h" #include "Vector.h" @@ -116,10 +116,14 @@ void VectorTest::debug() { } void VectorTest::configuration() { + Configuration c; + Vector4 vec(3.0f, 3.125f, 9.0f, 9.55f); string value("3 3.125 9 9.55"); - CORRADE_COMPARE(ConfigurationValue::toString(vec), value); - CORRADE_COMPARE(ConfigurationValue::fromString(value), vec); + + c.setValue("vector", vec); + CORRADE_COMPARE(c.value("vector"), value); + CORRADE_COMPARE(c.value("vector"), vec); } }}} diff --git a/src/Mesh.cpp b/src/Mesh.cpp index a979a9a9c..351e58bd2 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -265,4 +265,55 @@ void Mesh::unbindImplementationDefault() { void Mesh::unbindImplementationVAO() {} +#ifndef DOXYGEN_GENERATING_OUTPUT +Debug operator<<(Debug debug, Mesh::Primitive value) { + switch(value) { + #define _c(value) case Mesh::Primitive::value: return debug << "Mesh::Primitive::" #value; + _c(Points) + _c(Lines) + _c(LineStrip) + _c(LineLoop) + _c(Triangles) + _c(TriangleStrip) + _c(TriangleFan) + #undef _c + } + + return debug << "Mesh::Primitive::(invalid)"; +} +#endif + +} + +namespace Corrade { namespace Utility { + +std::string ConfigurationValue::toString(Magnum::Mesh::Primitive value, ConfigurationValueFlags) { + switch(value) { + #define _c(value) case Magnum::Mesh::Primitive::value: return #value; + _c(Points) + _c(Lines) + _c(LineStrip) + _c(LineLoop) + _c(Triangles) + _c(TriangleStrip) + _c(TriangleFan) + #undef _c + } + + return ""; } + +Magnum::Mesh::Primitive ConfigurationValue::fromString(const std::string& stringValue, ConfigurationValueFlags) { + #define _c(value) if(stringValue == #value) return Magnum::Mesh::Primitive::value; + _c(Lines) + _c(LineStrip) + _c(LineLoop) + _c(Triangles) + _c(TriangleStrip) + _c(TriangleFan) + #undef _c + + return Magnum::Mesh::Primitive::Points; +} + +}} diff --git a/src/Mesh.h b/src/Mesh.h index cf3b6e176..8a1b9385f 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -33,8 +33,8 @@ namespace Magnum { @section Mesh-configuration Mesh configuration To properly configure mesh, you have to set primitive either in constructor or -using setPrimitive() and call setVertexCount(). Then create vertex buffers, -and them with vertex data. You can also use MeshTools::interleave() to +using setPrimitive() and call setVertexCount(). Then create vertex buffers and +fill them with vertex data. You can also use MeshTools::interleave() to conveniently set vertex count and buffer data. At last assign them to mesh and @ref AbstractShaderProgram::Attribute "shader attributes" using addVertexBuffer(), addInterleavedVertexBuffer() or addVertexBufferStride(). @@ -742,6 +742,30 @@ class MAGNUM_EXPORT Mesh { #endif }; +/** @debugoperator{Magnum::Mesh} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::Primitive value); + } +namespace Corrade { namespace Utility { + +/** @configurationvalue{Magnum::Mesh} */ +template<> struct MAGNUM_EXPORT ConfigurationValue { + /** + * @brief Writes enum value as string + * + * If the value is invalid, returns empty string. + */ + static std::string toString(Magnum::Mesh::Primitive value, ConfigurationValueFlags); + + /** + * @brief Reads enum value as string + * + * If the value is invalid, returns @ref Magnum::Mesh::Primitive "Mesh::Primitive::Points". + */ + static Magnum::Mesh::Primitive fromString(const std::string& stringValue, ConfigurationValueFlags); +}; + +}} + #endif diff --git a/src/MeshTools/CompressIndices.h b/src/MeshTools/CompressIndices.h index e9bf40c9e..34ccb7991 100644 --- a/src/MeshTools/CompressIndices.h +++ b/src/MeshTools/CompressIndices.h @@ -31,7 +31,7 @@ namespace Magnum { namespace MeshTools { #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { -class MESHTOOLS_EXPORT CompressIndices { +class MAGNUM_MESHTOOLS_EXPORT CompressIndices { public: CompressIndices(const std::vector& indices): indices(indices) {} diff --git a/src/MeshTools/FlipNormals.h b/src/MeshTools/FlipNormals.h index c113e908d..98d71eb08 100644 --- a/src/MeshTools/FlipNormals.h +++ b/src/MeshTools/FlipNormals.h @@ -34,7 +34,7 @@ namespace Magnum { namespace MeshTools { The same as flipNormals(std::vector&, std::vector&), but flips only face winding. */ -void MESHTOOLS_EXPORT flipFaceWinding(std::vector& indices); +void MAGNUM_MESHTOOLS_EXPORT flipFaceWinding(std::vector& indices); /** @brief Flip mesh normals @@ -42,7 +42,7 @@ void MESHTOOLS_EXPORT flipFaceWinding(std::vector& indices); The same as flipNormals(std::vector&, std::vector&), but flips only normals, not face winding. */ -void MESHTOOLS_EXPORT flipNormals(std::vector& normals); +void MAGNUM_MESHTOOLS_EXPORT flipNormals(std::vector& normals); /** @brief Flip mesh normals and face winding diff --git a/src/MeshTools/GenerateFlatNormals.h b/src/MeshTools/GenerateFlatNormals.h index 2e23dfa5e..35a6e8047 100644 --- a/src/MeshTools/GenerateFlatNormals.h +++ b/src/MeshTools/GenerateFlatNormals.h @@ -51,7 +51,7 @@ use the same indices. @attention Index count must be divisible by 3, otherwise zero length result is generated. */ -std::tuple, std::vector> MESHTOOLS_EXPORT generateFlatNormals(const std::vector& indices, const std::vector& positions); +std::tuple, std::vector> MAGNUM_MESHTOOLS_EXPORT generateFlatNormals(const std::vector& indices, const std::vector& positions); }} diff --git a/src/MeshTools/Tipsify.h b/src/MeshTools/Tipsify.h index ca93c1297..69d65082e 100644 --- a/src/MeshTools/Tipsify.h +++ b/src/MeshTools/Tipsify.h @@ -29,7 +29,7 @@ namespace Magnum { namespace MeshTools { #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { -class MESHTOOLS_EXPORT Tipsify { +class MAGNUM_MESHTOOLS_EXPORT Tipsify { public: inline Tipsify(std::vector& indices, std::uint32_t vertexCount): indices(indices), vertexCount(vertexCount) {} diff --git a/src/MeshTools/magnumMeshToolsVisibility.h b/src/MeshTools/magnumMeshToolsVisibility.h index 61b0a0d39..ebef4ae43 100644 --- a/src/MeshTools/magnumMeshToolsVisibility.h +++ b/src/MeshTools/magnumMeshToolsVisibility.h @@ -17,12 +17,12 @@ #ifdef _WIN32 #if defined(MagnumMeshTools_EXPORTS) || defined(MagnumMeshToolsObjects_EXPORTS) - #define MESHTOOLS_EXPORT __declspec(dllexport) + #define MAGNUM_MESHTOOLS_EXPORT __declspec(dllexport) #else - #define MESHTOOLS_EXPORT __declspec(dllimport) + #define MAGNUM_MESHTOOLS_EXPORT __declspec(dllimport) #endif #else - #define MESHTOOLS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_MESHTOOLS_EXPORT __attribute__ ((visibility ("default"))) #endif #endif diff --git a/src/Physics/AbstractShape.h b/src/Physics/AbstractShape.h index c4e6dff67..cebb5f61e 100644 --- a/src/Physics/AbstractShape.h +++ b/src/Physics/AbstractShape.h @@ -65,7 +65,7 @@ namespace Implementation { See @ref collision-detection for brief introduction. @see AbstractShape2D, AbstractShape3D */ -template class PHYSICS_EXPORT AbstractShape { +template class MAGNUM_PHYSICS_EXPORT AbstractShape { public: /** @brief Dimension count */ static const std::uint8_t Dimensions = dimensions; @@ -100,12 +100,12 @@ template class PHYSICS_EXPORT AbstractShape { virtual Type type() const = 0; /** - * @brief Apply transformation + * @brief Apply transformation matrix * - * Applies transformation to user-defined shape properties and caches - * them for later usage in collision detection. + * Applies transformation matrix to user-defined shape properties and + * caches them for later usage in collision detection. */ - virtual void applyTransformation(const typename DimensionTraits::MatrixType& transformation) = 0; + virtual void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) = 0; /** * @brief Detect collision with other shape @@ -126,8 +126,8 @@ typedef AbstractShape<3> AbstractShape3D; /** @debugoperator{Magnum::Physics::AbstractShape} */ #ifndef DOXYGEN_GENERATING_OUTPUT -Debug PHYSICS_EXPORT operator<<(Debug debug, AbstractShape2D::Type value); -Debug PHYSICS_EXPORT operator<<(Debug debug, AbstractShape3D::Type value); +Debug MAGNUM_PHYSICS_EXPORT operator<<(Debug debug, AbstractShape2D::Type value); +Debug MAGNUM_PHYSICS_EXPORT operator<<(Debug debug, AbstractShape3D::Type value); #else template Debug operator<<(Debug debug, typename AbstractShape::Type value); #endif diff --git a/src/Physics/AxisAlignedBox.cpp b/src/Physics/AxisAlignedBox.cpp index 8b15efa27..9c2f004cf 100644 --- a/src/Physics/AxisAlignedBox.cpp +++ b/src/Physics/AxisAlignedBox.cpp @@ -20,9 +20,9 @@ namespace Magnum { namespace Physics { -template void AxisAlignedBox::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { - _transformedPosition = (transformation*typename DimensionTraits::PointType(_position)).vector(); - _transformedSize = transformation.rotationScaling()*_size; +template void AxisAlignedBox::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { + _transformedPosition = (matrix*typename DimensionTraits::PointType(_position)).vector(); + _transformedSize = matrix.rotationScaling()*_size; } template class AxisAlignedBox<2>; diff --git a/src/Physics/AxisAlignedBox.h b/src/Physics/AxisAlignedBox.h index 2c00e8f35..b94a1c70e 100644 --- a/src/Physics/AxisAlignedBox.h +++ b/src/Physics/AxisAlignedBox.h @@ -31,7 +31,7 @@ namespace Magnum { namespace Physics { @see AxisAlignedBox2D, AxisAlignedBox3D */ -template class PHYSICS_EXPORT AxisAlignedBox: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT AxisAlignedBox: public AbstractShape { public: /** @brief Constructor */ inline AxisAlignedBox(const typename DimensionTraits::VectorType& position, const typename DimensionTraits::VectorType& size): _position(position), _transformedPosition(position), _size(size), _transformedSize(size) {} @@ -40,7 +40,7 @@ template class PHYSICS_EXPORT AxisAlignedBox: public Ab return AbstractShape::Type::AxisAlignedBox; } - void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; /** @brief Position */ inline typename DimensionTraits::VectorType position() const { diff --git a/src/Physics/Box.cpp b/src/Physics/Box.cpp index e1ed39501..d71c6d570 100644 --- a/src/Physics/Box.cpp +++ b/src/Physics/Box.cpp @@ -20,8 +20,8 @@ namespace Magnum { namespace Physics { -template void Box::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { - _transformedTransformation = (transformation*_transformation); +template void Box::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { + _transformedTransformation = matrix*_transformation; } template class Box<2>; diff --git a/src/Physics/Box.h b/src/Physics/Box.h index 87f259a12..828f9e2af 100644 --- a/src/Physics/Box.h +++ b/src/Physics/Box.h @@ -33,7 +33,7 @@ namespace Magnum { namespace Physics { @todo Use quat + position + size instead? @see Box2D, Box3D */ -template class PHYSICS_EXPORT Box: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Box: public AbstractShape { public: /** @brief Constructor */ inline Box(const typename DimensionTraits::MatrixType& transformation): _transformation(transformation), _transformedTransformation(transformation) {} @@ -42,7 +42,7 @@ template class PHYSICS_EXPORT Box: public AbstractShape return AbstractShape::Type::Box; } - void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; /** @brief Transformation */ inline typename DimensionTraits::MatrixType transformation() const { diff --git a/src/Physics/Capsule.cpp b/src/Physics/Capsule.cpp index 422bd12bb..8fc516ba6 100644 --- a/src/Physics/Capsule.cpp +++ b/src/Physics/Capsule.cpp @@ -27,10 +27,10 @@ using namespace Magnum::Math::Geometry; namespace Magnum { namespace Physics { -template void Capsule::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { - _transformedA = (transformation*typename DimensionTraits::PointType(_a)).vector(); - _transformedB = (transformation*typename DimensionTraits::PointType(_b)).vector(); - float scaling = (transformation.rotationScaling()*typename DimensionTraits::VectorType(1/Constants::sqrt3())).length(); +template void Capsule::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { + _transformedA = (matrix*typename DimensionTraits::PointType(_a)).vector(); + _transformedB = (matrix*typename DimensionTraits::PointType(_b)).vector(); + float scaling = (matrix.rotationScaling()*typename DimensionTraits::VectorType(1/Constants::sqrt3())).length(); _transformedRadius = scaling*_radius; } diff --git a/src/Physics/Capsule.h b/src/Physics/Capsule.h index 3c5aad2d6..f279985de 100644 --- a/src/Physics/Capsule.h +++ b/src/Physics/Capsule.h @@ -34,7 +34,7 @@ Unlike other elements the capsule doesn't support asymmetric scaling. When applying transformation, the scale factor is averaged from all axes. @see Capsule2D, Capsule3D */ -template class PHYSICS_EXPORT Capsule: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Capsule: public AbstractShape { public: /** @brief Constructor */ inline Capsule(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b, float radius): _a(a), _transformedA(a), _b(b), _transformedB(b), _radius(radius), _transformedRadius(radius) {} @@ -43,7 +43,7 @@ template class PHYSICS_EXPORT Capsule: public AbstractS return AbstractShape::Type::Capsule; } - void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; bool collides(const AbstractShape* other) const override; diff --git a/src/Physics/DebugDrawResourceManager.cpp b/src/Physics/DebugDrawResourceManager.cpp index 8e958bc57..ba2560e02 100644 --- a/src/Physics/DebugDrawResourceManager.cpp +++ b/src/Physics/DebugDrawResourceManager.cpp @@ -43,8 +43,8 @@ template SceneGraph::Drawable* DebugDrawRes return renderer; } -template SceneGraph::Drawable<2> PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<2>* shape, ResourceKey options); -template SceneGraph::Drawable<3> PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<3>* shape, ResourceKey options); +template SceneGraph::Drawable<2> MAGNUM_PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<2>* shape, ResourceKey options); +template SceneGraph::Drawable<3> MAGNUM_PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<3>* shape, ResourceKey options); void DebugDrawResourceManager::createDebugMesh(Implementation::DebugRenderer<2>* renderer, AbstractShape2D* shape) { switch(shape->type()) { diff --git a/src/Physics/DebugDrawResourceManager.h b/src/Physics/DebugDrawResourceManager.h index d7a2fff44..ffabe9350 100644 --- a/src/Physics/DebugDrawResourceManager.h +++ b/src/Physics/DebugDrawResourceManager.h @@ -43,7 +43,7 @@ namespace Physics { namespace Implementation { }} #endif -extern template ResourceManager PHYSICS_EXPORT *& ResourceManager::internalInstance(); +extern template ResourceManager MAGNUM_PHYSICS_EXPORT *& ResourceManager::internalInstance(); namespace Physics { @@ -81,7 +81,7 @@ ObjectShape2D* shape; group.add(DebugDrawResourceManager::createDebugRenderer(shape, "red")); @endcode */ -class PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager { +class MAGNUM_PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager { public: #ifdef DOXYGEN_GENERATING_OUTPUT /** @brief %Options */ diff --git a/src/Physics/Implementation/AxisAlignedBoxRenderer.cpp b/src/Physics/Implementation/AxisAlignedBoxRenderer.cpp index d53732742..97102bf35 100644 --- a/src/Physics/Implementation/AxisAlignedBoxRenderer.cpp +++ b/src/Physics/Implementation/AxisAlignedBoxRenderer.cpp @@ -26,7 +26,7 @@ template void AxisAlignedBoxRenderer::draw( typename DimensionTraits::MatrixType transformation = DimensionTraits::MatrixType::translation(axisAlignedBox.transformedPosition())* DimensionTraits::MatrixType::scaling(axisAlignedBox.transformedSize()); - this->shader->setTransformationProjection(camera->projectionMatrix()*camera->cameraMatrix()*transformation) + this->shader->setTransformationProjectionMatrix(camera->projectionMatrix()*camera->cameraMatrix()*transformation) ->setColor(options->color) ->use(); this->mesh->draw(); diff --git a/src/Physics/Implementation/BoxRenderer.cpp b/src/Physics/Implementation/BoxRenderer.cpp index ea4531324..840c6b306 100644 --- a/src/Physics/Implementation/BoxRenderer.cpp +++ b/src/Physics/Implementation/BoxRenderer.cpp @@ -23,7 +23,7 @@ namespace Magnum { namespace Physics { namespace Implementation { template void BoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType&, typename SceneGraph::AbstractCamera* camera) { - this->shader->setTransformationProjection(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation()) + this->shader->setTransformationProjectionMatrix(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation()) ->setColor(options->color) ->use(); this->mesh->draw(); diff --git a/src/Physics/Line.cpp b/src/Physics/Line.cpp index 65533e3ef..49fbe566e 100644 --- a/src/Physics/Line.cpp +++ b/src/Physics/Line.cpp @@ -20,9 +20,9 @@ namespace Magnum { namespace Physics { -template void Line::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { - _transformedA = (transformation*typename DimensionTraits::PointType(_a)).vector(); - _transformedB = (transformation*typename DimensionTraits::PointType(_b)).vector(); +template void Line::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { + _transformedA = (matrix*typename DimensionTraits::PointType(_a)).vector(); + _transformedB = (matrix*typename DimensionTraits::PointType(_b)).vector(); } /* Explicitly instantiate the templates */ diff --git a/src/Physics/Line.h b/src/Physics/Line.h index df509d87d..9246133a4 100644 --- a/src/Physics/Line.h +++ b/src/Physics/Line.h @@ -32,7 +32,7 @@ namespace Magnum { namespace Physics { @see Line2D, Line3D @todo collision detection of two Line2D */ -template class PHYSICS_EXPORT Line: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Line: public AbstractShape { public: /** @brief Constructor */ inline Line(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): _a(a), _transformedA(a), _b(b), _transformedB(b) {} @@ -41,7 +41,7 @@ template class PHYSICS_EXPORT Line: public AbstractShap return AbstractShape::Type::Line; } - void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; /** @brief First point */ inline typename DimensionTraits::VectorType a() const { diff --git a/src/Physics/ObjectShape.cpp b/src/Physics/ObjectShape.cpp index 446433d5a..766a475a9 100644 --- a/src/Physics/ObjectShape.cpp +++ b/src/Physics/ObjectShape.cpp @@ -36,8 +36,8 @@ template void ObjectShape::markDirty() { group()->setDirty(); } -template void ObjectShape::clean(const typename DimensionTraits::MatrixType& absoluteTransformation) { - if(_shape) _shape->applyTransformation(absoluteTransformation); +template void ObjectShape::clean(const typename DimensionTraits::MatrixType& absoluteTransformationMatrix) { + if(_shape) _shape->applyTransformationMatrix(absoluteTransformationMatrix); } template class ObjectShape<2>; diff --git a/src/Physics/ObjectShape.h b/src/Physics/ObjectShape.h index 8a2d23d6a..b1d04e1fd 100644 --- a/src/Physics/ObjectShape.h +++ b/src/Physics/ObjectShape.h @@ -32,7 +32,7 @@ namespace Magnum { namespace Physics { Adds shape for collision detection to object. @see ObjectShape2D, ObjectShape3D */ -template class PHYSICS_EXPORT ObjectShape: public SceneGraph::AbstractGroupedFeature> { +template class MAGNUM_PHYSICS_EXPORT ObjectShape: public SceneGraph::AbstractGroupedFeature> { public: /** * @brief Constructor @@ -78,7 +78,7 @@ template class PHYSICS_EXPORT ObjectShape: public Scene void markDirty() override; /** Applies transformation to associated shape. */ - void clean(const typename DimensionTraits::MatrixType& absoluteTransformation) override; + void clean(const typename DimensionTraits::MatrixType& absoluteTransformationMatrix) override; private: AbstractShape* _shape; diff --git a/src/Physics/ObjectShapeGroup.h b/src/Physics/ObjectShapeGroup.h index e05233434..4e2c1a188 100644 --- a/src/Physics/ObjectShapeGroup.h +++ b/src/Physics/ObjectShapeGroup.h @@ -34,7 +34,7 @@ namespace Magnum { namespace Physics { @see ObjectShapeGroup2D, ObjectShapeGroup3D */ -template class PHYSICS_EXPORT ObjectShapeGroup: public SceneGraph::FeatureGroup> { +template class MAGNUM_PHYSICS_EXPORT ObjectShapeGroup: public SceneGraph::FeatureGroup> { friend class ObjectShape; public: diff --git a/src/Physics/Plane.cpp b/src/Physics/Plane.cpp index e1ddf5ac5..4798b991c 100644 --- a/src/Physics/Plane.cpp +++ b/src/Physics/Plane.cpp @@ -27,9 +27,9 @@ using namespace Magnum::Math::Geometry; namespace Magnum { namespace Physics { -void Plane::applyTransformation(const Matrix4& transformation) { - _transformedPosition = (transformation*Magnum::Point3D(_position)).xyz(); - _transformedNormal = transformation.rotation()*_normal; +void Plane::applyTransformationMatrix(const Matrix4& matrix) { + _transformedPosition = (matrix*Magnum::Point3D(_position)).xyz(); + _transformedNormal = matrix.rotation()*_normal; } bool Plane::collides(const AbstractShape<3>* other) const { diff --git a/src/Physics/Plane.h b/src/Physics/Plane.h index 253e41484..4a622ec58 100644 --- a/src/Physics/Plane.h +++ b/src/Physics/Plane.h @@ -28,7 +28,7 @@ namespace Magnum { namespace Physics { /** @brief Infinite plane, defined by position and normal (3D only) */ -class PHYSICS_EXPORT Plane: public AbstractShape<3> { +class MAGNUM_PHYSICS_EXPORT Plane: public AbstractShape<3> { public: /** @brief Constructor */ inline Plane(const Vector3& position, const Vector3& normal): _position(position), _transformedPosition(position), _normal(normal), _transformedNormal(normal) {} @@ -36,10 +36,10 @@ class PHYSICS_EXPORT Plane: public AbstractShape<3> { inline Type type() const override { return Type::Plane; } #ifndef DOXYGEN_GENERATING_OUTPUT - void applyTransformation(const Matrix4& transformation) override; + void applyTransformationMatrix(const Matrix4& matrix) override; bool collides(const AbstractShape<3>* other) const override; #else - void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; bool collides(const AbstractShape* other) const override; #endif diff --git a/src/Physics/Point.cpp b/src/Physics/Point.cpp index 06850fd68..53f697109 100644 --- a/src/Physics/Point.cpp +++ b/src/Physics/Point.cpp @@ -20,8 +20,8 @@ namespace Magnum { namespace Physics { -template void Point::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { - _transformedPosition = (transformation*typename DimensionTraits::PointType(_position)).vector(); +template void Point::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { + _transformedPosition = (matrix*typename DimensionTraits::PointType(_position)).vector(); } template class Point<2>; diff --git a/src/Physics/Point.h b/src/Physics/Point.h index a228173f9..5c8e48574 100644 --- a/src/Physics/Point.h +++ b/src/Physics/Point.h @@ -31,7 +31,7 @@ namespace Magnum { namespace Physics { @see Point2D, Point3D */ -template class PHYSICS_EXPORT Point: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Point: public AbstractShape { public: /** @brief Constructor */ inline Point(const typename DimensionTraits::VectorType& position): _position(position), _transformedPosition(position) {} @@ -40,7 +40,7 @@ template class PHYSICS_EXPORT Point: public AbstractSha return AbstractShape::Type::Point; } - void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; /** @brief Position */ inline typename DimensionTraits::VectorType position() const { diff --git a/src/Physics/ShapeGroup.cpp b/src/Physics/ShapeGroup.cpp index 3352a2664..d77a0ce18 100644 --- a/src/Physics/ShapeGroup.cpp +++ b/src/Physics/ShapeGroup.cpp @@ -43,9 +43,9 @@ template ShapeGroup& ShapeGroup return *this; } -template void ShapeGroup::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { - if(a) a->applyTransformation(transformation); - if(b) b->applyTransformation(transformation); +template void ShapeGroup::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { + if(a) a->applyTransformationMatrix(matrix); + if(b) b->applyTransformationMatrix(matrix); } template bool ShapeGroup::collides(const AbstractShape* other) const { diff --git a/src/Physics/ShapeGroup.h b/src/Physics/ShapeGroup.h index 04992413d..88fd7bd1b 100644 --- a/src/Physics/ShapeGroup.h +++ b/src/Physics/ShapeGroup.h @@ -57,7 +57,7 @@ Result of logical operations on shapes. See @ref collision-detection for brief introduction. @see ShapeGroup2D, ShapeGroup3D */ -template class PHYSICS_EXPORT ShapeGroup: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT ShapeGroup: public AbstractShape { #ifndef DOXYGEN_GENERATING_OUTPUT // template friend constexpr operator~(const T& a) -> enableIfIsBaseType; // template friend constexpr operator~(T&& a) -> enableIfIsBaseType; @@ -105,7 +105,7 @@ template class PHYSICS_EXPORT ShapeGroup: public Abstra return AbstractShape::Type::ShapeGroup; } - void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; bool collides(const AbstractShape* other) const override; diff --git a/src/Physics/Sphere.cpp b/src/Physics/Sphere.cpp index 94b971b3e..9bd6f754e 100644 --- a/src/Physics/Sphere.cpp +++ b/src/Physics/Sphere.cpp @@ -39,9 +39,9 @@ namespace { } } -template void Sphere::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { - _transformedPosition = (transformation*typename DimensionTraits::PointType(_position)).vector(); - float scaling = (transformation.rotationScaling()*unitVector()).length(); +template void Sphere::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { + _transformedPosition = (matrix*typename DimensionTraits::PointType(_position)).vector(); + float scaling = (matrix.rotationScaling()*unitVector()).length(); _transformedRadius = scaling*_radius; } diff --git a/src/Physics/Sphere.h b/src/Physics/Sphere.h index f77cf8415..083fea64e 100644 --- a/src/Physics/Sphere.h +++ b/src/Physics/Sphere.h @@ -34,7 +34,7 @@ Unlike other elements the sphere doesn't support asymmetric scaling. When applying transformation, the scale factor is averaged from all axes. @see Sphere2D, Sphere3D */ -template class PHYSICS_EXPORT Sphere: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Sphere: public AbstractShape { public: /** @brief Constructor */ inline Sphere(const typename DimensionTraits::VectorType& position, float radius): _position(position), _transformedPosition(position), _radius(radius), _transformedRadius(radius) {} @@ -43,7 +43,7 @@ template class PHYSICS_EXPORT Sphere: public AbstractSh return AbstractShape::Type::Sphere; } - void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; bool collides(const AbstractShape* other) const override; diff --git a/src/Physics/Test/AxisAlignedBoxTest.cpp b/src/Physics/Test/AxisAlignedBoxTest.cpp index da5cd0894..a3b8595d8 100644 --- a/src/Physics/Test/AxisAlignedBoxTest.cpp +++ b/src/Physics/Test/AxisAlignedBoxTest.cpp @@ -30,11 +30,11 @@ AxisAlignedBoxTest::AxisAlignedBoxTest() { void AxisAlignedBoxTest::applyTransformation() { Physics::AxisAlignedBox3D box({-1.0f, -2.0f, -3.0f}, {1.0f, 2.0f, 3.0f}); - box.applyTransformation(Matrix4::scaling({2.0f, -1.0f, 1.5f})); + box.applyTransformationMatrix(Matrix4::scaling({2.0f, -1.0f, 1.5f})); CORRADE_COMPARE(box.transformedPosition(), Vector3(-2.0f, 2.0f, -4.5f)); CORRADE_COMPARE(box.transformedSize(), Vector3(2.0f, -2.0f, 4.5f)); - box.applyTransformation(Matrix4::translation(Vector3(1.0f))*Matrix4::rotation(deg(90.0f), Vector3::xAxis())); + box.applyTransformationMatrix(Matrix4::translation(Vector3(1.0f))*Matrix4::rotation(deg(90.0f), Vector3::xAxis())); CORRADE_COMPARE(box.transformedPosition(), Vector3(0.0f, 4.0f, -1.0f)); CORRADE_COMPARE(box.transformedSize(), Vector3(1.0f, -3.0f, 2.0f)); } diff --git a/src/Physics/Test/BoxTest.cpp b/src/Physics/Test/BoxTest.cpp index 32c04ff48..824ce34d9 100644 --- a/src/Physics/Test/BoxTest.cpp +++ b/src/Physics/Test/BoxTest.cpp @@ -29,7 +29,7 @@ BoxTest::BoxTest() { void BoxTest::applyTransformation() { Physics::Box3D box(Matrix4::translation({1.0f, 2.0f, -3.0f})); - box.applyTransformation(Matrix4::scaling({2.0f, -1.0f, 1.5f})); + box.applyTransformationMatrix(Matrix4::scaling({2.0f, -1.0f, 1.5f})); CORRADE_COMPARE(box.transformedTransformation(), Matrix4::scaling({2.0f, -1.0f, 1.5f})*Matrix4::translation({1.0f, 2.0f, -3.0f})); } diff --git a/src/Physics/Test/CapsuleTest.cpp b/src/Physics/Test/CapsuleTest.cpp index 698778a90..04c85235b 100644 --- a/src/Physics/Test/CapsuleTest.cpp +++ b/src/Physics/Test/CapsuleTest.cpp @@ -32,13 +32,13 @@ CapsuleTest::CapsuleTest() { void CapsuleTest::applyTransformation() { Physics::Capsule3D capsule({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}, 7.0f); - capsule.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::zAxis())); + capsule.applyTransformationMatrix(Matrix4::rotation(deg(90.0f), Vector3::zAxis())); CORRADE_COMPARE(capsule.transformedA(), Vector3(-2.0f, 1.0f, 3.0f)); CORRADE_COMPARE(capsule.transformedB(), Vector3(2.0f, -1.0f, -3.0f)); CORRADE_COMPARE(capsule.radius(), 7.0f); /* Apply average scaling to radius */ - capsule.applyTransformation(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); + capsule.applyTransformationMatrix(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); CORRADE_COMPARE(capsule.transformedRadius(), Constants::sqrt3()*7.0f); } diff --git a/src/Physics/Test/LineTest.cpp b/src/Physics/Test/LineTest.cpp index 2a673d33c..2de48f44a 100644 --- a/src/Physics/Test/LineTest.cpp +++ b/src/Physics/Test/LineTest.cpp @@ -29,7 +29,7 @@ LineTest::LineTest() { void LineTest::applyTransformation() { Physics::Line3D line({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}); - line.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::zAxis())); + line.applyTransformationMatrix(Matrix4::rotation(deg(90.0f), Vector3::zAxis())); CORRADE_COMPARE(line.transformedA(), Vector3(-2.0f, 1.0f, 3.0f)); CORRADE_COMPARE(line.transformedB(), Vector3(2.0f, -1.0f, -3.0f)); } diff --git a/src/Physics/Test/PlaneTest.cpp b/src/Physics/Test/PlaneTest.cpp index 294032de7..2ec0ab9d0 100644 --- a/src/Physics/Test/PlaneTest.cpp +++ b/src/Physics/Test/PlaneTest.cpp @@ -33,12 +33,12 @@ PlaneTest::PlaneTest() { void PlaneTest::applyTransformation() { Physics::Plane plane({1.0f, 2.0f, 3.0f}, {Constants::sqrt2(), -Constants::sqrt2(), 0}); - plane.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::xAxis())); + plane.applyTransformationMatrix(Matrix4::rotation(deg(90.0f), Vector3::xAxis())); CORRADE_COMPARE(plane.transformedPosition(), Vector3(1.0f, -3.0f, 2.0f)); CORRADE_COMPARE(plane.transformedNormal(), Vector3(Constants::sqrt2(), 0, -Constants::sqrt2())); /* The normal should stay normalized */ - plane.applyTransformation(Matrix4::scaling({1.5f, 2.0f, 3.0f})); + plane.applyTransformationMatrix(Matrix4::scaling({1.5f, 2.0f, 3.0f})); CORRADE_COMPARE(plane.transformedPosition(), Vector3(1.5f, 4.0f, 9.0f)); CORRADE_COMPARE(plane.transformedNormal(), Vector3(Constants::sqrt2(), -Constants::sqrt2(), 0)); } diff --git a/src/Physics/Test/PointTest.cpp b/src/Physics/Test/PointTest.cpp index f6e47e785..25c36bf53 100644 --- a/src/Physics/Test/PointTest.cpp +++ b/src/Physics/Test/PointTest.cpp @@ -28,7 +28,7 @@ PointTest::PointTest() { void PointTest::applyTransformation() { Physics::Point3D point({1.0f, 2.0f, 3.0f}); - point.applyTransformation(Matrix4::translation({5.0f, 6.0f, 7.0f})); + point.applyTransformationMatrix(Matrix4::translation({5.0f, 6.0f, 7.0f})); CORRADE_COMPARE(point.transformedPosition(), Vector3(6.0f, 8.0f, 10.0f)); } diff --git a/src/Physics/Test/ShapeGroupTest.cpp b/src/Physics/Test/ShapeGroupTest.cpp index 01e68e6c0..0dcf6d728 100644 --- a/src/Physics/Test/ShapeGroupTest.cpp +++ b/src/Physics/Test/ShapeGroupTest.cpp @@ -43,7 +43,7 @@ void ShapeGroupTest::copy() { } /* Just to test that it doesn't crash */ - group.applyTransformation(Matrix4::translation(Vector3::xAxis(1.0f))); + group.applyTransformationMatrix(Matrix4::translation(Vector3::xAxis(1.0f))); CORRADE_VERIFY(true); } @@ -54,7 +54,7 @@ void ShapeGroupTest::reference() { ShapeGroup3D group = !(ref(point) || ref(segment)); - group.applyTransformation(Matrix4::translation(Vector3(1.0f))); + group.applyTransformationMatrix(Matrix4::translation(Vector3(1.0f))); CORRADE_VERIFY((point.transformedPosition() == Vector3(2.0f, 3.0f, 4.0f))); CORRADE_VERIFY((segment.transformedA() == Vector3(3.0f, 2.0f, 31.0f))); diff --git a/src/Physics/Test/ShapeTestBase.h b/src/Physics/Test/ShapeTestBase.h index d1d1c2e5f..b1a3bfe29 100644 --- a/src/Physics/Test/ShapeTestBase.h +++ b/src/Physics/Test/ShapeTestBase.h @@ -25,7 +25,7 @@ namespace Magnum { namespace Physics { namespace Test { class ShapeTestBase { protected: template void randomTransformation(T& shape) { - shape.applyTransformation(Matrix4::translation(Vector3(7.0f, 8.0f, -9.0f))); + shape.applyTransformationMatrix(Matrix4::translation(Vector3(7.0f, 8.0f, -9.0f))); } }; diff --git a/src/Physics/Test/SphereTest.cpp b/src/Physics/Test/SphereTest.cpp index f845b942e..3b8414e79 100644 --- a/src/Physics/Test/SphereTest.cpp +++ b/src/Physics/Test/SphereTest.cpp @@ -35,17 +35,17 @@ SphereTest::SphereTest() { void SphereTest::applyTransformation() { Physics::Sphere3D sphere({1.0f, 2.0f, 3.0f}, 7.0f); - sphere.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::yAxis())); + sphere.applyTransformationMatrix(Matrix4::rotation(deg(90.0f), Vector3::yAxis())); CORRADE_COMPARE(sphere.transformedPosition(), Vector3(3.0f, 2.0f, -1.0f)); CORRADE_COMPARE(sphere.transformedRadius(), 7.0f); /* Symmetric scaling */ - sphere.applyTransformation(Matrix4::scaling(Vector3(2.0f))); + sphere.applyTransformationMatrix(Matrix4::scaling(Vector3(2.0f))); CORRADE_COMPARE(sphere.transformedPosition(), Vector3(2.0f, 4.0f, 6.0f)); CORRADE_COMPARE(sphere.transformedRadius(), 14.0f); /* Apply average scaling to radius */ - sphere.applyTransformation(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); + sphere.applyTransformationMatrix(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); CORRADE_COMPARE(sphere.transformedRadius(), Constants::sqrt3()*7.0f); } diff --git a/src/Physics/magnumPhysicsVisibility.h b/src/Physics/magnumPhysicsVisibility.h index f7af6cd73..a2e487560 100644 --- a/src/Physics/magnumPhysicsVisibility.h +++ b/src/Physics/magnumPhysicsVisibility.h @@ -17,12 +17,12 @@ #ifdef _WIN32 #ifdef MagnumPhysics_EXPORTS - #define PHYSICS_EXPORT __declspec(dllexport) + #define MAGNUM_PHYSICS_EXPORT __declspec(dllexport) #else - #define PHYSICS_EXPORT __declspec(dllimport) + #define MAGNUM_PHYSICS_EXPORT __declspec(dllimport) #endif #else - #define PHYSICS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_PHYSICS_EXPORT __attribute__ ((visibility ("default"))) #endif #endif diff --git a/src/Platform/AbstractXApplication.cpp b/src/Platform/AbstractXApplication.cpp index 50948e61b..9379d7492 100644 --- a/src/Platform/AbstractXApplication.cpp +++ b/src/Platform/AbstractXApplication.cpp @@ -15,6 +15,8 @@ #include "AbstractXApplication.h" +#include + #include "Context.h" #include "ExtensionWrangler.h" diff --git a/src/Platform/Sdl2Application.cpp b/src/Platform/Sdl2Application.cpp index 165cbcfe8..cf6a31b34 100644 --- a/src/Platform/Sdl2Application.cpp +++ b/src/Platform/Sdl2Application.cpp @@ -15,6 +15,8 @@ #include "Sdl2Application.h" +#include + #include "Context.h" #include "ExtensionWrangler.h" diff --git a/src/Resource.cpp b/src/Resource.cpp new file mode 100644 index 000000000..6093091d4 --- /dev/null +++ b/src/Resource.cpp @@ -0,0 +1,39 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "Resource.h" + +namespace Magnum { + +#ifndef DOXYGEN_GENERATING_OUTPUT +Debug MAGNUM_EXPORT operator<<(Debug debug, ResourceState value) { + switch(value) { + #define _c(value) case ResourceState::value: return debug << "ResourceState::" #value; + _c(NotLoaded) + _c(NotLoadedFallback) + _c(Loading) + _c(LoadingFallback) + _c(NotFound) + _c(NotFoundFallback) + _c(Mutable) + _c(Final) + #undef _c + } + + return debug << "ResourceState::(invalid)"; +} +#endif + +} diff --git a/src/Resource.h b/src/Resource.h new file mode 100644 index 000000000..33085cb7c --- /dev/null +++ b/src/Resource.h @@ -0,0 +1,266 @@ +#ifndef Magnum_Resource_h +#define Magnum_Resource_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file /Resource.h + * @brief Class Magnum::ResourceKey, Magnum::Resource, enum Magnum::ResourceState + */ + +#include + +#include "Magnum.h" + +#include "magnumVisibility.h" + +namespace Magnum { + +/** @relates Resource + * @brief %Resource state + * + * @see Resource::state(), ResourceManager::state() + */ +enum class ResourceState: std::uint8_t { + /** The resource is not yet loaded (and no fallback is available). */ + NotLoaded, + + /** The resource is not yet loaded and fallback resource is used instead. */ + NotLoadedFallback, + + /** The resource is currently loading (and no fallback is available). */ + Loading, + + /** The resource is currently loading and fallback resource is used instead. */ + LoadingFallback, + + /** The resource was not found (and no fallback is available). */ + NotFound, + + /** The resource was not found and fallback resource is used instead. */ + NotFoundFallback, + + /** The resource is loaded, but can be changed by the manager at any time. */ + Mutable, + + /** The resource is loaded and won't be changed by the manager anymore. */ + Final +}; + +/** @debugoperator{Magnum::Resource} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, ResourceState value); + +/** +@brief Key for accessing resource + +@see ResourceManager::referenceCount(), ResourceManager::state(), + ResourceManager::get(), ResourceManager::set(), Resource::key() +*/ +class ResourceKey: public Corrade::Utility::MurmurHash2::Digest { + public: + /** + * @brief Default constructor + * + * Creates zero key. Note that it is not the same as calling other + * constructors with empty string. + */ + inline constexpr ResourceKey() {} + + /** @brief Constructor */ + inline ResourceKey(const std::string& key): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {} + + /** + * @brief Constructor + * @todo constexpr + */ + template inline constexpr ResourceKey(const char(&key)[size]): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {} +}; + +/** @debugoperator{Magnum::ResourceKey} */ +inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const ResourceKey& value) { + return debug << static_cast&>(value); +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + template class ResourceManagerData; +} +#endif + +/** +@brief %Resource reference + +See ResourceManager for more information. +*/ +#ifndef DOXYGEN_GENERATING_OUTPUT +template +#else +template +#endif +class Resource { + friend class Implementation::ResourceManagerData; + + public: + /** + * @brief Default constructor + * + * Creates empty resource. Resources are acquired from the manager by + * calling ResourceManager::get(). + */ + inline Resource(): manager(nullptr), lastCheck(0), _state(ResourceState::Final), data(nullptr) {} + + /** @brief Copy constructor */ + inline Resource(const Resource& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { + if(manager) manager->incrementReferenceCount(_key); + } + + /** @brief Move constructor */ + inline Resource(Resource&& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { + other.manager = nullptr; + } + + /** @brief Destructor */ + inline ~Resource() { + if(manager) manager->decrementReferenceCount(_key); + } + + /** @brief Assignment operator */ + Resource& operator=(const Resource& other) { + if(manager) manager->decrementReferenceCount(_key); + + manager = other.manager; + _key = other._key; + lastCheck = other.lastCheck; + _state = other._state; + data = other.data; + + if(manager) manager->incrementReferenceCount(_key); + return *this; + } + + /** @brief Assignment move operator */ + Resource& operator=(Resource&& other) { + if(manager) manager->decrementReferenceCount(_key); + + manager = other.manager; + _key = other._key; + lastCheck = other.lastCheck; + _state = other._state; + data = other.data; + + other.manager = nullptr; + return *this; + } + + /** @brief Resource key */ + inline ResourceKey key() const { return _key; } + + /** + * @brief %Resource state + * + * @see operator bool(), ResourceManager::state() + */ + inline ResourceState state() { + acquire(); + return _state; + } + + /** + * @brief Whether the resource is available + * + * Returns `false` when resource is not loaded and no fallback is + * available (i.e. state() is either @ref ResourceState "ResourceState::NotLoaded", + * @ref ResourceState "ResourceState::Loading" or + * @ref ResourceState "ResourceState::NotFound"), true otherwise. + */ + inline operator bool() { + acquire(); + return data; + } + + /** + * @brief %Resource data + * + * The resource must be loaded before accessing it. Use boolean + * conversion operator or state() for testing whether it is loaded. + */ + inline operator U*() { + acquire(); + CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr); + return static_cast(data); + } + + /** @overload */ + inline U* operator->() { + acquire(); + CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr); + return static_cast(data); + } + + /** @overload */ + inline U& operator*() { + acquire(); + CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), *static_cast(data)); + return *static_cast(data); + } + + private: + inline Resource(Implementation::ResourceManagerData* manager, ResourceKey key): manager(manager), _key(key), lastCheck(0), _state(ResourceState::NotLoaded), data(nullptr) { + manager->incrementReferenceCount(key); + } + + void acquire() { + /* The data are already final, nothing to do */ + if(_state == ResourceState::Final) return; + + /* Nothing changed since last check */ + if(manager->lastChange() < lastCheck) return; + + /* Acquire new data and save last check time */ + const typename Implementation::ResourceManagerData::Data& d = manager->data(_key); + lastCheck = manager->lastChange(); + + /* Try to get the data */ + data = d.data; + _state = static_cast(d.state); + + /* Data are not available */ + if(!data) { + /* Fallback found, add *Fallback to state */ + if((data = manager->fallback())) { + if(_state == ResourceState::Loading) + _state = ResourceState::LoadingFallback; + else if(_state == ResourceState::NotFound) + _state = ResourceState::NotFoundFallback; + else _state = ResourceState::NotLoadedFallback; + + /* Fallback not found and loading didn't start yet */ + } else if(_state != ResourceState::Loading && _state != ResourceState::NotFound) + _state = ResourceState::NotLoaded; + } + } + + Implementation::ResourceManagerData* manager; + ResourceKey _key; + std::size_t lastCheck; + ResourceState _state; + T* data; +}; + +} + +/* Make the definition complete */ +#include "ResourceManager.h" + +#endif diff --git a/src/ResourceManager.h b/src/ResourceManager.h index fdef3867f..2a3b9ce2b 100644 --- a/src/ResourceManager.h +++ b/src/ResourceManager.h @@ -16,53 +16,47 @@ */ /** @file - * @brief Class Magnum::ResourceManager, Magnum::ResourceKey, Magnum::Resource, enum Magnum::ResourceState, Magnum::ResourceDataState, Magnum::ResourcePolicy + * @brief Class Magnum::ResourceManager, enum Magnum::ResourceDataState, Magnum::ResourcePolicy */ #include -#include -namespace Magnum { - -/** @relates ResourceManager - * @brief %Resource state - * - * @see Resource::state(), ResourceManager::state() - */ -enum class ResourceState: std::uint8_t { - /** The resource is not yet loaded. */ - NotLoaded, - - /** The resource is not yet loaded and fallback resource is used instead. */ - Fallback, +#include "Resource.h" - /** The resource is loaded, but can be changed by the manager at any time. */ - Mutable, - - /** The resource is loaded and won't be changed by the manager anymore. */ - Final -}; +namespace Magnum { /** @relates ResourceManager * @brief %Resource data state * - * @see ResourceManager::set() + * @see ResourceManager::set(), ResourceState */ enum class ResourceDataState: std::uint8_t { + /** + * The resource is currently loading. Parameter @p data in ResourceManager::set() + * should be set to `null`. + */ + Loading = int(ResourceState::Loading), + + /** + * The resource was not found. Parameter @p data in ResourceManager::set() + * should be set to `null`. + */ + NotFound = int(ResourceState::NotFound), + /** * The resource can be changed by the manager in the future. This is * slower, as Resource needs to ask the manager for new version every time * the data are accessed, but allows changing the data for e.g. debugging * purposes. */ - Mutable = int(ResourceState::Mutable), + Mutable = std::uint8_t(ResourceState::Mutable), /** * The resource cannot be changed by the manager in the future. This is * faster, as Resource instances will ask for the data only one time, thus * suitable for production code. */ - Final = int(ResourceState::Final) + Final = std::uint8_t(ResourceState::Final) }; /** @relates ResourceManager @@ -84,33 +78,7 @@ enum class ResourcePolicy: std::uint8_t { ReferenceCounted }; -/** -@brief Key for accessing resource - -@see ResourceManager::referenceCount(), ResourceManager::state(), - ResourceManager::get(), ResourceManager::set(), Resource::key() -*/ -class ResourceKey: public Corrade::Utility::MurmurHash2::Digest { - public: - /** - * @brief Default constructor - * - * Creates zero key. Note that it is not the same as calling other - * constructors with empty string. - */ - inline constexpr ResourceKey() {} - - /** @brief Constructor */ - inline ResourceKey(const std::string& key): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {} - - /** - * @brief Constructor - * @todo constexpr - */ - template inline constexpr ResourceKey(const char(&key)[size]): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {} -}; - -template class Resource; +template class AbstractResourceLoader; #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { @@ -122,46 +90,22 @@ namespace Implementation { }; template class ResourceManagerData { + template friend class Resource; + friend class AbstractResourceLoader; + ResourceManagerData(const ResourceManagerData&) = delete; ResourceManagerData(ResourceManagerData&&) = delete; ResourceManagerData& operator=(const ResourceManagerData&) = delete; ResourceManagerData& operator=(ResourceManagerData&&) = delete; public: - struct Data { - Data& operator=(const Data&) = delete; - Data& operator=(Data&&) = delete; - - inline Data(): data(nullptr), state(ResourceDataState::Mutable), policy(ResourcePolicy::Manual), referenceCount(0) {} - - /* Fugly hack for GCC 4.5, because std::pair doesn't have move constructor yet */ - #ifndef CORRADE_GCC45_COMPATIBILITY - Data(const Data&) = delete; - #else - Data(const Data& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) { - const_cast(other).data = nullptr; - const_cast(other).referenceCount = 0; - } - #endif - - inline Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) { - other.data = nullptr; - other.referenceCount = 0; - } - - inline ~Data() { - CORRADE_ASSERT(referenceCount == 0, "ResourceManager: cannot destruct it while data are still referenced", ); - delete data; - } - - T* data; - ResourceDataState state; - ResourcePolicy policy; - std::size_t referenceCount; - }; - inline virtual ~ResourceManagerData() { delete _fallback; + + if(_loader) { + _loader->manager = nullptr; + delete _loader; + } } inline std::size_t lastChange() const { return _lastChange; } @@ -176,21 +120,45 @@ namespace Implementation { ResourceState state(ResourceKey key) const { auto it = _data.find(key); - if(it == _data.end() || !it->second.data) - return _fallback ? ResourceState::Fallback : ResourceState::NotLoaded; - else - return static_cast(it->second.state); + + /* Resource not loaded */ + if(it == _data.end() || !it->second.data) { + /* Fallback found, add *Fallback to state */ + if(_fallback) { + if(it != _data.end() && it->second.state == ResourceDataState::Loading) + return ResourceState::LoadingFallback; + else if(it != _data.end() && it->second.state == ResourceDataState::NotFound) + return ResourceState::NotFoundFallback; + else return ResourceState::NotLoadedFallback; + } + + /* Fallback not found, loading didn't start yet */ + if(it == _data.end() || (it->second.state != ResourceDataState::Loading && it->second.state != ResourceDataState::NotFound)) + return ResourceState::NotLoaded; + } + + /* Loading / NotFound without fallback, Mutable / Final */ + return static_cast(it->second.state); } template inline Resource get(ResourceKey key) { + /* Ask loader for the data, if they aren't there yet */ + if(_loader && _data.find(key) == _data.end()) + _loader->load(key); + return Resource(this, key); } void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) { auto it = _data.find(key); + /* NotFound / Loading state shouldn't have any data */ + CORRADE_ASSERT((data == nullptr) == (state == ResourceDataState::NotFound || state == ResourceDataState::Loading), + "ResourceManager::set(): data should be null if and only if state is NotFound or Loading", ); + /* Cannot change resource with already final state */ - CORRADE_ASSERT(it == _data.end() || it->second.state != ResourceDataState::Final, "ResourceManager: cannot change already final resource", ); + CORRADE_ASSERT(it == _data.end() || it->second.state != ResourceDataState::Final, + "ResourceManager::set(): cannot change already final resource", ); /* If nothing is referencing reference-counted resource, we're done */ if(policy == ResourcePolicy::ReferenceCounted && (it == _data.end() || it->second.referenceCount == 0)) { @@ -216,6 +184,9 @@ namespace Implementation { ++_lastChange; } + inline T* fallback() { return _fallback; } + inline const T* fallback() const { return _fallback; } + inline void setFallback(T* data) { delete _fallback; _fallback = data; @@ -230,7 +201,53 @@ namespace Implementation { } } - inline T* fallback() const { return _fallback; } + inline AbstractResourceLoader* loader() { return _loader; } + inline const AbstractResourceLoader* loader() const { return _loader; } + + inline void setLoader(AbstractResourceLoader* loader) { + /* Delete previous loader */ + delete _loader; + + /* Add new loader */ + _loader = loader; + if(_loader) _loader->manager = this; + } + + protected: + inline ResourceManagerData(): _fallback(nullptr), _loader(nullptr), _lastChange(0) {} + + private: + struct Data { + Data& operator=(const Data&) = delete; + Data& operator=(Data&&) = delete; + + inline Data(): data(nullptr), state(ResourceDataState::Mutable), policy(ResourcePolicy::Manual), referenceCount(0) {} + + /* Fugly hack for GCC 4.5, because std::pair doesn't have move constructor yet */ + #ifndef CORRADE_GCC45_COMPATIBILITY + Data(const Data&) = delete; + #else + Data(const Data& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) { + const_cast(other).data = nullptr; + const_cast(other).referenceCount = 0; + } + #endif + + inline Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) { + other.data = nullptr; + other.referenceCount = 0; + } + + inline ~Data() { + CORRADE_ASSERT(referenceCount == 0, "ResourceManager: cannot destruct it while data are still referenced", ); + delete data; + } + + T* data; + ResourceDataState state; + ResourcePolicy policy; + std::size_t referenceCount; + }; inline const Data& data(ResourceKey key) { return _data[key]; @@ -248,160 +265,14 @@ namespace Implementation { _data.erase(it); } - protected: - inline ResourceManagerData(): _fallback(nullptr), _lastChange(0) {} - - private: std::unordered_map _data; T* _fallback; + AbstractResourceLoader* _loader; std::size_t _lastChange; }; } #endif -/** -@brief %Resource reference - -See ResourceManager for more information. -*/ -template class Resource { - friend class Implementation::ResourceManagerData; - - public: - /** - * @brief Default constructor - * - * Creates empty resource. Resources are acquired from the manager by - * calling ResourceManager::get(). - */ - inline Resource(): manager(nullptr), lastCheck(0), _state(ResourceState::Final), data(nullptr) {} - - /** @brief Copy constructor */ - inline Resource(const Resource& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { - if(manager) manager->incrementReferenceCount(_key); - } - - /** @brief Move constructor */ - inline Resource(Resource&& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { - other.manager = nullptr; - } - - /** @brief Destructor */ - inline ~Resource() { - if(manager) manager->decrementReferenceCount(_key); - } - - /** @brief Assignment operator */ - Resource& operator=(const Resource& other) { - if(manager) manager->decrementReferenceCount(_key); - - manager = other.manager; - _key = other._key; - lastCheck = other.lastCheck; - _state = other._state; - data = other.data; - - if(manager) manager->incrementReferenceCount(_key); - return *this; - } - - /** @brief Assignment move operator */ - Resource& operator=(Resource&& other) { - if(manager) manager->decrementReferenceCount(_key); - - manager = other.manager; - _key = other._key; - lastCheck = other.lastCheck; - _state = other._state; - data = other.data; - - other.manager = nullptr; - return *this; - } - - /** @brief Resource key */ - inline ResourceKey key() const { return _key; } - - /** - * @brief %Resource state - * - * @see operator bool() - */ - inline ResourceState state() { - acquire(); - return _state; - } - - /** - * @brief Whether the resource is available - * @return False when resource is not loaded and no fallback is - * available, true otherwise. - * - * @see state() - */ - inline operator bool() { - acquire(); - return data; - } - - /** - * @brief %Resource data - * - * The resource must be loaded before accessing it. Use boolean - * conversion operator or state() for testing whether it is loaded. - */ - inline operator U*() { - acquire(); - CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr); - return static_cast(data); - } - - /** @overload */ - inline U* operator->() { - acquire(); - CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr); - return static_cast(data); - } - - /** @overload */ - inline U& operator*() { - acquire(); - CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), *static_cast(data)); - return *static_cast(data); - } - - private: - inline Resource(Implementation::ResourceManagerData* manager, ResourceKey key): manager(manager), _key(key), lastCheck(0), _state(ResourceState::NotLoaded), data(nullptr) { - manager->incrementReferenceCount(key); - } - - void acquire() { - /* The data are already final, nothing to do */ - if(_state == ResourceState::Final) return; - - /* Nothing changed since last check */ - if(manager->lastChange() < lastCheck) return; - - /* Acquire new data and save last check time */ - const typename Implementation::ResourceManagerData::Data& d = manager->data(_key); - lastCheck = manager->lastChange(); - - /* Try to get the data */ - if((data = d.data)) - _state = static_cast(d.state); - else if((data = manager->fallback())) - _state = ResourceState::Fallback; - else - _state = ResourceState::NotLoaded; - } - - Implementation::ResourceManagerData* manager; - ResourceKey _key; - std::size_t lastCheck; - ResourceState _state; - T* data; -}; - /** @brief %Resource manager @@ -468,7 +339,7 @@ cube->draw(); /* Due to too much work involved with explicit template instantiation (all Resource combinations, all ResourceManagerData...), this class doesn't have template implementation file. */ -template class ResourceManager: protected Implementation::ResourceManagerData... { +template class ResourceManager: private Implementation::ResourceManagerData... { public: /** @brief Global instance */ inline static ResourceManager* instance() { @@ -554,13 +425,23 @@ template class ResourceManager: protected Implementation::Resour * } * @endcode * @attention If resource state is already `ResourceState::Final`, - * subsequent updates are not possible. + * subsequent updates are not possible. * @see referenceCount(), state() */ template inline void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) { this->Implementation::ResourceManagerData::set(key, data, state, policy); } + /** @brief Fallback for not found resources */ + template inline T* fallback() { + return this->Implementation::ResourceManagerData::fallback(); + } + + /** @overload */ + template inline const T* fallback() const { + return this->Implementation::ResourceManagerData::fallback(); + } + /** @brief Set fallback for not found resources */ template inline void setFallback(T* data) { return this->Implementation::ResourceManagerData::setFallback(data); @@ -576,6 +457,26 @@ template class ResourceManager: protected Implementation::Resour freeInternal(std::common_type()...); } + /** @brief Loader for given type of resources */ + template inline AbstractResourceLoader* loader() { + return this->Implementation::ResourceManagerData::loader(); + } + + /** @overload */ + template inline const AbstractResourceLoader* loader() const { + return this->Implementation::ResourceManagerData::loader(); + } + + /** + * @brief Set loader for given type of resources + * + * The loader will affect only loading of resources requested after + * that. + */ + template inline void setLoader(AbstractResourceLoader* loader) { + return this->Implementation::ResourceManagerData::setLoader(loader); + } + private: template inline void freeInternal(std::common_type, std::common_type... t) { free(); @@ -593,11 +494,9 @@ template ResourceManager*& ResourceManager:: } #endif -/** @debugoperator{Magnum::ResourceKey} */ -template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const ResourceKey& value) { - return debug << static_cast&>(value); } -} +/* Make the definition complete */ +#include "AbstractResourceLoader.h" #endif diff --git a/src/SceneGraph/AbstractCamera.h b/src/SceneGraph/AbstractCamera.h index 0b538d672..e5a3793f6 100644 --- a/src/SceneGraph/AbstractCamera.h +++ b/src/SceneGraph/AbstractCamera.h @@ -69,7 +69,7 @@ template #else template #endif -class SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature { +class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature { public: /** * @brief Constructor @@ -141,8 +141,8 @@ class SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature { protected: /** Recalculates camera matrix */ - inline void cleanInverted(const typename DimensionTraits::MatrixType& invertedAbsoluteTransformation) override { - _cameraMatrix = invertedAbsoluteTransformation; + inline void cleanInverted(const typename DimensionTraits::MatrixType& invertedAbsoluteTransformationMatrix) override { + _cameraMatrix = invertedAbsoluteTransformationMatrix; } #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/SceneGraph/AbstractFeature.h b/src/SceneGraph/AbstractFeature.h index f48b88034..9e29b77a6 100644 --- a/src/SceneGraph/AbstractFeature.h +++ b/src/SceneGraph/AbstractFeature.h @@ -72,8 +72,8 @@ class CachingFeature: public SceneGraph::AbstractFeature3D<> { } protected: - void clean(const Matrix4& absoluteTransformation) override { - absolutePosition = absoluteTransformation.translation(); + void clean(const Matrix4& absoluteTransformationMatrix) override { + absolutePosition = absoluteTransformationMatrix.translation(); } private: @@ -258,7 +258,7 @@ template class AbstractFeature * Default implementation does nothing. * @see @ref scenegraph-caching, cleanInverted() */ - virtual void clean(const typename DimensionTraits::MatrixType& absoluteTransformation); + virtual void clean(const typename DimensionTraits::MatrixType& absoluteTransformationMatrix); /** * @brief Clean data based on inverted absolute transformation @@ -272,7 +272,7 @@ template class AbstractFeature * Default implementation does nothing. * @see @ref scenegraph-caching, clean() */ - virtual void cleanInverted(const typename DimensionTraits::MatrixType& invertedAbsoluteTransformation); + virtual void cleanInverted(const typename DimensionTraits::MatrixType& invertedAbsoluteTransformationMatrix); /*@}*/ diff --git a/src/SceneGraph/Camera.cpp b/src/SceneGraph/Camera.cpp index dbb8e1081..1bdc04553 100644 --- a/src/SceneGraph/Camera.cpp +++ b/src/SceneGraph/Camera.cpp @@ -19,10 +19,10 @@ namespace Magnum { namespace SceneGraph { #ifndef DOXYGEN_GENERATING_OUTPUT -template class SCENEGRAPH_EXPORT AbstractCamera<2, GLfloat>; -template class SCENEGRAPH_EXPORT AbstractCamera<3, GLfloat>; -template class SCENEGRAPH_EXPORT Camera2D; -template class SCENEGRAPH_EXPORT Camera3D; +template class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera<2, GLfloat>; +template class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera<3, GLfloat>; +template class MAGNUM_SCENEGRAPH_EXPORT Camera2D; +template class MAGNUM_SCENEGRAPH_EXPORT Camera3D; #endif }} diff --git a/src/SceneGraph/Camera2D.h b/src/SceneGraph/Camera2D.h index c38e9d052..072fc6f92 100644 --- a/src/SceneGraph/Camera2D.h +++ b/src/SceneGraph/Camera2D.h @@ -43,7 +43,7 @@ template #else template #endif -class SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2, T> { +class MAGNUM_SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2, T> { public: /** * @brief Constructor diff --git a/src/SceneGraph/Camera3D.h b/src/SceneGraph/Camera3D.h index 4c6056fc5..fae8579ff 100644 --- a/src/SceneGraph/Camera3D.h +++ b/src/SceneGraph/Camera3D.h @@ -48,7 +48,7 @@ template #else template #endif -class SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> { +class MAGNUM_SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> { public: /** * @brief Constructor diff --git a/src/SceneGraph/MatrixTransformation2D.cpp b/src/SceneGraph/MatrixTransformation2D.cpp index 340371b97..7850ca48c 100644 --- a/src/SceneGraph/MatrixTransformation2D.cpp +++ b/src/SceneGraph/MatrixTransformation2D.cpp @@ -20,7 +20,7 @@ namespace Magnum { namespace SceneGraph { #ifndef DOXYGEN_GENERATING_OUTPUT -template class SCENEGRAPH_EXPORT Object>; +template class MAGNUM_SCENEGRAPH_EXPORT Object>; #endif }} diff --git a/src/SceneGraph/MatrixTransformation3D.cpp b/src/SceneGraph/MatrixTransformation3D.cpp index 8c2d78a48..bbcc227e8 100644 --- a/src/SceneGraph/MatrixTransformation3D.cpp +++ b/src/SceneGraph/MatrixTransformation3D.cpp @@ -20,7 +20,7 @@ namespace Magnum { namespace SceneGraph { #ifndef DOXYGEN_GENERATING_OUTPUT -template class SCENEGRAPH_EXPORT Object>; +template class MAGNUM_SCENEGRAPH_EXPORT Object>; #endif }} diff --git a/src/SceneGraph/magnumSceneGraphVisibility.h b/src/SceneGraph/magnumSceneGraphVisibility.h index 2e1c2e758..cd1be31fa 100644 --- a/src/SceneGraph/magnumSceneGraphVisibility.h +++ b/src/SceneGraph/magnumSceneGraphVisibility.h @@ -17,13 +17,13 @@ #ifdef _WIN32 #if defined(MagnumSceneGraph_EXPORTS) || defined(MagnumSceneGraphObjects_EXPORTS) - #define SCENEGRAPH_EXPORT __declspec(dllexport) + #define MAGNUM_SCENEGRAPH_EXPORT __declspec(dllexport) #else - #define SCENEGRAPH_EXPORT __declspec(dllimport) + #define MAGNUM_SCENEGRAPH_EXPORT __declspec(dllimport) #endif #define SCENEGRAPH_LOCAL #else - #define SCENEGRAPH_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_SCENEGRAPH_EXPORT __attribute__ ((visibility ("default"))) #define SCENEGRAPH_LOCAL __attribute__ ((visibility ("hidden"))) #endif diff --git a/src/Shaders/FlatShader.cpp b/src/Shaders/FlatShader.cpp index 96e713653..34859cdfb 100644 --- a/src/Shaders/FlatShader.cpp +++ b/src/Shaders/FlatShader.cpp @@ -76,7 +76,7 @@ template FlatShader::FlatShader() { link(); - transformationProjectionUniform = uniformLocation("transformationProjection"); + transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix"); colorUniform = uniformLocation("color"); } diff --git a/src/Shaders/FlatShader.h b/src/Shaders/FlatShader.h index 68ff70231..e8787cdd4 100644 --- a/src/Shaders/FlatShader.h +++ b/src/Shaders/FlatShader.h @@ -35,7 +35,7 @@ namespace Magnum { namespace Shaders { Draws whole mesh with one color. @see FlatShader2D, FlatShader3D */ -template class SHADERS_EXPORT FlatShader: public AbstractShaderProgram { +template class MAGNUM_SHADERS_EXPORT FlatShader: public AbstractShaderProgram { public: /** @brief Vertex position */ typedef Attribute<0, typename DimensionTraits::PointType> Position; @@ -46,8 +46,8 @@ template class SHADERS_EXPORT FlatShader: public Abstra * @brief Set transformation and projection matrix * @return Pointer to self (for method chaining) */ - FlatShader* setTransformationProjection(const typename DimensionTraits::MatrixType& matrix) { - setUniform(transformationProjectionUniform, matrix); + FlatShader* setTransformationProjectionMatrix(const typename DimensionTraits::MatrixType& matrix) { + setUniform(transformationProjectionMatrixUniform, matrix); return this; } @@ -61,7 +61,7 @@ template class SHADERS_EXPORT FlatShader: public Abstra } private: - GLint transformationProjectionUniform, + GLint transformationProjectionMatrixUniform, colorUniform; }; diff --git a/src/Shaders/FlatShader2D.vert b/src/Shaders/FlatShader2D.vert index dc702bf98..78d041e8d 100644 --- a/src/Shaders/FlatShader2D.vert +++ b/src/Shaders/FlatShader2D.vert @@ -2,7 +2,7 @@ #define in attribute #endif -uniform highp mat3 transformationProjection; +uniform highp mat3 transformationProjectionMatrix; #ifdef EXPLICIT_ATTRIB_LOCATION layout(location = 0) in highp vec3 position; @@ -11,5 +11,5 @@ in highp vec3 position; #endif void main() { - gl_Position.xywz = vec4(transformationProjection*position, 0.0); + gl_Position.xywz = vec4(transformationProjectionMatrix*position, 0.0); } diff --git a/src/Shaders/PhongShader.h b/src/Shaders/PhongShader.h index 9ec97be53..6be38d84c 100644 --- a/src/Shaders/PhongShader.h +++ b/src/Shaders/PhongShader.h @@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders { If supported, uses GLSL 3.20 and @extension{ARB,explicit_attrib_location}, otherwise falls back to GLSL 1.20. */ -class SHADERS_EXPORT PhongShader: public AbstractShaderProgram { +class MAGNUM_SHADERS_EXPORT PhongShader: public AbstractShaderProgram { public: typedef Attribute<0, Point3D> Position; /**< @brief Vertex position */ typedef Attribute<1, Vector3> Normal; /**< @brief Normal direction */ @@ -84,10 +84,10 @@ class SHADERS_EXPORT PhongShader: public AbstractShaderProgram { } /** - * @brief Set transformation matrix and normal matrix + * @brief Set transformation and normal matrix * @return Pointer to self (for method chaining) */ - inline PhongShader* setTransformation(const Matrix4& matrix) { + inline PhongShader* setTransformationMatrix(const Matrix4& matrix) { setUniform(transformationMatrixUniform, matrix); setUniform(normalMatrixUniform, matrix.rotation()); return this; @@ -97,7 +97,7 @@ class SHADERS_EXPORT PhongShader: public AbstractShaderProgram { * @brief Set projection matrix * @return Pointer to self (for method chaining) */ - inline PhongShader* setProjection(const Matrix4& matrix) { + inline PhongShader* setProjectionMatrix(const Matrix4& matrix) { setUniform(projectionMatrixUniform, matrix); return this; } diff --git a/src/Shaders/VertexColorShader.cpp b/src/Shaders/VertexColorShader.cpp index 3a270e994..714756f1b 100644 --- a/src/Shaders/VertexColorShader.cpp +++ b/src/Shaders/VertexColorShader.cpp @@ -77,7 +77,7 @@ template VertexColorShader::VertexColorShad link(); - transformationProjectionUniform = uniformLocation("transformationProjection"); + transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix"); } template class VertexColorShader<2>; diff --git a/src/Shaders/VertexColorShader.h b/src/Shaders/VertexColorShader.h index fbed9f38a..896fefdc6 100644 --- a/src/Shaders/VertexColorShader.h +++ b/src/Shaders/VertexColorShader.h @@ -35,7 +35,7 @@ namespace Magnum { namespace Shaders { Draws vertex-colored mesh. @see VertexColorShader2D, VertexColorShader3D */ -template class SHADERS_EXPORT VertexColorShader: public AbstractShaderProgram { +template class MAGNUM_SHADERS_EXPORT VertexColorShader: public AbstractShaderProgram { public: /** @brief Vertex position */ typedef Attribute<0, typename DimensionTraits::PointType> Position; @@ -46,16 +46,16 @@ template class SHADERS_EXPORT VertexColorShader: public VertexColorShader(); /** - * @brief Set transformation and projection + * @brief Set transformation and projection matrix * @return Pointer to self (for method chaining) */ - inline VertexColorShader* setTransformationProjection(const typename DimensionTraits::MatrixType& matrix) { - setUniform(transformationProjectionUniform, matrix); + inline VertexColorShader* setTransformationProjectionMatrix(const typename DimensionTraits::MatrixType& matrix) { + setUniform(transformationProjectionMatrixUniform, matrix); return this; } private: - GLint transformationProjectionUniform; + GLint transformationProjectionMatrixUniform; }; /** @brief 2D vertex color shader */ diff --git a/src/Shaders/VertexColorShader2D.vert b/src/Shaders/VertexColorShader2D.vert index 12be1d046..88c8fc9a5 100644 --- a/src/Shaders/VertexColorShader2D.vert +++ b/src/Shaders/VertexColorShader2D.vert @@ -3,7 +3,7 @@ #define out varying #endif -uniform highp mat3 transformationProjection; +uniform highp mat3 transformationProjectionMatrix; #ifdef EXPLICIT_ATTRIB_LOCATION layout(location = 0) in highp vec3 position; @@ -16,6 +16,6 @@ in lowp vec3 color; out lowp vec3 interpolatedColor; void main() { - gl_Position.xywz = vec4(transformationProjection*position, 0.0); + gl_Position.xywz = vec4(transformationProjectionMatrix*position, 0.0); interpolatedColor = color; } diff --git a/src/Shaders/magnumShadersVisibility.h b/src/Shaders/magnumShadersVisibility.h index 75d681731..047ee9eca 100644 --- a/src/Shaders/magnumShadersVisibility.h +++ b/src/Shaders/magnumShadersVisibility.h @@ -17,12 +17,12 @@ #ifdef _WIN32 #ifdef MagnumShaders_EXPORTS - #define SHADERS_EXPORT __declspec(dllexport) + #define MAGNUM_SHADERS_EXPORT __declspec(dllexport) #else - #define SHADERS_EXPORT __declspec(dllimport) + #define MAGNUM_SHADERS_EXPORT __declspec(dllimport) #endif #else - #define SHADERS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_SHADERS_EXPORT __attribute__ ((visibility ("default"))) #endif #endif diff --git a/src/Test/CMakeLists.txt b/src/Test/CMakeLists.txt index 2a2c2ebc8..2e6f58e3e 100644 --- a/src/Test/CMakeLists.txt +++ b/src/Test/CMakeLists.txt @@ -1,5 +1,7 @@ corrade_add_test2(ColorTest ColorTest.cpp LIBRARIES MagnumMathTestLib) -corrade_add_test2(ResourceManagerTest ResourceManagerTest.cpp) +corrade_add_test2(MeshTest MeshTest.cpp LIBRARIES Magnum) +corrade_add_test2(ResourceManagerTest ResourceManagerTest.cpp LIBRARIES MagnumTestLib) corrade_add_test2(SwizzleTest SwizzleTest.cpp LIBRARIES MagnumMathTestLib) +corrade_add_test2(TypeTraitsTest TypeTraitsTest.cpp LIBRARIES Magnum) set_target_properties(ResourceManagerTest PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) diff --git a/src/Test/ColorTest.cpp b/src/Test/ColorTest.cpp index 7625131af..176270f2b 100644 --- a/src/Test/ColorTest.cpp +++ b/src/Test/ColorTest.cpp @@ -15,6 +15,8 @@ #include "ColorTest.h" +#include + #include "Color.h" using namespace std; @@ -135,15 +137,21 @@ void ColorTest::debug() { } void ColorTest::configuration() { + Configuration c; + Color3f color3(0.5f, 0.75f, 1.0f); string value3("0.5 0.75 1"); - CORRADE_COMPARE(ConfigurationValue::toString(color3), value3); - CORRADE_COMPARE(ConfigurationValue::fromString(value3), color3); + + c.setValue("color3", color3); + CORRADE_COMPARE(c.value("color3"), value3); + CORRADE_COMPARE(c.value("color3"), color3); Color4f color4(0.5f, 0.75f, 0.0f, 1.0f); string value4("0.5 0.75 0 1"); - CORRADE_COMPARE(ConfigurationValue::toString(color4), value4); - CORRADE_COMPARE(ConfigurationValue::fromString(value4), color4); + + c.setValue("color4", color4); + CORRADE_COMPARE(c.value("color4"), value4); + CORRADE_COMPARE(c.value("color4"), color4); } }} diff --git a/src/Test/MeshTest.cpp b/src/Test/MeshTest.cpp new file mode 100644 index 000000000..0e1a9d949 --- /dev/null +++ b/src/Test/MeshTest.cpp @@ -0,0 +1,47 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "MeshTest.h" + +#include + +#include "Mesh.h" + +CORRADE_TEST_MAIN(Magnum::Test::MeshTest) + +using namespace Corrade::Utility; + +namespace Magnum { namespace Test { + +MeshTest::MeshTest() { + addTests(&MeshTest::debug, + &MeshTest::configuration); +} + +void MeshTest::debug() { + std::ostringstream o; + Debug(&o) << Mesh::Primitive::TriangleFan; + CORRADE_COMPARE(o.str(), "Mesh::Primitive::TriangleFan\n"); +} + +void MeshTest::configuration() { + Configuration c; + + c.setValue("primitive", Mesh::Primitive::LineStrip); + CORRADE_COMPARE(c.value("primitive"), "LineStrip"); + CORRADE_COMPARE(c.value("primitive"), Mesh::Primitive::LineStrip); +} + +}} diff --git a/src/Test/MeshTest.h b/src/Test/MeshTest.h new file mode 100644 index 000000000..051488fbf --- /dev/null +++ b/src/Test/MeshTest.h @@ -0,0 +1,32 @@ +#ifndef Magnum_Test_MeshTest_h +#define Magnum_Test_MeshTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include + +namespace Magnum { namespace Test { + +class MeshTest: public Corrade::TestSuite::Tester { + public: + MeshTest(); + + void debug(); + void configuration(); +}; + +}} + +#endif diff --git a/src/Test/ResourceManagerTest.cpp b/src/Test/ResourceManagerTest.cpp index bf99d364f..9b87ea360 100644 --- a/src/Test/ResourceManagerTest.cpp +++ b/src/Test/ResourceManagerTest.cpp @@ -17,6 +17,7 @@ #include +#include "AbstractResourceLoader.h" #include "ResourceManager.h" using namespace std; @@ -26,94 +27,214 @@ CORRADE_TEST_MAIN(Magnum::Test::ResourceManagerTest) namespace Magnum { namespace Test { +class Data { + public: + static std::size_t count; + + inline Data() { ++count; } + inline ~Data() { --count; } +}; + +typedef Magnum::ResourceManager ResourceManager; + +class IntResourceLoader: public AbstractResourceLoader { + public: + void load(ResourceKey key) override { + AbstractResourceLoader::load(key); + } + + void load() { + set("hello", new std::int32_t(773), ResourceDataState::Final, ResourcePolicy::Resident); + setNotFound("world"); + } +}; + size_t Data::count = 0; ResourceManagerTest::ResourceManagerTest() { - rm = new ResourceManager; - addTests(&ResourceManagerTest::state, + &ResourceManagerTest::stateFallback, + &ResourceManagerTest::stateDisallowed, + &ResourceManagerTest::basic, + &ResourceManagerTest::residentPolicy, &ResourceManagerTest::referenceCountedPolicy, &ResourceManagerTest::manualPolicy, - &ResourceManagerTest::destroy); + &ResourceManagerTest::loader); } void ResourceManagerTest::state() { - ResourceKey questionKey("the-question"); - rm->set(questionKey, new int32_t(10), ResourceDataState::Mutable, ResourcePolicy::Resident); - Resource theQuestion = rm->get(questionKey); - CORRADE_VERIFY(theQuestion.state() == ResourceState::Mutable); - CORRADE_COMPARE(*theQuestion, 10); + ResourceManager rm; + + Resource data = rm.get("data"); + CORRADE_VERIFY(!data); + CORRADE_COMPARE(data.state(), ResourceState::NotLoaded); + CORRADE_COMPARE(rm.state("data"), ResourceState::NotLoaded); + + rm.set("data", nullptr, ResourceDataState::Loading, ResourcePolicy::Resident); + CORRADE_VERIFY(!data); + CORRADE_COMPARE(data.state(), ResourceState::Loading); + CORRADE_COMPARE(rm.state("data"), ResourceState::Loading); + + rm.set("data", nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident); + CORRADE_VERIFY(!data); + CORRADE_COMPARE(data.state(), ResourceState::NotFound); + CORRADE_COMPARE(rm.state("data"), ResourceState::NotFound); + + /* Nothing happened at all */ + CORRADE_COMPARE(Data::count, 0); +} + +void ResourceManagerTest::stateFallback() { + { + ResourceManager rm; + rm.setFallback(new Data); + + Resource data = rm.get("data"); + CORRADE_VERIFY(data); + CORRADE_COMPARE(data.state(), ResourceState::NotLoadedFallback); + CORRADE_COMPARE(rm.state("data"), ResourceState::NotLoadedFallback); + + rm.set("data", nullptr, ResourceDataState::Loading, ResourcePolicy::Resident); + CORRADE_VERIFY(data); + CORRADE_COMPARE(data.state(), ResourceState::LoadingFallback); + CORRADE_COMPARE(rm.state("data"), ResourceState::LoadingFallback); + + rm.set("data", nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident); + CORRADE_VERIFY(data); + CORRADE_COMPARE(data.state(), ResourceState::NotFoundFallback); + CORRADE_COMPARE(rm.state("data"), ResourceState::NotFoundFallback); + + /* Only fallback is here */ + CORRADE_COMPARE(Data::count, 1); + } + + /* Fallback gets destroyed */ + CORRADE_COMPARE(Data::count, 0); +} + +void ResourceManagerTest::stateDisallowed() { + ResourceManager rm; - /* Check that hash function is working properly */ + stringstream out; + Error::setOutput(&out); + + Data d; + rm.set("data", &d, ResourceDataState::Loading, ResourcePolicy::Resident); + CORRADE_COMPARE(out.str(), "ResourceManager::set(): data should be null if and only if state is NotFound or Loading\n"); + + out.str(""); + rm.set("data", nullptr, ResourceDataState::Final, ResourcePolicy::Resident); + CORRADE_COMPARE(out.str(), "ResourceManager::set(): data should be null if and only if state is NotFound or Loading\n"); +} + +void ResourceManagerTest::basic() { + ResourceManager rm; + + /* One mutable, one final */ + ResourceKey questionKey("the-question"); ResourceKey answerKey("the-answer"); - rm->set(answerKey, new int32_t(42), ResourceDataState::Final, ResourcePolicy::Resident); - Resource theAnswer = rm->get(answerKey); - CORRADE_VERIFY(theAnswer.state() == ResourceState::Final); + rm.set(questionKey, new int32_t(10), ResourceDataState::Mutable, ResourcePolicy::Resident); + rm.set(answerKey, new int32_t(42), ResourceDataState::Final, ResourcePolicy::Resident); + Resource theQuestion = rm.get(questionKey); + Resource theAnswer = rm.get(answerKey); + + /* Check basic functionality */ + CORRADE_COMPARE(theQuestion.state(), ResourceState::Mutable); + CORRADE_COMPARE(theAnswer.state(), ResourceState::Final); + CORRADE_COMPARE(*theQuestion, 10); CORRADE_COMPARE(*theAnswer, 42); - - CORRADE_COMPARE(rm->count(), 2); + CORRADE_COMPARE(rm.count(), 2); /* Cannot change already final resource */ stringstream out; Error::setOutput(&out); - rm->set(answerKey, new int32_t(43), ResourceDataState::Mutable, ResourcePolicy::Resident); + rm.set(answerKey, new int32_t(43), ResourceDataState::Mutable, ResourcePolicy::Resident); CORRADE_COMPARE(*theAnswer, 42); - CORRADE_COMPARE(out.str(), "ResourceManager: cannot change already final resource\n"); + CORRADE_COMPARE(out.str(), "ResourceManager::set(): cannot change already final resource\n"); - /* Check non-final resource changes */ - rm->set(questionKey, new int32_t(20), ResourceDataState::Final, ResourcePolicy::Resident); - CORRADE_VERIFY(theQuestion.state() == ResourceState::Final); + /* But non-final can be changed */ + rm.set(questionKey, new int32_t(20), ResourceDataState::Final, ResourcePolicy::Resident); + CORRADE_COMPARE(theQuestion.state(), ResourceState::Final); CORRADE_COMPARE(*theQuestion, 20); } +void ResourceManagerTest::residentPolicy() { + ResourceManager* rm = new ResourceManager; + + rm->set("blah", new Data(), ResourceDataState::Mutable, ResourcePolicy::Resident); + CORRADE_COMPARE(Data::count, 1); + + rm->free(); + CORRADE_COMPARE(Data::count, 1); + + delete rm; + CORRADE_COMPARE(Data::count, 0); +} + void ResourceManagerTest::referenceCountedPolicy() { + ResourceManager rm; + ResourceKey dataRefCountKey("dataRefCount"); /* Reference counted resources must be requested first */ { - rm->set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted); - CORRADE_COMPARE(rm->count(), 0); - Resource data = rm->get(dataRefCountKey); - CORRADE_VERIFY(data.state() == ResourceState::NotLoaded); + rm.set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted); + CORRADE_COMPARE(rm.count(), 0); + Resource data = rm.get(dataRefCountKey); + CORRADE_COMPARE(data.state(), ResourceState::NotLoaded); CORRADE_COMPARE(Data::count, 0); } { - Resource data = rm->get(dataRefCountKey); - CORRADE_COMPARE(rm->count(), 1); - CORRADE_VERIFY(data.state() == ResourceState::NotLoaded); - rm->set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted); - CORRADE_VERIFY(data.state() == ResourceState::Final); + Resource data = rm.get(dataRefCountKey); + CORRADE_COMPARE(rm.count(), 1); + CORRADE_COMPARE(data.state(), ResourceState::NotLoaded); + rm.set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted); + CORRADE_COMPARE(data.state(), ResourceState::Final); CORRADE_COMPARE(Data::count, 1); } - CORRADE_COMPARE(rm->count(), 0); + CORRADE_COMPARE(rm.count(), 0); CORRADE_COMPARE(Data::count, 0); } void ResourceManagerTest::manualPolicy() { + ResourceManager rm; + ResourceKey dataKey("data"); /* Manual free */ { - rm->set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual); - Resource data = rm->get(dataKey); - rm->free(); + rm.set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual); + Resource data = rm.get(dataKey); + rm.free(); } - CORRADE_COMPARE(rm->count(), 1); + CORRADE_COMPARE(rm.count(), 1); CORRADE_COMPARE(Data::count, 1); - rm->free(); - CORRADE_COMPARE(rm->count(), 0); + rm.free(); + CORRADE_COMPARE(rm.count(), 0); CORRADE_COMPARE(Data::count, 0); - rm->set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual); - CORRADE_COMPARE(rm->count(), 1); + rm.set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual); + CORRADE_COMPARE(rm.count(), 1); CORRADE_COMPARE(Data::count, 1); } -void ResourceManagerTest::destroy() { - delete rm; - rm = nullptr; - CORRADE_COMPARE(Data::count, 0); +void ResourceManagerTest::loader() { + ResourceManager rm; + IntResourceLoader loader; + rm.setLoader(&loader); + + Resource data = rm.get("data"); + Resource hello = rm.get("hello"); + Resource world = rm.get("world"); + CORRADE_COMPARE(data.state(), ResourceState::NotLoaded); + CORRADE_COMPARE(hello.state(), ResourceState::Loading); + CORRADE_COMPARE(world.state(), ResourceState::Loading); + + loader.load(); + CORRADE_COMPARE(hello.state(), ResourceState::Final); + CORRADE_COMPARE(*hello, 773); + CORRADE_COMPARE(world.state(), ResourceState::NotFound); } }} diff --git a/src/Test/ResourceManagerTest.h b/src/Test/ResourceManagerTest.h index ef7c1826a..fa95ec724 100644 --- a/src/Test/ResourceManagerTest.h +++ b/src/Test/ResourceManagerTest.h @@ -17,33 +17,20 @@ #include -namespace Magnum { - -template class ResourceManager; - -namespace Test { - -class Data { - public: - static std::size_t count; - - inline Data() { ++count; } - inline ~Data() { --count; } -}; - -typedef Magnum::ResourceManager ResourceManager; +namespace Magnum { namespace Test { class ResourceManagerTest: public Corrade::TestSuite::Tester { public: ResourceManagerTest(); void state(); + void stateFallback(); + void stateDisallowed(); + void basic(); + void residentPolicy(); void referenceCountedPolicy(); void manualPolicy(); - void destroy(); - - private: - ResourceManager* rm; + void loader(); }; }} diff --git a/src/Test/TypeTraitsTest.cpp b/src/Test/TypeTraitsTest.cpp new file mode 100644 index 000000000..521e16019 --- /dev/null +++ b/src/Test/TypeTraitsTest.cpp @@ -0,0 +1,47 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "TypeTraitsTest.h" + +#include + +#include "TypeTraits.h" + +CORRADE_TEST_MAIN(Magnum::Test::TypeTraitsTest) + +using namespace Corrade::Utility; + +namespace Magnum { namespace Test { + +TypeTraitsTest::TypeTraitsTest() { + addTests(&TypeTraitsTest::debug, + &TypeTraitsTest::configuration); +} + +void TypeTraitsTest::debug() { + std::ostringstream o; + Debug(&o) << Type::UnsignedShort; + CORRADE_COMPARE(o.str(), "Type::UnsignedShort\n"); +} + +void TypeTraitsTest::configuration() { + Configuration c; + + c.setValue("type", Type::Byte); + CORRADE_COMPARE(c.value("type"), "Byte"); + CORRADE_COMPARE(c.value("type"), Type::Byte); +} + +}} diff --git a/src/Test/TypeTraitsTest.h b/src/Test/TypeTraitsTest.h new file mode 100644 index 000000000..2f634f50c --- /dev/null +++ b/src/Test/TypeTraitsTest.h @@ -0,0 +1,32 @@ +#ifndef Magnum_Test_TypeTraitsTest_h +#define Magnum_Test_TypeTraitsTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include + +namespace Magnum { namespace Test { + +class TypeTraitsTest: public Corrade::TestSuite::Tester { + public: + TypeTraitsTest(); + + void debug(); + void configuration(); +}; + +}} + +#endif diff --git a/src/TypeTraits.cpp b/src/TypeTraits.cpp index 4dad71afe..2d598de4a 100644 --- a/src/TypeTraits.cpp +++ b/src/TypeTraits.cpp @@ -16,6 +16,7 @@ #include "TypeTraits.h" #include +#include using namespace std; @@ -67,4 +68,64 @@ bool TypeInfo::isIntegral(Type type) { } } +#ifndef DOXYGEN_GENERATING_OUTPUT +Debug operator<<(Debug debug, Type value) { + switch(value) { + #define _c(value) case Type::value: return debug << "Type::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + _c(Float) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + #endif + #undef _c + } + + return debug << "Type::(invalid)"; } +#endif + +} + +namespace Corrade { namespace Utility { + +std::string ConfigurationValue::toString(Magnum::Type value, ConfigurationValueFlags) { + switch(value) { + #define _c(value) case Magnum::Type::value: return #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + _c(Float) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + #endif + #undef _c + } + + return ""; +} + +Magnum::Type ConfigurationValue::fromString(const std::string& stringValue, ConfigurationValueFlags) { + #define _c(value) if(stringValue == #value) return Magnum::Type::value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + #endif + #undef _c + + return Magnum::Type::Float; +} + +}} diff --git a/src/TypeTraits.h b/src/TypeTraits.h index 49e75e871..c6f878e61 100644 --- a/src/TypeTraits.h +++ b/src/TypeTraits.h @@ -19,6 +19,8 @@ * @brief Enum Magnum::Type, class Magnum::TypeOf, Magnum::TypeInfo, Magnum::TypeTraits */ +#include + #include "Math/MathTypeTraits.h" #include "AbstractImage.h" @@ -114,6 +116,9 @@ enum class Type: GLenum { #endif }; +/** @debugoperator{Magnum::TypeInfo} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, Type value); + /** @brief Class for converting Type enum values to types @@ -340,4 +345,25 @@ template struct TypeTraits>: TypeTraits struct MAGNUM_EXPORT ConfigurationValue { + /** + * @brief Writes enum value as string + * + * If the value is invalid, returns empty string. + */ + static std::string toString(Magnum::Type value, ConfigurationValueFlags); + + /** + * @brief Reads enum value as string + * + * If the value is invalid, returns @ref Magnum::Type "Magnum::Type::Float". + */ + static Magnum::Type fromString(const std::string& stringValue, ConfigurationValueFlags); +}; + +}} + #endif