Skip to content

Instantly share code, notes, and snippets.

@marty1885
Created November 30, 2020 15:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marty1885/28590f08778bd50810770d4dbb4e47d0 to your computer and use it in GitHub Desktop.
Save marty1885/28590f08778bd50810770d4dbb4e47d0 to your computer and use it in GitHub Desktop.
PoC code hacked from various sources, SDL with OpenGL (ES) using external context
// To compile: (Tested on Arch Linux)
// c++ sdl_gl.cpp -o sdl_gl `pkg-config sdl2 --cflags --libs` -lwayland-egl -lwayland-egl -lGL -lEGL -lX11 && ./sdl_gl
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include "SDL2/SDL_syswm.h"
#include <GL/gl.h>
#include <EGL/egl.h>
#include <wayland-client.h>
#include <wayland-egl.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#define WINDOW_WIDTH 1000
#define WINDOW_HEIGHT 1000
int main(int ArgCount, char **Args)
{
SDL_Window *window = SDL_CreateWindow("OpenGL Test", 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL) {
fprintf(stderr, "Failed to create SDL window\n");
exit(1);
}
// Instead of calling SDL_GL_CreateContext. We can do the following long code
//SDL_GLContext Context = SDL_GL_CreateContext(window);
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if(SDL_GetWindowWMInfo(window, &info) == false) {
fprintf(stderr, "Failed to get SDL window info\n");
exit(1);
}
EGLNativeDisplayType native_display;
EGLNativeWindowType native_window;
EGLDisplay egl_display;
if(info.subsystem == SDL_SYSWM_WAYLAND) {
auto native_window_ = info.info.wl.surface;
native_window = reinterpret_cast<EGLNativeWindowType>(wl_egl_window_create(native_window_, WINDOW_WIDTH, WINDOW_HEIGHT));
native_display = reinterpret_cast<EGLNativeDisplayType>(info.info.wl.display);
}
else if(info.subsystem == SDL_SYSWM_X11) {
native_window = static_cast<EGLNativeWindowType>(info.info.x11.window);
native_display = static_cast<EGLNativeDisplayType>(info.info.x11.display);
}
else {
fprintf(stderr, "Should be running on X11 or Wayland\n");
exit(1);
}
if(native_window == 0) {
fprintf(stderr, "Native Window does not exist\n");
exit(1);
}
egl_display = eglGetDisplay(native_display);
if(egl_display == EGL_NO_DISPLAY) {
fprintf(stderr, "No EGL Display\n");
exit(1);
}
if(eglInitialize(egl_display, NULL, NULL) == false) {
fprintf(stderr, "Failed to initalize EGL\n");
exit(1);
}
if(eglBindAPI(EGL_OPENGL_API) == false) {
fprintf(stderr, "Failed to bind EGL API to OpenGL\n");
exit(1);
}
EGLint attr[] = {EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE};
EGLConfig config;
EGLint num_config;
if(eglChooseConfig(egl_display, attr, &config, 1, &num_config) == false) {
fprintf(stderr, "Failed to choose config (eglError: %d)\n", eglGetError());
exit(1);
}
if (num_config != 1) {
fprintf(stderr, "Didn't get exactly one config, but %d\n", num_config);
exit(1);
}
auto egl_surface = eglCreateWindowSurface(egl_display, config, native_window, nullptr);
if (egl_surface == EGL_NO_SURFACE) {
fprintf(stderr, "Unable to create EGL surface (eglError: %d)\n", eglGetError());
exit(1);
}
EGLint ctxattr[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
auto egl_context = eglCreateContext(egl_display, config, EGL_NO_CONTEXT, ctxattr);
if(egl_context == EGL_NO_CONTEXT) {
fprintf(stderr, "Unable to create EGL context (eglError: %d)\n", eglGetError());
return 1;
}
if(eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == false) {
fprintf(stderr, "Failed to make EGL context curret\n");
exit(1);
}
int Running = 1;
int FullScreen = 0;
printf("Hoping a purple window would pop up..\n");
while (Running) {
SDL_Event Event;
while (SDL_WaitEventTimeout(&Event, 100)){
if (Event.type == SDL_KEYDOWN) {
switch (Event.key.keysym.sym) {
case SDLK_ESCAPE:
Running = 0;
break;
default:
break;
}
}
else if (Event.type == SDL_QUIT) {
Running = 0;
}
}
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glClearColor(1.f, 0.f, 1.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
// SDL_GL_SwapWindow(Window);
eglSwapBuffers (egl_display, egl_surface);
}
eglTerminate(egl_display);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment