Difference between revisions of "Combining OpenGL ES 1.1 and SDL to create a window on the Pandora"

From Pandora Wiki
Jump to: navigation, search
m (Undo revision 2595 by Waexu (Talk) spam)
Line 1: Line 1:
 +
There are two options for combining GLES and SDL:
 +
 +
= 1: Grab the modified version of SDL =
 +
 
There is a special SDL source code for pandora with OpenGL ES capability  
 
There is a special SDL source code for pandora with OpenGL ES capability  
 
available here : http://github.com/Cpasjuste
 
available here : http://github.com/Cpasjuste
Line 5: Line 9:
  
 
An SDL/GLES exemple is also available on the git repository.
 
An SDL/GLES exemple is also available on the git repository.
 +
 +
= 2: Use EGL =
 +
 +
Sometimes its not best to use the modified version of SDl (when working on cross platform games). Instead you can use EGL to create the GLES graphics context for you.
 +
The following functions do just that.
 +
 +
Steps:
 +
#1- Make sure you call InitOpenGL() straight after creating the window (SDL_SetVideoMode()).
 +
#2- When using EGL you should not pass in the SDL_OPENGL flag to SDL_SetVideoMode(). SDL_HWSurface and SDL_SWSurface should do.
 +
#3- You will notice '#ifdef GLES1' around much of the EGL code. Simply define GLES1 in your preprocessor (-DGLES1 on the command line of gcc if i recall correctly?) to use GLES. Without the define SDL will be set up for standard OpenGL (I left it in as its useful for cross platform dev).
 +
#4 - Once you have finished with the window and just before terminating it call TerminateOpenGL() to clean up.
 +
 +
NOTE - If you call SDL_SetVideoMode more than once you will probably need to terminate and reset the context (TerminateOpenGL(); SDL_SetVideoMode(); InitOpenGL();)
 +
 +
// OpenGLInit.c
 +
[code]
 +
 +
#ifdef GLES1
 +
#include <EGL/egl.h>
 +
#include <GLES/gl.h>
 +
#include <SDL/SDL_syswm.h>
 +
#else
 +
#include <GL/gl.h>
 +
#include <SDL/SDL.h>
 +
#endif
 +
 +
#include "OpenGLInit.h"
 +
 +
#ifdef GLES1
 +
EGLDisplay g_eglDisplay = 0;
 +
EGLConfig g_eglConfig = 0;
 +
EGLContext g_eglContext = 0;
 +
EGLSurface g_eglSurface = 0;
 +
#endif
 +
 +
// consts
 +
#define COLOURDEPTH_RED_SIZE  5
 +
#define COLOURDEPTH_GREEN_SIZE 6
 +
#define COLOURDEPTH_BLUE_SIZE 5
 +
#define COLOURDEPTH_DEPTH_SIZE 16
 +
 +
#ifdef GLES1
 +
static const EGLint g_configAttribs[] ={
 +
  EGL_RED_SIZE,      COLOURDEPTH_RED_SIZE,
 +
  EGL_GREEN_SIZE,    COLOURDEPTH_GREEN_SIZE,
 +
  EGL_BLUE_SIZE,    COLOURDEPTH_BLUE_SIZE,
 +
  EGL_DEPTH_SIZE, COLOURDEPTH_DEPTH_SIZE,
 +
  EGL_SURFACE_TYPE,        EGL_WINDOW_BIT,
 +
  EGL_RENDERABLE_TYPE,      EGL_OPENGL_ES_BIT,
 +
  EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
 +
  EGL_NONE
 +
  };
 +
#endif
 +
 +
/*===========================================================
 +
Initialise opengl settings. Call straight after SDL_SetVideoMode()
 +
===========================================================*/
 +
 +
