#include <iostream>
-#include "glws.hpp"
+#include <dlfcn.h>
#include "glproc.hpp"
+#include "glws.hpp"
namespace glws {
EglDrawable(const Visual *vis, int w, int h) :
Drawable(vis, w, h), api(EGL_OPENGL_ES_API)
{
- XVisualInfo *visinfo = dynamic_cast<const EglVisual *>(visual)->visinfo;
+ XVisualInfo *visinfo = static_cast<const EglVisual *>(visual)->visinfo;
Window root = RootWindow(display, screen);
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
- EGLConfig config = dynamic_cast<const EglVisual *>(visual)->config;
- surface = eglCreateWindowSurface(eglDisplay, config, window, NULL);
+ EGLConfig config = static_cast<const EglVisual *>(visual)->config;
+ surface = eglCreateWindowSurface(eglDisplay, config, (EGLNativeWindowType)window, NULL);
}
void waitForEvent(int type) {
~EglDrawable() {
eglDestroySurface(eglDisplay, surface);
+ eglWaitClient();
XDestroyWindow(display, window);
+ eglWaitNative(EGL_CORE_NATIVE_ENGINE);
}
void
}
};
+/**
+ * Load the symbols from the specified shared object into global namespace, so
+ * that they can be later found by dlsym(RTLD_NEXT, ...);
+ */
+static void
+load(const char *filename)
+{
+ if (!dlopen(filename, RTLD_GLOBAL | RTLD_LAZY)) {
+ std::cerr << "error: unable to open " << filename << "\n";
+ exit(1);
+ }
+}
+
void
init(void) {
+ load("libEGL.so.1");
+
display = XOpenDisplay(NULL);
if (!display) {
std::cerr << "error: unable to open display " << XDisplayName(NULL) << "\n";
screen = DefaultScreen(display);
- eglDisplay = eglGetDisplay(display);
+ eglDisplay = eglGetDisplay((EGLNativeDisplayType)display);
if (eglDisplay == EGL_NO_DISPLAY) {
std::cerr << "error: unable to get EGL display\n";
XCloseDisplay(display);
}
Visual *
-createVisual(bool doubleBuffer) {
+createVisual(bool doubleBuffer, Profile profile) {
EglVisual *visual = new EglVisual();
// possible combinations
- const EGLint api_bits[7] = {
+ const EGLint api_bits_gl[7] = {
EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
- EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
+ EGL_OPENGL_BIT,
+ EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
+ EGL_OPENGL_ES2_BIT,
+ EGL_OPENGL_ES_BIT,
+ };
+ const EGLint api_bits_gles1[7] = {
+ EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
+ EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
+ EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
EGL_OPENGL_ES_BIT,
+ EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
+ EGL_OPENGL_BIT,
+ EGL_OPENGL_ES2_BIT,
+ };
+ const EGLint api_bits_gles2[7] = {
+ EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
+ EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
+ EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
EGL_OPENGL_ES2_BIT,
+ EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
EGL_OPENGL_BIT,
+ EGL_OPENGL_ES_BIT,
+ };
+ const EGLint *api_bits;
+
+ switch(profile) {
+ case PROFILE_COMPAT:
+ api_bits = api_bits_gl;
+ break;
+ case PROFILE_ES1:
+ api_bits = api_bits_gles1;
+ break;
+ case PROFILE_ES2:
+ api_bits = api_bits_gles2;
+ break;
+ default:
+ return NULL;
};
for (int i = 0; i < 7; i++) {
Context *
createContext(const Visual *_visual, Context *shareContext, Profile profile)
{
- const EglVisual *visual = dynamic_cast<const EglVisual *>(_visual);
+ const EglVisual *visual = static_cast<const EglVisual *>(_visual);
EGLContext share_context = EGL_NO_CONTEXT;
EGLContext context;
Attributes<EGLint> attribs;
if (shareContext) {
- share_context = dynamic_cast<EglContext*>(shareContext)->context;
+ share_context = static_cast<EglContext*>(shareContext)->context;
}
EGLint api = eglQueryAPI();
switch (profile) {
case PROFILE_COMPAT:
+ load("libGL.so.1");
eglBindAPI(EGL_OPENGL_API);
break;
+ case PROFILE_CORE:
+ assert(0);
+ return NULL;
case PROFILE_ES1:
+ load("libGLESv1_CM.so.1");
eglBindAPI(EGL_OPENGL_ES_API);
break;
case PROFILE_ES2:
+ load("libGLESv2.so.2");
eglBindAPI(EGL_OPENGL_ES_API);
attribs.add(EGL_CONTEXT_CLIENT_VERSION, 2);
break;
+ default:
+ return NULL;
}
attribs.end(EGL_NONE);
if (!drawable || !context) {
return eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
} else {
- EglDrawable *eglDrawable = dynamic_cast<EglDrawable *>(drawable);
- EglContext *eglContext = dynamic_cast<EglContext *>(context);
+ EglDrawable *eglDrawable = static_cast<EglDrawable *>(drawable);
+ EglContext *eglContext = static_cast<EglContext *>(context);
EGLBoolean ok;
ok = eglMakeCurrent(eglDisplay, eglDrawable->surface,