diff --git a/src/SceneGraph/Camera.cpp b/src/SceneGraph/Camera.cpp index ad3b794fe..32fba23f8 100644 --- a/src/SceneGraph/Camera.cpp +++ b/src/SceneGraph/Camera.cpp @@ -24,29 +24,22 @@ namespace Magnum { namespace SceneGraph { #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { -Matrix4 Camera<3>::fixAspectRatio(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& viewport) { - /* Don't divide by zero */ - if(viewport.x() == 0 || viewport.y() == 0) - return Matrix4(); - - /* Extend on larger side = scale larger side down */ - if(aspectRatioPolicy == AspectRatioPolicy::Extend) - return ((viewport.x() > viewport.y()) ? - Matrix4::scaling({GLfloat(viewport.y())/viewport.x(), 1, 1}) : - Matrix4::scaling({1, GLfloat(viewport.x())/viewport.y(), 1}) - ); - - /* Clip on smaller side = scale smaller side up */ - if(aspectRatioPolicy == AspectRatioPolicy::Clip) - return ((viewport.x() > viewport.y()) ? - Matrix4::scaling({1, GLfloat(viewport.x())/viewport.y(), 1}) : - Matrix4::scaling({GLfloat(viewport.y())/viewport.x(), 1, 1}) - ); - - /* Don't preserve anything */ - return Matrix4(); +template MatrixType aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& viewport) { + /* Don't divide by zero / don't preserve anything */ + if(viewport.x() == 0 || viewport.y() == 0 || aspectRatioPolicy == AspectRatioPolicy::NotPreserved) + return MatrixType(); + + /* Extend on larger side = scale larger side down + Clip on smaller side = scale smaller side up */ + return Camera::aspectRatioScale( + (viewport.x() > viewport.y()) == (aspectRatioPolicy == AspectRatioPolicy::Extend) ? + Vector2(GLfloat(viewport.y())/viewport.x(), 1.0f) : + Vector2(1.0f, GLfloat(viewport.x())/viewport.y())); } +/* Explicitly instantiate the templates */ +template Matrix4 aspectRatioFix(AspectRatioPolicy, const Math::Vector2&); + } #endif diff --git a/src/SceneGraph/Camera.h b/src/SceneGraph/Camera.h index b5fa51e51..96f71cef4 100644 --- a/src/SceneGraph/Camera.h +++ b/src/SceneGraph/Camera.h @@ -28,6 +28,8 @@ namespace Magnum { namespace SceneGraph { +/** @todo Export implementation symbols only for tests */ + #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { enum class AspectRatioPolicy { @@ -35,6 +37,11 @@ namespace Implementation { }; template class Camera {}; + + template MatrixType aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& viewport); + + /* These templates are instantiated in source file */ + extern template SCENEGRAPH_EXPORT Matrix4 aspectRatioFix(AspectRatioPolicy, const Math::Vector2&); } #endif @@ -123,7 +130,7 @@ template::fixAspectRatio(_aspectRatioPolicy, _viewport)*rawProjectionMatrix; + _projectionMatrix = Implementation::aspectRatioFix(_aspectRatioPolicy, _viewport)*rawProjectionMatrix; } MatrixType rawProjectionMatrix; @@ -137,16 +144,16 @@ template _viewport; }; -/** @todo Export implementation symbols only for tests */ - #ifndef DOXYGEN_GENERATING_OUTPUT /* These templates are instantiated in source file */ extern template class SCENEGRAPH_EXPORT Camera; namespace Implementation { - template<> class SCENEGRAPH_EXPORT Camera<3> { + template<> class Camera<3> { public: - static Matrix4 fixAspectRatio(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& viewport); + inline constexpr static Matrix4 aspectRatioScale(const Vector2& scale) { + return Matrix4::scaling({scale.x(), scale.y(), 1.0f}); + } }; } #endif diff --git a/src/SceneGraph/Test/CameraTest.cpp b/src/SceneGraph/Test/CameraTest.cpp index 496dd2de3..2a72ac5a9 100644 --- a/src/SceneGraph/Test/CameraTest.cpp +++ b/src/SceneGraph/Test/CameraTest.cpp @@ -31,27 +31,27 @@ void CameraTest::fixAspectRatio() { /* Division by zero */ Math::Vector2 sizeZeroY(400, 0); Math::Vector2 sizeZeroX(0, 300); - CORRADE_COMPARE(Implementation::Camera<3>::fixAspectRatio(Implementation::AspectRatioPolicy::Clip, sizeZeroY), Matrix4()); - CORRADE_COMPARE(Implementation::Camera<3>::fixAspectRatio(Implementation::AspectRatioPolicy::Extend, sizeZeroX), Matrix4()); + CORRADE_COMPARE(Implementation::aspectRatioFix(Implementation::AspectRatioPolicy::Clip, sizeZeroY), Matrix4()); + CORRADE_COMPARE(Implementation::aspectRatioFix(Implementation::AspectRatioPolicy::Extend, sizeZeroX), Matrix4()); Math::Vector2 size(400, 300); /* Not preserved */ - CORRADE_COMPARE(Implementation::Camera<3>::fixAspectRatio(Implementation::AspectRatioPolicy::NotPreserved, size), Matrix4()); + CORRADE_COMPARE(Implementation::aspectRatioFix(Implementation::AspectRatioPolicy::NotPreserved, size), Matrix4()); /* Clip */ Matrix4 expectedClip(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 4.0f/3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); - CORRADE_COMPARE(Implementation::Camera<3>::fixAspectRatio(Implementation::AspectRatioPolicy::Clip, size), expectedClip); + CORRADE_COMPARE(Implementation::aspectRatioFix(Implementation::AspectRatioPolicy::Clip, size), expectedClip); /* Extend */ Matrix4 expectedExtend(3.0f/4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); - CORRADE_COMPARE(Implementation::Camera<3>::fixAspectRatio(Implementation::AspectRatioPolicy::Extend, size), expectedExtend); + CORRADE_COMPARE(Implementation::aspectRatioFix(Implementation::AspectRatioPolicy::Extend, size), expectedExtend); } void CameraTest::orthographic() {