int InitOpenGL()
 +
{
 +
#ifdef GLES1
 +
// use EGL to initialise GLES
 +
g_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
 +
if (g_eglDisplay == EGL_NO_DISPLAY)
 +
{
 +
printf("Unable to initialise EGL display.");
 +
return 0;
 +
}
 +
 +
// Initialise egl
 +
if (!eglInitialize(g_eglDisplay, NULL, NULL))
 +
{
 +
printf("Unable to initialise EGL display.");
 +
return 0;
 +
}
 +
 +
// Find a matching config
 +
EGLint numConfigsOut = 0;
 +
if (eglChooseConfig(g_eglDisplay, g_configAttribs, &g_eglConfig, 1, &numConfigsOut) != EGL_TRUE || numConfigsOut == 0)
 +
{
 +
fprintf(stderr, "Unable to find appropriate EGL config.");
 +
return 0;
 +
}
 +
 +
// Get the SDL window handle
 +
SDL_SysWMinfo sysInfo; //Will hold our Window information
 +
SDL_VERSION(&sysInfo.version); //Set SDL version
 +
if(SDL_GetWMInfo(&sysInfo) <= 0)
 +
{
 +
printf("Unable to get window handle");
 +
return 0;
 +
}
 +
 +
g_eglSurface = eglCreateWindowSurface(g_eglDisplay, g_eglConfig, (EGLNativeWindowType)sysInfo.info.x11.window, 0);
 +
if ( g_eglSurface == EGL_NO_SURFACE)
 +
{
 +
printf("Unable to create EGL surface!");
 +
return 0;
 +
}
 +
 +
// Bind GLES and create the context
 +
eglBindAPI(EGL_OPENGL_ES_API);
 +
EGLint contextParams[] = {EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE}; // Use GLES version 1.x
 +
g_eglContext = eglCreateContext(g_eglDisplay, g_eglConfig, NULL, NULL);
 +
if (g_eglContext == EGL_NO_CONTEXT)
 +
{
 +
printf("Unable to create GLES context!");
 +
return 0;
 +
}
 +
 +
if (eglMakeCurrent(g_eglDisplay,  g_eglSurface,  g_eglSurface, g_eglContext) == EGL_FALSE)
 +
{
 +
printf("Unable to make GLES context current");
 +
return 0;
 +
}
 +
 +
#else
 +
 +
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, COLOURDEPTH_RED_SIZE);
 +
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, COLOURDEPTH_GREEN_SIZE);
 +
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, COLOURDEPTH_BLUE_SIZE);
 +
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, COLOURDEPTH_DEPTH_SIZE);
 +
 +
#endif
 +
 +
return 1;
 +
}
 +
 +
/*======================================================
 +
* Kill off any opengl specific details
 +
  ====================================================*/
 +
void TerminateOpenGL()
 +
{
 +
#ifdef GLES1
 +
eglMakeCurrent(g_eglDisplay, NULL, NULL, EGL_NO_CONTEXT);
 +
eglDestroySurface(g_eglDisplay, g_eglSurface);
 +
eglDestroyContext(g_eglDisplay, g_eglContext);
 +
g_eglSurface = 0;
 +
g_eglContext = 0;
 +
g_eglConfig = 0;
 +
eglTerminate(g_eglDisplay);
 +
g_eglDisplay = 0;
 +
#endif
 +
}
 +
 +
 +
int SwapBuffers()
 +
{
 +
#ifdef GLES1
 +
eglSwapBuffers(g_eglDisplay, g_eglSurface);
 +
#else
 +
SDL_GL_SwapBuffers();
 +
#endif
 +
}
 +
[/code]
 +
  
 
[[Category:Development]]
 
[[Category:Development]]

Revision as of 22:05, 21 July 2010

There are two options for combining GLES and SDL:

1: Grab the modified version of SDL

There is a special SDL source code for pandora with OpenGL ES capability available here : http://github.com/Cpasjuste

The screen initialisation is now easy as this : SDL_SetVideoMode(800, 480, 16, SDL_OPENGLES)

An SDL/GLES exemple is also available on the git repository.

2: Use EGL

Sometimes its not best to use the modified version of SDl (when working on cross platform games). Instead you can use EGL to create the GLES graphics context for you. The following functions do just that.

Steps:

  1. 1- Make sure you call InitOpenGL() straight after creating the window (SDL_SetVideoMode()).
  2. 2- When using EGL you should not pass in the SDL_OPENGL flag to SDL_SetVideoMode(). SDL_HWSurface and SDL_SWSurface should do.
  3. 3- You will notice '#ifdef GLES1' around much of the EGL code. Simply define GLES1 in your preprocessor (-DGLES1 on the command line of gcc if i recall correctly?) to use GLES. Without the define SDL will be set up for standard OpenGL (I left it in as its useful for cross platform dev).
  4. 4 - Once you have finished with the window and just before terminating it call TerminateOpenGL() to clean up.

