EGL and SDL Context Creation.

Hello,

I’ve been using the PowerVR OpenGL ES 2.0 emulation library on Windows and recently looked into ~portable context creation via SDL… This is my first foray into EGL.

Here’s my code so far:

#include "g_window.hpp"

namespace Window{

    GLuint BackBuffer;
    GLuint Width;
    GLuint Height;
    GLuint BPP;
    GLuint ZBufferDepth;
    GLuint StencilDepth;

    EGLDisplay  Display;
    EGLContext  Context;
    EGLConfig   Config;
    EGLSurface  Surface;

#if defined(WINDOWS) || defined(WIN32)
    HWND        Handle;
    HDC         Device;
#endif
};

const EGLint SurfaceAttribs[] = {
    EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
    EGL_NONE
};

const EGLint ConfigAttribs[] = {
    EGL_LEVEL,				0,
    EGL_SURFACE_TYPE,		EGL_WINDOW_BIT,
    EGL_RENDERABLE_TYPE,	EGL_OPENGL_ES2_BIT,
    EGL_NATIVE_RENDERABLE,	EGL_FALSE,
    EGL_DEPTH_SIZE,			EGL_DONT_CARE,
    EGL_NONE
};

const char* EGLErrorString()
{
	EGLint nErr = eglGetError();
	switch(nErr){
		case EGL_SUCCESS:
			return "EGL_SUCCESS";
		case EGL_BAD_DISPLAY:
			return "EGL_BAD_DISPLAY";
		case EGL_NOT_INITIALIZED:
			return "EGL_NOT_INITIALIZED";
		case EGL_BAD_ACCESS:
			return "EGL_BAD_ACCESS";
		case EGL_BAD_ALLOC:
			return "EGL_BAD_ALLOC";
		case EGL_BAD_ATTRIBUTE:
			return "EGL_BAD_ATTRIBUTE";
		case EGL_BAD_CONFIG:
			return "EGL_BAD_CONFIG";
		case EGL_BAD_CONTEXT:
			return "EGL_BAD_CONTEXT";
		case EGL_BAD_CURRENT_SURFACE:
			return "EGL_BAD_CURRENT_SURFACE";
		case EGL_BAD_MATCH:
			return "EGL_BAD_MATCH";
		case EGL_BAD_NATIVE_PIXMAP:
			return "EGL_BAD_NATIVE_PIXMAP";
		case EGL_BAD_NATIVE_WINDOW:
			return "EGL_BAD_NATIVE_WINDOW";
		case EGL_BAD_PARAMETER:
			return "EGL_BAD_PARAMETER";
		case EGL_BAD_SURFACE:
			return "EGL_BAD_SURFACE";
		default:
			return "unknown";
	}
}

void Window::Init(){
    BackBuffer = 0;
    Width = 800;
    Height = 480;
    BPP = 32;
    ZBufferDepth = 0;
    StencilDepth = 0;

    EGLint nConfigs;

    SDL_Init(SDL_INIT_VIDEO);
    SDL_SetVideoMode(Width, Height, BPP, SDL_SWSURFACE);
    SDL_SysWMinfo info;
    SDL_VERSION(&info.version);
    if (!SDL_GetWMInfo(&info)){
        PRINT_ERROR("Could Not Obtain SDL window.")
    };

#if defined(WINDOWS) || defined(WIN32)
    Handle = info.window;
    Device = GetDC(Handle);
    Display = eglGetDisplay(Device);
#else
    Display = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY);
#endif
    if (Display == EGL_NO_DISPLAY){
        PRINT_ERROR("Display Initialize failed: %s", EGLErrorString());
    }
    if (!eglInitialize(Display, NULL, NULL)){
        PRINT_ERROR("Display Initialize failed: %s", EGLErrorString());
    }

    if (!eglChooseConfig(Display, ConfigAttribs, &Config, 1, &nConfigs)){
        PRINT_ERROR("Configuration failed: %s", EGLErrorString());
    }
    if (nConfigs != 1){
        PRINT_ERROR("Configuration failed: %s", EGLErrorString());
    }

    Surface = eglCreateWindowSurface(Display, &Config, info.window, NULL);
    if (Surface == EGL_NO_SURFACE){
        EGLErrorString();
        Surface = eglCreateWindowSurface(Display, &Config, NULL, NULL);
        if (Surface == EGL_NO_SURFACE){
            PRINT_ERROR("Surface Creation failed: %s", EGLErrorString());
        }
    }
    eglBindAPI(EGL_OPENGL_ES_API);

    Context = eglCreateContext(Display, &Config, NULL, NULL);
    if (Context == EGL_NO_CONTEXT){
        PRINT_ERROR("Context Creation failed: %s", EGLErrorString());
    }

    if (!eglMakeCurrent(Display, Surface, Surface, Context)){
        PRINT_ERROR("Make Current failed: %s", EGLErrorString());
    };
};

