diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index ed6c4d45e..09a41585c 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -147,6 +147,9 @@ foreach(component ${Magnum_FIND_COMPONENTS}) find_path(_MAGNUM_${_COMPONENT}_INCLUDE_DIR NAMES ${_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES} PATHS ${MAGNUM_INCLUDE_DIR}/${_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX}) + + # Don't expose this variable to end users + mark_as_advanced(FORCE _MAGNUM_${_COMPONENT}_INCLUDE_DIR) endif() # Decide if the library was found diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e9ebcf35..7f4379482 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,7 +67,6 @@ set(Magnum_HEADERS Query.h Renderbuffer.h Scene.h - Set.h Shader.h SizeTraits.h Texture.h diff --git a/src/Contexts/EglContext.cpp b/src/Contexts/EglContext.cpp index a6f8a842c..b05890ab8 100644 --- a/src/Contexts/EglContext.cpp +++ b/src/Contexts/EglContext.cpp @@ -17,6 +17,9 @@ #define None 0L // redef Xlib nonsense +/* Mask for X events */ +#define INPUT_MASK KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|StructureNotifyMask + using namespace std; namespace Magnum { namespace Contexts { @@ -73,13 +76,17 @@ EglContext::EglContext(int&, char**, const string& title, const Math::Vector2visual, AllocNone); - attr.event_mask = StructureNotifyMask|ExposureMask|KeyPressMask; + attr.colormap = XCreateColormap(xDisplay, root, visInfo->visual, AllocNone); + attr.event_mask = 0; unsigned long mask = CWBackPixel|CWBorderPixel|CWColormap|CWEventMask; xWindow = XCreateWindow(xDisplay, root, 20, 20, size.x(), size.y(), 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr); XSetStandardProperties(xDisplay, xWindow, title.c_str(), 0, None, 0, 0, 0); XFree(visInfo); + /* Be notified about closing the window */ + deleteWindow = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True); + XSetWMProtocols(xDisplay, xWindow, &deleteWindow, 1); + /* Create context and window surface */ static const EGLint contextAttributes[] = { #ifdef MAGNUM_TARGET_GLES @@ -98,8 +105,10 @@ EglContext::EglContext(int&, char**, const string& title, const Math::Vector2 size(event.xconfigure.width, event.xconfigure.height); + if(size != viewportSize) { + viewportSize = size; + viewportEvent(size); + } + } break; + + /* Key/mouse events */ + case KeyPress: + keyPressEvent(static_cast(XLookupKeysym(&event.xkey, 0)), {event.xkey.x, event.xkey.y}); + break; + case KeyRelease: + keyReleaseEvent(static_cast(XLookupKeysym(&event.xkey, 0)), {event.xkey.x, event.xkey.y}); + break; + case ButtonPress: + mousePressEvent(static_cast(event.xbutton.button), {event.xbutton.x, event.xbutton.y}); + break; + case ButtonRelease: + mouseReleaseEvent(static_cast(event.xbutton.button), {event.xbutton.x, event.xbutton.y}); + break; + } + } + /** @todo Handle at least window closing and resizing */ - eglMakeCurrent(display, surface, surface, context); drawEvent(); } diff --git a/src/Contexts/EglContext.h b/src/Contexts/EglContext.h index fe2e48cb2..2779b7708 100644 --- a/src/Contexts/EglContext.h +++ b/src/Contexts/EglContext.h @@ -62,6 +62,8 @@ class EglContext: public AbstractContext { int exec(); + /** @{ @name Drawing functions */ + protected: /** @copydoc GlutContext::viewportEvent() */ virtual void viewportEvent(const Math::Vector2& size) = 0; @@ -72,9 +74,88 @@ class EglContext: public AbstractContext { /** @copydoc GlutContext::swapBuffers() */ inline void swapBuffers() { eglSwapBuffers(display, surface); } + /*@}*/ + + /** @{ @name Keyboard handling */ + + public: + /** @brief Key */ + enum class Key: KeySym { + Up = XK_Up, /**< Up arrow */ + Down = XK_Down, /**< Down arrow */ + Left = XK_Left, /**< Left arrow */ + Right = XK_Right, /**< Right arrow */ + F1 = XK_F1, /**< F1 */ + F2 = XK_F2, /**< F2 */ + F3 = XK_F3, /**< F3 */ + F4 = XK_F4, /**< F4 */ + F5 = XK_F5, /**< F5 */ + F6 = XK_F6, /**< F6 */ + F7 = XK_F7, /**< F7 */ + F8 = XK_F8, /**< F8 */ + F9 = XK_F9, /**< F9 */ + F10 = XK_F10, /**< F10 */ + F11 = XK_F11, /**< F11 */ + F12 = XK_F12, /**< F12 */ + Home = XK_Home, /**< Home */ + End = XK_End, /**< End */ + PageUp = XK_Page_Up, /**< Page up */ + PageDown = XK_Page_Down /**< Page down */ + }; + + protected: + /** + * @brief Key press event + * @param key Key pressed + * @param position Cursor position + * + * Called when an key is pressed. Default implementation does nothing. + */ + virtual void keyPressEvent(Key key, const Math::Vector2& position) = 0; + + /** + * @brief Key press event + * @param key Key released + * @param position Cursor position + * + * Called when an key is released. Default implementation does nothing. + */ + virtual void keyReleaseEvent(Key key, const Math::Vector2& position) = 0; + + /*@}*/ + + /** @{ @name Mouse handling */ + public: + /** @brief Mouse button */ + enum class MouseButton: unsigned int { + Left = Button1, /**< Left button */ + Middle = Button2, /**< Middle button */ + Right = Button3, /**< Right button */ + WheelUp = Button4, /**< Wheel up */ + WheelDown = Button5 /**< Wheel down */ + }; + + protected: + /** + * @brief Mouse press event + * + * Called when mouse button is pressed. Default implementation does + * nothing. + */ + virtual void mousePressEvent(MouseButton button, const Math::Vector2& position); + + /** + * @brief Mouse release event + * + * Called when mouse button is released. Default implementation does + * nothing. + */ + virtual void mouseReleaseEvent(MouseButton button, const Math::Vector2& position); + private: Display* xDisplay; Window xWindow; + Atom deleteWindow; EGLDisplay display; EGLSurface surface; @@ -84,6 +165,12 @@ class EglContext: public AbstractContext { Math::Vector2 viewportSize; }; +inline void EglContext::keyPressEvent(EglContext::Key, const Math::Vector2&) {} +inline void EglContext::keyReleaseEvent(EglContext::Key, const Math::Vector2&) {} +inline void EglContext::mousePressEvent(EglContext::MouseButton, const Math::Vector2&) {} +inline void EglContext::mouseReleaseEvent(EglContext::MouseButton, const Math::Vector2&) {} + + }} #endif diff --git a/src/Contexts/Sdl2Context.h b/src/Contexts/Sdl2Context.h index 906daf49a..221a2dccc 100644 --- a/src/Contexts/Sdl2Context.h +++ b/src/Contexts/Sdl2Context.h @@ -100,7 +100,7 @@ class Sdl2Context: public AbstractContext { /** * @brief Key release event - * @param key Key release + * @param key Key released */ virtual void keyReleaseEvent(Key key); diff --git a/src/Math/CMakeLists.txt b/src/Math/CMakeLists.txt index a0cc17b69..d12a6a16c 100644 --- a/src/Math/CMakeLists.txt +++ b/src/Math/CMakeLists.txt @@ -6,6 +6,7 @@ set(MagnumMath_HEADERS Matrix.h Matrix3.h Matrix4.h + Swizzle.h Vector.h Vector2.h Vector3.h diff --git a/src/Math/Swizzle.h b/src/Math/Swizzle.h new file mode 100644 index 000000000..cfbec9290 --- /dev/null +++ b/src/Math/Swizzle.h @@ -0,0 +1,77 @@ +#ifndef Magnum_Math_Swizzle_h +#define Magnum_Math_Swizzle_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Function Magnum::Math::swizzle() + */ + +#include "Vector4.h" + +namespace Magnum { namespace Math { + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + template struct GetPosition { + static_assert(size > position, "Swizzle parameter out of range of base vector"); + + inline constexpr static size_t value() { return position; } + }; + + template struct GetComponent {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + template struct GetComponent: public GetPosition {}; + + template struct TypeForSize { + typedef Vector Type; + }; + + template struct TypeForSize<2, T> { typedef Vector2 Type; }; + template struct TypeForSize<3, T> { typedef Vector3 Type; }; + template struct TypeForSize<4, T> { typedef Vector4 Type; }; +} +#endif + +/** +@brief Swizzle Vector components + +Creates new vector from given components. Example: +@code +Vector4 original(1, 2, 3, 4); + +auto vec = swizzle<'a', 'b', 'b', 'g', 'r', 'r'>(original); +// vec == { 4, 3, 3, 2, 1, 1 } +@endcode +You can use letters `x`, `y`, `z`, `w` and `r`, `g`, `b`, `a`. Count of +elements is unlimited, but must be at least one. If the resulting vector is +two, three or four-component, corresponding Vector2, Vector3 or Vector4 +specialization is returned. + +@see Vector4::xyz(), Vector4::rgb(), Vector4::xy(), Vector3::xy() +*/ +template inline constexpr typename Implementation::TypeForSize::Type swizzle(const Vector& vector) { + return {vector[Implementation::GetComponent::value()]...}; +} + +}} + +#endif diff --git a/src/Math/Test/CMakeLists.txt b/src/Math/Test/CMakeLists.txt index 9c843abb3..6dbf2abc9 100644 --- a/src/Math/Test/CMakeLists.txt +++ b/src/Math/Test/CMakeLists.txt @@ -5,6 +5,8 @@ corrade_add_test2(MathVector2Test Vector2Test.cpp) corrade_add_test2(MathVector3Test Vector3Test.cpp) corrade_add_test2(MathVector4Test Vector4Test.cpp) +corrade_add_test2(MathSwizzleTest SwizzleTest.cpp) + corrade_add_test2(MathMatrixTest MatrixTest.cpp) corrade_add_test2(MathMatrix3Test Matrix3Test.cpp) corrade_add_test2(MathMatrix4Test Matrix4Test.cpp) diff --git a/src/Math/Test/SwizzleTest.cpp b/src/Math/Test/SwizzleTest.cpp new file mode 100644 index 000000000..f71cc8d6d --- /dev/null +++ b/src/Math/Test/SwizzleTest.cpp @@ -0,0 +1,62 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "SwizzleTest.h" + +#include "Swizzle.h" + +using namespace std; + +CORRADE_TEST_MAIN(Magnum::Math::Test::SwizzleTest) + +namespace Magnum { namespace Math { namespace Test { + +typedef Math::Vector2 Vector2; +typedef Math::Vector3 Vector3; +typedef Math::Vector4 Vector4; + +template using Vector = Math::Vector; + +SwizzleTest::SwizzleTest() { + addTests(&SwizzleTest::xyzw, + &SwizzleTest::rgba, + &SwizzleTest::type, + &SwizzleTest::defaultType); +} + +void SwizzleTest::xyzw() { + Vector4 orig(2, 4, 5, 7); + CORRADE_COMPARE((swizzle<'z', 'x', 'w', 'y'>(orig)), Vector4(5, 2, 7, 4)); +} + +void SwizzleTest::rgba() { + Vector4 orig(2, 4, 5, 7); + CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g'>(orig)), Vector4(5, 2, 7, 4)); +} + +void SwizzleTest::type() { + Vector4 orig; + CORRADE_VERIFY((is_same(orig)), Vector2>::value)); + CORRADE_VERIFY((is_same(orig)), Vector3>::value)); + CORRADE_VERIFY((is_same(orig)), Vector4>::value)); +} + +void SwizzleTest::defaultType() { + Vector4 orig(1, 2, 3, 4); + CORRADE_COMPARE(swizzle<'b'>(orig), Vector<1>(3)); + CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g', 'z', 'y', 'x'>(orig)), Vector<7>(3, 1, 4, 2, 3, 2, 1)); +} + +}}} diff --git a/src/Math/Test/SwizzleTest.h b/src/Math/Test/SwizzleTest.h new file mode 100644 index 000000000..f68a05e45 --- /dev/null +++ b/src/Math/Test/SwizzleTest.h @@ -0,0 +1,34 @@ +#ifndef Magnum_Math_Test_SwizzleTest_h +#define Magnum_Math_Test_SwizzleTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include + +namespace Magnum { namespace Math { namespace Test { + +class SwizzleTest: public Corrade::TestSuite::Tester { + public: + SwizzleTest(); + + void xyzw(); + void rgba(); + void type(); + void defaultType(); +}; + +}}} + +#endif diff --git a/src/Math/Vector.h b/src/Math/Vector.h index d84f312ab..0a56fa479 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -103,7 +103,11 @@ template class Vector { * @brief Constructor * @param value Value for all fields */ + #ifndef DOXYGEN_GENERATING_OUTPUT + template inline explicit Vector(typename std::enable_if::value && size != 1, U>::type value) { + #else inline explicit Vector(T value) { + #endif for(size_t i = 0; i != size; ++i) _data[i] = value; } diff --git a/src/Math/Vector3.h b/src/Math/Vector3.h index e9b691914..30072d7f5 100644 --- a/src/Math/Vector3.h +++ b/src/Math/Vector3.h @@ -81,6 +81,8 @@ template class Vector3: public Vector<3, T> { /** * @brief XY part of the vector * @return First two components of the vector + * + * @see swizzle() */ inline constexpr Vector2 xy() const { return Vector2::from(Vector<3, T>::data()); } diff --git a/src/Math/Vector4.h b/src/Math/Vector4.h index a447bfac4..c406ef19b 100644 --- a/src/Math/Vector4.h +++ b/src/Math/Vector4.h @@ -70,12 +70,16 @@ template class Vector4: public Vector<4, T> { /** * @brief XYZ part of the vector * @return First three components of the vector + * + * @see swizzle() */ inline constexpr Vector3 xyz() const { return Vector3::from(Vector<4, T>::data()); } /** * @brief XY part of the vector * @return First two components of the vector + * + * @see swizzle() */ inline constexpr Vector2 xy() const { return Vector2::from(Vector<4, T>::data()); } @@ -92,6 +96,8 @@ template class Vector4: public Vector<4, T> { /** * @brief RGB part of the vector * @return First three components of the vector + * + * @see swizzle() */ inline constexpr Vector3 rgb() const { return xyz(); }