From bb39338008650741b818755603cc3921d6c55452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 7 Apr 2013 13:02:44 +0200 Subject: [PATCH 01/30] Platform: better diagnostic in Sdl2Application::tryCreateContext(). --- src/Platform/Sdl2Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Platform/Sdl2Application.cpp b/src/Platform/Sdl2Application.cpp index d5e5b3855..8289ab5dd 100644 --- a/src/Platform/Sdl2Application.cpp +++ b/src/Platform/Sdl2Application.cpp @@ -94,7 +94,7 @@ bool Sdl2Application::tryCreateContext(Configuration* configuration) { SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, configuration->size().x(), configuration->size().y(), SDL_WINDOW_OPENGL|flags))) { - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window"; + Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); std::exit(2); } From ef0efecc9c295613bdd3c93ee1670868b6dc9ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 7 Apr 2013 13:12:37 +0200 Subject: [PATCH 02/30] Platform: fixed Sdl2Application::tryCreateContext(). It seems that the context is negotiated when creating the window, thus it fails there and not later when actually creating the context. --- src/Platform/Sdl2Application.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Platform/Sdl2Application.cpp b/src/Platform/Sdl2Application.cpp index 8289ab5dd..2470d6639 100644 --- a/src/Platform/Sdl2Application.cpp +++ b/src/Platform/Sdl2Application.cpp @@ -93,10 +93,8 @@ bool Sdl2Application::tryCreateContext(Configuration* configuration) { if(!(window = SDL_CreateWindow(configuration->title().c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, configuration->size().x(), configuration->size().y(), - SDL_WINDOW_OPENGL|flags))) { - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); - std::exit(2); - } + SDL_WINDOW_OPENGL|flags))) + return false; if(!(context = SDL_GL_CreateContext(window))) { SDL_DestroyWindow(window); From a80b4b146dc27e5e2e0b1ea11da56dc743233241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 9 Apr 2013 10:11:38 +0200 Subject: [PATCH 03/30] Math: write Vector2::cross() in terms of perpendicular() and dot(). --- src/Math/Vector2.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Math/Vector2.h b/src/Math/Vector2.h index 4e7b17c00..11a6d4285 100644 --- a/src/Math/Vector2.h +++ b/src/Math/Vector2.h @@ -83,15 +83,16 @@ template class Vector2: public Vector<2, T> { /** * @brief 2D cross product * - * 2D version of cross product, equivalent to calling Vector3::cross() - * with Z coordinate set to `0` and extracting only Z coordinate from - * the result (X and Y coordinates are always zero). - * @f[ - * \boldsymbol a \times \boldsymbol b = a_xb_y - a_yb_x + * 2D version of cross product, also called perp-dot product, + * equivalent to calling Vector3::cross() with Z coordinate set to `0` + * and extracting only Z coordinate from the result (X and Y + * coordinates are always zero). @f[ + * \boldsymbol a \times \boldsymbol b = \boldsymbol a_\perp \cdot \boldsymbol b = a_xb_y - a_yb_x * @f] + * @see perpendicular(), dot(const Vector&, const Vector&) */ inline static T cross(const Vector2& a, const Vector2& b) { - return a.x()*b.y() - a.y()*b.x(); + return Vector<2, T>::dot(a.perpendicular(), b); } /** @copydoc Vector::Vector() */ @@ -129,7 +130,7 @@ template class Vector2: public Vector<2, T> { * Returns vector rotated 90° counterclockwise. @f[ * \boldsymbol v_\perp = \begin{pmatrix} -v_y \\ v_x \end{pmatrix} * @f] - * @see dot(const Vector&, const Vector&), operator-() const + * @see cross(), dot(const Vector&, const Vector&), operator-() const */ inline Vector2 perpendicular() const { return {-y(), x()}; } From 5a377a568eb884f16a4b2a12e67d916fe8343359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 11 Apr 2013 12:58:16 +0200 Subject: [PATCH 04/30] Physics: default constructors for shapes. --- src/Physics/AxisAlignedBox.h | 7 +++++++ src/Physics/Box.h | 7 +++++++ src/Physics/Capsule.h | 7 +++++++ src/Physics/Line.h | 7 +++++++ src/Physics/LineSegment.h | 7 +++++++ src/Physics/Plane.h | 7 +++++++ src/Physics/Point.h | 7 +++++++ src/Physics/Sphere.h | 7 +++++++ 8 files changed, 56 insertions(+) diff --git a/src/Physics/AxisAlignedBox.h b/src/Physics/AxisAlignedBox.h index d987c8674..1a0a1e6d7 100644 --- a/src/Physics/AxisAlignedBox.h +++ b/src/Physics/AxisAlignedBox.h @@ -46,6 +46,13 @@ radius. */ template class MAGNUM_PHYSICS_EXPORT AxisAlignedBox: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates zero sized box positioned at origin. + */ + inline explicit AxisAlignedBox() {} + /** @brief Constructor */ inline explicit AxisAlignedBox(const typename DimensionTraits::VectorType& min, const typename DimensionTraits::VectorType& max): _min(min), _max(max), _transformedMin(min), _transformedMax(max) {} diff --git a/src/Physics/Box.h b/src/Physics/Box.h index e0b79de96..cf7276187 100644 --- a/src/Physics/Box.h +++ b/src/Physics/Box.h @@ -47,6 +47,13 @@ radius. */ template class MAGNUM_PHYSICS_EXPORT Box: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates zero-sized box positioned at origin. + */ + inline explicit Box(): _transformation(DimensionTraits::MatrixType::Zero), _transformedTransformation(DimensionTraits::MatrixType::Zero) {} + /** @brief Constructor */ inline explicit Box(const typename DimensionTraits::MatrixType& transformation): _transformation(transformation), _transformedTransformation(transformation) {} diff --git a/src/Physics/Capsule.h b/src/Physics/Capsule.h index bdb9975d7..7880a7102 100644 --- a/src/Physics/Capsule.h +++ b/src/Physics/Capsule.h @@ -46,6 +46,13 @@ applying transformation, the scale factor is averaged from all axes. */ template class MAGNUM_PHYSICS_EXPORT Capsule: public AbstractShape { public: + /** + * @brief Constructor + * + * Creates zero-sized capsule at origin. + */ + inline explicit Capsule(): _radius(0.0f), _transformedRadius(0.0f) {} + /** @brief Constructor */ inline explicit 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) {} diff --git a/src/Physics/Line.h b/src/Physics/Line.h index 0c9abb333..bfb9bdceb 100644 --- a/src/Physics/Line.h +++ b/src/Physics/Line.h @@ -43,6 +43,13 @@ namespace Magnum { namespace Physics { */ template class MAGNUM_PHYSICS_EXPORT Line: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates line with both points at origin. + */ + inline explicit Line() {} + /** @brief Constructor */ inline explicit Line(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): _a(a), _transformedA(a), _b(b), _transformedB(b) {} diff --git a/src/Physics/LineSegment.h b/src/Physics/LineSegment.h index ab1684480..666764734 100644 --- a/src/Physics/LineSegment.h +++ b/src/Physics/LineSegment.h @@ -39,6 +39,13 @@ namespace Magnum { namespace Physics { */ template class LineSegment: public Line { public: + /** + * @brief Default constructor + * + * Creates line segment with both points at origin. + */ + inline explicit LineSegment() {} + /** @brief Constructor */ inline explicit LineSegment(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): Line(a, b) {} diff --git a/src/Physics/Plane.h b/src/Physics/Plane.h index 7dbf76e22..fbb576eb6 100644 --- a/src/Physics/Plane.h +++ b/src/Physics/Plane.h @@ -39,6 +39,13 @@ namespace Magnum { namespace Physics { /** @brief Infinite plane, defined by position and normal (3D only) */ class MAGNUM_PHYSICS_EXPORT Plane: public AbstractShape<3> { public: + /** + * @brief Default constructor + * + * Creates plane with zero-sized normal at origin. + */ + inline explicit Plane() {} + /** @brief Constructor */ inline explicit Plane(const Vector3& position, const Vector3& normal): _position(position), _transformedPosition(position), _normal(normal), _transformedNormal(normal) {} diff --git a/src/Physics/Point.h b/src/Physics/Point.h index 2ab8f362e..606ad0b51 100644 --- a/src/Physics/Point.h +++ b/src/Physics/Point.h @@ -42,6 +42,13 @@ namespace Magnum { namespace Physics { */ template class MAGNUM_PHYSICS_EXPORT Point: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates point at origin. + */ + inline explicit Point() {} + /** @brief Constructor */ inline explicit Point(const typename DimensionTraits::VectorType& position): _position(position), _transformedPosition(position) {} diff --git a/src/Physics/Sphere.h b/src/Physics/Sphere.h index c1324c550..6f83d2ddb 100644 --- a/src/Physics/Sphere.h +++ b/src/Physics/Sphere.h @@ -46,6 +46,13 @@ applying transformation, the scale factor is averaged from all axes. */ template class MAGNUM_PHYSICS_EXPORT Sphere: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates zero-sized sphere at origin. + */ + inline explicit Sphere(): _radius(0.0f), _transformedRadius(0.0f) {} + /** @brief Constructor */ inline explicit Sphere(const typename DimensionTraits::VectorType& position, Float radius): _position(position), _transformedPosition(position), _radius(radius), _transformedRadius(radius) {} From bf58bb3cb1e717489961bea7353c7cec90b65245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 11 Apr 2013 15:34:58 +0200 Subject: [PATCH 05/30] Math: rework of component-wise matrix and vector functions. First, removed functions which can be done with Vector's member functions and functions from Functions.h. More flexibility and less redundant code which leads to easier SIMD implementation later. Vector4 a; Float b = a.maxAbs(); // before Float b = Math::abs(a).max(); // now Second, removed all functions from RectangularMatrix which are implemented in Vector and added conversion from RectangularMatrix to Vector and back. Also for more flexibility and less redundant code (i.e. reusing SIMD-optimized Vector::max() instead of writing it again). Matrix4x3 a; Float b = a.max(); // before Float b = a.toVector().max(); // now --- src/Math/Algorithms/Test/SvdTest.cpp | 4 +- src/Math/Functions.h | 4 +- src/Math/RectangularMatrix.h | 80 +++++++------------------ src/Math/Test/RectangularMatrixTest.cpp | 66 ++++---------------- src/Math/Test/VectorTest.cpp | 16 ----- src/Math/Vector.h | 48 +++++++-------- 6 files changed, 61 insertions(+), 157 deletions(-) diff --git a/src/Math/Algorithms/Test/SvdTest.cpp b/src/Math/Algorithms/Test/SvdTest.cpp index 3397f92f3..c46448fc4 100644 --- a/src/Math/Algorithms/Test/SvdTest.cpp +++ b/src/Math/Algorithms/Test/SvdTest.cpp @@ -107,14 +107,14 @@ void SvdTest::testFloat() { /* Test composition (single precision is not enough, test for similarity) */ Matrix8f u2(u[0], u[1], u[2], u[3], u[4], Vector8f(), Vector8f(), Vector8f()); Matrix5x8f w2 = Matrix5x8f::fromDiagonal(w); - CORRADE_VERIFY((u2*w2*v.transposed()-af).maxAbs() < 1.0e-5f); + CORRADE_VERIFY(Math::abs((u2*w2*v.transposed()-af).toVector()).max() < 1.0e-5f); /* Test that V is unitary */ CORRADE_COMPARE(v*v.transposed(), Matrix5f(Matrix5f::Identity)); CORRADE_COMPARE(v.transposed()*v, Matrix5f(Matrix5f::Identity)); /* Test W (single precision is not enough, test for similarity) */ - CORRADE_VERIFY((w-expectedf).maxAbs() < 1.0e-5f); + CORRADE_VERIFY(Math::abs(w-expectedf).max() < 1.0e-5f); } }}}} diff --git a/src/Math/Functions.h b/src/Math/Functions.h index f5af1e56a..fb4bafd1b 100644 --- a/src/Math/Functions.h +++ b/src/Math/Functions.h @@ -126,7 +126,7 @@ perform the operations component-wise. /** @brief Minimum -@see min(), clamp() +@see min(), clamp(), Vector::min() */ #ifdef DOXYGEN_GENERATING_OUTPUT template inline T min(T a, T b); @@ -145,7 +145,7 @@ template inline Vector min(const Vector inline T max(const T& a, const T& b); diff --git a/src/Math/RectangularMatrix.h b/src/Math/RectangularMatrix.h index fb869992d..48b86a3f8 100644 --- a/src/Math/RectangularMatrix.h +++ b/src/Math/RectangularMatrix.h @@ -96,6 +96,17 @@ template class RectangularMatrix { return out; } + /** + * @brief Construct matrix from vector + * + * Rolls the vector into matrix, i.e. first `rows` elements of the + * vector will make first column of resulting matrix. + * @see toVector() + */ + inline static RectangularMatrix fromVector(const Vector& vector) { + return *reinterpret_cast*>(vector.data()); + } + /** @brief Construct zero-filled matrix */ inline constexpr /*implicit*/ RectangularMatrix() {} @@ -381,64 +392,17 @@ template class RectangularMatrix { return out; } - /** @brief Sum of values in the matrix */ - T sum() const { - T out(_data[0].sum()); - - for(std::size_t i = 1; i != cols; ++i) - out += _data[i].sum(); - - return out; - } - - /** @brief Product of values in the matrix */ - T product() const { - T out(_data[0].product()); - - for(std::size_t i = 1; i != cols; ++i) - out *= _data[i].product(); - - return out; - } - - /** @brief Minimal value in the matrix */ - T min() const { - T out(_data[0].min()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::min(out, _data[i].min()); - - return out; - } - - /** @brief Minimal absolute value in the matrix */ - T minAbs() const { - T out(_data[0].minAbs()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::min(out, _data[i].minAbs()); - - return out; - } - - /** @brief Maximal value in the matrix */ - T max() const { - T out(_data[0].max()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::max(out, _data[i].max()); - - return out; - } - - /** @brief Maximal absolute value in the matrix */ - T maxAbs() const { - T out(_data[0].maxAbs()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::max(out, _data[i].maxAbs()); - - return out; + /** + * @brief Convert matrix to vector + * + * Returns the matrix unrolled into one large vector, i.e. first column + * of the matrix will make first `rows` elements of resulting vector. + * Useful for performing vector operations with the matrix (e.g. + * summing the elements etc.). + * @see fromVector() + */ + inline Vector toVector() const { + return *reinterpret_cast*>(data()); } private: diff --git a/src/Math/Test/RectangularMatrixTest.cpp b/src/Math/Test/RectangularMatrixTest.cpp index 9ce624889..ab25a608c 100644 --- a/src/Math/Test/RectangularMatrixTest.cpp +++ b/src/Math/Test/RectangularMatrixTest.cpp @@ -54,12 +54,7 @@ class RectangularMatrixTest: public Corrade::TestSuite::Tester { void transposed(); void diagonal(); - void sum(); - void product(); - void min(); - void minAbs(); - void max(); - void maxAbs(); + void vector(); void debug(); void configuration(); @@ -95,12 +90,7 @@ RectangularMatrixTest::RectangularMatrixTest() { &RectangularMatrixTest::transposed, &RectangularMatrixTest::diagonal, - &RectangularMatrixTest::sum, - &RectangularMatrixTest::product, - &RectangularMatrixTest::min, - &RectangularMatrixTest::minAbs, - &RectangularMatrixTest::max, - &RectangularMatrixTest::maxAbs, + &RectangularMatrixTest::vector, &RectangularMatrixTest::debug, &RectangularMatrixTest::configuration}); @@ -338,50 +328,20 @@ void RectangularMatrixTest::diagonal() { CORRADE_COMPARE(b.diagonal(), diagonal); } -void RectangularMatrixTest::sum() { - Matrix2 matrix(Vector2(1.0f, 2.0f), - Vector2(3.0f, 4.0f)); - CORRADE_COMPARE(matrix.sum(), 10.0f); -} - -void RectangularMatrixTest::product() { - Matrix2 matrix(Vector2(1.0f, 2.0f), - Vector2(3.0f, 4.0f)); - CORRADE_COMPARE(matrix.product(), 24.0f); -} - -void RectangularMatrixTest::min() { - /* Check also that initial value isn't initialized to 0 */ - Matrix2 matrix(Vector2(-2.0f, 1.0f), - Vector2(3.0f, 4.0f)); - CORRADE_COMPARE(matrix.min(), -2.0f); -} +void RectangularMatrixTest::vector() { + typedef Vector<3, Int> Vector3i; + typedef RectangularMatrix<4, 3, Int> Matrix4x3i; + typedef Vector<12, Int> Vector12i; -void RectangularMatrixTest::minAbs() { - /* Check that initial value is absolute and also all others */ - Matrix2 a(Vector2(-2.0f, 1.0f), - Vector2(3.0f, 4.0f)); - Matrix2 b(Vector2(3.0f, 4.0f), - Vector2(-2.0f, 1.0f)); - CORRADE_COMPARE(a.minAbs(), 1.0f); - CORRADE_COMPARE(a.minAbs(), 1.0f); -} + Matrix4x3i a(Vector3i(0, 1, 2), + Vector3i(3, 4, 5), + Vector3i(6, 7, 8), + Vector3i(9, 10, 11)); -void RectangularMatrixTest::max() { - /* Check also that initial value isn't initialized to 0 */ - Matrix2 matrix(Vector2(-2.0f, -1.0f), - Vector2(-3.0f, -4.0f)); - CORRADE_COMPARE(matrix.max(), -1.0f); -} + Vector12i b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); -void RectangularMatrixTest::maxAbs() { - /* Check that initial value is absolute and also all others */ - Matrix2 a(Vector2(2.0f, 1.0f), - Vector2(3.0f, -4.0f)); - Matrix2 b(Vector2(3.0f, -4.0f), - Vector2(2.0f, 1.0f)); - CORRADE_COMPARE(a.maxAbs(), 4.0f); - CORRADE_COMPARE(b.maxAbs(), 4.0f); + CORRADE_COMPARE(a.toVector(), b); + CORRADE_COMPARE(Matrix4x3i::fromVector(b), a); } void RectangularMatrixTest::debug() { diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 7c93976b6..583df6b19 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -83,9 +83,7 @@ class VectorTest: public Corrade::TestSuite::Tester { void sum(); void product(); void min(); - void minAbs(); void max(); - void maxAbs(); void projected(); void projectedOntoNormalized(); @@ -130,9 +128,7 @@ VectorTest::VectorTest() { &VectorTest::sum, &VectorTest::product, &VectorTest::min, - &VectorTest::minAbs, &VectorTest::max, - &VectorTest::maxAbs, &VectorTest::projected, &VectorTest::projectedOntoNormalized, @@ -331,23 +327,11 @@ void VectorTest::min() { CORRADE_COMPARE(Vector3(1.0f, -2.0f, 3.0f).min(), -2.0f); } -void VectorTest::minAbs() { - /* Check that initial value is absolute and also all others */ - CORRADE_COMPARE(Vector3(-2.0f, 1.0f, 3.0f).minAbs(), 1.0f); - CORRADE_COMPARE(Vector3(1.0f, -2.0f, 3.0f).minAbs(), 1.0f); -} - void VectorTest::max() { /* Check also that initial value isn't initialized to 0 */ CORRADE_COMPARE(Vector3(-1.0f, -2.0f, -3.0f).max(), -1.0f); } -void VectorTest::maxAbs() { - /* Check that initial value is absolute and also all others */ - CORRADE_COMPARE(Vector3(-5.0f, 1.0f, 3.0f).maxAbs(), 5.0f); - CORRADE_COMPARE(Vector3(1.0f, -5.0f, 3.0f).maxAbs(), 5.0f); -} - void VectorTest::projected() { Vector3 line(1.0f, -1.0f, 0.5f); Vector3 projected = Vector3(1.0f, 2.0f, 3.0f).projected(line); diff --git a/src/Math/Vector.h b/src/Math/Vector.h index e49f1700b..ad4ea4314 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -300,7 +300,7 @@ template class Vector { /** * @brief Add vector * - * @see operator+=() + * @see operator+=(), sum() */ inline Vector operator+(const Vector& other) const { return Vector(*this) += other; @@ -408,7 +408,7 @@ template class Vector { /** * @brief Multiply vector component-wise * - * @see operator*=(const Vector&) + * @see operator*=(const Vector&), product() */ template inline Vector operator*(const Vector& other) const { return Vector(*this) *= other; @@ -499,7 +499,11 @@ template class Vector { return line*dot(*this, line); } - /** @brief Sum of values in the vector */ + /** + * @brief Sum of values in the vector + * + * @see operator+() + */ T sum() const { T out(_data[0]); @@ -509,7 +513,11 @@ template class Vector { return out; } - /** @brief Product of values in the vector */ + /** + * @brief Product of values in the vector + * + * @see operator*(const Vector&) + */ T product() const { T out(_data[0]); @@ -519,7 +527,11 @@ template class Vector { return out; } - /** @brief Minimal value in the vector */ + /** + * @brief Minimal value in the vector + * + * @see Math::min() + */ T min() const { T out(_data[0]); @@ -529,17 +541,11 @@ template class Vector { return out; } - /** @brief Minimal absolute value in the vector */ - T minAbs() const { - T out(std::abs(_data[0])); - - for(std::size_t i = 1; i != size; ++i) - out = std::min(out, std::abs(_data[i])); - - return out; - } - - /** @brief Maximal value in the vector */ + /** + * @brief Maximal value in the vector + * + * @see Math::max() + */ T max() const { T out(_data[0]); @@ -549,16 +555,6 @@ template class Vector { return out; } - /** @brief Maximal absolute value in the vector */ - T maxAbs() const { - T out(std::abs(_data[0])); - - for(std::size_t i = 1; i != size; ++i) - out = std::max(out, std::abs(_data[i])); - - return out; - } - private: /* Implementation for Vector::Vector(const Vector&) */ template inline constexpr explicit Vector(Implementation::Sequence, const Vector& vector): _data{T(vector._data[sequence])...} {} From 7c3cb652bdfac18453edbf60f61f5bef1efa2359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 11 Apr 2013 17:19:35 +0200 Subject: [PATCH 06/30] Math: doc++ --- src/Math/Vector.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Math/Vector.h b/src/Math/Vector.h index ad4ea4314..3aacdc675 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -457,7 +457,7 @@ template class Vector { * values. @f[ * |\boldsymbol a| = \sqrt{\boldsymbol a \cdot \boldsymbol a} * @f] - * @see isNormalized() + * @see Math::sqrt(), normalized() * @todo something like std::hypot() for possibly better precision? */ inline T length() const { @@ -479,7 +479,7 @@ template class Vector { * Returns vector projected onto @p line. @f[ * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b * @f] - * @see projectedOntoNormalized() + * @see dot(), projectedOntoNormalized() */ inline Vector projected(const Vector& line) const { return line*dot(*this, line)/line.dot(); @@ -493,6 +493,7 @@ template class Vector { * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b = * (\boldsymbol a \cdot \boldsymbol b) \boldsymbol b * @f] + * @see dot() */ inline Vector projectedOntoNormalized(const Vector& line) const { CORRADE_ASSERT(line.isNormalized(), "Math::Vector::projectedOntoNormalized(): line must be normalized", (Vector(std::numeric_limits::quiet_NaN()))); From 6124ad3c27063f1540984c167601d9896d4c8419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 11 Apr 2013 17:18:04 +0200 Subject: [PATCH 07/30] Math: added sqrtInverted() function. There are SIMD instructions for that, so why not have it in place. --- src/Math/Functions.h | 25 ++++++++++++++++++++++++- src/Math/Test/FunctionsTest.cpp | 7 +++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/Math/Functions.h b/src/Math/Functions.h index fb4bafd1b..d3a9be345 100644 --- a/src/Math/Functions.h +++ b/src/Math/Functions.h @@ -197,7 +197,11 @@ template Vector abs(const Vector& a } #endif -/** @brief Square root */ +/** +@brief Square root + +@see sqrtInverted(), Vector::length() +*/ #ifdef DOXYGEN_GENERATING_OUTPUT template inline T sqrt(const T& a); #else @@ -212,6 +216,25 @@ template Vector sqrt(const Vector& } #endif +/** +@brief Inverse square root + +@see sqrt() +*/ +#ifdef DOXYGEN_GENERATING_OUTPUT +template inline T sqrtInverted(const T& a); +#else +template inline typename std::enable_if::value, T>::type sqrtInverted(T a) { + return T(1)/std::sqrt(a); +} +template Vector sqrtInverted(const Vector& a) { + Vector out; + for(std::size_t i = 0; i != size; ++i) + out[i] = T(1)/std::sqrt(a[i]); + return out; +} +#endif + /** @brief Clamp value diff --git a/src/Math/Test/FunctionsTest.cpp b/src/Math/Test/FunctionsTest.cpp index 93c09d86b..cda253c74 100644 --- a/src/Math/Test/FunctionsTest.cpp +++ b/src/Math/Test/FunctionsTest.cpp @@ -38,6 +38,7 @@ class FunctionsTest: public Corrade::TestSuite::Tester { void sign(); void abs(); void sqrt(); + void sqrtInverted(); void clamp(); void lerp(); void normalizeUnsigned(); @@ -70,6 +71,7 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::sign, &FunctionsTest::abs, &FunctionsTest::sqrt, + &FunctionsTest::sqrtInverted, &FunctionsTest::clamp, &FunctionsTest::lerp, &FunctionsTest::normalizeUnsigned, @@ -116,6 +118,11 @@ void FunctionsTest::sqrt() { CORRADE_COMPARE(Math::sqrt(Vector3i(256, 1, 0)), Vector3i(16, 1, 0)); } +void FunctionsTest::sqrtInverted() { + CORRADE_COMPARE(Math::sqrtInverted(16.0f), 0.25f); + CORRADE_COMPARE(Math::sqrtInverted(Vector3(1.0f, 4.0f, 16.0f)), Vector3(1.0f, 0.5f, 0.25f)); +} + void FunctionsTest::clamp() { CORRADE_COMPARE(Math::clamp(0.5f, -1.0f, 5.0f), 0.5f); CORRADE_COMPARE(Math::clamp(-1.6f, -1.0f, 5.0f), -1.0f); From 4ab3ab6534cdeea8a95ae00001961c664b024aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 11 Apr 2013 17:19:51 +0200 Subject: [PATCH 08/30] Math: added Vector::lengthInverted(). Also because there are SIMD instructions for that. --- src/Math/Functions.h | 2 +- src/Math/Test/VectorTest.cpp | 6 ++++++ src/Math/Vector.h | 16 ++++++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Math/Functions.h b/src/Math/Functions.h index d3a9be345..f3e2f091d 100644 --- a/src/Math/Functions.h +++ b/src/Math/Functions.h @@ -219,7 +219,7 @@ template Vector sqrt(const Vector& /** @brief Inverse square root -@see sqrt() +@see sqrt(), Vector::lengthInverted() */ #ifdef DOXYGEN_GENERATING_OUTPUT template inline T sqrtInverted(const T& a); diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 583df6b19..7cc938656 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -78,6 +78,7 @@ class VectorTest: public Corrade::TestSuite::Tester { void dot(); void dotSelf(); void length(); + void lengthInverted(); void normalized(); void sum(); @@ -123,6 +124,7 @@ VectorTest::VectorTest() { &VectorTest::dot, &VectorTest::dotSelf, &VectorTest::length, + &VectorTest::lengthInverted, &VectorTest::normalized, &VectorTest::sum, @@ -310,6 +312,10 @@ void VectorTest::length() { CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).length(), 5.4772256f); } +void VectorTest::lengthInverted() { + CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).lengthInverted(), 0.182574f); +} + void VectorTest::normalized() { CORRADE_COMPARE(Vector4(1.0f, 1.0f, 1.0f, 1.0f).normalized(), Vector4(0.5f, 0.5f, 0.5f, 0.5f)); } diff --git a/src/Math/Vector.h b/src/Math/Vector.h index 3aacdc675..2fb6adfa0 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -457,20 +457,32 @@ template class Vector { * values. @f[ * |\boldsymbol a| = \sqrt{\boldsymbol a \cdot \boldsymbol a} * @f] - * @see Math::sqrt(), normalized() + * @see lengthInverted(), Math::sqrt(), normalized() * @todo something like std::hypot() for possibly better precision? */ inline T length() const { return std::sqrt(dot()); } + /** + * @brief Inverse vector length + * + * @f[ + * \frac{1}{|\boldsymbol a|} = \frac{1}{\sqrt{\boldsymbol a \cdot \boldsymbol a}} + * @f] + * @see length(), Math::sqrtInverted(), normalized() + */ + inline T lengthInverted() const { + return T(1)/length(); + } + /** * @brief Normalized vector (of unit length) * * @see isNormalized() */ inline Vector normalized() const { - return *this/length(); + return *this*lengthInverted(); } /** From 8923f2debb40dc8073df2207af19c41465144de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 11 Apr 2013 18:57:58 +0200 Subject: [PATCH 09/30] Added support for uniform arrays. Also not including Math/Matrix.h in AbstractShaderProgram.cpp and using just RectangularMatrix everywhere. --- src/AbstractShaderProgram.cpp | 290 +++++++++++----------- src/AbstractShaderProgram.h | 448 ++++++++++++++++++---------------- 2 files changed, 381 insertions(+), 357 deletions(-) diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index b353ca475..afef65c5e 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -27,7 +27,7 @@ #include #include -#include "Math/Matrix.h" +#include "Math/RectangularMatrix.h" #include "Shader.h" #include "Implementation/State.h" #include "Implementation/ShaderProgramState.h" @@ -37,22 +37,22 @@ namespace Magnum { -AbstractShaderProgram::Uniform1fImplementation AbstractShaderProgram::uniform1fImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1fvImplementation AbstractShaderProgram::uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform2fvImplementation AbstractShaderProgram::uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform3fvImplementation AbstractShaderProgram::uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform4fvImplementation AbstractShaderProgram::uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; -AbstractShaderProgram::Uniform1iImplementation AbstractShaderProgram::uniform1iImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1ivImplementation AbstractShaderProgram::uniform1ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform2ivImplementation AbstractShaderProgram::uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform3ivImplementation AbstractShaderProgram::uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform4ivImplementation AbstractShaderProgram::uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; #ifndef MAGNUM_TARGET_GLES2 -AbstractShaderProgram::Uniform1uiImplementation AbstractShaderProgram::uniform1uiImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1uivImplementation AbstractShaderProgram::uniform1uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform2uivImplementation AbstractShaderProgram::uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform3uivImplementation AbstractShaderProgram::uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform4uivImplementation AbstractShaderProgram::uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; #endif #ifndef MAGNUM_TARGET_GLES -AbstractShaderProgram::Uniform1dImplementation AbstractShaderProgram::uniform1dImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1dvImplementation AbstractShaderProgram::uniform1dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform2dvImplementation AbstractShaderProgram::uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform3dvImplementation AbstractShaderProgram::uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform4dvImplementation AbstractShaderProgram::uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; @@ -181,19 +181,19 @@ void AbstractShaderProgram::initializeContextBasedFunctionality(Context* context context->isExtensionSupported()) { Debug() << "AbstractShaderProgram: using" << (context->isExtensionSupported() ? Extensions::GL::ARB::separate_shader_objects::string() : Extensions::GL::EXT::direct_state_access::string()) << "features"; - uniform1fImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; - uniform1iImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; - uniform1uiImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; - uniform1dImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; @@ -222,359 +222,359 @@ void AbstractShaderProgram::initializeContextBasedFunctionality(Context* context #endif } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLfloat value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const GLfloat* const values) { use(); - glUniform1f(location, value); + glUniform1fv(location, count, values); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLfloat value) { - glProgramUniform1f(_id, location, value); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLfloat* const values) { + glProgramUniform1fv(_id, location, count, values); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<2, GLfloat>* const values) { use(); - glUniform2fv(location, 1, value.data()); + glUniform2fv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLfloat>& value) { - glProgramUniform2fv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLfloat>* const values) { + glProgramUniform2fv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<3, GLfloat>* const values) { use(); - glUniform3fv(location, 1, value.data()); + glUniform3fv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLfloat>& value) { - glProgramUniform3fv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLfloat>* const values) { + glProgramUniform3fv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<4, GLfloat>* const values) { use(); - glUniform4fv(location, 1, value.data()); + glUniform4fv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLfloat>& value) { - glProgramUniform4fv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLfloat>* const values) { + glProgramUniform4fv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLint value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const GLint* const values) { use(); - glUniform1i(location, value); + glUniform1iv(location, count, values); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLint value) { - glProgramUniform1i(_id, location, value); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLint* const values) { + glProgramUniform1iv(_id, location, count, values); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<2, GLint>* const values) { use(); - glUniform2iv(location, 1, value.data()); + glUniform2iv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLint>& value) { - glProgramUniform2iv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLint>* const values) { + glProgramUniform2iv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<3, GLint>* const values) { use(); - glUniform3iv(location, 1, value.data()); + glUniform3iv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLint>& value) { - glProgramUniform3iv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLint>* const values) { + glProgramUniform3iv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<4, GLint>* const values) { use(); - glUniform4iv(location, 1, value.data()); + glUniform4iv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLint>& value) { - glProgramUniform4iv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLint>* const values) { + glProgramUniform4iv(_id, location, count, values[0].data()); } #endif #ifndef MAGNUM_TARGET_GLES2 -void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLuint value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const GLuint* const values) { use(); - glUniform1ui(location, value); + glUniform1uiv(location, count, values); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLuint value) { - glProgramUniform1ui(_id, location, value); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLuint* const values) { + glProgramUniform1uiv(_id, location, count, values); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLuint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<2, GLuint>* const values) { use(); - glUniform2uiv(location, 1, value.data()); + glUniform2uiv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLuint>& value) { - glProgramUniform2uiv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLuint>* const values) { + glProgramUniform2uiv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLuint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<3, GLuint>* const values) { use(); - glUniform3uiv(location, 1, value.data()); + glUniform3uiv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLuint>& value) { - glProgramUniform3uiv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLuint>* const values) { + glProgramUniform3uiv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLuint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<4, GLuint>* const values) { use(); - glUniform4uiv(location, 1, value.data()); + glUniform4uiv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLuint>& value) { - glProgramUniform4uiv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLuint>* const values) { + glProgramUniform4uiv(_id, location, count, values[0].data()); } #endif #endif #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLdouble value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const GLdouble* const values) { use(); - glUniform1d(location, value); + glUniform1dv(location, count, values); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLdouble value) { - glProgramUniform1d(_id, location, value); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLdouble* const values) { + glProgramUniform1dv(_id, location, count, values); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<2, GLdouble>* const values) { use(); - glUniform2dv(location, 1, value.data()); + glUniform2dv(location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLdouble>& value) { - glProgramUniform2dv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLdouble>* const values) { + glProgramUniform2dv(_id, location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<3, GLdouble>* const values) { use(); - glUniform3dv(location, 1, value.data()); + glUniform3dv(location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLdouble>& value) { - glProgramUniform3dv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLdouble>* const values) { + glProgramUniform3dv(_id, location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<4, GLdouble>* const values) { use(); - glUniform4dv(location, 1, value.data()); + glUniform4dv(location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLdouble>& value) { - glProgramUniform4dv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLdouble>* const values) { + glProgramUniform4dv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<2, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* const values) { use(); - glUniformMatrix2fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<2, GLfloat>& value) { - glProgramUniformMatrix2fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* const values) { + glProgramUniformMatrix2fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<3, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* const values) { use(); - glUniformMatrix3fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<3, GLfloat>& value) { - glProgramUniformMatrix3fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* const values) { + glProgramUniformMatrix3fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<4, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* const values) { use(); - glUniformMatrix4fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<4, GLfloat>& value) { - glProgramUniformMatrix4fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* const values) { + glProgramUniformMatrix4fv(_id, location, count, GL_FALSE, values[0].data()); } #endif #ifndef MAGNUM_TARGET_GLES2 -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* const values) { use(); - glUniformMatrix2x3fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2x3fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { - glProgramUniformMatrix2x3fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* const values) { + glProgramUniformMatrix2x3fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* const values) { use(); - glUniformMatrix3x2fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3x2fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { - glProgramUniformMatrix3x2fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* const values) { + glProgramUniformMatrix3x2fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* const values) { use(); - glUniformMatrix2x4fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2x4fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { - glProgramUniformMatrix2x4fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* const values) { + glProgramUniformMatrix2x4fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* const values) { use(); - glUniformMatrix4x2fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4x2fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { - glProgramUniformMatrix4x2fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* const values) { + glProgramUniformMatrix4x2fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* const values) { use(); - glUniformMatrix3x4fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3x4fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { - glProgramUniformMatrix3x4fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* const values) { + glProgramUniformMatrix3x4fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* const values) { use(); - glUniformMatrix4x3fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4x3fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { - glProgramUniformMatrix4x3fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* const values) { + glProgramUniformMatrix4x3fv(_id, location, count, GL_FALSE, values[0].data()); } #endif #endif #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<2, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* const values) { use(); - glUniformMatrix2dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<2, GLdouble>& value) { - glProgramUniformMatrix2dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* const values) { + glProgramUniformMatrix2dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<3, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* const values) { use(); - glUniformMatrix3dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<3, GLdouble>& value) { - glProgramUniformMatrix3dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* const values) { + glProgramUniformMatrix3dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<4, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* const values) { use(); - glUniformMatrix4dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<4, GLdouble>& value) { - glProgramUniformMatrix4dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* const values) { + glProgramUniformMatrix4dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* const values) { use(); - glUniformMatrix2x3dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2x3dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { - glProgramUniformMatrix2x3dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* const values) { + glProgramUniformMatrix2x3dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* const values) { use(); - glUniformMatrix3x2dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3x2dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { - glProgramUniformMatrix3x2dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* const values) { + glProgramUniformMatrix3x2dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* const values) { use(); - glUniformMatrix2x4dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2x4dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { - glProgramUniformMatrix2x4dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* const values) { + glProgramUniformMatrix2x4dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* const values) { use(); - glUniformMatrix4x2dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4x2dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { - glProgramUniformMatrix4x2dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* const values) { + glProgramUniformMatrix4x2dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* const values) { use(); - glUniformMatrix3x4dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3x4dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { - glProgramUniformMatrix3x4dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* const values) { + glProgramUniformMatrix3x4dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* const values) { use(); - glUniformMatrix4x3dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4x3dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { - glProgramUniformMatrix4x3dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* const values) { + glProgramUniformMatrix4x3dv(_id, location, count, GL_FALSE, values[0].data()); } #endif diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index 814cf4d33..9bb375aad 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -42,6 +42,18 @@ namespace Magnum { #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { template struct Attribute; + + /* Used in setUniform(Int, const T&), otherwise it would not be possible to + pass enum values as uniforms */ + struct NonEnumType { + template inline static typename std::enable_if::value, const typename std::conditional::value, UnsignedInt, Int>::type&>::type cast(const T& value) { + return static_cast::value, UnsignedInt, Int>::type&>(value); + } + + template inline static typename std::enable_if::value, const T&>::type cast(const T& value) { + return value; + } + }; } #endif @@ -279,8 +291,6 @@ setUniform() documentation for more information. To achieve least state changes, set all uniforms in one run -- method chaining comes in handy. - -@todo Uniform arrays support */ class MAGNUM_EXPORT AbstractShaderProgram { friend class Context; @@ -678,275 +688,289 @@ class MAGNUM_EXPORT AbstractShaderProgram { /** * @brief Set uniform value - * @param location Uniform location (see uniformLocation()) + * @param location Uniform location * @param value Value * + * Convenience alternative for setting one value, see + * setUniform(Int, UnsignedInt, const Float*) for more information. + */ + template inline void setUniform(Int location, const T& value) { + setUniform(location, 1, &Implementation::NonEnumType::cast(value)); + } + + /** + * @brief Set uniform values + * @param location Uniform location + * @param count Value count + * @param values Values + * * If neither @extension{ARB,separate_shader_objects} nor * @extension{EXT,direct_state_access} is available, the shader is * marked for use before the operation. - * @see @fn_gl{UseProgram}, @fn_gl{Uniform} or `glProgramUniform()` - * from @extension{ARB,separate_shader_objects}/@extension{EXT,direct_state_access}. + * @see setUniform(Int, const T&), @fn_gl{UseProgram}, @fn_gl{Uniform} + * or `glProgramUniform()` from + * @extension{ARB,separate_shader_objects}/@extension{EXT,direct_state_access}. */ - inline void setUniform(Int location, Float value) { - (this->*uniform1fImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Float* values) { + (this->*uniform1fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<2, Float>& value) { - (this->*uniform2fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Float>* values) { + (this->*uniform2fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<3, Float>& value) { - (this->*uniform3fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Float>* values) { + (this->*uniform3fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<4, Float>& value) { - (this->*uniform4fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Float>* values) { + (this->*uniform4fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, Int value) { - (this->*uniform1iImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Int* values) { + (this->*uniform1ivImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<2, Int>& value) { - (this->*uniform2ivImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Int>* values) { + (this->*uniform2ivImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<3, Int>& value) { - (this->*uniform3ivImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Int>* values) { + (this->*uniform3ivImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<4, Int>& value) { - (this->*uniform4ivImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Int>* values) { + (this->*uniform4ivImplementation)(location, count, values); } #ifndef MAGNUM_TARGET_GLES2 /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, UnsignedInt value) { - (this->*uniform1uiImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const UnsignedInt* values) { + (this->*uniform1uivImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::Vector<2, UnsignedInt>& value) { - (this->*uniform2uivImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, UnsignedInt>* values) { + (this->*uniform2uivImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::Vector<3, UnsignedInt>& value) { - (this->*uniform3uivImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, UnsignedInt>* values) { + (this->*uniform3uivImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::Vector<4, UnsignedInt>& value) { - (this->*uniform4uivImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, UnsignedInt>* values) { + (this->*uniform4uivImplementation)(location, count, values); } #endif #ifndef MAGNUM_TARGET_GLES /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, Double value) { - (this->*uniform1dImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Double* values) { + (this->*uniform1dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Vector<2, Double>& value) { - (this->*uniform2dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Double>* values) { + (this->*uniform2dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Vector<3, Double>& value) { - (this->*uniform3dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Double>* values) { + (this->*uniform3dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Vector<4, Double>& value) { - (this->*uniform4dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Double>* values) { + (this->*uniform4dvImplementation)(location, count, values); } #endif - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Matrix<2, Float>& value) { - (this->*uniformMatrix2fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Float>* values) { + (this->*uniformMatrix2fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Matrix<3, Float>& value) { - (this->*uniformMatrix3fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Float>* values) { + (this->*uniformMatrix3fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Matrix<4, Float>& value) { - (this->*uniformMatrix4fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Float>* values) { + (this->*uniformMatrix4fvImplementation)(location, count, values); } #ifndef MAGNUM_TARGET_GLES2 /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<2, 3, Float>& value) { - (this->*uniformMatrix2x3fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Float>* values) { + (this->*uniformMatrix2x3fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<3, 2, Float>& value) { - (this->*uniformMatrix3x2fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Float>* values) { + (this->*uniformMatrix3x2fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<2, 4, Float>& value) { - (this->*uniformMatrix2x4fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Float>* values) { + (this->*uniformMatrix2x4fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<4, 2, Float>& value) { - (this->*uniformMatrix4x2fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Float>* values) { + (this->*uniformMatrix4x2fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<3, 4, Float>& value) { - (this->*uniformMatrix3x4fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Float>* values) { + (this->*uniformMatrix3x4fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<4, 3, Float>& value) { - (this->*uniformMatrix4x3fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Float>* values) { + (this->*uniformMatrix4x3fvImplementation)(location, count, values); } #endif #ifndef MAGNUM_TARGET_GLES /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Matrix<2, Double>& value) { - (this->*uniformMatrix2dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Double>* values) { + (this->*uniformMatrix2dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Matrix<3, Double>& value) { - (this->*uniformMatrix3dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Double>* values) { + (this->*uniformMatrix3dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Matrix<4, Double>& value) { - (this->*uniformMatrix4dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Double>* values) { + (this->*uniformMatrix4dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<2, 3, Double>& value) { - (this->*uniformMatrix2x3dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Double>* values) { + (this->*uniformMatrix2x3dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<3, 2, Double>& value) { - (this->*uniformMatrix3x2dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Double>* values) { + (this->*uniformMatrix3x2dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<2, 4, Double>& value) { - (this->*uniformMatrix2x4dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Double>* values) { + (this->*uniformMatrix2x4dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<4, 2, Double>& value) { - (this->*uniformMatrix4x2dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Double>* values) { + (this->*uniformMatrix4x2dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<3, 4, Double>& value) { - (this->*uniformMatrix3x4dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Double>* values) { + (this->*uniformMatrix3x4dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<4, 3, Double>& value) { - (this->*uniformMatrix4x3dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Double>* values) { + (this->*uniformMatrix4x3dvImplementation)(location, count, values); } #endif @@ -959,144 +983,144 @@ class MAGNUM_EXPORT AbstractShaderProgram { static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); - typedef void(AbstractShaderProgram::*Uniform1fImplementation)(GLint, GLfloat); - typedef void(AbstractShaderProgram::*Uniform2fvImplementation)(GLint, const Math::Vector<2, GLfloat>&); - typedef void(AbstractShaderProgram::*Uniform3fvImplementation)(GLint, const Math::Vector<3, GLfloat>&); - typedef void(AbstractShaderProgram::*Uniform4fvImplementation)(GLint, const Math::Vector<4, GLfloat>&); - typedef void(AbstractShaderProgram::*Uniform1iImplementation)(GLint, GLint); - typedef void(AbstractShaderProgram::*Uniform2ivImplementation)(GLint, const Math::Vector<2, GLint>&); - typedef void(AbstractShaderProgram::*Uniform3ivImplementation)(GLint, const Math::Vector<3, GLint>&); - typedef void(AbstractShaderProgram::*Uniform4ivImplementation)(GLint, const Math::Vector<4, GLint>&); + typedef void(AbstractShaderProgram::*Uniform1fvImplementation)(GLint, GLsizei, const GLfloat*); + typedef void(AbstractShaderProgram::*Uniform2fvImplementation)(GLint, GLsizei, const Math::Vector<2, GLfloat>*); + typedef void(AbstractShaderProgram::*Uniform3fvImplementation)(GLint, GLsizei, const Math::Vector<3, GLfloat>*); + typedef void(AbstractShaderProgram::*Uniform4fvImplementation)(GLint, GLsizei, const Math::Vector<4, GLfloat>*); + typedef void(AbstractShaderProgram::*Uniform1ivImplementation)(GLint, GLsizei, const GLint*); + typedef void(AbstractShaderProgram::*Uniform2ivImplementation)(GLint, GLsizei, const Math::Vector<2, GLint>*); + typedef void(AbstractShaderProgram::*Uniform3ivImplementation)(GLint, GLsizei, const Math::Vector<3, GLint>*); + typedef void(AbstractShaderProgram::*Uniform4ivImplementation)(GLint, GLsizei, const Math::Vector<4, GLint>*); #ifndef MAGNUM_TARGET_GLES2 - typedef void(AbstractShaderProgram::*Uniform1uiImplementation)(GLint, GLuint); - typedef void(AbstractShaderProgram::*Uniform2uivImplementation)(GLint, const Math::Vector<2, GLuint>&); - typedef void(AbstractShaderProgram::*Uniform3uivImplementation)(GLint, const Math::Vector<3, GLuint>&); - typedef void(AbstractShaderProgram::*Uniform4uivImplementation)(GLint, const Math::Vector<4, GLuint>&); + typedef void(AbstractShaderProgram::*Uniform1uivImplementation)(GLint, GLsizei, const GLuint*); + typedef void(AbstractShaderProgram::*Uniform2uivImplementation)(GLint, GLsizei, const Math::Vector<2, GLuint>*); + typedef void(AbstractShaderProgram::*Uniform3uivImplementation)(GLint, GLsizei, const Math::Vector<3, GLuint>*); + typedef void(AbstractShaderProgram::*Uniform4uivImplementation)(GLint, GLsizei, const Math::Vector<4, GLuint>*); #endif #ifndef MAGNUM_TARGET_GLES - typedef void(AbstractShaderProgram::*Uniform1dImplementation)(GLint, GLdouble); - typedef void(AbstractShaderProgram::*Uniform2dvImplementation)(GLint, const Math::Vector<2, GLdouble>&); - typedef void(AbstractShaderProgram::*Uniform3dvImplementation)(GLint, const Math::Vector<3, GLdouble>&); - typedef void(AbstractShaderProgram::*Uniform4dvImplementation)(GLint, const Math::Vector<4, GLdouble>&); + typedef void(AbstractShaderProgram::*Uniform1dvImplementation)(GLint, GLsizei, const GLdouble*); + typedef void(AbstractShaderProgram::*Uniform2dvImplementation)(GLint, GLsizei, const Math::Vector<2, GLdouble>*); + typedef void(AbstractShaderProgram::*Uniform3dvImplementation)(GLint, GLsizei, const Math::Vector<3, GLdouble>*); + typedef void(AbstractShaderProgram::*Uniform4dvImplementation)(GLint, GLsizei, const Math::Vector<4, GLdouble>*); #endif - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLfloat value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLint value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLint>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const GLfloat* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const GLint* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<2, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<4, GLint>* values); #ifndef MAGNUM_TARGET_GLES2 - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLuint value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLuint>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const GLuint* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<2, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<4, GLuint>* values); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLdouble value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLfloat value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLint value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLuint value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLdouble value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const GLdouble* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLfloat* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLint* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLuint* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLdouble* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLdouble>* values); #endif - static Uniform1fImplementation uniform1fImplementation; + static Uniform1fvImplementation uniform1fvImplementation; static Uniform2fvImplementation uniform2fvImplementation; static Uniform3fvImplementation uniform3fvImplementation; static Uniform4fvImplementation uniform4fvImplementation; - static Uniform1iImplementation uniform1iImplementation; + static Uniform1ivImplementation uniform1ivImplementation; static Uniform2ivImplementation uniform2ivImplementation; static Uniform3ivImplementation uniform3ivImplementation; static Uniform4ivImplementation uniform4ivImplementation; #ifndef MAGNUM_TARGET_GLES2 - static Uniform1uiImplementation uniform1uiImplementation; + static Uniform1uivImplementation uniform1uivImplementation; static Uniform2uivImplementation uniform2uivImplementation; static Uniform3uivImplementation uniform3uivImplementation; static Uniform4uivImplementation uniform4uivImplementation; #endif #ifndef MAGNUM_TARGET_GLES - static Uniform1dImplementation uniform1dImplementation; + static Uniform1dvImplementation uniform1dvImplementation; static Uniform2dvImplementation uniform2dvImplementation; static Uniform3dvImplementation uniform3dvImplementation; static Uniform4dvImplementation uniform4dvImplementation; #endif - typedef void(AbstractShaderProgram::*UniformMatrix2fvImplementation)(GLint, const Math::Matrix<2, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix3fvImplementation)(GLint, const Math::Matrix<3, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix4fvImplementation)(GLint, const Math::Matrix<4, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix2fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 2, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix3fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 3, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix4fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 4, GLfloat>*); #ifndef MAGNUM_TARGET_GLES2 - typedef void(AbstractShaderProgram::*UniformMatrix2x3fvImplementation)(GLint, const Math::RectangularMatrix<2, 3, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix3x2fvImplementation)(GLint, const Math::RectangularMatrix<3, 2, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix2x4fvImplementation)(GLint, const Math::RectangularMatrix<2, 4, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix4x2fvImplementation)(GLint, const Math::RectangularMatrix<4, 2, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix3x4fvImplementation)(GLint, const Math::RectangularMatrix<3, 4, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix4x3fvImplementation)(GLint, const Math::RectangularMatrix<4, 3, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix2x3fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 3, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix3x2fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 2, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix2x4fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 4, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix4x2fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 2, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix3x4fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 4, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix4x3fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 3, GLfloat>*); #endif #ifndef MAGNUM_TARGET_GLES - typedef void(AbstractShaderProgram::*UniformMatrix2dvImplementation)(GLint, const Math::Matrix<2, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix3dvImplementation)(GLint, const Math::Matrix<3, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix4dvImplementation)(GLint, const Math::Matrix<4, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix2x3dvImplementation)(GLint, const Math::RectangularMatrix<2, 3, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix3x2dvImplementation)(GLint, const Math::RectangularMatrix<3, 2, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix2x4dvImplementation)(GLint, const Math::RectangularMatrix<2, 4, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix4x2dvImplementation)(GLint, const Math::RectangularMatrix<4, 2, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix3x4dvImplementation)(GLint, const Math::RectangularMatrix<3, 4, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix4x3dvImplementation)(GLint, const Math::RectangularMatrix<4, 3, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix2dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 2, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix3dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 3, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix4dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 4, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix2x3dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 3, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix3x2dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 2, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix2x4dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 4, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix4x2dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 2, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix3x4dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 4, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix4x3dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 3, GLdouble>*); #endif - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<4, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* values); #ifndef MAGNUM_TARGET_GLES2 - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* values); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* values); #endif static UniformMatrix2fvImplementation uniformMatrix2fvImplementation; static UniformMatrix3fvImplementation uniformMatrix3fvImplementation; From 62ecc2470f746e0c8019097b6d16f3d0a8a992dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 12 Apr 2013 13:21:15 +0200 Subject: [PATCH 10/30] Made some constructors constexpr. --- src/Implementation/FramebufferState.h | 2 +- src/Implementation/MeshState.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Implementation/FramebufferState.h b/src/Implementation/FramebufferState.h index 4d213425c..df7464cff 100644 --- a/src/Implementation/FramebufferState.h +++ b/src/Implementation/FramebufferState.h @@ -30,7 +30,7 @@ namespace Magnum { namespace Implementation { struct FramebufferState { - inline FramebufferState(): readBinding(0), drawBinding(0), renderbufferBinding(0) {} + inline constexpr FramebufferState(): readBinding(0), drawBinding(0), renderbufferBinding(0) {} GLuint readBinding, drawBinding, renderbufferBinding; Rectanglei viewport; diff --git a/src/Implementation/MeshState.h b/src/Implementation/MeshState.h index b2a18d756..b12b1c5ae 100644 --- a/src/Implementation/MeshState.h +++ b/src/Implementation/MeshState.h @@ -29,7 +29,7 @@ namespace Magnum { namespace Implementation { struct MeshState { - inline MeshState(): currentVAO(0) {} + inline constexpr MeshState(): currentVAO(0) {} GLuint currentVAO; }; From 1e383e3d7002eb02bf48547c2feba8f0db16050c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 12 Apr 2013 13:22:34 +0200 Subject: [PATCH 11/30] Physics: very minor code cleanup. --- src/Physics/AbstractShape.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Physics/AbstractShape.h b/src/Physics/AbstractShape.h index ea5083982..aaa541663 100644 --- a/src/Physics/AbstractShape.h +++ b/src/Physics/AbstractShape.h @@ -130,7 +130,6 @@ template class MAGNUM_PHYSICS_EXPORT AbstractShape { virtual bool collides(const AbstractShape* other) const; }; - /** @brief Abstract two-dimensional shape */ typedef AbstractShape<2> AbstractShape2D; From 61e1ec00826ffc01636dfbf023cb9e78b9b4ed1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 12 Apr 2013 13:26:45 +0200 Subject: [PATCH 12/30] No need to have `const` also in function declarations. --- src/Text/AbstractFont.h | 6 +++--- src/Text/DistanceFieldGlyphCache.h | 4 ++-- src/Text/GlyphCache.h | 10 +++++----- src/Text/TextRenderer.h | 8 ++++---- src/TextureTools/DistanceField.h | 2 +- src/Trade/AbstractImageConverter.h | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Text/AbstractFont.h b/src/Text/AbstractFont.h index df2d06437..495af5f5e 100644 --- a/src/Text/AbstractFont.h +++ b/src/Text/AbstractFont.h @@ -96,7 +96,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public Corrade::PluginManager::AbstractPl * * Fills the cache with given characters. */ - virtual void createGlyphCache(GlyphCache* const cache, const std::string& characters) = 0; + virtual void createGlyphCache(GlyphCache* cache, const std::string& characters) = 0; /** * @brief Layout the text using font own layouter @@ -106,7 +106,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public Corrade::PluginManager::AbstractPl * * @see createGlyphCache() */ - virtual AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) = 0; + virtual AbstractLayouter* layout(const GlyphCache* cache, Float size, const std::string& text) = 0; #ifdef DOXYGEN_GENERATING_OUTPUT private: @@ -144,7 +144,7 @@ class MAGNUM_TEXT_EXPORT AbstractLayouter { * Returns quad position, texture coordinates and advance to next * glyph. */ - virtual std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) = 0; + virtual std::tuple renderGlyph(const Vector2& cursorPosition, UnsignedInt i) = 0; #ifdef DOXYGEN_GENERATING_OUTPUT private: diff --git a/src/Text/DistanceFieldGlyphCache.h b/src/Text/DistanceFieldGlyphCache.h index 80bcaceba..e9161a95f 100644 --- a/src/Text/DistanceFieldGlyphCache.h +++ b/src/Text/DistanceFieldGlyphCache.h @@ -72,7 +72,7 @@ class MAGNUM_TEXT_EXPORT DistanceFieldGlyphCache: public GlyphCache { * Uploads image for one or more glyphs to given offset in original * cache texture. The texture is then converted to distance field. */ - void setImage(const Vector2i& offset, Image2D* const image) override; + void setImage(const Vector2i& offset, Image2D* image) override; /** * @brief Set distance field cache image @@ -80,7 +80,7 @@ class MAGNUM_TEXT_EXPORT DistanceFieldGlyphCache: public GlyphCache { * Uploads already computed distance field image to given offset in * distance field texture. */ - void setDistanceFieldImage(const Vector2i& offset, Image2D* const image); + void setDistanceFieldImage(const Vector2i& offset, Image2D* image); private: const Vector2 scale; diff --git a/src/Text/GlyphCache.h b/src/Text/GlyphCache.h index 92f91544b..6d452a72c 100644 --- a/src/Text/GlyphCache.h +++ b/src/Text/GlyphCache.h @@ -62,7 +62,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * @param size Glyph cache texture size * @param internalFormat Internal texture format */ - explicit GlyphCache(const Vector2i& size, const Texture2D::InternalFormat internalFormat); + explicit GlyphCache(const Vector2i& size, Texture2D::InternalFormat internalFormat); /** * @brief Constructor @@ -97,7 +97,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * second element is glyph region in texture atlas. If no glyph is * found, glyph on zero index is returned. */ - inline std::pair operator[](const UnsignedInt glyph) const { + inline std::pair operator[](UnsignedInt glyph) const { auto it = glyphs.find(glyph); return it == glyphs.end() ? glyphs.at(0) : it->second; } @@ -124,7 +124,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * You can obtain unused non-overlapping regions with reserve(). See * also setImage() to upload glyph image. */ - void insert(const UnsignedInt glyph, Vector2i position, Rectanglei rectangle); + void insert(UnsignedInt glyph, Vector2i position, Rectanglei rectangle); /** * @brief Set cache image @@ -132,7 +132,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * Uploads image for one or more glyphs to given offset in cache * texture. */ - virtual void setImage(const Vector2i& offset, Image2D* const image); + virtual void setImage(const Vector2i& offset, Image2D* image); #ifdef DOXYGEN_GENERATING_OUTPUT private: @@ -142,7 +142,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { /* Used from DistanceFieldGlyphCache */ explicit MAGNUM_LOCAL GlyphCache(const Vector2i& size, const Vector2i& padding); - void MAGNUM_LOCAL initialize(const Texture2D::InternalFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL initialize(Texture2D::InternalFormat internalFormat, const Vector2i& size); const Vector2i _size; Texture2D _texture; diff --git a/src/Text/TextRenderer.h b/src/Text/TextRenderer.h index 2d722f681..b4f470723 100644 --- a/src/Text/TextRenderer.h +++ b/src/Text/TextRenderer.h @@ -60,7 +60,7 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { * Returns tuple with vertex positions, texture coordinates, indices * and rectangle spanning the rendered text. */ - static std::tuple, std::vector, std::vector, Rectangle> render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text); + static std::tuple, std::vector, std::vector, Rectangle> render(AbstractFont* font, const GlyphCache* cache, Float size, const std::string& text); /** * @brief Constructor @@ -68,7 +68,7 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { * @param cache Glyph cache * @param size Font size */ - explicit AbstractTextRenderer(AbstractFont* const font, const GlyphCache* const cache, Float size); + explicit AbstractTextRenderer(AbstractFont* font, const GlyphCache* cache, Float size); virtual ~AbstractTextRenderer() = 0; @@ -97,7 +97,7 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { * Initially zero capacity is reserved. * @see capacity() */ - void reserve(const UnsignedInt glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage); + void reserve(UnsignedInt glyphCount, Buffer::Usage vertexBufferUsage, Buffer::Usage indexBufferUsage); /** * @brief Render text @@ -117,7 +117,7 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { #else private: #endif - static std::tuple MAGNUM_LOCAL render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); + static std::tuple MAGNUM_LOCAL render(AbstractFont* font, const GlyphCache* cache, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); Mesh _mesh; Buffer vertexBuffer, indexBuffer; diff --git a/src/TextureTools/DistanceField.h b/src/TextureTools/DistanceField.h index a88ab940e..dfe8c409d 100644 --- a/src/TextureTools/DistanceField.h +++ b/src/TextureTools/DistanceField.h @@ -67,7 +67,7 @@ http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnifica @attention This is GPU-only implementation, so it expects active context. */ -void MAGNUM_TEXTURETOOLS_EXPORT distanceField(Texture2D* input, Texture2D* output, const Rectanglei& rectangle, const Int radius); +void MAGNUM_TEXTURETOOLS_EXPORT distanceField(Texture2D* input, Texture2D* output, const Rectanglei& rectangle, Int radius); }} diff --git a/src/Trade/AbstractImageConverter.h b/src/Trade/AbstractImageConverter.h index 5434618db..b0870c87b 100644 --- a/src/Trade/AbstractImageConverter.h +++ b/src/Trade/AbstractImageConverter.h @@ -91,7 +91,7 @@ class MAGNUM_EXPORT AbstractImageConverter: public Corrade::PluginManager::Abstr * Returns converted image on success, `nullptr` otherwise. * @see features(), convertToData(), convertToFile() */ - virtual Image2D* convertToImage(const Image2D* const image) const; + virtual Image2D* convertToImage(const Image2D* image) const; /** * @brief Convert image to raw data @@ -100,7 +100,7 @@ class MAGNUM_EXPORT AbstractImageConverter: public Corrade::PluginManager::Abstr * Returns data pointer and size on success, `nullptr` otherwise. * @see features(), convertToImage(), convertToFile() */ - virtual std::pair convertToData(const Image2D* const image) const; + virtual std::pair convertToData(const Image2D* image) const; /** * @brief Convert image and save it to file @@ -109,7 +109,7 @@ class MAGNUM_EXPORT AbstractImageConverter: public Corrade::PluginManager::Abstr * Returns `true` on success, `false` otherwise. * @see features(), convertToImage(), convertToData() */ - virtual bool convertToFile(const Image2D* const image, const std::string& filename) const; + virtual bool convertToFile(const Image2D* image, const std::string& filename) const; }; CORRADE_ENUMSET_OPERATORS(AbstractImageConverter::Features) From f0958647c174db42ce9f569a0e9127888e2f2835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 13 Apr 2013 19:27:52 +0200 Subject: [PATCH 13/30] Platform: more intuitive argc/argv Arguments structure. --- src/Platform/AbstractXApplication.h | 5 ++++- src/Platform/GlutApplication.cpp | 4 ++-- src/Platform/GlutApplication.h | 5 ++++- src/Platform/Sdl2Application.h | 5 ++++- src/Platform/WindowlessGlxApplication.h | 5 ++++- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 3afdd40c2..4913d03bb 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -56,7 +56,10 @@ Supports keyboard and mouse handling. See @ref platform for brief introduction. class AbstractXApplication { public: /** @brief Application arguments */ - typedef std::pair Arguments; + struct Arguments { + int& argc; /**< @brief Argument count */ + char** argv; /**< @brief Argument values */ + }; class Configuration; class InputEvent; diff --git a/src/Platform/GlutApplication.cpp b/src/Platform/GlutApplication.cpp index 705264312..65ea0566c 100644 --- a/src/Platform/GlutApplication.cpp +++ b/src/Platform/GlutApplication.cpp @@ -32,12 +32,12 @@ namespace Magnum { namespace Platform { GlutApplication* GlutApplication::instance = nullptr; GlutApplication::GlutApplication(const Arguments& arguments): c(nullptr) { - initialize(arguments.first, arguments.second); + initialize(arguments.argc, arguments.argv); createContext(new Configuration); } GlutApplication::GlutApplication(const Arguments& arguments, Configuration* configuration): c(nullptr) { - initialize(arguments.first, arguments.second); + initialize(arguments.argc, arguments.argv); if(configuration) createContext(configuration); } diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 4987ccf60..0f0ab185a 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -68,7 +68,10 @@ to simplify porting. class GlutApplication { public: /** @brief Application arguments */ - typedef std::pair Arguments; + struct Arguments { + int& argc; /**< @brief Argument count */ + char** argv; /**< @brief Argument values */ + }; class Configuration; class InputEvent; diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 5ed06ed7a..10733d3cb 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -69,7 +69,10 @@ to simplify porting. class Sdl2Application { public: /** @brief Application arguments */ - typedef std::pair Arguments; + struct Arguments { + int& argc; /**< @brief Argument count */ + char** argv; /**< @brief Argument values */ + }; class Configuration; class InputEvent; diff --git a/src/Platform/WindowlessGlxApplication.h b/src/Platform/WindowlessGlxApplication.h index b7c8d940a..c38cfb5a6 100644 --- a/src/Platform/WindowlessGlxApplication.h +++ b/src/Platform/WindowlessGlxApplication.h @@ -66,7 +66,10 @@ If no other application header is included this class is also aliased to class WindowlessGlxApplication { public: /** @brief Application arguments */ - typedef std::pair Arguments; + struct Arguments { + int& argc; /**< @brief Argument count */ + char** argv; /**< @brief Argument values */ + }; class Configuration; From 3bf9dbc3f75cdb9d7f97e5e34fe441e4f9067e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 13 Apr 2013 19:08:00 +0200 Subject: [PATCH 14/30] Trade: properly implement move constructor and assignment in MeshData. Default implementation of move constructor won't set pointer to indices to `nullptr` in `other` object, thus implementing it explicitly. Not sure what will happen in move assignment, implementing it explicitly too. --- src/Trade/MeshData2D.cpp | 12 ++++++++++-- src/Trade/MeshData3D.cpp | 13 +++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/Trade/MeshData2D.cpp b/src/Trade/MeshData2D.cpp index 57cde771b..44ea06609 100644 --- a/src/Trade/MeshData2D.cpp +++ b/src/Trade/MeshData2D.cpp @@ -30,9 +30,17 @@ namespace Magnum { namespace Trade { MeshData2D::MeshData2D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> textureCoords2D): _primitive(primitive), _indices(indices), _positions(std::move(positions)), _textureCoords2D(std::move(textureCoords2D)) {} -MeshData2D::MeshData2D(MeshData2D&&) = default; +MeshData2D::MeshData2D(MeshData2D&& other): _primitive(other._primitive), _indices(other._indices), _positions(std::move(other._positions)), _textureCoords2D(std::move(other._textureCoords2D)) { + other._indices = nullptr; +} -MeshData2D& MeshData2D::operator=(MeshData2D&&) = default; +MeshData2D& MeshData2D::operator=(MeshData2D&& other) { + _primitive = other._primitive; + std::swap(_indices, other._indices); + std::swap(_positions, other._positions); + std::swap(_textureCoords2D, other._textureCoords2D); + return *this; +} MeshData2D::~MeshData2D() { delete _indices; diff --git a/src/Trade/MeshData3D.cpp b/src/Trade/MeshData3D.cpp index ee6e27253..5ad47c640 100644 --- a/src/Trade/MeshData3D.cpp +++ b/src/Trade/MeshData3D.cpp @@ -30,9 +30,18 @@ namespace Magnum { namespace Trade { MeshData3D::MeshData3D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> normals, std::vector*> textureCoords2D): _primitive(primitive), _indices(indices), _positions(std::move(positions)), _normals(std::move(normals)), _textureCoords2D(std::move(textureCoords2D)) {} -MeshData3D::MeshData3D(MeshData3D&&) = default; +MeshData3D::MeshData3D(MeshData3D&& other): _primitive(other._primitive), _indices(other._indices), _positions(std::move(other._positions)), _normals(std::move(other._normals)), _textureCoords2D(std::move(other._textureCoords2D)) { + other._indices = nullptr; +} -MeshData3D& MeshData3D::operator=(MeshData3D&&) = default; +MeshData3D& MeshData3D::operator=(MeshData3D&& other) { + _primitive = other._primitive; + std::swap(_indices, other._indices); + std::swap(_positions, other._positions); + std::swap(_normals, other._normals); + std::swap(_textureCoords2D, other._textureCoords2D); + return *this; +} MeshData3D::~MeshData3D() { delete _indices; From 70ba2bd77c136ed5f374bc2c4a5ffb1dd6e55f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 13 Apr 2013 19:12:17 +0200 Subject: [PATCH 15/30] Primitives: reworked remaining classes to have the same API as the rest. Now every primitive can be created using `solid()` or `wireframe()` function returning directly Trade::MeshData. --- src/Primitives/CMakeLists.txt | 4 +- src/Primitives/Capsule.cpp | 138 +++--------------- src/Primitives/Capsule.h | 38 ++--- src/Primitives/Circle.h | 2 +- src/Primitives/Cylinder.cpp | 44 ++---- src/Primitives/Cylinder.h | 21 ++- src/Primitives/Implementation/Spheroid.cpp | 162 +++++++++++++++++++++ src/Primitives/Implementation/Spheroid.h | 54 +++++++ src/Primitives/Test/CapsuleTest.cpp | 5 +- src/Primitives/Test/CylinderTest.cpp | 5 +- src/Primitives/Test/UVSphereTest.cpp | 5 +- src/Primitives/UVSphere.cpp | 23 ++- src/Primitives/UVSphere.h | 29 ++-- 13 files changed, 313 insertions(+), 217 deletions(-) create mode 100644 src/Primitives/Implementation/Spheroid.cpp create mode 100644 src/Primitives/Implementation/Spheroid.h diff --git a/src/Primitives/CMakeLists.txt b/src/Primitives/CMakeLists.txt index 9675469aa..01224000d 100644 --- a/src/Primitives/CMakeLists.txt +++ b/src/Primitives/CMakeLists.txt @@ -32,7 +32,9 @@ set(MagnumPrimitives_SRCS Line.cpp Plane.cpp Square.cpp - UVSphere.cpp) + UVSphere.cpp + + Implementation/Spheroid.cpp) set(MagnumPrimitives_HEADERS Capsule.h diff --git a/src/Primitives/Capsule.cpp b/src/Primitives/Capsule.cpp index e35ecb34f..1447e2e16 100644 --- a/src/Primitives/Capsule.cpp +++ b/src/Primitives/Capsule.cpp @@ -24,147 +24,43 @@ #include "Capsule.h" -#include "Math/Functions.h" -#include "Math/Vector3.h" +#include "Math/Angle.h" +#include "Primitives/Implementation/Spheroid.h" namespace Magnum { namespace Primitives { -Capsule::Capsule(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords): MeshData3D(Mesh::Primitive::Triangles, new std::vector, {new std::vector()}, {new std::vector()}, textureCoords == TextureCoords::Generate ? std::vector*>{new std::vector()} : std::vector*>()), segments(segments), textureCoords(textureCoords) { - CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", ); +Trade::MeshData3D Capsule::solid(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords) { + CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, nullptr, {}, {}, {})); + + Implementation::Spheroid capsule(segments, textureCoords == TextureCoords::Generate ? + Implementation::Spheroid::TextureCoords::Generate : + Implementation::Spheroid::TextureCoords::DontGenerate); Float height = 2.0f+length; Float hemisphereTextureCoordsVIncrement = 1.0f/(hemisphereRings*height); Rad hemisphereRingAngleIncrement(Constants::pi()/(2*hemisphereRings)); /* Bottom cap vertex */ - capVertex(-height/2, -1.0f, 0.0f); + capsule.capVertex(-height/2, -1.0f, 0.0f); /* Rings of bottom hemisphere */ - hemisphereVertexRings(hemisphereRings-1, -length/2, -Rad(Constants::pi())/2+hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); + capsule.hemisphereVertexRings(hemisphereRings-1, -length/2, -Rad(Constants::pi())/2+hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); /* Rings of cylinder */ - cylinderVertexRings(cylinderRings+1, -length/2, length/cylinderRings, 1.0f/height, length/(cylinderRings*height)); + capsule.cylinderVertexRings(cylinderRings+1, -length/2, length/cylinderRings, 1.0f/height, length/(cylinderRings*height)); /* Rings of top hemisphere */ - hemisphereVertexRings(hemisphereRings-1, length/2, hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, (1.0f + length)/height+hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); + capsule.hemisphereVertexRings(hemisphereRings-1, length/2, hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, (1.0f + length)/height+hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); /* Top cap vertex */ - capVertex(height/2, 1.0f, 1.0f); + capsule.capVertex(height/2, 1.0f, 1.0f); /* Faces */ - bottomFaceRing(); - faceRings(hemisphereRings*2-2+cylinderRings); - topFaceRing(); -} - -Capsule::Capsule(UnsignedInt segments, TextureCoords textureCoords): MeshData3D(Mesh::Primitive::Triangles, new std::vector, {new std::vector()}, {new std::vector()}, textureCoords == TextureCoords::Generate ? std::vector*>{new std::vector()} : std::vector*>()), segments(segments), textureCoords(textureCoords) {} - -void Capsule::capVertex(Float y, Float normalY, Float textureCoordsV) { - positions(0)->push_back({0.0f, y, 0.0f}); - normals(0)->push_back({0.0f, normalY, 0.0f}); - - if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({0.5, textureCoordsV}); -} - -void Capsule::hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { - Rad segmentAngleIncrement(2*Constants::pi()/segments); - Float x, y, z; - for(UnsignedInt i = 0; i != count; ++i) { - Rad ringAngle = startRingAngle + i*ringAngleIncrement; - x = z = Math::cos(ringAngle); - y = Math::sin(ringAngle); - - for(UnsignedInt j = 0; j != segments; ++j) { - Rad segmentAngle = j*segmentAngleIncrement; - positions(0)->push_back({x*Math::sin(segmentAngle), centerY+y, z*Math::cos(segmentAngle)}); - normals(0)->push_back({x*Math::sin(segmentAngle), y, z*Math::cos(segmentAngle)}); - - if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); - } - - /* Duplicate first segment in the ring for additional vertex for texture coordinate */ - if(textureCoords == TextureCoords::Generate) { - positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); - normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); - textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); - } - } -} - -void Capsule::cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { - Rad segmentAngleIncrement(2*Constants::pi()/segments); - for(UnsignedInt i = 0; i != count; ++i) { - for(UnsignedInt j = 0; j != segments; ++j) { - Rad segmentAngle = j*segmentAngleIncrement; - positions(0)->push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)}); - normals(0)->push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)}); - - if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); - } - - /* Duplicate first segment in the ring for additional vertex for texture coordinate */ - if(textureCoords == TextureCoords::Generate) { - positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); - normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); - textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); - } - - startY += yIncrement; - } -} - -void Capsule::bottomFaceRing() { - for(UnsignedInt j = 0; j != segments; ++j) { - /* Bottom vertex */ - indices()->push_back(0); - - /* Top right vertex */ - indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? - j+2 : 1); - - /* Top left vertex */ - indices()->push_back(j+1); - } -} - -void Capsule::faceRings(UnsignedInt count, UnsignedInt offset) { - UnsignedInt vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); - - for(UnsignedInt i = 0; i != count; ++i) { - for(UnsignedInt j = 0; j != segments; ++j) { - UnsignedInt bottomLeft = i*vertexSegments+j+offset; - UnsignedInt bottomRight = ((j != segments-1 || textureCoords == TextureCoords::Generate) ? - i*vertexSegments+j+1+offset : i*segments+offset); - UnsignedInt topLeft = bottomLeft+vertexSegments; - UnsignedInt topRight = bottomRight+vertexSegments; - - indices()->push_back(bottomLeft); - indices()->push_back(bottomRight); - indices()->push_back(topRight); - indices()->push_back(bottomLeft); - indices()->push_back(topRight); - indices()->push_back(topLeft); - } - } -} - -void Capsule::topFaceRing() { - UnsignedInt vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); - - for(UnsignedInt j = 0; j != segments; ++j) { - /* Bottom left vertex */ - indices()->push_back(normals(0)->size()-vertexSegments+j-1); - - /* Bottom right vertex */ - indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? - normals(0)->size()-vertexSegments+j : normals(0)->size()-segments-1); + capsule.bottomFaceRing(); + capsule.faceRings(hemisphereRings*2-2+cylinderRings); + capsule.topFaceRing(); - /* Top vertex */ - indices()->push_back(normals(0)->size()-1); - } + return std::move(capsule); } }} diff --git a/src/Primitives/Capsule.h b/src/Primitives/Capsule.h index 00111ae74..fbefe1c30 100644 --- a/src/Primitives/Capsule.h +++ b/src/Primitives/Capsule.h @@ -28,56 +28,40 @@ * @brief Class Magnum::Primitives::Capsule */ -#include "Trade/MeshData3D.h" - #include "Primitives/magnumPrimitivesVisibility.h" +#include "Trade/Trade.h" namespace Magnum { namespace Primitives { /** @brief 3D capsule primitive -%Cylinder along Y axis with hemispheres instead of caps. Indexed @ref Mesh::Primitive "Triangles" -with normals and optional 2D texture coordinates. +%Cylinder of radius `1` along Y axis with hemispheres instead of caps. */ -class Capsule: public Trade::MeshData3D { - friend class UVSphere; - friend class Cylinder; - +class MAGNUM_PRIMITIVES_EXPORT Capsule { public: /** @brief Whether to generate texture coordinates */ - enum class TextureCoords { + enum class TextureCoords: UnsignedByte { Generate, /**< Generate texture coordinates */ DontGenerate /**< Don't generate texture coordinates */ }; /** - * @brief Constructor + * @brief Solid capsule * @param hemisphereRings Number of (face) rings for each hemisphere. * Must be larger or equal to 1. * @param cylinderRings Number of (face) rings for cylinder. Must be * larger or equal to 1. - * @param segments Number of (face) segments. Must be larger or equal to 3. + * @param segments Number of (face) segments. Must be larger or + * equal to 3. * @param length Length of the capsule, excluding hemispheres. * @param textureCoords Whether to generate texture coordinates. * - * If texture coordinates are generated, vertices of one segment are - * duplicated for texture wrapping. + * Indexed @ref Mesh::Primitive "Triangles" with normals and optional + * 2D texture coordinates. If texture coordinates are generated, + * vertices of one segment are duplicated for texture wrapping. */ - explicit MAGNUM_PRIMITIVES_EXPORT Capsule(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords = TextureCoords::DontGenerate); - - private: - Capsule(UnsignedInt segments, TextureCoords textureCoords); - - void capVertex(Float y, Float normalY, Float textureCoordsV); - void hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement); - void cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement); - void bottomFaceRing(); - void faceRings(UnsignedInt count, UnsignedInt offset = 1); - void topFaceRing(); - - UnsignedInt segments; - TextureCoords textureCoords; + static Trade::MeshData3D solid(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords = TextureCoords::DontGenerate); }; }} diff --git a/src/Primitives/Circle.h b/src/Primitives/Circle.h index a27876e31..b97c1e7b2 100644 --- a/src/Primitives/Circle.h +++ b/src/Primitives/Circle.h @@ -37,7 +37,7 @@ namespace Magnum { namespace Primitives { /** @brief 2D circle primitive -Circle with radius 1. +Circle with radius `1`. */ class MAGNUM_PRIMITIVES_EXPORT Circle { public: diff --git a/src/Primitives/Cylinder.cpp b/src/Primitives/Cylinder.cpp index 691e5402b..13c043b3a 100644 --- a/src/Primitives/Cylinder.cpp +++ b/src/Primitives/Cylinder.cpp @@ -24,56 +24,40 @@ #include "Cylinder.h" -#include "Math/Functions.h" #include "Math/Vector3.h" +#include "Primitives/Implementation/Spheroid.h" namespace Magnum { namespace Primitives { -Cylinder::Cylinder(UnsignedInt rings, UnsignedInt segments, Float length, Flags flags): Capsule(segments, flags & Flag::GenerateTextureCoords ? TextureCoords::Generate : TextureCoords::DontGenerate) { - CORRADE_ASSERT(rings >= 1 && segments >= 3, "Cylinder must have at least one ring and three segments", ); +Trade::MeshData3D Cylinder::solid(UnsignedInt rings, UnsignedInt segments, Float length, Cylinder::Flags flags) { + CORRADE_ASSERT(rings >= 1 && segments >= 3, "Primitives::Cylinder::solid(): cylinder must have at least one ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, nullptr, {}, {}, {})); + + Implementation::Spheroid cylinder(segments, flags & Flag::GenerateTextureCoords ? Implementation::Spheroid::TextureCoords::Generate : Implementation::Spheroid::TextureCoords::DontGenerate); Float y = length*0.5f; Float textureCoordsV = flags & Flag::CapEnds ? 1.0f/(length+2.0f) : 0.0f; /* Bottom cap */ if(flags & Flag::CapEnds) { - capVertex(-y, -1.0f, 0.0f); - capVertexRing(-y, textureCoordsV, Vector3::yAxis(-1.0f)); + cylinder.capVertex(-y, -1.0f, 0.0f); + cylinder.capVertexRing(-y, textureCoordsV, Vector3::yAxis(-1.0f)); } /* Vertex rings */ - cylinderVertexRings(rings+1, -y, length/rings, textureCoordsV, length/(rings*(flags & Flag::CapEnds ? length + 2.0f : length))); + cylinder.cylinderVertexRings(rings+1, -y, length/rings, textureCoordsV, length/(rings*(flags & Flag::CapEnds ? length + 2.0f : length))); /* Top cap */ if(flags & Flag::CapEnds) { - capVertexRing(y, 1.0f - textureCoordsV, Vector3::yAxis(1.0f)); - capVertex(y, 1.0f, 1.0f); + cylinder.capVertexRing(y, 1.0f - textureCoordsV, Vector3::yAxis(1.0f)); + cylinder.capVertex(y, 1.0f, 1.0f); } /* Faces */ - if(flags & Flag::CapEnds) bottomFaceRing(); - faceRings(rings, flags & Flag::CapEnds ? 1 : 0); - if(flags & Flag::CapEnds) topFaceRing(); -} - -void Cylinder::capVertexRing(Float y, Float textureCoordsV, const Vector3& normal) { - Rad segmentAngleIncrement(2*Constants::pi()/segments); - - for(UnsignedInt i = 0; i != segments; ++i) { - Rad segmentAngle = i*segmentAngleIncrement; - positions(0)->push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)}); - normals(0)->push_back(normal); + if(flags & Flag::CapEnds) cylinder.bottomFaceRing(); + cylinder.faceRings(rings, flags & Flag::CapEnds ? 1 : 0); + if(flags & Flag::CapEnds) cylinder.topFaceRing(); - if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({i*1.0f/segments, textureCoordsV}); - } - - /* Duplicate first segment in the ring for additional vertex for texture coordinate */ - if(textureCoords == TextureCoords::Generate) { - positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); - normals(0)->push_back(normal); - textureCoords2D(0)->push_back({1.0f, textureCoordsV}); - } + return std::move(cylinder); } }} diff --git a/src/Primitives/Cylinder.h b/src/Primitives/Cylinder.h index eac16de9d..ed38da5ae 100644 --- a/src/Primitives/Cylinder.h +++ b/src/Primitives/Cylinder.h @@ -30,19 +30,17 @@ #include -#include "Primitives/Capsule.h" - #include "Primitives/magnumPrimitivesVisibility.h" +#include "Trade/Trade.h" namespace Magnum { namespace Primitives { /** @brief 3D cylinder primitive -Indexed @ref Mesh::Primitive "Triangles" with normals, optional 2D texture -coordinates and optional capped ends. +%Cylinder along Y axis of radius `1`. */ -class Cylinder: public Capsule { +class MAGNUM_PRIMITIVES_EXPORT Cylinder { public: /** * @brief %Flags @@ -58,7 +56,7 @@ class Cylinder: public Capsule { typedef Corrade::Containers::EnumSet Flags; /** - * @brief Constructor + * @brief Solid cylinder * @param rings Number of (face) rings. Must be larger or * equal to 1. * @param segments Number of (face) segments. Must be larger or @@ -66,13 +64,12 @@ class Cylinder: public Capsule { * @param length Cylinder length * @param flags Flags * - * If texture coordinates are generated, vertices of one segment are - * duplicated for texture wrapping. + * Indexed @ref Mesh::Primitive "Triangles" with normals, optional 2D + * texture coordinates and optional capped ends. If texture coordinates + * are generated, vertices of one segment are duplicated for texture + * wrapping. */ - explicit MAGNUM_PRIMITIVES_EXPORT Cylinder(UnsignedInt rings, UnsignedInt segments, Float length, Flags flags = Flags()); - - private: - void capVertexRing(Float y, Float textureCoordsV, const Vector3& normal); + static Trade::MeshData3D solid(UnsignedInt rings, UnsignedInt segments, Float length, Flags flags = Flags()); }; CORRADE_ENUMSET_OPERATORS(Cylinder::Flags) diff --git a/src/Primitives/Implementation/Spheroid.cpp b/src/Primitives/Implementation/Spheroid.cpp new file mode 100644 index 000000000..288279160 --- /dev/null +++ b/src/Primitives/Implementation/Spheroid.cpp @@ -0,0 +1,162 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Spheroid.h" + +#include "Math/Functions.h" +#include "Math/Vector3.h" + +namespace Magnum { namespace Primitives { namespace Implementation { + +Spheroid::Spheroid(UnsignedInt segments, TextureCoords textureCoords): MeshData3D(Mesh::Primitive::Triangles, new std::vector, {new std::vector()}, {new std::vector()}, textureCoords == TextureCoords::Generate ? std::vector*>{new std::vector()} : std::vector*>()), segments(segments), textureCoords(textureCoords) {} + +void Spheroid::capVertex(Float y, Float normalY, Float textureCoordsV) { + positions(0)->push_back({0.0f, y, 0.0f}); + normals(0)->push_back({0.0f, normalY, 0.0f}); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({0.5, textureCoordsV}); +} + +void Spheroid::hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { + Rad segmentAngleIncrement(2*Constants::pi()/segments); + Float x, y, z; + for(UnsignedInt i = 0; i != count; ++i) { + Rad ringAngle = startRingAngle + i*ringAngleIncrement; + x = z = Math::cos(ringAngle); + y = Math::sin(ringAngle); + + for(UnsignedInt j = 0; j != segments; ++j) { + Rad segmentAngle = j*segmentAngleIncrement; + positions(0)->push_back({x*Math::sin(segmentAngle), centerY+y, z*Math::cos(segmentAngle)}); + normals(0)->push_back({x*Math::sin(segmentAngle), y, z*Math::cos(segmentAngle)}); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); + } + + /* Duplicate first segment in the ring for additional vertex for texture coordinate */ + if(textureCoords == TextureCoords::Generate) { + positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); + normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); + textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); + } + } +} + +void Spheroid::cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { + Rad segmentAngleIncrement(2*Constants::pi()/segments); + for(UnsignedInt i = 0; i != count; ++i) { + for(UnsignedInt j = 0; j != segments; ++j) { + Rad segmentAngle = j*segmentAngleIncrement; + positions(0)->push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)}); + normals(0)->push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)}); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); + } + + /* Duplicate first segment in the ring for additional vertex for texture coordinate */ + if(textureCoords == TextureCoords::Generate) { + positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); + normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); + textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); + } + + startY += yIncrement; + } +} + +void Spheroid::bottomFaceRing() { + for(UnsignedInt j = 0; j != segments; ++j) { + /* Bottom vertex */ + indices()->push_back(0); + + /* Top right vertex */ + indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? + j+2 : 1); + + /* Top left vertex */ + indices()->push_back(j+1); + } +} + +void Spheroid::faceRings(UnsignedInt count, UnsignedInt offset) { + UnsignedInt vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); + + for(UnsignedInt i = 0; i != count; ++i) { + for(UnsignedInt j = 0; j != segments; ++j) { + UnsignedInt bottomLeft = i*vertexSegments+j+offset; + UnsignedInt bottomRight = ((j != segments-1 || textureCoords == TextureCoords::Generate) ? + i*vertexSegments+j+1+offset : i*segments+offset); + UnsignedInt topLeft = bottomLeft+vertexSegments; + UnsignedInt topRight = bottomRight+vertexSegments; + + indices()->push_back(bottomLeft); + indices()->push_back(bottomRight); + indices()->push_back(topRight); + indices()->push_back(bottomLeft); + indices()->push_back(topRight); + indices()->push_back(topLeft); + } + } +} + +void Spheroid::topFaceRing() { + UnsignedInt vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); + + for(UnsignedInt j = 0; j != segments; ++j) { + /* Bottom left vertex */ + indices()->push_back(normals(0)->size()-vertexSegments+j-1); + + /* Bottom right vertex */ + indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? + normals(0)->size()-vertexSegments+j : normals(0)->size()-segments-1); + + /* Top vertex */ + indices()->push_back(normals(0)->size()-1); + } +} + +void Spheroid::capVertexRing(Float y, Float textureCoordsV, const Vector3& normal) { + Rad segmentAngleIncrement(2*Constants::pi()/segments); + + for(UnsignedInt i = 0; i != segments; ++i) { + Rad segmentAngle = i*segmentAngleIncrement; + positions(0)->push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)}); + normals(0)->push_back(normal); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({i*1.0f/segments, textureCoordsV}); + } + + /* Duplicate first segment in the ring for additional vertex for texture coordinate */ + if(textureCoords == TextureCoords::Generate) { + positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); + normals(0)->push_back(normal); + textureCoords2D(0)->push_back({1.0f, textureCoordsV}); + } +} + +}}} diff --git a/src/Primitives/Implementation/Spheroid.h b/src/Primitives/Implementation/Spheroid.h new file mode 100644 index 000000000..9a3f89203 --- /dev/null +++ b/src/Primitives/Implementation/Spheroid.h @@ -0,0 +1,54 @@ +#ifndef Magnum_Primitives_Spheroid_h +#define Magnum_Primitives_Spheroid_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Trade/MeshData3D.h" + +namespace Magnum { namespace Primitives { namespace Implementation { + +class Spheroid: public Trade::MeshData3D { + public: + enum class TextureCoords: UnsignedByte { + DontGenerate, + Generate + }; + + Spheroid(UnsignedInt segments, TextureCoords textureCoords); + + void capVertex(Float y, Float normalY, Float textureCoordsV); + void hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement); + void cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement); + void bottomFaceRing(); + void faceRings(UnsignedInt count, UnsignedInt offset = 1); + void topFaceRing(); + void capVertexRing(Float y, Float textureCoordsV, const Vector3& normal); + + UnsignedInt segments; + TextureCoords textureCoords; +}; + +}}} + +#endif diff --git a/src/Primitives/Test/CapsuleTest.cpp b/src/Primitives/Test/CapsuleTest.cpp index 3d74a2680..56b5bc569 100644 --- a/src/Primitives/Test/CapsuleTest.cpp +++ b/src/Primitives/Test/CapsuleTest.cpp @@ -29,6 +29,7 @@ #include #include "Math/Vector3.h" +#include "Trade/MeshData3D.h" #include "Primitives/Capsule.h" using Corrade::TestSuite::Compare::Container; @@ -49,7 +50,7 @@ CapsuleTest::CapsuleTest() { } void CapsuleTest::withoutTextureCoords() { - Capsule capsule(2, 2, 3, 1.0f); + Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f); CORRADE_COMPARE_AS(*capsule.positions(0), (std::vector{ {0.0f, -1.5f, 0.0f}, @@ -114,7 +115,7 @@ void CapsuleTest::withoutTextureCoords() { } void CapsuleTest::withTextureCoords() { - Capsule capsule(2, 2, 3, 1.0f, Capsule::TextureCoords::Generate); + Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f, Capsule::TextureCoords::Generate); CORRADE_COMPARE_AS(*capsule.positions(0), (std::vector{ {0.0f, -1.5f, 0.0f}, diff --git a/src/Primitives/Test/CylinderTest.cpp b/src/Primitives/Test/CylinderTest.cpp index 938162fab..ef861c206 100644 --- a/src/Primitives/Test/CylinderTest.cpp +++ b/src/Primitives/Test/CylinderTest.cpp @@ -27,6 +27,7 @@ #include "Math/Vector3.h" #include "Primitives/Cylinder.h" +#include "Trade/MeshData3D.h" using Corrade::TestSuite::Compare::Container; @@ -46,7 +47,7 @@ CylinderTest::CylinderTest() { } void CylinderTest::withoutAnything() { - Cylinder cylinder(2, 3, 3.0f); + Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f); CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector{ {0.0f, -1.5f, 1.0f}, @@ -83,7 +84,7 @@ void CylinderTest::withoutAnything() { } void CylinderTest::withTextureCoordsAndCaps() { - Cylinder cylinder(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds); + Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds); CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector{ {0.0f, -1.5f, 0.0f}, diff --git a/src/Primitives/Test/UVSphereTest.cpp b/src/Primitives/Test/UVSphereTest.cpp index beaa6b46f..93cb2ff1f 100644 --- a/src/Primitives/Test/UVSphereTest.cpp +++ b/src/Primitives/Test/UVSphereTest.cpp @@ -27,6 +27,7 @@ #include "Math/Vector3.h" #include "Primitives/UVSphere.h" +#include "Trade/MeshData3D.h" using Corrade::TestSuite::Compare::Container; @@ -46,7 +47,7 @@ UVSphereTest::UVSphereTest() { } void UVSphereTest::withoutTextureCoords() { - UVSphere sphere(3, 3); + Trade::MeshData3D sphere = UVSphere::solid(3, 3); CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector{ {0.0f, -1.0f, 0.0f}, @@ -84,7 +85,7 @@ void UVSphereTest::withoutTextureCoords() { } void UVSphereTest::withTextureCoords() { - UVSphere sphere(3, 3, UVSphere::TextureCoords::Generate); + Trade::MeshData3D sphere = UVSphere::solid(3, 3, UVSphere::TextureCoords::Generate); CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector{ {0.0f, -1.0f, 0.0f}, diff --git a/src/Primitives/UVSphere.cpp b/src/Primitives/UVSphere.cpp index b6cde4ca3..5ec1d72c5 100644 --- a/src/Primitives/UVSphere.cpp +++ b/src/Primitives/UVSphere.cpp @@ -25,28 +25,35 @@ #include "UVSphere.h" #include "Math/Angle.h" +#include "Implementation/Spheroid.h" namespace Magnum { namespace Primitives { -UVSphere::UVSphere(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords): Capsule(segments, textureCoords) { - CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", ); +Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords) { + CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, nullptr, {}, {}, {})); + + Implementation::Spheroid sphere(segments, textureCoords == TextureCoords::Generate ? + Implementation::Spheroid::TextureCoords::Generate : + Implementation::Spheroid::TextureCoords::DontGenerate); Float textureCoordsVIncrement = 1.0f/rings; Rad ringAngleIncrement(Constants::pi()/rings); /* Bottom cap vertex */ - capVertex(-1.0f, -1.0f, 0.0f); + sphere.capVertex(-1.0f, -1.0f, 0.0f); /* Vertex rings */ - hemisphereVertexRings(rings-1, 0.0f, -Rad(Constants::pi())/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); + sphere.hemisphereVertexRings(rings-1, 0.0f, -Rad(Constants::pi())/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); /* Top cap vertex */ - capVertex(1.0f, 1.0f, 1.0f); + sphere.capVertex(1.0f, 1.0f, 1.0f); /* Faces */ - bottomFaceRing(); - faceRings(rings-2); - topFaceRing(); + sphere.bottomFaceRing(); + sphere.faceRings(rings-2); + sphere.topFaceRing(); + + return std::move(sphere); } }} diff --git a/src/Primitives/UVSphere.h b/src/Primitives/UVSphere.h index 8b6266c45..7cfb75b94 100644 --- a/src/Primitives/UVSphere.h +++ b/src/Primitives/UVSphere.h @@ -28,30 +28,37 @@ * @brief Class Magnum::Primitives::UVSphere */ -#include "Primitives/Capsule.h" - #include "Primitives/magnumPrimitivesVisibility.h" +#include "Trade/Trade.h" namespace Magnum { namespace Primitives { /** @brief 3D UV sphere primitive -Indexed @ref Mesh::Primitive "Triangles" with normals and optional 2D texture -coordinates. +Sphere with radius `1`. */ -class UVSphere: public Capsule { +class MAGNUM_PRIMITIVES_EXPORT UVSphere { public: + /** @brief Whether to generate texture coordinates */ + enum class TextureCoords: UnsignedByte { + Generate, /**< Generate texture coordinates */ + DontGenerate /**< Don't generate texture coordinates */ + }; + /** - * @brief Constructor - * @param rings Number of (face) rings. Must be larger or equal to 2. - * @param segments Number of (face) segments. Must be larger or equal to 3. + * @brief Solid UV sphere + * @param rings Number of (face) rings. Must be larger or equal + * to 2. + * @param segments Number of (face) segments. Must be larger or + * equal to 3. * @param textureCoords Whether to generate texture coordinates. * - * If texture coordinates are generated, vertices of one segment are - * duplicated for texture wrapping. + * Indexed @ref Mesh::Primitive "Triangles" with normals and optional + * 2D texture coordinates. If texture coordinates are generated, + * vertices of one segment are duplicated for texture wrapping. */ - explicit MAGNUM_PRIMITIVES_EXPORT UVSphere(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords = TextureCoords::DontGenerate); + static Trade::MeshData3D solid(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords = TextureCoords::DontGenerate); }; }} From 71c7480299b9e48e63315bb328acbc84c80fc4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 13 Apr 2013 21:03:54 +0200 Subject: [PATCH 16/30] Fixed one-value AbstractShaderProgram::setUniform(). The original workaround for enums didn't work (all enums were treated as UnsignedInt even though they had Int as underlying type), moreover the solution didn't scale for other possible types with implicit conversions. Now explicitly listing all scalar types and templated vectors/matrices, it should work for most cases. --- src/AbstractShaderProgram.h | 39 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index 9bb375aad..1dbf1d640 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -42,18 +42,6 @@ namespace Magnum { #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { template struct Attribute; - - /* Used in setUniform(Int, const T&), otherwise it would not be possible to - pass enum values as uniforms */ - struct NonEnumType { - template inline static typename std::enable_if::value, const typename std::conditional::value, UnsignedInt, Int>::type&>::type cast(const T& value) { - return static_cast::value, UnsignedInt, Int>::type&>(value); - } - - template inline static typename std::enable_if::value, const T&>::type cast(const T& value) { - return value; - } - }; } #endif @@ -694,9 +682,32 @@ class MAGNUM_EXPORT AbstractShaderProgram { * Convenience alternative for setting one value, see * setUniform(Int, UnsignedInt, const Float*) for more information. */ - template inline void setUniform(Int location, const T& value) { - setUniform(location, 1, &Implementation::NonEnumType::cast(value)); + #ifdef DOXYGEN_GENERATING_OUTPUT + template inline void setUniform(Int location, const T& value); + #else + inline void setUniform(Int location, Float value) { + setUniform(location, 1, &value); + } + inline void setUniform(Int location, Int value) { + setUniform(location, 1, &value); + } + #ifndef MAGNUM_TARGET_GLES2 + inline void setUniform(Int location, UnsignedInt value) { + setUniform(location, 1, &value); + } + #endif + #ifndef MAGNUM_TARGET_GLES + inline void setUniform(Int location, Double value) { + setUniform(location, 1, &value); } + #endif + template inline void setUniform(Int location, const Math::Vector& value) { + setUniform(location, 1, &value); + } + template inline void setUniform(Int location, const Math::RectangularMatrix& value) { + setUniform(location, 1, &value); + } + #endif /** * @brief Set uniform values From 2a6c52c97b6ed66eb7d3674f6b67b45982f55c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 14 Apr 2013 14:01:01 +0200 Subject: [PATCH 17/30] Platform: fix WindowlessGlxApplication context creation and destruction. The variable wasn't initialized so it exited with assertion failure, moreover the context wasn't deleted on destruction, causing memory leak. --- src/Platform/WindowlessGlxApplication.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Platform/WindowlessGlxApplication.cpp b/src/Platform/WindowlessGlxApplication.cpp index 2d7c017b8..0108bc2ca 100644 --- a/src/Platform/WindowlessGlxApplication.cpp +++ b/src/Platform/WindowlessGlxApplication.cpp @@ -33,11 +33,11 @@ namespace Magnum { namespace Platform { -WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&) { +WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&): c(nullptr) { createContext(new Configuration); } -WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, Configuration* configuration) { +WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, Configuration* configuration): c(nullptr) { if(configuration) createContext(configuration); } @@ -104,6 +104,8 @@ void WindowlessGlxApplication::createContext(Configuration* configuration) { } WindowlessGlxApplication::~WindowlessGlxApplication() { + delete c; + glXMakeCurrent(display, None, nullptr); glXDestroyContext(display, context); } From 00a17e3699ea5b9dd41a12ac5f4f29cc49041381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 14 Apr 2013 14:04:39 +0200 Subject: [PATCH 18/30] DebugTools: saner default color. Default framebuffer clear color is black, thus having black debug renderers by default isn't much useful. --- src/DebugTools/ForceRenderer.h | 4 ++-- src/DebugTools/ShapeRenderer.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DebugTools/ForceRenderer.h b/src/DebugTools/ForceRenderer.h index 79e521ab4..7af657909 100644 --- a/src/DebugTools/ForceRenderer.h +++ b/src/DebugTools/ForceRenderer.h @@ -44,7 +44,7 @@ See ForceRenderer documentation for more information. */ class ForceRendererOptions { public: - inline constexpr ForceRendererOptions(): _size(1.0f) {} + inline constexpr ForceRendererOptions(): _color(1.0f), _size(1.0f) {} /** @brief Color of rendered arrow */ inline constexpr Color4<> color() const { return _color; } @@ -53,7 +53,7 @@ class ForceRendererOptions { * @brief Set color of rendered arrow * @return Pointer to self (for method chaining) * - * Default is black. + * Default is 100% opaque white. */ inline ForceRendererOptions* setColor(const Color4<>& color) { _color = color; diff --git a/src/DebugTools/ShapeRenderer.h b/src/DebugTools/ShapeRenderer.h index e1af8bf93..675c0be21 100644 --- a/src/DebugTools/ShapeRenderer.h +++ b/src/DebugTools/ShapeRenderer.h @@ -57,7 +57,7 @@ See ShapeRenderer documentation for more information. */ class ShapeRendererOptions { public: - inline constexpr ShapeRendererOptions(): _pointSize(0.25f) {} + inline constexpr ShapeRendererOptions(): _color(1.0f), _pointSize(0.25f) {} /** @brief Color of rendered shape */ inline constexpr Color4<> color() const { return _color; } @@ -66,7 +66,7 @@ class ShapeRendererOptions { * @brief Set color of rendered shape * @return Pointer to self (for method chaining) * - * Default is black. + * Default is 100% opaque white. */ inline ShapeRendererOptions* setColor(const Color4<>& color) { _color = color; From fd531b5101374f5e8980a782eafb5f21de3fda6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 14 Apr 2013 21:19:35 +0200 Subject: [PATCH 19/30] Math: cleaned up plane/line intersection. The function now accepts starting point and direction of the line (not starting and ending point). Also improved the documentation and test a bit. --- src/Math/Geometry/Intersection.h | 32 +++++++++------------ src/Math/Geometry/Test/CMakeLists.txt | 2 +- src/Math/Geometry/Test/IntersectionTest.cpp | 8 +++--- src/Physics/Plane.cpp | 4 +-- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/Math/Geometry/Intersection.h b/src/Math/Geometry/Intersection.h index 9d3bff5c7..35100ed86 100644 --- a/src/Math/Geometry/Intersection.h +++ b/src/Math/Geometry/Intersection.h @@ -41,34 +41,30 @@ class Intersection { * @brief %Intersection of a plane and line * @param planePosition Plane position * @param planeNormal Plane normal - * @param a Starting point of the line - * @param b Ending point of the line - * @return %Intersection point position, NaN if the line lies on the - * plane or infinity if the intersection doesn't exist. %Intersection - * point can be computed from the position with `a+intersection(...)*b`. - * If returned value is in range @f$ [ 0 ; 1 ] @f$, the intersection - * is inside the line segment defined by `a` and `b`. + * @param p Starting point of the line + * @param r Direction of the line + * @return %Intersection point position `t` on the line, NaN if the + * line lies on the plane or infinity if the intersection doesn't + * exist. %Intersection point can be then computed from with + * `p + t*r`. If returned value is in range @f$ [ 0 ; 1 ] @f$, the + * intersection is inside the line segment defined by `p` and `r`. * * First the parameter *f* of parametric equation of the plane * is computed from plane normal **n** and plane position: @f[ * \begin{pmatrix} n_0 \\ n_1 \\ n_2 \end{pmatrix} \cdot * \begin{pmatrix} x \\ y \\ z \end{pmatrix} - f = 0 * @f] - * Using plane normal **n**, parameter *f* and points **a** and **b**, - * value of *t* is computed and returned. @f[ + * Using plane normal **n**, parameter *f* and line defined by **p** + * and **r**, value of *t* is computed and returned. @f[ * \begin{array}{rcl} - * \Delta \boldsymbol b & = & \boldsymbol b - \boldsymbol a \\ - * f & = & \boldsymbol n \cdot (\boldsymbol a + \Delta \boldsymbol b \cdot t) \\ - * \Rightarrow t & = & \cfrac{f - \boldsymbol n \cdot \boldsymbol a}{\boldsymbol n \cdot \Delta \boldsymbol b} + * f & = & \boldsymbol n \cdot (\boldsymbol p + t \boldsymbol r) \\ + * \Rightarrow t & = & \cfrac{f - \boldsymbol n \cdot \boldsymbol p}{\boldsymbol n \cdot \boldsymbol r} * \end{array} * @f] */ - template static T planeLine(const Vector3& planePosition, const Vector3& planeNormal, const Vector3& a, const Vector3& b) { - /* Compute f from normal and plane position */ - T f = Vector3::dot(planePosition, planeNormal); - - /* Compute t */ - return (f-Vector3::dot(planeNormal, a))/Vector3::dot(planeNormal, b-a); + template static T planeLine(const Vector3& planePosition, const Vector3& planeNormal, const Vector3& p, const Vector3& r) { + const T f = Vector3::dot(planePosition, planeNormal); + return (f-Vector3::dot(planeNormal, p))/Vector3::dot(planeNormal, r); } }; diff --git a/src/Math/Geometry/Test/CMakeLists.txt b/src/Math/Geometry/Test/CMakeLists.txt index e60e23aa3..21fcaedb2 100644 --- a/src/Math/Geometry/Test/CMakeLists.txt +++ b/src/Math/Geometry/Test/CMakeLists.txt @@ -23,5 +23,5 @@ # corrade_add_test(MathGeometryDistanceTest DistanceTest.cpp) -corrade_add_test(MathGeometryIntersectionTest IntersectionTest.cpp) +corrade_add_test(MathGeometryIntersectionTest IntersectionTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathGeometryRectangleTest RectangleTest.cpp LIBRARIES MagnumMathTestLib) diff --git a/src/Math/Geometry/Test/IntersectionTest.cpp b/src/Math/Geometry/Test/IntersectionTest.cpp index c70f48747..0b30b760c 100644 --- a/src/Math/Geometry/Test/IntersectionTest.cpp +++ b/src/Math/Geometry/Test/IntersectionTest.cpp @@ -48,19 +48,19 @@ void IntersectionTest::planeLine() { /* Inside line segment */ CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal, - Vector3(0.0f, 0.0f, -1.0f), Vector3(0.0f, 0.0f, 1.0f))), 0.75f); + Vector3(0.0f, 0.0f, -1.0f), Vector3(0.0f, 0.0f, 2.0f))), 0.75f); /* Outside line segment */ CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal, - Vector3(0.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 2.0f))), -0.5f); + Vector3(0.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 1.0f))), -0.5f); /* Line lies on the plane */ CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, - Vector3(1.0f, 0.5f, 0.5f), Vector3(0.0f, 1.0f, 0.5f)), std::numeric_limits::quiet_NaN()); + Vector3(1.0f, 0.5f, 0.5f), Vector3(-1.0f, 0.5f, 0.0f)), std::numeric_limits::quiet_NaN()); /* Line is parallell to the plane */ CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal, - Vector3(1.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 1.0f))), -std::numeric_limits::infinity()); + Vector3(1.0f, 0.0f, 1.0f), Vector3(-1.0f, 0.0f, 0.0f))), -std::numeric_limits::infinity()); } }}}} diff --git a/src/Physics/Plane.cpp b/src/Physics/Plane.cpp index 8c3ae2b50..047e22773 100644 --- a/src/Physics/Plane.cpp +++ b/src/Physics/Plane.cpp @@ -49,12 +49,12 @@ bool Plane::collides(const AbstractShape<3>* other) const { } bool Plane::operator%(const Line3D& other) const { - Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()); + Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()-other.transformedA()); return t != t || (t != std::numeric_limits::infinity() && t != -std::numeric_limits::infinity()); } bool Plane::operator%(const LineSegment3D& other) const { - Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()); + Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()-other.transformedA()); return t > 0.0f && t < 1.0f; } From 6385ae14788480858d95f50a3f19218748448a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 17 Apr 2013 12:35:27 +0200 Subject: [PATCH 20/30] Math: more Intersection test cleanup. --- src/Math/Geometry/Test/IntersectionTest.cpp | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Math/Geometry/Test/IntersectionTest.cpp b/src/Math/Geometry/Test/IntersectionTest.cpp index 0b30b760c..5d7581a3b 100644 --- a/src/Math/Geometry/Test/IntersectionTest.cpp +++ b/src/Math/Geometry/Test/IntersectionTest.cpp @@ -22,8 +22,8 @@ DEALINGS IN THE SOFTWARE. */ -#include #include +#include #include "Math/Geometry/Intersection.h" @@ -43,24 +43,24 @@ IntersectionTest::IntersectionTest() { } void IntersectionTest::planeLine() { - Vector3 planePosition(-1.0f, 1.0f, 0.5f); - Vector3 planeNormal(0.0f, 0.0f, 1.0f); + const Vector3 planePosition(-1.0f, 1.0f, 0.5f); + const Vector3 planeNormal(0.0f, 0.0f, 1.0f); /* Inside line segment */ - CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal, - Vector3(0.0f, 0.0f, -1.0f), Vector3(0.0f, 0.0f, 2.0f))), 0.75f); + CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 2.0f}), 0.75f); /* Outside line segment */ - CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal, - Vector3(0.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 1.0f))), -0.5f); + CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}), -0.5f); /* Line lies on the plane */ CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, - Vector3(1.0f, 0.5f, 0.5f), Vector3(-1.0f, 0.5f, 0.0f)), std::numeric_limits::quiet_NaN()); + {1.0f, 0.5f, 0.5f}, {-1.0f, 0.5f, 0.0f}), std::numeric_limits::quiet_NaN()); - /* Line is parallell to the plane */ - CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal, - Vector3(1.0f, 0.0f, 1.0f), Vector3(-1.0f, 0.0f, 0.0f))), -std::numeric_limits::infinity()); + /* Line is parallel to the plane */ + CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + {1.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}), -std::numeric_limits::infinity()); } }}}} From 3f696533fff866bc6ca74d400ea44f0215d858ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 17 Apr 2013 12:36:06 +0200 Subject: [PATCH 21/30] Math: algorithm for computing intersection of two lines in 2D. --- src/Math/Geometry/Intersection.h | 57 +++++++++++++++++++++ src/Math/Geometry/Test/IntersectionTest.cpp | 37 ++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/Math/Geometry/Intersection.h b/src/Math/Geometry/Intersection.h index 35100ed86..35adfe578 100644 --- a/src/Math/Geometry/Intersection.h +++ b/src/Math/Geometry/Intersection.h @@ -37,6 +37,63 @@ class Intersection { public: Intersection() = delete; + /** + * @brief %Intersection of two line segments in 2D + * @param p Starting point of first line segment + * @param r Direction of first line segment + * @param q Starting point of second line segment + * @param s Direction of second line segment + * @return %Intersection point positions `t`, `u` on both lines, NaN if + * the lines are collinear or infinity if they are parallel. + * %Intersection point can be then computed with `p + t*r` or + * `q + u*s`. If `t` is in range @f$ [ 0 ; 1 ] @f$, the + * intersection is inside the line segment defined by `p` and + * `p + r`, if `u` is in range @f$ [ 0 ; 1 ] @f$, the intersection + * is inside the line segment defined by `q` and `q + s`. + * + * The two lines intersect if **t** and **u** exist such that: @f[ + * \boldsymbol p + t \boldsymbol r = \boldsymbol q + u \boldsymbol s + * @f] + * Crossing both sides with **s**, distributing the cross product and + * eliminating @f$ \boldsymbol s \times \boldsymbol s = 0 @f$, then + * solving for **t** and similarly for **u**: @f[ + * \begin{array}{rcl} + * (\boldsymbol p + t \boldsymbol r) \times s & = & (\boldsymbol q + u \boldsymbol s) \times s \\ + * t (\boldsymbol r \times s) & = & (\boldsymbol q - \boldsymbol p) \times s \\ + * t & = & \cfrac{(\boldsymbol q - \boldsymbol p) \times s}{\boldsymbol r \times \boldsymbol s} \\ + * u & = & \cfrac{(\boldsymbol q - \boldsymbol p) \times r}{\boldsymbol r \times \boldsymbol s} + * \end{array} + * @f] + * + * See also lineSegmentLine() which computes only **t**, which is + * useful if you don't need to test that the intersection lies inside + * line segment defined by `q` and `q + s`. + */ + template static std::pair lineSegmentLineSegment(const Vector2& p, const Vector2& r, const Vector2& q, const Vector2& s) { + const Vector2 qp = q - p; + const T rs = Vector2::cross(r, s); + return {Vector2::cross(qp, s)/rs, + Vector2::cross(qp, r)/rs}; + } + + /** + * @brief %Intersection of line segment and line in 2D + * @param p Starting point of first line segment + * @param r Direction of first line segment + * @param q Starting point of second line + * @param s Direction of second line + * @return %Intersection point position `t` on first line, NaN if the + * lines are collinear or infinity if they are parallel. + * %Intersection point can be then with `p + t*r`. If returned + * value is in range @f$ [ 0 ; 1 ] @f$, the intersection is inside + * the line segment defined by `p` and `p + r`. + * + * Unlike lineSegmentLineSegment() computes only **t**. + */ + template static T lineSegmentLine(const Vector2& p, const Vector2& r, const Vector2& q, const Vector2& s) { + return Vector2::cross(q - p, s)/Vector2::cross(r, s); + } + /** * @brief %Intersection of a plane and line * @param planePosition Plane position diff --git a/src/Math/Geometry/Test/IntersectionTest.cpp b/src/Math/Geometry/Test/IntersectionTest.cpp index 5d7581a3b..db23f96f8 100644 --- a/src/Math/Geometry/Test/IntersectionTest.cpp +++ b/src/Math/Geometry/Test/IntersectionTest.cpp @@ -34,12 +34,15 @@ class IntersectionTest: public Corrade::TestSuite::Tester { IntersectionTest(); void planeLine(); + void lineLine(); }; +typedef Math::Vector2 Vector2; typedef Math::Vector3 Vector3; IntersectionTest::IntersectionTest() { - addTests({&IntersectionTest::planeLine}); + addTests({&IntersectionTest::planeLine, + &IntersectionTest::lineLine}); } void IntersectionTest::planeLine() { @@ -63,6 +66,38 @@ void IntersectionTest::planeLine() { {1.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}), -std::numeric_limits::infinity()); } +void IntersectionTest::lineLine() { + const Vector2 p(-1.0f, -1.0f); + const Vector2 r(1.0, 2.0f); + + /* Inside both line segments */ + CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r, + {0.0f, 0.0f}, {-1.0f, 0.0f}), std::make_pair(0.5f, 0.5f)); + CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, + {0.0f, 0.0f}, {-1.0f, 0.0f}), 0.5); + + /* Outside both line segments */ + CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r, + {0.0f, -2.0f}, {-1.0f, 0.0f}), std::make_pair(-0.5f, 1.5f)); + CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, + {0.0f, -2.0f}, {-1.0f, 0.0f}), -0.5f); + + /* Collinear lines */ + const auto tu = Intersection::lineSegmentLineSegment(p, r, + {0.0f, 1.0f}, {-1.0f, -2.0f}); + CORRADE_COMPARE(tu.first, -std::numeric_limits::quiet_NaN()); + CORRADE_COMPARE(tu.second, -std::numeric_limits::quiet_NaN()); + CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, + {0.0f, 1.0f}, {-1.0f, -2.0f}), -std::numeric_limits::quiet_NaN()); + + /* Parallel lines */ + CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r, + {0.0f, 0.0f}, {1.0f, 2.0f}), std::make_pair(std::numeric_limits::infinity(), + std::numeric_limits::infinity())); + CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, + {0.0f, 0.0f}, {1.0f, 2.0f}), std::numeric_limits::infinity()); +} + }}}} CORRADE_TEST_MAIN(Magnum::Math::Geometry::Test::IntersectionTest) From c534a714015cef49e99d34a433aa48e6d41cf0cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 17 Apr 2013 12:52:10 +0200 Subject: [PATCH 22/30] DebugTools: preparation for ability to render also solid shapes. --- .../Implementation/AbstractBoxRenderer.cpp | 4 +-- .../Implementation/AbstractShapeRenderer.cpp | 8 +++--- .../Implementation/AbstractShapeRenderer.h | 4 +-- .../Implementation/AxisAlignedBoxRenderer.cpp | 4 +-- src/DebugTools/Implementation/BoxRenderer.cpp | 4 +-- .../Implementation/LineSegmentRenderer.cpp | 6 ++--- .../Implementation/PointRenderer.cpp | 6 ++--- .../Implementation/SphereRenderer.cpp | 6 ++--- src/DebugTools/ShapeRenderer.h | 27 ++++++++++++++++++- 9 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp index 011997e4f..60fb738a8 100644 --- a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp @@ -32,11 +32,11 @@ namespace Magnum { namespace DebugTools { namespace Implementation { AbstractBoxRenderer<2>::AbstractBoxRenderer(): AbstractShapeRenderer<2>("box2d", "box2d-vertices", {}) { - if(!mesh) this->createResources(Primitives::Square::wireframe()); + if(!wireframeMesh) this->createResources(Primitives::Square::wireframe()); } AbstractBoxRenderer<3>::AbstractBoxRenderer(): AbstractShapeRenderer<3>("box3d", "box3d-vertices", "box3d-indices") { - if(!mesh) this->createResources(Primitives::Cube::wireframe()); + if(!wireframeMesh) this->createResources(Primitives::Cube::wireframe()); } template class AbstractBoxRenderer<2>; diff --git a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp index 06f9b30cd..b976cb576 100644 --- a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp @@ -90,19 +90,19 @@ template<> void create<3>(Trade::MeshData3D& data, Resource& meshResource, } template AbstractShapeRenderer::AbstractShapeRenderer(ResourceKey meshKey, ResourceKey vertexBufferKey, ResourceKey indexBufferKey) { - shader = ResourceManager::instance()->get>(shaderKey()); - mesh = ResourceManager::instance()->get(meshKey); + wireframeShader = ResourceManager::instance()->get>(shaderKey()); + wireframeMesh = ResourceManager::instance()->get(meshKey); vertexBuffer = ResourceManager::instance()->get(vertexBufferKey); indexBuffer = ResourceManager::instance()->get(indexBufferKey); - if(!shader) ResourceManager::instance()->set(shaderKey(), + if(!wireframeShader) ResourceManager::instance()->set(shaderKey(), new Shaders::FlatShader, ResourceDataState::Final, ResourcePolicy::Resident); } template AbstractShapeRenderer::~AbstractShapeRenderer() {} template void AbstractShapeRenderer::createResources(typename MeshData::Type data) { - create(data, this->mesh, this->vertexBuffer, this->indexBuffer); + create(data, this->wireframeMesh, this->vertexBuffer, this->indexBuffer); } template class AbstractShapeRenderer<2>; diff --git a/src/DebugTools/Implementation/AbstractShapeRenderer.h b/src/DebugTools/Implementation/AbstractShapeRenderer.h index 16f7f6606..25105f6c4 100644 --- a/src/DebugTools/Implementation/AbstractShapeRenderer.h +++ b/src/DebugTools/Implementation/AbstractShapeRenderer.h @@ -49,8 +49,8 @@ template class AbstractShapeRenderer { /* Call only if the mesh resource isn't already present */ void createResources(typename MeshData::Type data); - Resource> shader; - Resource mesh; + Resource> wireframeShader; + Resource wireframeMesh; private: Resource indexBuffer, vertexBuffer; diff --git a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp index 9ef7904d5..4072650b5 100644 --- a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp @@ -34,12 +34,12 @@ namespace Magnum { namespace DebugTools { namespace Implementation { template AxisAlignedBoxRenderer::AxisAlignedBoxRenderer(Physics::AxisAlignedBox& axisAlignedBox): axisAlignedBox(axisAlignedBox) {} template void AxisAlignedBoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - this->shader->setTransformationProjectionMatrix(projectionMatrix* + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix* DimensionTraits::MatrixType::translation((axisAlignedBox.transformedMin()+axisAlignedBox.transformedMax())/2)* DimensionTraits::MatrixType::scaling(axisAlignedBox.transformedMax()-axisAlignedBox.transformedMin())) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class AxisAlignedBoxRenderer<2>; diff --git a/src/DebugTools/Implementation/BoxRenderer.cpp b/src/DebugTools/Implementation/BoxRenderer.cpp index d9a34c62d..4e0bcb9fd 100644 --- a/src/DebugTools/Implementation/BoxRenderer.cpp +++ b/src/DebugTools/Implementation/BoxRenderer.cpp @@ -34,10 +34,10 @@ namespace Magnum { namespace DebugTools { namespace Implementation { template BoxRenderer::BoxRenderer(Physics::Box& box): box(box) {} template void BoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - this->shader->setTransformationProjectionMatrix(projectionMatrix*box.transformedTransformation()) + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*box.transformedTransformation()) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class BoxRenderer<2>; diff --git a/src/DebugTools/Implementation/LineSegmentRenderer.cpp b/src/DebugTools/Implementation/LineSegmentRenderer.cpp index c9a0240c8..900b96055 100644 --- a/src/DebugTools/Implementation/LineSegmentRenderer.cpp +++ b/src/DebugTools/Implementation/LineSegmentRenderer.cpp @@ -51,15 +51,15 @@ namespace { } template LineSegmentRenderer::LineSegmentRenderer(Physics::Line& line): AbstractShapeRenderer(meshKey(), vertexBufferKey(), {}), line(line) { - if(!this->mesh) this->createResources(meshData()); + if(!this->wireframeMesh) this->createResources(meshData()); } template void LineSegmentRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - this->shader->setTransformationProjectionMatrix(projectionMatrix* + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix* Implementation::lineSegmentRendererTransformation(line.transformedA(), line.transformedB())) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class LineSegmentRenderer<2>; diff --git a/src/DebugTools/Implementation/PointRenderer.cpp b/src/DebugTools/Implementation/PointRenderer.cpp index c414813f2..31283541a 100644 --- a/src/DebugTools/Implementation/PointRenderer.cpp +++ b/src/DebugTools/Implementation/PointRenderer.cpp @@ -49,17 +49,17 @@ namespace { } template PointRenderer::PointRenderer(Physics::Point& point): AbstractShapeRenderer(meshKey(), vertexBufferKey(), {}), point(point) { - if(!this->mesh) this->createResources(meshData()); + if(!this->wireframeMesh) this->createResources(meshData()); } template void PointRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { /* Half scale, because the point is 2x2(x2) */ - this->shader->setTransformationProjectionMatrix(projectionMatrix* + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix* DimensionTraits::MatrixType::translation(point.transformedPosition())* DimensionTraits::MatrixType::scaling(typename DimensionTraits::VectorType(options->pointSize()/2))) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class PointRenderer<2>; diff --git a/src/DebugTools/Implementation/SphereRenderer.cpp b/src/DebugTools/Implementation/SphereRenderer.cpp index 60b27c880..be6f8d2f5 100644 --- a/src/DebugTools/Implementation/SphereRenderer.cpp +++ b/src/DebugTools/Implementation/SphereRenderer.cpp @@ -34,18 +34,18 @@ namespace Magnum { namespace DebugTools { namespace Implementation { AbstractSphereRenderer<2>::AbstractSphereRenderer(): AbstractShapeRenderer<2>("sphere2d", "sphere2d-vertices", {}) { - if(!mesh) this->createResources(Primitives::Circle::wireframe(40)); + if(!wireframeMesh) createResources(Primitives::Circle::wireframe(40)); } template SphereRenderer::SphereRenderer(Physics::Sphere& sphere): sphere(sphere) {} template void SphereRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - this->shader->setTransformationProjectionMatrix(projectionMatrix* + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix* DimensionTraits::MatrixType::translation(sphere.transformedPosition())* DimensionTraits::MatrixType::scaling(typename DimensionTraits::VectorType(sphere.transformedRadius()))) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class SphereRenderer<2>; diff --git a/src/DebugTools/ShapeRenderer.h b/src/DebugTools/ShapeRenderer.h index 675c0be21..35c062915 100644 --- a/src/DebugTools/ShapeRenderer.h +++ b/src/DebugTools/ShapeRenderer.h @@ -57,7 +57,31 @@ See ShapeRenderer documentation for more information. */ class ShapeRendererOptions { public: - inline constexpr ShapeRendererOptions(): _color(1.0f), _pointSize(0.25f) {} + /** + * @brief Shape rendering mode + * + * @see setRenderMode() + */ + enum class RenderMode: UnsignedByte { + Wireframe, + Solid + }; + + inline constexpr ShapeRendererOptions(): _color(1.0f), _pointSize(0.25f), _renderMode(RenderMode::Wireframe) {} + + /** @brief Shape rendering mode */ + inline constexpr RenderMode renderMode() const { return _renderMode; } + + /** + * @brief Set shape rendering mode + * @return Pointer to self (for method chaining) + * + * Default is @ref RenderMode "RenderMode::Wireframe". + */ + inline ShapeRendererOptions* setRenderMode(RenderMode mode) { + _renderMode = mode; + return this; + } /** @brief Color of rendered shape */ inline constexpr Color4<> color() const { return _color; } @@ -91,6 +115,7 @@ class ShapeRendererOptions { private: Color4<> _color; Float _pointSize; + RenderMode _renderMode; }; /** From a2d84ebf0c60bc8f21c4e35c75bfe90aec07d2fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 17 Apr 2013 14:39:21 +0200 Subject: [PATCH 23/30] Physics: forgot to add test case to the list. --- src/Physics/Test/CapsuleTest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Physics/Test/CapsuleTest.cpp b/src/Physics/Test/CapsuleTest.cpp index 8f1bc43d3..0174324df 100644 --- a/src/Physics/Test/CapsuleTest.cpp +++ b/src/Physics/Test/CapsuleTest.cpp @@ -41,7 +41,8 @@ class CapsuleTest: public Corrade::TestSuite::Tester, ShapeTestBase { CapsuleTest::CapsuleTest() { addTests({&CapsuleTest::applyTransformation, - &CapsuleTest::collisionPoint}); + &CapsuleTest::collisionPoint, + &CapsuleTest::collisionSphere}); } void CapsuleTest::applyTransformation() { From 66352a015049800797307f76ed33a0033e3de197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 17 Apr 2013 14:40:27 +0200 Subject: [PATCH 24/30] Physics: copypaste error. TWICE! OMG! --- src/Physics/Capsule.h | 2 +- src/Physics/Line.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Physics/Capsule.h b/src/Physics/Capsule.h index 7880a7102..b40a33b4f 100644 --- a/src/Physics/Capsule.h +++ b/src/Physics/Capsule.h @@ -71,7 +71,7 @@ template class MAGNUM_PHYSICS_EXPORT Capsule: public Abs /** @brief End point */ inline typename DimensionTraits::VectorType b() const { - return _a; + return _b; } /** @brief Set start point */ diff --git a/src/Physics/Line.h b/src/Physics/Line.h index bfb9bdceb..49e835c3c 100644 --- a/src/Physics/Line.h +++ b/src/Physics/Line.h @@ -66,7 +66,7 @@ template class MAGNUM_PHYSICS_EXPORT Line: public Abstra /** @brief Second point */ inline typename DimensionTraits::VectorType b() const { - return _a; + return _b; } /** @brief Set first point */ From 39348ddf0633989aee8888e7dcfeff6b077e08ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 17 Apr 2013 14:42:54 +0200 Subject: [PATCH 25/30] Physics: another mistake in CapsuleTest. The way the shapes are currently implemented is unsustainable. --- src/Physics/Test/CapsuleTest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Physics/Test/CapsuleTest.cpp b/src/Physics/Test/CapsuleTest.cpp index 0174324df..9e69302fe 100644 --- a/src/Physics/Test/CapsuleTest.cpp +++ b/src/Physics/Test/CapsuleTest.cpp @@ -51,7 +51,8 @@ void CapsuleTest::applyTransformation() { 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); + CORRADE_COMPARE(capsule.transformedRadius(), 7.0f); +} /* Apply average scaling to radius */ capsule.applyTransformationMatrix(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); From fac75962d02af4c702c7c23a353708beb53ef8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 18 Apr 2013 10:16:38 +0200 Subject: [PATCH 26/30] SceneGraph: assert that original Object::setClean() is called. --- src/SceneGraph/Object.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SceneGraph/Object.hpp b/src/SceneGraph/Object.hpp index 15b659aab..8940f51de 100644 --- a/src/SceneGraph/Object.hpp +++ b/src/SceneGraph/Object.hpp @@ -142,7 +142,9 @@ template void Object::setClean() { /* Compose transformation and clean object */ absoluteTransformation = Transformation::compose(absoluteTransformation, o->transformation()); + CORRADE_INTERNAL_ASSERT(o->isDirty()); o->setClean(absoluteTransformation); + CORRADE_ASSERT(!o->isDirty(), "SceneGraph::Object::setClean(): original implementation was not called", ); } } @@ -343,8 +345,11 @@ template void Object::setClean(std::vector std::vector transformations(scene->transformations(objects)); /* Go through all objects and clean them */ - for(std::size_t i = 0; i != objects.size(); ++i) + for(std::size_t i = 0; i != objects.size(); ++i) { + CORRADE_INTERNAL_ASSERT(objects[i]->isDirty()); objects[i]->setClean(transformations[i]); + CORRADE_ASSERT(!objects[i]->isDirty(), "SceneGraph::Object::setClean(): original implementation was not called", ); + } } template void Object::setClean(const typename Transformation::DataType& absoluteTransformation) { From 1aac14d05918ef0cff927579e125577498d03a84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 18 Apr 2013 11:34:02 +0200 Subject: [PATCH 27/30] Using CORRADE_ASSERT_UNREACHABLE() instead of CORRADE_ASSERT(false). --- src/AbstractFramebuffer.cpp | 2 +- src/AbstractImage.cpp | 4 ++-- src/AbstractShaderProgram.cpp | 8 ++++---- src/Color.h | 2 +- src/Implementation/BufferState.cpp | 2 +- src/Mesh.cpp | 2 +- src/Shader.cpp | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/AbstractFramebuffer.cpp b/src/AbstractFramebuffer.cpp index 6fd62aab8..7c353bcbd 100644 --- a/src/AbstractFramebuffer.cpp +++ b/src/AbstractFramebuffer.cpp @@ -62,7 +62,7 @@ void AbstractFramebuffer::bindInternal(Target target) { } else if(target == Target::ReadDraw) { if(state->readBinding == _id && state->drawBinding == _id) return; state->readBinding = state->drawBinding = _id; - } else CORRADE_INTERNAL_ASSERT(false); + } else CORRADE_ASSERT_UNREACHABLE(); glBindFramebuffer(static_cast(target), _id); } diff --git a/src/AbstractImage.cpp b/src/AbstractImage.cpp index c7bd56b2d..761f15dd8 100644 --- a/src/AbstractImage.cpp +++ b/src/AbstractImage.cpp @@ -129,10 +129,10 @@ std::size_t AbstractImage::pixelSize(Format format, Type type) { case Format::StencilIndex: #endif case Format::DepthStencil: - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index afef65c5e..bd5c52273 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -600,7 +600,7 @@ std::size_t FloatAttribute::size(GLint components, DataType dataType) { #endif } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } @@ -618,7 +618,7 @@ std::size_t IntAttribute::size(GLint components, DataType dataType) { return 4*components; } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } #endif @@ -630,7 +630,7 @@ std::size_t DoubleAttribute::size(GLint components, DataType dataType) { return 8*components; } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } #endif @@ -665,7 +665,7 @@ std::size_t Attribute>::size(GLint components, DataType d #endif } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } diff --git a/src/Color.h b/src/Color.h index 74b634d84..f6b06325d 100644 --- a/src/Color.h +++ b/src/Color.h @@ -63,7 +63,7 @@ template inline typename std::enable_if::valu case 3: return {p, q, value}; case 4: return {t, p, value}; case 5: return {value, p, q}; - default: CORRADE_INTERNAL_ASSERT(false); + default: CORRADE_ASSERT_UNREACHABLE(); } } template inline typename std::enable_if::value, Color3>::type fromHSV(typename Color3::HSV hsv) { diff --git a/src/Implementation/BufferState.cpp b/src/Implementation/BufferState.cpp index 15ecc9a9e..e844f8991 100644 --- a/src/Implementation/BufferState.cpp +++ b/src/Implementation/BufferState.cpp @@ -71,7 +71,7 @@ std::size_t BufferState::indexForTarget(Buffer::Target target) { #endif } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); } }} diff --git a/src/Mesh.cpp b/src/Mesh.cpp index d94e4d1a2..475f869f1 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -55,7 +55,7 @@ std::size_t Mesh::indexSize(IndexType type) { case IndexType::UnsignedInt: return 4; } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); } Mesh::Mesh(Primitive primitive): _primitive(primitive), _vertexCount(0), _indexCount(0) diff --git a/src/Shader.cpp b/src/Shader.cpp index 741d2b3c3..64e3679e5 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -59,7 +59,7 @@ Shader::Shader(Version version, Type type): _type(type), _state(State::Initializ CORRADE_ASSERT(false, "Shader::Shader(): unsupported version" << version, ); } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); } Shader::Shader(Shader&& other): _type(other._type), _state(other._state), sources(other.sources), shader(other.shader) { From 14028335537f7236c1516a5fa7beb67560bbebba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 18 Apr 2013 11:37:27 +0200 Subject: [PATCH 28/30] Math: added TODO. --- src/Math/Math.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Math/Math.h b/src/Math/Math.h index 081d7acdf..0e11a8b5e 100644 --- a/src/Math/Math.h +++ b/src/Math/Math.h @@ -32,6 +32,8 @@ namespace Magnum { namespace Math { +/** @todo Denormals to zero */ + /** @todoc Remove `ifndef` when Doxygen is sane again */ #ifndef DOXYGEN_GENERATING_OUTPUT /* Class Constants used only statically */ From f6ae87376bd3655f39fb8d6a17697ac90ef685a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 18 Apr 2013 12:38:43 +0200 Subject: [PATCH 29/30] Math: added function fma(). --- src/Math/Functions.h | 16 ++++++++++++++++ src/Math/Test/FunctionsTest.cpp | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/Math/Functions.h b/src/Math/Functions.h index f3e2f091d..c1b330ca7 100644 --- a/src/Math/Functions.h +++ b/src/Math/Functions.h @@ -280,6 +280,22 @@ template inline Vector lerp(const V } #endif +/** +@brief Fused multiply-add + +Computes and returns @f$ ab + c @f$. +*/ +#ifdef DOXYGEN_GENERATING_OUTPUT +template inline T fma(const T& a, const T& b, const T& c); +#else +template inline typename std::enable_if::value, T>::type fma(T a, T b, T c) { + return std::fma(a, b, c); +} +template inline Vector fma(const Vector& a, const Vector& b, const Vector& c) { + return a*b + c; +} +#endif + /** @brief Normalize integral value diff --git a/src/Math/Test/FunctionsTest.cpp b/src/Math/Test/FunctionsTest.cpp index cda253c74..25e519f92 100644 --- a/src/Math/Test/FunctionsTest.cpp +++ b/src/Math/Test/FunctionsTest.cpp @@ -41,6 +41,7 @@ class FunctionsTest: public Corrade::TestSuite::Tester { void sqrtInverted(); void clamp(); void lerp(); + void fma(); void normalizeUnsigned(); void normalizeSigned(); void denormalizeUnsigned(); @@ -74,6 +75,7 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::sqrtInverted, &FunctionsTest::clamp, &FunctionsTest::lerp, + &FunctionsTest::fma, &FunctionsTest::normalizeUnsigned, &FunctionsTest::normalizeSigned, &FunctionsTest::denormalizeUnsigned, @@ -148,6 +150,14 @@ void FunctionsTest::lerp() { CORRADE_COMPARE(Math::lerp(c, d, 0.25f), Vector3ub(4, 96, 56)); } +void FunctionsTest::fma() { + CORRADE_COMPARE(Math::fma(2.0f, 3.0f, 0.75f), 6.75f); + CORRADE_COMPARE(Math::fma(Vector3( 2.0f, 1.5f, 0.5f), + Vector3( 3.0f, 2.0f, -1.0f), + Vector3(0.75f, 0.25f, 0.1f)), + Vector3(6.75f, 3.25f, -0.4f)); +} + void FunctionsTest::normalizeUnsigned() { CORRADE_COMPARE((Math::normalize(0)), 0.0f); CORRADE_COMPARE((Math::normalize(255)), 1.0f); From f2df328fe2948943858c40bf3bf29869c40003ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 19 Apr 2013 13:10:09 +0200 Subject: [PATCH 30/30] Using Corrade's visibility macros instead of copypasta all over again. --- src/DebugTools/magnumDebugToolsVisibility.h | 12 +++++------- src/MeshTools/magnumMeshToolsVisibility.h | 12 +++++------- src/Physics/magnumPhysicsVisibility.h | 12 +++++------- src/Primitives/magnumPrimitivesVisibility.h | 12 +++++------- src/SceneGraph/magnumSceneGraphVisibility.h | 15 ++++++--------- src/Shaders/magnumShadersVisibility.h | 12 +++++------- src/Text/magnumTextVisibility.h | 15 ++++++--------- src/TextureTools/magnumTextureToolsVisibility.h | 12 +++++------- src/magnumVisibility.h | 15 ++++++--------- 9 files changed, 48 insertions(+), 69 deletions(-) diff --git a/src/DebugTools/magnumDebugToolsVisibility.h b/src/DebugTools/magnumDebugToolsVisibility.h index 46eda28fd..d08f88d14 100644 --- a/src/DebugTools/magnumDebugToolsVisibility.h +++ b/src/DebugTools/magnumDebugToolsVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumDebugTools_EXPORTS - #define MAGNUM_DEBUGTOOLS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_DEBUGTOOLS_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumDebugTools_EXPORTS + #define MAGNUM_DEBUGTOOLS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_DEBUGTOOLS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_DEBUGTOOLS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/MeshTools/magnumMeshToolsVisibility.h b/src/MeshTools/magnumMeshToolsVisibility.h index 2c4934962..f7d8a63c4 100644 --- a/src/MeshTools/magnumMeshToolsVisibility.h +++ b/src/MeshTools/magnumMeshToolsVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #if defined(MagnumMeshTools_EXPORTS) || defined(MagnumMeshToolsObjects_EXPORTS) - #define MAGNUM_MESHTOOLS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_MESHTOOLS_EXPORT __declspec(dllimport) - #endif +#include + +#if defined(MagnumMeshTools_EXPORTS) || defined(MagnumMeshToolsObjects_EXPORTS) + #define MAGNUM_MESHTOOLS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_MESHTOOLS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_MESHTOOLS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/Physics/magnumPhysicsVisibility.h b/src/Physics/magnumPhysicsVisibility.h index 07d22128b..6ee2b89c0 100644 --- a/src/Physics/magnumPhysicsVisibility.h +++ b/src/Physics/magnumPhysicsVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumPhysics_EXPORTS - #define MAGNUM_PHYSICS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_PHYSICS_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumPhysics_EXPORTS + #define MAGNUM_PHYSICS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_PHYSICS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_PHYSICS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/Primitives/magnumPrimitivesVisibility.h b/src/Primitives/magnumPrimitivesVisibility.h index 13a5c93cb..0acf6cf82 100644 --- a/src/Primitives/magnumPrimitivesVisibility.h +++ b/src/Primitives/magnumPrimitivesVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumPrimitives_EXPORTS - #define MAGNUM_PRIMITIVES_EXPORT __declspec(dllexport) - #else - #define MAGNUM_PRIMITIVES_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumPrimitives_EXPORTS + #define MAGNUM_PRIMITIVES_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_PRIMITIVES_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_PRIMITIVES_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/SceneGraph/magnumSceneGraphVisibility.h b/src/SceneGraph/magnumSceneGraphVisibility.h index b4b023eef..366634198 100644 --- a/src/SceneGraph/magnumSceneGraphVisibility.h +++ b/src/SceneGraph/magnumSceneGraphVisibility.h @@ -24,16 +24,13 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #if defined(MagnumSceneGraph_EXPORTS) || defined(MagnumSceneGraphObjects_EXPORTS) - #define MAGNUM_SCENEGRAPH_EXPORT __declspec(dllexport) - #else - #define MAGNUM_SCENEGRAPH_EXPORT __declspec(dllimport) - #endif - #define MAGNUM_SCENEGRAPH_LOCAL +#include + +#if defined(MagnumSceneGraph_EXPORTS) || defined(MagnumSceneGraphObjects_EXPORTS) + #define MAGNUM_SCENEGRAPH_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_SCENEGRAPH_EXPORT __attribute__ ((visibility ("default"))) - #define MAGNUM_SCENEGRAPH_LOCAL __attribute__ ((visibility ("hidden"))) + #define MAGNUM_SCENEGRAPH_EXPORT CORRADE_VISIBILITY_IMPORT #endif +#define MAGNUM_SCENEGRAPH_LOCAL CORRADE_VISIBILITY_LOCAL #endif diff --git a/src/Shaders/magnumShadersVisibility.h b/src/Shaders/magnumShadersVisibility.h index 238ddeb04..93c270176 100644 --- a/src/Shaders/magnumShadersVisibility.h +++ b/src/Shaders/magnumShadersVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumShaders_EXPORTS - #define MAGNUM_SHADERS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_SHADERS_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumShaders_EXPORTS + #define MAGNUM_SHADERS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_SHADERS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_SHADERS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/Text/magnumTextVisibility.h b/src/Text/magnumTextVisibility.h index a5608044a..b69855471 100644 --- a/src/Text/magnumTextVisibility.h +++ b/src/Text/magnumTextVisibility.h @@ -24,16 +24,13 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumText_EXPORTS - #define MAGNUM_TEXT_EXPORT __declspec(dllexport) - #else - #define MAGNUM_TEXT_EXPORT __declspec(dllimport) - #endif - #define MAGNUM_TEXT_LOCAL +#include + +#ifdef MagnumText_EXPORTS + #define MAGNUM_TEXT_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_TEXT_EXPORT __attribute__ ((visibility ("default"))) - #define MAGNUM_TEXT_LOCAL __attribute__ ((visibility ("hidden"))) + #define MAGNUM_TEXT_EXPORT CORRADE_VISIBILITY_IMPORT #endif +#define MAGNUM_TEXT_LOCAL CORRADE_VISIBILITY_LOCAL #endif diff --git a/src/TextureTools/magnumTextureToolsVisibility.h b/src/TextureTools/magnumTextureToolsVisibility.h index ad0dbb333..30f40eb1c 100644 --- a/src/TextureTools/magnumTextureToolsVisibility.h +++ b/src/TextureTools/magnumTextureToolsVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumTextureTools_EXPORTS - #define MAGNUM_TEXTURETOOLS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_TEXTURETOOLS_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumTextureTools_EXPORTS + #define MAGNUM_TEXTURETOOLS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_TEXTURETOOLS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_TEXTURETOOLS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/magnumVisibility.h b/src/magnumVisibility.h index c23a8066b..60e1f8cca 100644 --- a/src/magnumVisibility.h +++ b/src/magnumVisibility.h @@ -24,16 +24,13 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #if defined(Magnum_EXPORTS) || defined(MagnumObjects_EXPORTS) - #define MAGNUM_EXPORT __declspec(dllexport) - #else - #define MAGNUM_EXPORT __declspec(dllimport) - #endif - #define MAGNUM_LOCAL +#include + +#if defined(Magnum_EXPORTS) || defined(MagnumObjects_EXPORTS) + #define MAGNUM_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_EXPORT __attribute__ ((visibility ("default"))) - #define MAGNUM_LOCAL __attribute__ ((visibility ("hidden"))) + #define MAGNUM_EXPORT CORRADE_VISIBILITY_IMPORT #endif +#define MAGNUM_LOCAL CORRADE_VISIBILITY_LOCAL #endif