diff --git a/src/Contexts/AbstractGlInterface.h b/src/Contexts/AbstractGlInterface.h new file mode 100644 index 000000000..629eb1dc3 --- /dev/null +++ b/src/Contexts/AbstractGlInterface.h @@ -0,0 +1,53 @@ +#ifndef Magnum_Contexts_AbstractGlInterface_h +#define Magnum_Contexts_AbstractGlInterface_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::Contexts::AbstractGlInterface + */ + +namespace Magnum { namespace Contexts { + +/** @brief Base for OpenGL interfaces */ +template class AbstractGlInterface { + public: + /** + * @brief Get visual ID + * + * Initializes the interface on given display and returns visual ID. + */ + virtual VisualId getVisualId(Display nativeDisplay) = 0; + + /** + * @brief Destructor + * + * Finalizes and closes the interface. + */ + virtual ~AbstractGlInterface() {} + + /** @brief Create context */ + virtual void createContext(Window nativeWindow) = 0; + + /** @brief Make the context current */ + virtual void makeCurrent() = 0; + + /** @brief Swap buffers */ + virtual void swapBuffers() = 0; +}; + +}} + +#endif diff --git a/src/Contexts/XEglContext.cpp b/src/Contexts/AbstractXContext.cpp similarity index 50% rename from src/Contexts/XEglContext.cpp rename to src/Contexts/AbstractXContext.cpp index 8fbd47fec..5195b5387 100644 --- a/src/Contexts/XEglContext.cpp +++ b/src/Contexts/AbstractXContext.cpp @@ -13,7 +13,7 @@ GNU Lesser General Public License version 3 for more details. */ -#include "XEglContext.h" +#include "AbstractXContext.h" #define None 0L // redef Xlib nonsense @@ -24,117 +24,70 @@ using namespace std; namespace Magnum { namespace Contexts { -XEglContext::XEglContext(int&, char**, const string& title, const Math::Vector2& size): viewportSize(size) { - /* Get default X display and root window, init EGL */ - xDisplay = XOpenDisplay(0); - display = eglGetDisplay(xDisplay); - eglInitialize(display, 0, 0); - #ifndef MAGNUM_TARGET_GLES - eglBindAPI(EGL_OPENGL_API); - #else - eglBindAPI(EGL_OPENGL_ES_API); - #endif +AbstractXContext::AbstractXContext(AbstractGlInterface* glInterface, int&, char**, const string& title, const Math::Vector2& size): glInterface(glInterface), viewportSize(size) { + /* Get default X display */ + display = XOpenDisplay(0); - /* Choose EGL config */ - static const EGLint attribs[] = { - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - EGL_DEPTH_SIZE, 1, - #ifndef MAGNUM_TARGET_GLES - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - #else - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - #endif - EGL_NONE - }; - EGLConfig config; - EGLint configCount; - if(!eglChooseConfig(display, attribs, &config, 1, &configCount)) { - Error() << "Cannot get EGL visual config"; - exit(1); - } + /* Get visual ID */ + VisualID visualId = glInterface->getVisualId(display); - /* Get X visual */ - EGLint visualId; - if(!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &visualId)) { - Error() << "Cannot get native visual ID"; - exit(1); - } + /* Get visual info */ XVisualInfo *visInfo, visTemplate; int visualCount; visTemplate.visualid = visualId; - visInfo = XGetVisualInfo(xDisplay, VisualIDMask, &visTemplate, &visualCount); + visInfo = XGetVisualInfo(display, VisualIDMask, &visTemplate, &visualCount); if(!visInfo) { Error() << "Cannot get X visual"; exit(1); } /* Create X Window */ - Window root = RootWindow(xDisplay, DefaultScreen(display)); + Window root = RootWindow(display, DefaultScreen(display)); XSetWindowAttributes attr; attr.background_pixel = 0; attr.border_pixel = 0; - attr.colormap = XCreateColormap(xDisplay, root, visInfo->visual, AllocNone); + attr.colormap = XCreateColormap(display, 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); + window = XCreateWindow(display, root, 20, 20, size.x(), size.y(), 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr); + XSetStandardProperties(display, window, 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 - EGL_CONTEXT_CLIENT_VERSION, 2, - #endif - EGL_NONE - }; - context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); - if(!context) { - Error() << "Cannot create EGL context"; - exit(1); - } - surface = eglCreateWindowSurface(display, config, xWindow, NULL); - if(!surface) { - Error() << "Cannot create window surface"; - exit(1); - } + deleteWindow = XInternAtom(display, "WM_DELETE_WINDOW", True); + XSetWMProtocols(display, window, &deleteWindow, 1); + + /* Create context */ + glInterface->createContext(window); /* Capture exposure, keyboard and mouse button events */ - XSelectInput(xDisplay, xWindow, INPUT_MASK); + XSelectInput(display, window, INPUT_MASK); /* Set OpenGL context as current */ - eglMakeCurrent(display, surface, surface, context); + glInterface->makeCurrent(); - /** @bug Fixme: GLEW initialization fails (thinks that the context is not created) */ #ifndef MAGNUM_TARGET_GLES /* Init GLEW */ GLenum err = glewInit(); if(err != GLEW_OK) { - Error() << "XEglContext: cannot initialize GLEW:" << glewGetErrorString(err); + Error() << "AbstractXContext: cannot initialize GLEW:" << glewGetErrorString(err); exit(1); } #endif } -XEglContext::~XEglContext() { - /* Shut down EGL */ - eglDestroyContext(display, context); - eglDestroySurface(display, surface); - eglTerminate(display); +AbstractXContext::~AbstractXContext() { + /* Shut down the interface */ + delete glInterface; /* Shut down X */ - XDestroyWindow(xDisplay, xWindow); - XCloseDisplay(xDisplay); + XDestroyWindow(display, window); + XCloseDisplay(display); } -int XEglContext::exec() { +int AbstractXContext::exec() { /* Show window */ - XMapWindow(xDisplay, xWindow); + XMapWindow(display, window); /* Call viewportEvent for the first time */ viewportEvent(viewportSize); @@ -143,12 +96,12 @@ int XEglContext::exec() { XEvent event; /* Closed window */ - if(XCheckTypedWindowEvent(xDisplay, xWindow, ClientMessage, &event) && + if(XCheckTypedWindowEvent(display, window, ClientMessage, &event) && Atom(event.xclient.data.l[0]) == deleteWindow) { return 0; } - while(XCheckWindowEvent(xDisplay, xWindow, INPUT_MASK, &event)) { + while(XCheckWindowEvent(display, window, INPUT_MASK, &event)) { switch(event.type) { /* Window resizing */ case ConfigureNotify: { diff --git a/src/Contexts/AbstractXContext.h b/src/Contexts/AbstractXContext.h new file mode 100644 index 000000000..971240d98 --- /dev/null +++ b/src/Contexts/AbstractXContext.h @@ -0,0 +1,227 @@ +#ifndef Magnum_Contexts_AbstractXContext_h +#define Magnum_Contexts_AbstractXContext_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::Contexts::AbstractXContext + */ + +#include "Magnum.h" + +#include +#include +/* undef Xlib nonsense to avoid conflicts */ +#undef None +#undef Always + +#include "AbstractContext.h" +#include "AbstractGlInterface.h" + +namespace Magnum { namespace Contexts { + +/** +@brief Base for X11-based contexts + +Supports keyboard and mouse handling. + +@note Not meant to be used directly, see subclasses. +*/ +class AbstractXContext: public AbstractContext { + public: + /** + * @brief Constructor + * @param glInterface Interface to OpenGL + * @param argc Count of arguments of `main()` function + * @param argv Arguments of `main()` function + * @param title Window title + * @param size Window size + * + * Creates window with double-buffered OpenGL ES 2 context. + */ + AbstractXContext(AbstractGlInterface* glInterface, int& argc, char** argv, const std::string& title = "Magnum X/EGL context", const Math::Vector2& size = Math::Vector2(800, 600)); + + /** + * @brief Destructor + * + * Deletes context and destroys the window. + */ + virtual ~AbstractXContext() = 0; + + int exec(); + + /** @{ @name Drawing functions */ + + protected: + /** @copydoc GlutContext::viewportEvent() */ + virtual void viewportEvent(const Math::Vector2& size) = 0; + + /** @copydoc GlutContext::drawEvent() */ + virtual void drawEvent() = 0; + + /** @copydoc GlutContext::swapBuffers() */ + inline void swapBuffers() { glInterface->swapBuffers(); } + + /** @todo implement */ + inline void redraw() {} + + /*@}*/ + + /** @{ @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 */ + + Space = XK_space, /**< Space */ + Comma = XK_comma, /**< Comma */ + Period = XK_period, /**< Period */ + Minus = XK_minus, /**< Minus */ + Plus = XK_plus, /**< Plus */ + Slash = XK_slash, /**< Slash */ + Percent = XK_percent, /**< Percent */ + Equal = XK_equal, /**< Equal */ + + Zero = XK_0, /**< Zero */ + One = XK_1, /**< One */ + Two = XK_2, /**< Two */ + Three = XK_3, /**< Three */ + Four = XK_4, /**< Four */ + Five = XK_5, /**< Five */ + Six = XK_6, /**< Six */ + Seven = XK_7, /**< Seven */ + Eight = XK_8, /**< Eight */ + Nine = XK_9, /**< Nine */ + + A = XK_a, /**< Small letter A */ + B = XK_b, /**< Small letter B */ + C = XK_c, /**< Small letter C */ + D = XK_d, /**< Small letter D */ + E = XK_e, /**< Small letter E */ + F = XK_f, /**< Small letter F */ + G = XK_g, /**< Small letter G */ + H = XK_h, /**< Small letter H */ + I = XK_i, /**< Small letter I */ + J = XK_j, /**< Small letter J */ + K = XK_k, /**< Small letter K */ + L = XK_l, /**< Small letter L */ + M = XK_m, /**< Small letter M */ + N = XK_n, /**< Small letter N */ + O = XK_o, /**< Small letter O */ + P = XK_p, /**< Small letter P */ + Q = XK_q, /**< Small letter Q */ + R = XK_r, /**< Small letter R */ + S = XK_s, /**< Small letter S */ + T = XK_t, /**< Small letter T */ + U = XK_u, /**< Small letter U */ + V = XK_v, /**< Small letter V */ + W = XK_w, /**< Small letter W */ + X = XK_x, /**< Small letter X */ + Y = XK_y, /**< Small letter Y */ + Z = XK_z /**< Small letter Z */ + }; + + 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); + + /** + * @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); + + /*@}*/ + + /** @{ @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* display; + Window window; + Atom deleteWindow; + + AbstractGlInterface* glInterface; + + /** @todo Get this from the created window */ + Math::Vector2 viewportSize; +}; + +inline void AbstractXContext::keyPressEvent(AbstractXContext::Key, const Math::Vector2&) {} +inline void AbstractXContext::keyReleaseEvent(AbstractXContext::Key, const Math::Vector2&) {} +inline void AbstractXContext::mousePressEvent(AbstractXContext::MouseButton, const Math::Vector2&) {} +inline void AbstractXContext::mouseReleaseEvent(AbstractXContext::MouseButton, const Math::Vector2&) {} + + +}} + +#endif diff --git a/src/Contexts/CMakeLists.txt b/src/Contexts/CMakeLists.txt index e65a8ecee..dee2f25e6 100644 --- a/src/Contexts/CMakeLists.txt +++ b/src/Contexts/CMakeLists.txt @@ -1,4 +1,7 @@ -install(FILES AbstractContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) +set(MagnumContexts_HEADERS + AbstractContext.h + AbstractGlInterface.h) +install(FILES ${MagnumContexts_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) # GLUT context if(WITH_GLUTCONTEXT) @@ -27,15 +30,33 @@ endif() # X/EGL context if(WITH_XEGLCONTEXT) - find_package(EGL) + set(NEED_ABSTRACTXCONTEXT 1) + set(NEED_EGLINTERFACE 1) + add_library(MagnumXEglContext STATIC $ $) + install(FILES XEglContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + install(TARGETS MagnumXEglContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) +endif() + +# Abstract X context +if(NEED_ABSTRACTXCONTEXT) find_package(X11) - if(EGL_FOUND AND X11_FOUND) - add_library(MagnumXEglContext STATIC XEglContext.cpp) - # X11 macros are a mess, disable warnings for C-style casts - set_target_properties(MagnumXEglContext PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") - install(FILES XEglContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) - install(TARGETS MagnumXEglContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) - else() - message(FATAL_ERROR "EGL or X11 libraries, required by XEglContext, were not found. Set WITH_XEGLCONTEXT to OFF to skip building it.") + if(NOT X11_FOUND) + message(FATAL_ERROR "X11 library, required by some contexts, was not found. Set WITH_*X*CONTEXT to OFF to skip building them.") + endif() + add_library(MagnumAbstractXContext OBJECT AbstractXContext.cpp) + # X11 macros are a mess, disable warnings for C-style casts + set_target_properties(MagnumAbstractXContext PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") + install(FILES AbstractXContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) +endif() + +# EGL interface +if(NEED_EGLINTERFACE) + find_package(EGL) + if(NOT EGL_FOUND) + message(FATAL_ERROR "EGL library, required by some contexts, was not found. Set WITH_*EGL*CONTEXT to OFF to skip building them.") endif() + add_library(MagnumEglInterface OBJECT EglInterface.cpp) + # X11 macros are a mess, disable warnings for C-style casts + set_target_properties(MagnumEglInterface PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") + install(FILES EglInterface.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) endif() diff --git a/src/Contexts/EglInterface.cpp b/src/Contexts/EglInterface.cpp new file mode 100644 index 000000000..609f37322 --- /dev/null +++ b/src/Contexts/EglInterface.cpp @@ -0,0 +1,86 @@ +/* + 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 "EglInterface.h" + +namespace Magnum { namespace Contexts { + +EglInterface::~EglInterface() { + eglDestroyContext(display, context); + eglDestroySurface(display, surface); + eglTerminate(display); +} + +VisualId EglInterface::getVisualId(EGLNativeDisplayType nativeDisplay) { + /* Initialize */ + display = eglGetDisplay(nativeDisplay); + eglInitialize(display, 0, 0); + #ifndef MAGNUM_TARGET_GLES + eglBindAPI(EGL_OPENGL_API); + #else + eglBindAPI(EGL_OPENGL_ES_API); + #endif + + /* Choose EGL config */ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + #ifndef MAGNUM_TARGET_GLES + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + #else + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + #endif + EGL_NONE + }; + EGLint configCount; + if(!eglChooseConfig(display, attribs, &config, 1, &configCount)) { + Error() << "Cannot get EGL visual config"; + exit(1); + } + + /* Get visual ID */ + EGLint visualId; + if(!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &visualId)) { + Error() << "Cannot get native visual ID"; + exit(1); + } + + return visualId; +} + +void EglInterface::createContext(EGLNativeWindowType window) { + static const EGLint contextAttributes[] = { + #ifdef MAGNUM_TARGET_GLES + EGL_CONTEXT_CLIENT_VERSION, 2, + #endif + EGL_NONE + }; + context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); + if(!context) { + Error() << "Cannot create EGL context"; + exit(1); + } + surface = eglCreateWindowSurface(display, config, window, NULL); + if(!surface) { + Error() << "Cannot create window surface"; + exit(1); + } + + /** @bug Fixme: On desktop OpenGL and Mesa EGL implementation OpenGL version is 1.0, which is wrong */ +} + +}} diff --git a/src/Contexts/EglInterface.h b/src/Contexts/EglInterface.h new file mode 100644 index 000000000..671d6df18 --- /dev/null +++ b/src/Contexts/EglInterface.h @@ -0,0 +1,71 @@ +#ifndef Magnum_Contexts_EglInterface_h +#define Magnum_Contexts_EglInterface_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::Contexts::EglInterface + */ + +#include "Magnum.h" + +#ifndef SUPPORT_X11 +#define SUPPORT_X11 // OpenGL ES on BeagleBoard needs this (?) +#endif +#include + +#include "AbstractGlInterface.h" + +namespace Magnum { namespace Contexts { + +#ifndef DOXYGEN_GENERATING_OUTPUT +/* EGL returns visual ID as int, but Xorg expects long unsigned int */ +#ifdef __unix__ +typedef VisualID VisualId; +#else +typedef EGLInt VisualId; +#endif +#endif + +/** +@brief EGL interface + +Used in XEglContext. +*/ +class EglInterface: public AbstractGlInterface { + public: + ~EglInterface(); + + VisualId getVisualId(EGLNativeDisplayType nativeDisplay); + void createContext(EGLNativeWindowType nativeWindow); + + inline void makeCurrent() { + eglMakeCurrent(display, surface, surface, context); + } + + inline void swapBuffers() { + eglSwapBuffers(display, surface); + } + + private: + EGLDisplay display; + EGLConfig config; + EGLSurface surface; + EGLContext context; +}; + +}} + +#endif diff --git a/src/Contexts/XEglContext.h b/src/Contexts/XEglContext.h index 496ce7c63..fb368c1db 100644 --- a/src/Contexts/XEglContext.h +++ b/src/Contexts/XEglContext.h @@ -19,28 +19,17 @@ * @brief Class Magnum::Contexts::XEglContext */ -#include "Magnum.h" - -#include -/* undef Xlib nonsense to avoid conflicts */ -#undef None -#undef Always - -#ifndef SUPPORT_X11 -#define SUPPORT_X11 // OpenGL ES on BeagleBoard needs this (?) -#endif -#include - -#include "AbstractContext.h" +#include "AbstractXContext.h" +#include "EglInterface.h" namespace Magnum { namespace Contexts { /** @brief X/EGL context -Supports keyboard and mouse handling. +Uses EglInterface. */ -class XEglContext: public AbstractContext { +class XEglContext: public AbstractXContext { public: /** * @brief Constructor @@ -51,179 +40,9 @@ class XEglContext: public AbstractContext { * * Creates window with double-buffered OpenGL ES 2 context. */ - XEglContext(int& argc, char** argv, const std::string& title = "Magnum X/EGL context", const Math::Vector2& size = Math::Vector2(800, 600)); - - /** - * @brief Destructor - * - * Deletes context and destroys the window. - */ - ~XEglContext(); - - int exec(); - - /** @{ @name Drawing functions */ - - protected: - /** @copydoc GlutContext::viewportEvent() */ - virtual void viewportEvent(const Math::Vector2& size) = 0; - - /** @copydoc GlutContext::drawEvent() */ - virtual void drawEvent() = 0; - - /** @copydoc GlutContext::swapBuffers() */ - inline void swapBuffers() { eglSwapBuffers(display, surface); } - - /** @todo implement */ - inline void redraw() {} - - /*@}*/ - - /** @{ @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 */ - - Space = XK_space, /**< Space */ - Comma = XK_comma, /**< Comma */ - Period = XK_period, /**< Period */ - Minus = XK_minus, /**< Minus */ - Plus = XK_plus, /**< Plus */ - Slash = XK_slash, /**< Slash */ - Percent = XK_percent, /**< Percent */ - Equal = XK_equal, /**< Equal */ - - Zero = XK_0, /**< Zero */ - One = XK_1, /**< One */ - Two = XK_2, /**< Two */ - Three = XK_3, /**< Three */ - Four = XK_4, /**< Four */ - Five = XK_5, /**< Five */ - Six = XK_6, /**< Six */ - Seven = XK_7, /**< Seven */ - Eight = XK_8, /**< Eight */ - Nine = XK_9, /**< Nine */ - - A = XK_a, /**< Small letter A */ - B = XK_b, /**< Small letter B */ - C = XK_c, /**< Small letter C */ - D = XK_d, /**< Small letter D */ - E = XK_e, /**< Small letter E */ - F = XK_f, /**< Small letter F */ - G = XK_g, /**< Small letter G */ - H = XK_h, /**< Small letter H */ - I = XK_i, /**< Small letter I */ - J = XK_j, /**< Small letter J */ - K = XK_k, /**< Small letter K */ - L = XK_l, /**< Small letter L */ - M = XK_m, /**< Small letter M */ - N = XK_n, /**< Small letter N */ - O = XK_o, /**< Small letter O */ - P = XK_p, /**< Small letter P */ - Q = XK_q, /**< Small letter Q */ - R = XK_r, /**< Small letter R */ - S = XK_s, /**< Small letter S */ - T = XK_t, /**< Small letter T */ - U = XK_u, /**< Small letter U */ - V = XK_v, /**< Small letter V */ - W = XK_w, /**< Small letter W */ - X = XK_x, /**< Small letter X */ - Y = XK_y, /**< Small letter Y */ - Z = XK_z /**< Small letter Z */ - }; - - 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); - - /** - * @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); - - /*@}*/ - - /** @{ @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; - EGLContext context; - - /** @todo Get this from the created window */ - Math::Vector2 viewportSize; + inline XEglContext(int& argc, char** argv, const std::string& title = "Magnum X/EGL context", const Math::Vector2& size = Math::Vector2(800, 600)): AbstractXContext(new EglInterface, argc, argv, title, size) {} }; -inline void XEglContext::keyPressEvent(XEglContext::Key, const Math::Vector2&) {} -inline void XEglContext::keyReleaseEvent(XEglContext::Key, const Math::Vector2&) {} -inline void XEglContext::mousePressEvent(XEglContext::MouseButton, const Math::Vector2&) {} -inline void XEglContext::mouseReleaseEvent(XEglContext::MouseButton, const Math::Vector2&) {} - - }} #endif