From: Javier S. Pedro Date: Tue, 2 Mar 2010 20:57:19 +0000 (+0100) Subject: GLESv2 sample working X-Git-Tag: sdlgles_1_0_0~6 X-Git-Url: http://vcs.maemo.org/git/?a=commitdiff_plain;ds=sidebyside;h=9bbb182d4a8bc119cd76f5325de1be4c7217f2ad;p=sdlhildon GLESv2 sample working --- diff --git a/sdlgles/src/SDL_gles.c b/sdlgles/src/SDL_gles.c index c28dfdf..551c7c5 100644 --- a/sdlgles/src/SDL_gles.c +++ b/sdlgles/src/SDL_gles.c @@ -55,6 +55,7 @@ static EGLint attrib_list[] = { EGL_RED_SIZE, 0, EGL_GREEN_SIZE, 0, EGL_BLUE_SIZE, 0, + EGL_LUMINANCE_SIZE, 0, EGL_ALPHA_SIZE, 0, EGL_CONFIG_CAVEAT, EGL_DONT_CARE, EGL_CONFIG_ID, EGL_DONT_CARE, @@ -62,6 +63,7 @@ static EGLint attrib_list[] = { EGL_LEVEL, 0, EGL_NATIVE_RENDERABLE, EGL_DONT_CARE, EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_SAMPLE_BUFFERS, 0, EGL_SAMPLES, 0, EGL_STENCIL_SIZE, 0, @@ -72,6 +74,12 @@ static EGLint attrib_list[] = { EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE, EGL_NONE }; +static EGLint context_attrib_list[] = { + EGL_CONTEXT_CLIENT_VERSION, 1, + EGL_NONE +}; +static const int attrib_list_size = (sizeof(attrib_list) / sizeof(EGLint)) / 2; +static const int context_attrib_list_size = (sizeof(context_attrib_list) / sizeof(EGLint)) / 2; static SDL_GLES_ContextPriv *cur_context = NULL; static const char * get_error_string(int error) { @@ -111,6 +119,47 @@ static const char * get_error_string(int error) { } } +static int set_egl_attrib(EGLenum attrib, EGLint value) +{ + const EGLint a = attrib; + int i; + for (i = 0; i < attrib_list_size; i++) { + if (attrib_list[i * 2] == a) { + attrib_list[(i*2)+1] = value; + return 0; + } + } + + return -1; +} + +static EGLint get_egl_attrib(EGLenum attrib) +{ + const EGLint a = attrib; + int i; + for (i = 0; i < attrib_list_size; i++) { + if (attrib_list[i * 2] == a) { + return attrib_list[(i*2)+1]; + } + } + + return -1; +} + +static int set_egl_context_attrib(EGLenum attrib, EGLint value) +{ + const EGLint a = attrib; + int i; + for (i = 0; i < context_attrib_list_size; i++) { + if (context_attrib_list[i * 2] == a) { + context_attrib_list[(i*2)+1] = value; + return 0; + } + } + + return -1; +} + int SDL_GLES_LoadLibrary(const char *path) { if (!path) { @@ -171,6 +220,22 @@ int SDL_GLES_Init(SDL_GLES_Version version) } gl_version = version; + switch (gl_version) { + case SDL_GLES_VERSION_1_1: + /* defaults are OK */ + break; + case SDL_GLES_VERSION_2_0: + /* by default, set egl renderable type attribute to GL ES 2 */ + res = set_egl_attrib(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT) == 0; + assert(res); + /* and request GL ES 2.0 contexts */ + res = set_egl_context_attrib(EGL_CONTEXT_CLIENT_VERSION, 2) == 0; + assert(res); + break; + default: + break; + } + return 0; } @@ -253,12 +318,19 @@ SDL_GLES_Context* SDL_GLES_CreateContext(void) if (!res || num_config < 1) { SDL_SetError("EGL failed to find any valid config with required attributes: %s", get_error_string(eglGetError())); + free(context); return NULL; } context->egl_config = configs[0]; context->egl_context = eglCreateContext(egl_display, configs[0], - EGL_NO_CONTEXT, NULL); + EGL_NO_CONTEXT, context_attrib_list); + if (context->egl_context == EGL_NO_CONTEXT) { + SDL_SetError("EGL failed to create context: %s", + get_error_string(eglGetError())); + free(context); + return NULL; + } return (SDL_GLES_Context*) context; } @@ -292,18 +364,21 @@ int SDL_GLES_MakeCurrent(SDL_GLES_Context* c) /* TODO Update attrib_list. Make SDL_GLES_GetAttribute work. */ - switch (gl_version) { - case SDL_GLES_VERSION_1_1: - case SDL_GLES_VERSION_2_0: - res = eglBindAPI(EGL_OPENGL_ES_API); - if (!res) { - SDL_SetError("EGL failed to bind the required API: %s", - get_error_string(eglGetError())); - return -2; - } - break; - default: - break; + if (cur_context) { + /* If selecting a new context, bind the required API. */ + switch (gl_version) { + case SDL_GLES_VERSION_1_1: + case SDL_GLES_VERSION_2_0: + res = eglBindAPI(EGL_OPENGL_ES_API); + if (!res) { + SDL_SetError("EGL failed to bind the required API: %s", + get_error_string(eglGetError())); + return -2; + } + break; + default: + break; + } } return 0; diff --git a/sdlgles/test/gles1.c b/sdlgles/test/gles1.c index 6d844f0..5425ecd 100644 --- a/sdlgles/test/gles1.c +++ b/sdlgles/test/gles1.c @@ -18,7 +18,7 @@ static SDL_Surface *screen; static SDL_GLES_Context *context; -static float box_step = 0.05f; +static float box_step = 0.025f; static const float w = 0.28f, h = 0.4f; static float x = -0.5f, y = 0.0f; @@ -76,9 +76,10 @@ int main() screen = SDL_SetVideoMode(0, 0, 16, SDL_SWSURFACE); assert(screen); + SDL_WM_SetCaption("SDLgles v1 test"); SDL_ShowCursor(SDL_DISABLE); - SDL_TimerID timer = SDL_AddTimer(50, tick, NULL); + SDL_TimerID timer = SDL_AddTimer(30, tick, NULL); assert(timer != NULL); context = SDL_GLES_CreateContext(); diff --git a/sdlgles/test/gles2.c b/sdlgles/test/gles2.c new file mode 100644 index 0000000..3e35e73 --- /dev/null +++ b/sdlgles/test/gles2.c @@ -0,0 +1,151 @@ +/* gles1 - a simple SDL_gles OpenGL|ES 1.1 sample + * + * This file is in the public domain, furnished "as is", without technical + * support, and with no warranty, express or implied, as to its usefulness for + * any purpose. + */ + +#include +#include +#include +#include + +#include +#include + +#include + +static SDL_Surface *screen; +static SDL_GLES_Context *context; + +static GLuint program; +static bool fullscreen = false; + +static GLuint compile_shader(GLenum type, const char *src) +{ + GLuint shader = glCreateShader(type); + GLint compiled; + + assert(shader != 0), + glShaderSource(shader, 1, &src, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + assert(compiled); + + return shader; +} + +static void init() +{ + const char vertex_shader_src[] = + "attribute vec4 pos;\n" + "void main()\n" + "{\n" + " gl_Position = pos;\n" + "}\n"; + + const char fragment_shader_src[] = + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n" + "}\n"; + + GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_src); + GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_src); + + program = glCreateProgram(); + assert(program); + + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + + glBindAttribLocation(program, 0, "pos"); + + GLint linked; + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &linked); + assert(linked); + + glClearColor(0.0f, 0.0f, 0.2f, 0.0f); +} + +static void render() +{ + GLfloat tri_v[] = {0.0f, 0.5f, 0.0f, + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f}; + + glViewport(0, 0, screen->w, screen->h); + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(program); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, tri_v); + glEnableVertexAttribArray(0); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + SDL_GLES_SwapBuffers(); +} + +static void toggle_fullscreen() +{ + int res; + + fullscreen = !fullscreen; + + screen = SDL_SetVideoMode(0, 0, 16, SDL_SWSURFACE | + (fullscreen ? SDL_FULLSCREEN : 0)); + assert(screen); + + res = SDL_GLES_SetVideoMode(); + if (res != 0) puts(SDL_GetError()); + assert(res == 0); + + render(); +} + +int main() +{ + int res; + res = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); + assert(res == 0); + + res = SDL_GLES_Init(SDL_GLES_VERSION_2_0); + assert(res == 0); + + screen = SDL_SetVideoMode(0, 0, 16, SDL_SWSURFACE); + assert(screen); + + SDL_WM_SetCaption("SDLgles v2 test"); + SDL_ShowCursor(SDL_DISABLE); + + context = SDL_GLES_CreateContext(); + if (!context) puts(SDL_GetError()); + assert(context); + + res = SDL_GLES_MakeCurrent(context); + assert(res == 0); + + init(); + render(); + + SDL_Event event; + while (SDL_WaitEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + goto quit; + case SDL_MOUSEBUTTONDOWN: + toggle_fullscreen(); + break; + } + } + +quit: + SDL_GLES_DeleteContext(context); + + SDL_GLES_Quit(); + SDL_Quit(); + + return 0; +}