void Window::Destroy(){
	eglSwapBuffers(Display, Surface);
	eglMakeCurrent(Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 	eglDestroyContext(Display, Context);
	eglDestroySurface(Display, Surface);
   	eglTerminate(Display);
};

void Window::Render(){
    eglSwapBuffers(Display, Surface);
};

When i Init() the window it produces the following error:

Surface Creation failed: EGL_BAD_CONFIG

Basically, I’m stuck for ideas, no changes in the ConfigAttribs make a difference. Have i missed something EGL-wise or could it be something to do with SDL?

PS: I did notice the similar topic below mine, but my problem seems unrelated.

You are passing “&Config” to eglCreateWindowSurface, it should be “Config”

Wow, that was incredibly stupid of me. Strange that i didn’t get a compiler warning.

Thanks.

Edit: Alright its still not working, i think i can narrow it down to something to do with SDL. As you can see below i hacked in a simple Win32 window. When WIN32_WINDOW is defined the scene is rendered fine, including all shaders and blending, etc. Without the define (using SDL windows) i just get a Black window. Neither output any errors via PRINT_ERROR.

Heres my new code:

#include "g_window.hpp"

namespace Window{

    GLuint BackBuffer;
    GLuint Width;
    GLuint Height;
    GLuint BPP;
    GLuint ZBufferDepth;
    GLuint StencilDepth;


	EGLint		VersionMajor;
	EGLint		VersionMinor;

    EGLDisplay  Display;
    EGLContext  Context;
    EGLConfig   Config;
    EGLSurface  Surface;

#if defined(WINDOWS) || defined(WIN32)
    HWND        Handle;
    HDC         Device;
#endif
};

const EGLint ConfigAttribs[] = {
	EGL_LEVEL,				0,
	EGL_SURFACE_TYPE,		EGL_WINDOW_BIT,
	EGL_RENDERABLE_TYPE,	EGL_OPENGL_ES2_BIT,
	EGL_NATIVE_RENDERABLE,	EGL_FALSE,
	EGL_NONE
};

const EGLint ContextAttribs[] = {
	EGL_CONTEXT_CLIENT_VERSION, 	2,
	EGL_NONE
};

const char* EGLErrorString(){
	EGLint nErr = eglGetError();
	switch(nErr){
		case EGL_SUCCESS: 				return "EGL_SUCCESS";
		case EGL_BAD_DISPLAY:			return "EGL_BAD_DISPLAY";
		case EGL_NOT_INITIALIZED:		return "EGL_NOT_INITIALIZED";
		case EGL_BAD_ACCESS:			return "EGL_BAD_ACCESS";
		case EGL_BAD_ALLOC:				return "EGL_BAD_ALLOC";
		case EGL_BAD_ATTRIBUTE:			return "EGL_BAD_ATTRIBUTE";
		case EGL_BAD_CONFIG:			return "EGL_BAD_CONFIG";
		case EGL_BAD_CONTEXT:			return "EGL_BAD_CONTEXT";
		case EGL_BAD_CURRENT_SURFACE:	return "EGL_BAD_CURRENT_SURFACE";
		case EGL_BAD_MATCH:				return "EGL_BAD_MATCH";
		case EGL_BAD_NATIVE_PIXMAP:		return "EGL_BAD_NATIVE_PIXMAP";
		case EGL_BAD_NATIVE_WINDOW:		return "EGL_BAD_NATIVE_WINDOW";
		case EGL_BAD_PARAMETER:			return "EGL_BAD_PARAMETER";
		case EGL_BAD_SURFACE:			return "EGL_BAD_SURFACE";
		default:						return "unknown";
	}
}

void Window::PrintConfig(){
	EGLint r, g, b, a, zdepth, sdepth;

	PRINT_OUT("
	- Version: %i.%i", VersionMajor, VersionMinor);
	eglGetConfigAttrib(Display, Config, EGL_RED_SIZE, &r);
	eglGetConfigAttrib(Display, Config, EGL_GREEN_SIZE, &g);
	eglGetConfigAttrib(Display, Config, EGL_BLUE_SIZE, &b);
	eglGetConfigAttrib(Display, Config, EGL_ALPHA_SIZE, &a);
	PRINT_OUT("
	- Colour Format: RGBA%i%i%i%i", r, g, b, a);

	eglGetConfigAttrib(Display, Config, EGL_DEPTH_SIZE, &zdepth);
	eglGetConfigAttrib(Display, Config, EGL_STENCIL_SIZE, &sdepth);
	PRINT_OUT("
	- ZBuffer/Stencil Depth: %i/%i", zdepth, sdepth);
}


#if defined(WINDOWS) || defined(WIN32)

#define WINDOW_CLASS	 "OGLESWINDOW"
HINSTANCE Instance;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
	switch(message){
		case WM_DESTROY: 	GameCore::Destroy(); 			return 0;
		case WM_KEYDOWN:	Input::KeySet(wParam, true); 	break;
		case WM_KEYUP:		Input::KeySet(wParam, false); 	break;
		case WM_MBUTTONUP:	Input::MBSet(wParam, true);		break;
		case WM_MBUTTONDOWN:Input::MBSet(wParam, false);	break;
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}

void Window::InitWindowOS(){
	WNDCLASS wc;
	wc.style			= CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc		= (WNDPROC) WndProc;
    wc.cbClsExtra		= 0;
    wc.cbWndExtra		= 0;
    wc.hInstance		= Instance;
    wc.hIcon			= LoadIcon(Instance, ("ICON"));
    wc.hCursor			= 0;
    wc.lpszMenuName		= 0;
	wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszClassName	= WINDOW_CLASS;
	RegisterClass(&wc);
	Handle = CreateWindow(WINDOW_CLASS, "SuperLuminal", WS_VISIBLE, 0, 0, Width,  Height, NULL, NULL, Instance, NULL);
    Device = GetDC(Handle);
}

void Window::DestroyWindowOS(){
	ReleaseDC(Handle, Device);
	DestroyWindow(Handle);
}
#else
#endif

void Window::Init(){
    BackBuffer = 0;
    Width = 800;
    Height = 480;
    BPP = 32;
    ZBufferDepth = 0;
    StencilDepth = 0;
	Device = (EGLNativeDisplayType) EGL_DEFAULT_DISPLAY;
    EGLint nConfigs;

    SDL_Init(SDL_INIT_EVERYTHING);

#if defined(WIN32_WINDOW)
	InitWindowOS();
#else
	if (SDL_SetVideoMode(Width, Height, BPP, SDL_SWSURFACE) == NULL){
		PRINT_ERROR("
Could not set Video Mode");
	}

	SDL_SysWMinfo info;
	SDL_VERSION(&info.version);
	SDL_GetWMInfo(&info);
	Handle = (EGLNativeWindowType) info.window;
#if defined(WINDOWS) || defined(WIN32)
	Device = GetDC(Handle);
#endif
#endif

    Display = eglGetDisplay((EGLNativeDisplayType) Device);
    if (Display == EGL_NO_DISPLAY){
        PRINT_ERROR("
Display Get failed: %s", EGLErrorString());
    }

    if (!eglInitialize(Display, &VersionMajor, &VersionMinor)){
        PRINT_ERROR("
Display Initialize failed: %s", EGLErrorString());
    }

    if (!eglChooseConfig(Display, ConfigAttribs, &Config, 1, &nConfigs)){
        PRINT_ERROR("
Configuration failed: %s", EGLErrorString());
    } else if (nConfigs != 1){
        PRINT_ERROR("
Configuration failed: nconfig %i, %s", nConfigs, EGLErrorString());
    }

	//Print Resulting Config:
	PrintConfig();

    Surface = eglCreateWindowSurface(Display, Config, Handle, NULL);
    if (Surface == EGL_NO_SURFACE){
		PRINT_ERROR("
Surface Creation failed: %s will attempt without window...", EGLErrorString());
        Surface = eglCreateWindowSurface(Display, Config, NULL, NULL);
        if (Surface == EGL_NO_SURFACE){
            PRINT_ERROR("
Surface Creation failed: %s", EGLErrorString());
        }
    }
    eglBindAPI(EGL_OPENGL_ES_API);

    Context = eglCreateContext(Display, Config, EGL_NO_CONTEXT, ContextAttribs);
    if (Context == EGL_NO_CONTEXT){
        PRINT_ERROR("
Context Creation failed: %s", EGLErrorString());
    }

    if (!eglMakeCurrent(Display, Surface, Surface, Context)){
        PRINT_ERROR("
Make Current failed: %s", EGLErrorString());
    };
};

void Window::Destroy(){
	eglSwapBuffers(Display, Surface);
	eglMakeCurrent(Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 	eglDestroyContext(Display, Context);
	eglDestroySurface(Display, Surface);
   	eglTerminate(Display);

#if defined(WIN32_WINDOW)
	DestroyWindowOS();
#endif
};

void Window::Render(){
    eglSwapBuffers(Display, Surface);
};

Any ideas will be much appreciated.

Thanks,

Hi,

I am trying to use SDL with EGL in linux.

This line is always returning EGL_NO_DISPLAY. I am not having this problem in windows.
id = eglGetDisplay(EGL_DEFAULT_DISPLAY);

Can you let me know what to do ?
What info do u need ?

----edit-----------

actually now I am getting an id when I am passing this.


hwnd = wmInfo.info.x11.display;
id = eglGetDisplay(hwnd);

But now I am this problem, a segmentation fault !!!
this is caused right INSIDE eglCreateContext.


vendor: blythe  version: 1.0 reference extinfo: 
/usr/local/netbeans-6.5/cnd2/bin/dorun.sh: line 103:  8662 Segmentation fault      "$pgm" "$@"

any guess whats going wrong ?