PDA

View Full Version : EGL and SDL Context Creation.



Adventus
11-15-2008, 10:55 PM
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.

nishantkumar
11-16-2008, 02:51 PM
You are passing "&Config" to eglCreateWindowSurface, it should be "Config"

Adventus
11-16-2008, 03:12 PM
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("\n\t- 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("\n\t- 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("\n\t- 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("\nCould 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("\nDisplay Get failed: %s", EGLErrorString());
}

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

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

//Print Resulting Config:
PrintConfig();

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

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

if (!eglMakeCurrent(Display, Surface, Surface, Context)){
PRINT_ERROR("\nMake 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,

mkandula
03-07-2009, 03:03 AM
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 ?