Browse Source

Decoupled EGL interface from XEglContext.

New class EglInterface now handles only EGL, AbstractXContext is able to
take any OpenGL interface sublassed from AbstractGlInterface.
pull/279/head
Vladimír Vondruš 14 years ago
parent
commit
e372a71636
  1. 53
      src/Contexts/AbstractGlInterface.h
  2. 105
      src/Contexts/AbstractXContext.cpp
  3. 227
      src/Contexts/AbstractXContext.h
  4. 41
      src/Contexts/CMakeLists.txt
  5. 86
      src/Contexts/EglInterface.cpp
  6. 71
      src/Contexts/EglInterface.h
  7. 191
      src/Contexts/XEglContext.h

53
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š <mosra@centrum.cz>
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 Display, class VisualId, class Window> 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

105
src/Contexts/XEglContext.cpp → src/Contexts/AbstractXContext.cpp

@ -13,7 +13,7 @@
GNU Lesser General Public License version 3 for more details. GNU Lesser General Public License version 3 for more details.
*/ */
#include "XEglContext.h" #include "AbstractXContext.h"
#define None 0L // redef Xlib nonsense #define None 0L // redef Xlib nonsense
@ -24,117 +24,70 @@ using namespace std;
namespace Magnum { namespace Contexts { namespace Magnum { namespace Contexts {
XEglContext::XEglContext(int&, char**, const string& title, const Math::Vector2<GLsizei>& size): viewportSize(size) { AbstractXContext::AbstractXContext(AbstractGlInterface<Display*, VisualID, Window>* glInterface, int&, char**, const string& title, const Math::Vector2<GLsizei>& size): glInterface(glInterface), viewportSize(size) {
/* Get default X display and root window, init EGL */ /* Get default X display */
xDisplay = XOpenDisplay(0); display = XOpenDisplay(0);
display = eglGetDisplay(xDisplay);
eglInitialize(display, 0, 0);
#ifndef MAGNUM_TARGET_GLES
eglBindAPI(EGL_OPENGL_API);
#else
eglBindAPI(EGL_OPENGL_ES_API);
#endif
/* Choose EGL config */ /* Get visual ID */
static const EGLint attribs[] = { VisualID visualId = glInterface->getVisualId(display);
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 X visual */ /* Get visual info */
EGLint visualId;
if(!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &visualId)) {
Error() << "Cannot get native visual ID";
exit(1);
}
XVisualInfo *visInfo, visTemplate; XVisualInfo *visInfo, visTemplate;
int visualCount; int visualCount;
visTemplate.visualid = visualId; visTemplate.visualid = visualId;
visInfo = XGetVisualInfo(xDisplay, VisualIDMask, &visTemplate, &visualCount); visInfo = XGetVisualInfo(display, VisualIDMask, &visTemplate, &visualCount);
if(!visInfo) { if(!visInfo) {
Error() << "Cannot get X visual"; Error() << "Cannot get X visual";
exit(1); exit(1);
} }
/* Create X Window */ /* Create X Window */
Window root = RootWindow(xDisplay, DefaultScreen(display)); Window root = RootWindow(display, DefaultScreen(display));
XSetWindowAttributes attr; XSetWindowAttributes attr;
attr.background_pixel = 0; attr.background_pixel = 0;
attr.border_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; attr.event_mask = 0;
unsigned long mask = CWBackPixel|CWBorderPixel|CWColormap|CWEventMask; 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); window = XCreateWindow(display, 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); XSetStandardProperties(display, window, title.c_str(), 0, None, 0, 0, 0);
XFree(visInfo); XFree(visInfo);
/* Be notified about closing the window */ /* Be notified about closing the window */
deleteWindow = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True); deleteWindow = XInternAtom(display, "WM_DELETE_WINDOW", True);
XSetWMProtocols(xDisplay, xWindow, &deleteWindow, 1); XSetWMProtocols(display, window, &deleteWindow, 1);
/* Create context and window surface */ /* Create context */
static const EGLint contextAttributes[] = { glInterface->createContext(window);
#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);
}
/* Capture exposure, keyboard and mouse button events */ /* Capture exposure, keyboard and mouse button events */
XSelectInput(xDisplay, xWindow, INPUT_MASK); XSelectInput(display, window, INPUT_MASK);
/* Set OpenGL context as current */ /* 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 #ifndef MAGNUM_TARGET_GLES
/* Init GLEW */ /* Init GLEW */
GLenum err = glewInit(); GLenum err = glewInit();
if(err != GLEW_OK) { if(err != GLEW_OK) {
Error() << "XEglContext: cannot initialize GLEW:" << glewGetErrorString(err); Error() << "AbstractXContext: cannot initialize GLEW:" << glewGetErrorString(err);
exit(1); exit(1);
} }
#endif #endif
} }
XEglContext::~XEglContext() { AbstractXContext::~AbstractXContext() {
/* Shut down EGL */ /* Shut down the interface */
eglDestroyContext(display, context); delete glInterface;
eglDestroySurface(display, surface);
eglTerminate(display);
/* Shut down X */ /* Shut down X */
XDestroyWindow(xDisplay, xWindow); XDestroyWindow(display, window);
XCloseDisplay(xDisplay); XCloseDisplay(display);
} }
int XEglContext::exec() { int AbstractXContext::exec() {
/* Show window */ /* Show window */
XMapWindow(xDisplay, xWindow); XMapWindow(display, window);
/* Call viewportEvent for the first time */ /* Call viewportEvent for the first time */
viewportEvent(viewportSize); viewportEvent(viewportSize);
@ -143,12 +96,12 @@ int XEglContext::exec() {
XEvent event; XEvent event;
/* Closed window */ /* Closed window */
if(XCheckTypedWindowEvent(xDisplay, xWindow, ClientMessage, &event) && if(XCheckTypedWindowEvent(display, window, ClientMessage, &event) &&
Atom(event.xclient.data.l[0]) == deleteWindow) { Atom(event.xclient.data.l[0]) == deleteWindow) {
return 0; return 0;
} }
while(XCheckWindowEvent(xDisplay, xWindow, INPUT_MASK, &event)) { while(XCheckWindowEvent(display, window, INPUT_MASK, &event)) {
switch(event.type) { switch(event.type) {
/* Window resizing */ /* Window resizing */
case ConfigureNotify: { case ConfigureNotify: {

227
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š <mosra@centrum.cz>
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 <X11/Xlib.h>
#include <X11/Xutil.h>
/* 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<Display*, VisualID, Window>* glInterface, int& argc, char** argv, const std::string& title = "Magnum X/EGL context", const Math::Vector2<GLsizei>& size = Math::Vector2<GLsizei>(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<GLsizei>& 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<int>& 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<int>& 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<int>& position);
/**
* @brief Mouse release event
*
* Called when mouse button is released. Default implementation does
* nothing.
*/
virtual void mouseReleaseEvent(MouseButton button, const Math::Vector2<int>& position);
/*@}*/
private:
Display* display;
Window window;
Atom deleteWindow;
AbstractGlInterface<Display*, VisualID, Window>* glInterface;
/** @todo Get this from the created window */
Math::Vector2<GLsizei> viewportSize;
};
inline void AbstractXContext::keyPressEvent(AbstractXContext::Key, const Math::Vector2<int>&) {}
inline void AbstractXContext::keyReleaseEvent(AbstractXContext::Key, const Math::Vector2<int>&) {}
inline void AbstractXContext::mousePressEvent(AbstractXContext::MouseButton, const Math::Vector2<int>&) {}
inline void AbstractXContext::mouseReleaseEvent(AbstractXContext::MouseButton, const Math::Vector2<int>&) {}
}}
#endif

41
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 # GLUT context
if(WITH_GLUTCONTEXT) if(WITH_GLUTCONTEXT)
@ -27,15 +30,33 @@ endif()
# X/EGL context # X/EGL context
if(WITH_XEGLCONTEXT) if(WITH_XEGLCONTEXT)
find_package(EGL) set(NEED_ABSTRACTXCONTEXT 1)
set(NEED_EGLINTERFACE 1)
add_library(MagnumXEglContext STATIC $<TARGET_OBJECTS:MagnumAbstractXContext> $<TARGET_OBJECTS:MagnumEglInterface>)
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) find_package(X11)
if(EGL_FOUND AND X11_FOUND) if(NOT X11_FOUND)
add_library(MagnumXEglContext STATIC XEglContext.cpp) message(FATAL_ERROR "X11 library, required by some contexts, was not found. Set WITH_*X*CONTEXT to OFF to skip building them.")
# X11 macros are a mess, disable warnings for C-style casts endif()
set_target_properties(MagnumXEglContext PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") add_library(MagnumAbstractXContext OBJECT AbstractXContext.cpp)
install(FILES XEglContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) # X11 macros are a mess, disable warnings for C-style casts
install(TARGETS MagnumXEglContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) set_target_properties(MagnumAbstractXContext PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast")
else() install(FILES AbstractXContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts)
message(FATAL_ERROR "EGL or X11 libraries, required by XEglContext, were not found. Set WITH_XEGLCONTEXT to OFF to skip building it.") 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() 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() endif()

86
src/Contexts/EglInterface.cpp

@ -0,0 +1,86 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
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 */
}
}}

71
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š <mosra@centrum.cz>
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 <EGL/egl.h>
#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<EGLNativeDisplayType, VisualId, EGLNativeWindowType> {
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

191
src/Contexts/XEglContext.h

@ -19,28 +19,17 @@
* @brief Class Magnum::Contexts::XEglContext * @brief Class Magnum::Contexts::XEglContext
*/ */
#include "Magnum.h" #include "AbstractXContext.h"
#include "EglInterface.h"
#include <X11/Xlib.h>
/* undef Xlib nonsense to avoid conflicts */
#undef None
#undef Always
#ifndef SUPPORT_X11
#define SUPPORT_X11 // OpenGL ES on BeagleBoard needs this (?)
#endif
#include <EGL/egl.h>
#include "AbstractContext.h"
namespace Magnum { namespace Contexts { namespace Magnum { namespace Contexts {
/** /**
@brief X/EGL context @brief X/EGL context
Supports keyboard and mouse handling. Uses EglInterface.
*/ */
class XEglContext: public AbstractContext { class XEglContext: public AbstractXContext {
public: public:
/** /**
* @brief Constructor * @brief Constructor
@ -51,179 +40,9 @@ class XEglContext: public AbstractContext {
* *
* Creates window with double-buffered OpenGL ES 2 context. * 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<GLsizei>& size = Math::Vector2<GLsizei>(800, 600)); inline XEglContext(int& argc, char** argv, const std::string& title = "Magnum X/EGL context", const Math::Vector2<GLsizei>& size = Math::Vector2<GLsizei>(800, 600)): AbstractXContext(new EglInterface, argc, argv, title, size) {}
/**
* @brief Destructor
*
* Deletes context and destroys the window.
*/
~XEglContext();
int exec();
/** @{ @name Drawing functions */
protected:
/** @copydoc GlutContext::viewportEvent() */
virtual void viewportEvent(const Math::Vector2<GLsizei>& 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<int>& 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<int>& 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<int>& position);
/**
* @brief Mouse release event
*
* Called when mouse button is released. Default implementation does
* nothing.
*/
virtual void mouseReleaseEvent(MouseButton button, const Math::Vector2<int>& position);
/*@}*/
private:
Display* xDisplay;
Window xWindow;
Atom deleteWindow;
EGLDisplay display;
EGLSurface surface;
EGLContext context;
/** @todo Get this from the created window */
Math::Vector2<GLsizei> viewportSize;
}; };
inline void XEglContext::keyPressEvent(XEglContext::Key, const Math::Vector2<int>&) {}
inline void XEglContext::keyReleaseEvent(XEglContext::Key, const Math::Vector2<int>&) {}
inline void XEglContext::mousePressEvent(XEglContext::MouseButton, const Math::Vector2<int>&) {}
inline void XEglContext::mouseReleaseEvent(XEglContext::MouseButton, const Math::Vector2<int>&) {}
}} }}
#endif #endif

Loading…
Cancel
Save