NOTE - If you call SDL_SetVideoMode more than once you will probably need to terminate and reset the context (TerminateOpenGL(); SDL_SetVideoMode(); InitOpenGL();)

// OpenGLInit.c [code]

  1. ifdef GLES1

#include <EGL/egl.h> #include <GLES/gl.h> #include <SDL/SDL_syswm.h>

  1. else

#include <GL/gl.h> #include <SDL/SDL.h>

  1. endif
  1. include "OpenGLInit.h"
  1. ifdef GLES1

EGLDisplay g_eglDisplay = 0; EGLConfig g_eglConfig = 0; EGLContext g_eglContext = 0; EGLSurface g_eglSurface = 0;

  1. endif

// consts

  1. define COLOURDEPTH_RED_SIZE 5
  2. define COLOURDEPTH_GREEN_SIZE 6
  3. define COLOURDEPTH_BLUE_SIZE 5
  4. define COLOURDEPTH_DEPTH_SIZE 16
  1. ifdef GLES1

static const EGLint g_configAttribs[] ={ EGL_RED_SIZE, COLOURDEPTH_RED_SIZE, EGL_GREEN_SIZE, COLOURDEPTH_GREEN_SIZE, EGL_BLUE_SIZE, COLOURDEPTH_BLUE_SIZE, EGL_DEPTH_SIZE, COLOURDEPTH_DEPTH_SIZE, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE, EGL_NONE };

  1. endif

/*=========================================================== Initialise opengl settings. Call straight after SDL_SetVideoMode() ===========================================================*/

int InitOpenGL() {

  1. ifdef GLES1

// use EGL to initialise GLES g_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (g_eglDisplay == EGL_NO_DISPLAY) { printf("Unable to initialise EGL display."); return 0; }

// Initialise egl if (!eglInitialize(g_eglDisplay, NULL, NULL)) { printf("Unable to initialise EGL display."); return 0; }

// Find a matching config EGLint numConfigsOut = 0; if (eglChooseConfig(g_eglDisplay, g_configAttribs, &g_eglConfig, 1, &numConfigsOut) != EGL_TRUE || numConfigsOut == 0) { fprintf(stderr, "Unable to find appropriate EGL config."); return 0; }

// Get the SDL window handle SDL_SysWMinfo sysInfo; //Will hold our Window information SDL_VERSION(&sysInfo.version); //Set SDL version if(SDL_GetWMInfo(&sysInfo) <= 0) { printf("Unable to get window handle"); return 0; }

g_eglSurface = eglCreateWindowSurface(g_eglDisplay, g_eglConfig, (EGLNativeWindowType)sysInfo.info.x11.window, 0); if ( g_eglSurface == EGL_NO_SURFACE) { printf("Unable to create EGL surface!"); return 0; }

// Bind GLES and create the context eglBindAPI(EGL_OPENGL_ES_API); EGLint contextParams[] = {EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE}; // Use GLES version 1.x g_eglContext = eglCreateContext(g_eglDisplay, g_eglConfig, NULL, NULL); if (g_eglContext == EGL_NO_CONTEXT) { printf("Unable to create GLES context!"); return 0; }

if (eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext) == EGL_FALSE) { printf("Unable to make GLES context current"); return 0; }

  1. else

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, COLOURDEPTH_RED_SIZE); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, COLOURDEPTH_GREEN_SIZE); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, COLOURDEPTH_BLUE_SIZE); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, COLOURDEPTH_DEPTH_SIZE);

  1. endif

return 1; }

/*======================================================

* Kill off any opengl specific details
 ====================================================*/

void TerminateOpenGL() {

  1. ifdef GLES1

eglMakeCurrent(g_eglDisplay, NULL, NULL, EGL_NO_CONTEXT); eglDestroySurface(g_eglDisplay, g_eglSurface); eglDestroyContext(g_eglDisplay, g_eglContext); g_eglSurface = 0; g_eglContext = 0; g_eglConfig = 0; eglTerminate(g_eglDisplay); g_eglDisplay = 0;

  1. endif

}


int SwapBuffers() {

  1. ifdef GLES1

eglSwapBuffers(g_eglDisplay, g_eglSurface);

  1. else

SDL_GL_SwapBuffers();

  1. endif

} [/code]